changeset 1581:30c79f1dc4f8

fix suggestPrefixes to send suggestions to rdfdb Ignore-this: 637142dcc1de97c9046d75d1396a9446
author Drew Perttula <drewp@bigasterisk.com>
date Tue, 30 May 2017 07:36:42 +0000
parents 1db548d395fb
children d5761661ac31
files bin/effecteval bin/rdfdb light9/paint/capture.py light9/rdfdb/graphfile.py light9/rdfdb/syncedgraph.py
diffstat 5 files changed, 58 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/bin/effecteval	Tue May 30 06:14:49 2017 +0000
+++ b/bin/effecteval	Tue May 30 07:36:42 2017 +0000
@@ -72,7 +72,7 @@
         note, p = yield songNotePatch(self.settings.graph, dropped, song, event, ctx=song, note=note)
         
         self.settings.graph.patch(p)
-        self.settings.graph.suggestPrefixes({'song': URIRef(song + '/')})
+        self.settings.graph.suggestPrefixes(song, {'song': URIRef(song + '/')})
         self.write(json.dumps({'note': note}))
         
 class SongEffectsUpdates(cyclone.websocket.WebSocketHandler):
--- a/bin/rdfdb	Tue May 30 06:14:49 2017 +0000
+++ b/bin/rdfdb	Tue May 30 07:36:42 2017 +0000
@@ -180,7 +180,7 @@
 
     This object watches directories. Each GraphFile watches its own file.
     """
-    def __init__(self, dirUriMap, patch, getSubgraph, addlPrefixes=None):
+    def __init__(self, dirUriMap, patch, getSubgraph, addlPrefixes):
         self.dirUriMap = dirUriMap # {abspath : uri prefix}
         self.patch, self.getSubgraph = patch, getSubgraph
         self.addlPrefixes = addlPrefixes
@@ -239,10 +239,7 @@
             return
             
         ctx = uriFromFile(self.dirUriMap, inFile)
-        gf = GraphFile(self.notifier, inFile, ctx,
-                       self.patch, self.getSubgraph,
-                       addlPrefixes=self.addlPrefixes)
-        self.graphFiles[ctx] = gf
+        gf = self._addGraphFile(ctx, inFile)
         log.info("%s do initial read", inFile)
         gf.reread()
 
@@ -263,10 +260,19 @@
             outFile = fileForUri(self.dirUriMap, ctx)
             assert '//' not in outFile, (outFile, self.dirUriMap, ctx)
             log.info("starting new file %r", outFile)
-            self.graphFiles[ctx] = GraphFile(self.notifier, outFile, ctx,
-                                             self.patch, self.getSubgraph,
-                                             addlPrefixes=self.addlPrefixes)
+            self._addGraphFile(ctx, outFile)
 
+    def _addGraphFile(self, ctx, path):
+        self.addlPrefixes.setdefault(ctx, {})
+        self.addlPrefixes.setdefault(None, {})
+        gf = GraphFile(self.notifier, path, ctx,
+                       self.patch, self.getSubgraph,
+                       globalPrefixes=self.addlPrefixes[None],
+                       ctxPrefixes=self.addlPrefixes[ctx])
+        self.graphFiles[ctx] = gf 
+        return gf
+
+            
     def dirtyFiles(self, ctxs):
         """mark dirty the files that we watch in these contexts.
 
@@ -285,13 +291,14 @@
     """
     the master graph, all the connected clients, all the files we're watching
     """
-    def __init__(self, dirUriMap, addlPrefixes=None):
+    def __init__(self, dirUriMap, addlPrefixes):
       
         self.clients = []
         self.graph = ConjunctiveGraph()
 
         self.watchedFiles = WatchedFiles(dirUriMap,
-                                         self.patch, self.getSubgraph, addlPrefixes)
+                                         self.patch, self.getSubgraph,
+                                         addlPrefixes)
         
         self.summarizeToLog()
 
@@ -403,6 +410,12 @@
             traceback.print_exc()
             raise
             
+class Prefixes(PrettyErrorHandler, cyclone.web.RequestHandler):
+    def post(self):
+        suggestion = json.loads(self.request.body)
+        addlPrefixes = self.settings.db.watchedFiles.addlPrefixes
+        addlPrefixes.setdefault(URIRef(suggestion['ctx']), {}).update(suggestion['prefixes'])
+    
 _wsClientSerial = 0
 class WebsocketClient(cyclone.websocket.WebSocketHandler):
 
@@ -457,6 +470,8 @@
             path = path + ".html"
         cyclone.web.StaticFileHandler.get(self, path, *args, **kw)
 
+
+        
 if __name__ == "__main__":
     logging.basicConfig()
     log = logging.getLogger()
@@ -470,7 +485,15 @@
 
     db = Db(dirUriMap={os.environ['LIGHT9_SHOW'].rstrip('/') + '/':
                        showconfig.showUri() + '/'},
-            addlPrefixes={'show': URIRef(showconfig.showUri() + '/')})
+            addlPrefixes={None: {
+                'show': showconfig.showUri() + '/',
+                '': 'http://light9.bigasterisk.com/',
+                'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
+                'rdfs': 'http://www.w3.org/2000/01/rdf-schema#',
+                'xsd': 'http://www.w3.org/2001/XMLSchema#',
+                'effect': 'http://light9.bigasterisk.com/effect/',
+                'dev': 'http://light9.bigasterisk.com/device/',
+            }})
 
     from twisted.python import log as twlog
     twlog.startLogging(sys.stdout)
