Mercurial > code > home > repos > homeauto
annotate service/store/store.py @ 1261:1431cd58803d
change port, put to /values, build updates
Ignore-this: 8ebe7c9293d7ae47f6de73677053cafb
darcs-hash:d871c2ddabe6bf403fc15c7f56a7325a98d45b71
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sat, 20 Apr 2019 23:30:31 -0700 |
parents | c1792115b1d3 |
children | 92cb3245fdd1 |
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() |