Mercurial > code > home > repos > homeauto
view service/store/store.py @ 1453:ea942d383f62
index page is a data browser. support for -v
Ignore-this: cbe181b141420e0d6872203e4738f86f
darcs-hash:ddf89fabcec49046d70987597a5b421a415e2335
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Wed, 25 Sep 2019 17:29:12 -0700 |
parents | 1431cd58803d |
children | 281be4651a2f |
line wrap: on
line source
""" persistent store of rdf statements, meant for stmts from users. API is not typical rdf: putting statments replaces existing (s,o) matches so there can be only one object at a time. Putting the special object :unset clears the statement. """ import sys, logging from docopt import docopt from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler from rdfdb.patch import Patch from rdflib import Namespace, URIRef, Literal, Graph from rdflib.parser import StringInputSource from twisted.internet import reactor from twisted.python.filepath import FilePath import cyclone.web from standardservice.logsetup import log, verboseLogging ROOM = Namespace('http://projects.bigasterisk.com/room/') CTX = ROOM['stored'] class ValuesResource(cyclone.web.RequestHandler): def put(self): arg = self.request.arguments if arg.get('s') and arg.get('p'): self._onQueryStringStatement(arg['s'][-1], arg['p'][-1], self.request.body) else: self._onGraphBodyStatements(self.request.body, self.request.headers) post = put def _onQueryStringStatement(self, s, p, body): subj = URIRef(s) pred = URIRef(p) turtleLiteral = self.request.body try: obj = Literal(float(turtleLiteral)) except ValueError: obj = Literal(turtleLiteral) self._onStatements([(subj, pred, obj)]) def _onGraphBodyStatements(self, body, headers): # maybe quads only so we can track who made the input and from what interface? # Or your input of triples gets wrapped in a new quad in here? g = Graph() g.parse(StringInputSource(body), format='nt') if not g: raise ValueError("expected graph body") self._onStatements(list(g.triples((None, None, None)))) def _onStatements(self, stmts): g = self.settings.masterGraph for s, p, o in stmts: patch = g.getObjectPatch(CTX, s, p, o) if o == ROOM['unset']: patch = Patch(delQuads=patch.delQuads) g.patch(patch) nquads = g.serialize(None, format='nquads') self.settings.dbFile.setContent(nquads) if __name__ == '__main__': arg = docopt(""" Usage: store.py [options] -v Verbose """) verboseLogging(arg['-v']) masterGraph = PatchableGraph() dbFile = FilePath('/opt/homeauto_store/db.nquads') if dbFile.exists(): masterGraph._graph.parse(dbFile.open(), format='nquads') port = 10015 reactor.listenTCP(port, cyclone.web.Application([ (r"/()", cyclone.web.StaticFileHandler, {"path": ".", "default_filename": "index.html"}), (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}), (r"/graph/events", CycloneGraphEventsHandler, {'masterGraph': masterGraph}), (r'/values', ValuesResource), ], masterGraph=masterGraph, dbFile=dbFile, debug=arg['-v']), interface='::') log.warn('serving on %s', port) reactor.run()