@@ -481,6 +504,7 @@
         (r'/patches', Patches),
         (r'/graphClients', GraphClients),
         (r'/syncedGraph', WebsocketClient),
+        (r'/prefixes', Prefixes),
 
         (r'/(.*)', NoExts,
          {"path" : "light9/rdfdb/web",
--- a/light9/paint/capture.py	Tue May 30 06:14:49 2017 +0000
+++ b/light9/paint/capture.py	Tue May 30 07:36:42 2017 +0000
@@ -15,7 +15,8 @@
         (uri, RDF.type, L9['LightSample'], ctx),
         (uri, L9['imagePath'], URIRef('/'.join([showconfig.showUri(), relOutPath])), ctx),
         ]))
-    graph.suggestPrefixes('cap', URIRef(uri.rsplit('/', 1)[0] + '/'))
+    graph.suggestPrefixes(ctx, {'cap': uri.rsplit('/', 1)[0] + '/',
+                                'showcap': showconfig.showUri() + '/capture/'})
     
 class CaptureLoader(object):
     def __init__(self, graph):
--- a/light9/rdfdb/graphfile.py	Tue May 30 06:14:49 2017 +0000
+++ b/light9/rdfdb/graphfile.py	Tue May 30 07:36:42 2017 +0000
@@ -9,7 +9,7 @@
 log = logging.getLogger('graphfile')
 iolog = logging.getLogger('io')
 
-def patchN3SerializerToUseLessWhitespace():
+def patchN3SerializerToUseLessWhitespace(cutColumn=65):
     # todo: make a n3serializer subclass with whitespace settings
     from rdflib.plugins.serializers.turtle import TurtleSerializer, OBJECT
     originalWrite = TurtleSerializer.write
@@ -31,7 +31,7 @@
         for predicate in propList[1:]:
             self.write(';')
             # can't do proper wrapping since we don't know how much is coming
-            if self._column > 50:
+            if self._column > cutColumn:
                 self.write('\n' + self.indent(1))
             self.verb(predicate, newline=False)
             self.objectList(properties[predicate])
@@ -63,29 +63,24 @@
     """
     one rdf file that we read from, write to, and notice external changes to
     """
-    def __init__(self, notifier, path, uri, patch, getSubgraph, addlPrefixes=None):
+    def __init__(self, notifier, path, uri, patch, getSubgraph, globalPrefixes, ctxPrefixes):
         """
         uri is the context for the triples in this file. We assume
         sometimes that we're the only ones with triples in this
         context.
         
         this does not include an initial reread() call
+
+        Prefixes are mutable dicts. The caller may add to them later.
         """
         self.path, self.uri = path, uri
         self.patch, self.getSubgraph = patch, getSubgraph
 
         self.lastWriteTimestamp = 0 # mtime from the last time _we_ wrote
 
-        self.namespaces = {
-            '': 'http://light9.bigasterisk.com/',
-            'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
-            'rdfs': 'http://www.w3.org/2000/01/rdf-schema#',
-            'xsd': 'http://www.w3.org/2001/XMLSchema#',
-            'effect': 'http://light9.bigasterisk.com/effect/',
-            'dev': 'http://light9.bigasterisk.com/device/',
-        }
-        if addlPrefixes:
-            self.namespaces.update(addlPrefixes)
+        self.globalPrefixes = globalPrefixes
+        self.ctxPrefixes = ctxPrefixes
+        self.readPrefixes = {}
         
         if not os.path.exists(path):
             # can't start notify until file exists
@@ -187,7 +182,7 @@
                 return
 
             new.parse(location=self.path, format='n3')
-            self.namespaces.update(dict(new.namespaces()))
+            self.readPrefixes = dict(new.namespaces())
         except SyntaxError as e:
             print e
             traceback.print_exc()
@@ -239,7 +234,9 @@
         tmpOut = self.path + ".rdfdb-temp"
         f = open(tmpOut, 'w')
         t1 = time.time()
-        for p, n in self.namespaces.items():
+        for p, n in (self.globalPrefixes.items() +
+                     self.readPrefixes.items() +
+                     self.ctxPrefixes.items()):
             self.graphToWrite.bind(p, n)
         self.graphToWrite.serialize(destination=f, format='n3')
         serializeTime = time.time() - t1
--- a/light9/rdfdb/syncedgraph.py	Tue May 30 06:14:49 2017 +0000
+++ b/light9/rdfdb/syncedgraph.py	Tue May 30 07:36:42 2017 +0000
@@ -19,6 +19,7 @@
 from rdflib import ConjunctiveGraph
 import logging, cyclone.httpclient, traceback
 from twisted.internet import defer
+import treq, json
 log = logging.getLogger('syncedgraph')
 from light9.rdfdb.rdflibpatch import patchQuads
 
@@ -125,10 +126,13 @@
         self._sender.sendPatch(p).addErrback(self.sendFailed)
         log.debug('patch is done %s', debugKey)
 
-    def suggestPrefixes(self, prefixes):
-        if not hasattr(self, 'addlPrefixes'):
-            self.addlPrefixes = {}
-        self.addlPrefixes.update(prefixes)
+    def suggestPrefixes(self, ctx, prefixes):
+        """
+        when writing files for this ctx, try to use these n3
+        prefixes. async, not guaranteed to finish before any
+        particular file flush
+        """
+        treq.post(self.rdfdbRoot + 'prefixes', json.dumps({'ctx': ctx, 'prefixes': prefixes}))
 
     def sendFailed(self, result):
         """