# HG changeset patch # User Drew Perttula # Date 1496129802 0 # Node ID 30c79f1dc4f869bd09bbfe287d05734a7a80cf0a # Parent 1db548d395fb632e05bf108bff54afe7f3077b28 fix suggestPrefixes to send suggestions to rdfdb Ignore-this: 637142dcc1de97c9046d75d1396a9446 diff -r 1db548d395fb -r 30c79f1dc4f8 bin/effecteval --- 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): diff -r 1db548d395fb -r 30c79f1dc4f8 bin/rdfdb --- 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", diff -r 1db548d395fb -r 30c79f1dc4f8 light9/paint/capture.py --- 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): diff -r 1db548d395fb -r 30c79f1dc4f8 light9/rdfdb/graphfile.py --- 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 diff -r 1db548d395fb -r 30c79f1dc4f8 light9/rdfdb/syncedgraph.py --- 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): """