annotate service/store/store.py @ 1434:3ec2ca0b63ff

fix download url separator Ignore-this: 2426fe3cc2f5fd30e5c9c87903fed4f4 darcs-hash:be42c3ea21d197f0ed222855aaad88253d477313
author drewp <drewp@bigasterisk.com>
date Sun, 11 Aug 2019 03:25:50 -0700
parents 1431cd58803d
children 92cb3245fdd1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1214
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
1 """
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
2 persistent store of rdf statements, meant for stmts from users.
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
3
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
4 API is not typical rdf: putting statments replaces existing (s,o)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
5 matches so there can be only one object at a time. Putting the special
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
6 object :unset clears the statement.
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
7 """
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
8
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
9 import sys, logging
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
10 from docopt import docopt
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
11 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
12 from rdfdb.patch import Patch
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
13 from rdflib import Namespace, URIRef, Literal, Graph
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
14 from rdflib.parser import StringInputSource
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
15 from twisted.internet import reactor
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
16 from twisted.python.filepath import FilePath
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
17 import cyclone.web
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
18
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
19 ROOM = Namespace('http://projects.bigasterisk.com/room/')
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
20
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
21 logging.basicConfig()
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
22 log = logging.getLogger()
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
23
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
24 CTX = ROOM['stored']
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
25
1261
1431cd58803d change port, put to /values, build updates
drewp <drewp@bigasterisk.com>
parents: 1214
diff changeset
26 class ValuesResource(cyclone.web.RequestHandler):
1214
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
27 def put(self):
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
28 arg = self.request.arguments
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
29 if arg.get('s') and arg.get('p'):
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
30 self._onQueryStringStatement(arg['s'][-1], arg['p'][-1], self.request.body)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
31 else:
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
32 self._onGraphBodyStatements(self.request.body, self.request.headers)
1261
1431cd58803d change port, put to /values, build updates
drewp <drewp@bigasterisk.com>
parents: 1214
diff changeset
33 post = put
1214
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
34 def _onQueryStringStatement(self, s, p, body):
1261
1431cd58803d change port, put to /values, build updates
drewp <drewp@bigasterisk.com>
parents: 1214
diff changeset
35 subj = URIRef(s)
1431cd58803d change port, put to /values, build updates
drewp <drewp@bigasterisk.com>
parents: 1214
diff changeset
36 pred = URIRef(p)
1214
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
37 turtleLiteral = self.request.body
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
38 try:
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
39 obj = Literal(float(turtleLiteral))
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
40 except ValueError:
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
41 obj = Literal(turtleLiteral)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
42 self._onStatements([(subj, pred, obj)])
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
43
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
44 def _onGraphBodyStatements(self, body, headers):
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
45 # maybe quads only so we can track who made the input and from what interface?
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
46 # Or your input of triples gets wrapped in a new quad in here?
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
47 g = Graph()
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
48 g.parse(StringInputSource(body), format='nt')
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
49 if not g:
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
50 raise ValueError("expected graph body")
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
51 self._onStatements(list(g.triples((None, None, None))))
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
52
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
53 def _onStatements(self, stmts):
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
54 g = self.settings.masterGraph
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
55 for s, p, o in stmts:
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
56 patch = g.getObjectPatch(CTX, s, p, o)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
57 if o == ROOM['unset']:
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
58 patch = Patch(delQuads=patch.delQuads)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
59 g.patch(patch)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
60 nquads = g.serialize(None, format='nquads')
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
61 self.settings.dbFile.setContent(nquads)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
62
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
63 if __name__ == '__main__':
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
64 arg = docopt("""
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
65 Usage: store.py [options]
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
66
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
67 -v Verbose
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
68 """)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
69 log.setLevel(logging.WARN)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
70 if arg['-v']:
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
71 from twisted.python import log as twlog
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
72 twlog.startLogging(sys.stdout)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
73 log.setLevel(logging.DEBUG)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
74
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
75 masterGraph = PatchableGraph()
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
76 dbFile = FilePath('/opt/homeauto_store/db.nquads')
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
77 if dbFile.exists():
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
78 masterGraph._graph.parse(dbFile.open(), format='nquads')
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
79
1261
1431cd58803d change port, put to /values, build updates
drewp <drewp@bigasterisk.com>
parents: 1214
diff changeset
80 port = 10015
1214
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
81 reactor.listenTCP(port, cyclone.web.Application([
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
82 (r"/()", cyclone.web.StaticFileHandler,
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
83 {"path": ".", "default_filename": "index.html"}),
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
84 (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}),
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
85 (r"/graph/events", CycloneGraphEventsHandler,
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
86 {'masterGraph': masterGraph}),
1261
1431cd58803d change port, put to /values, build updates
drewp <drewp@bigasterisk.com>
parents: 1214
diff changeset
87 (r'/values', ValuesResource),
1214
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
88 ], masterGraph=masterGraph, dbFile=dbFile, debug=arg['-v']),
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
89 interface='::')
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
90 log.warn('serving on %s', port)
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
91
c1792115b1d3 new 'store' service for user inputs
drewp <drewp@bigasterisk.com>
parents:
diff changeset
92 reactor.run()