Mercurial > code > home > repos > light9
comparison bin/rdfdb @ 1045:c1face79c0e1
fix rdfdb's filename<->uri mapping system
Ignore-this: 2236b295035273370138943857894699
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Thu, 29 May 2014 06:46:18 +0000 |
parents | a4632a7b2e17 |
children | 473db8bebb8f |
comparison
equal
deleted
inserted
replaced
1044:a2081b9adfe4 | 1045:c1face79c0e1 |
---|---|
117 from light9 import networking, showconfig, prof | 117 from light9 import networking, showconfig, prof |
118 from rdflib import ConjunctiveGraph, URIRef, Graph | 118 from rdflib import ConjunctiveGraph, URIRef, Graph |
119 from light9.rdfdb.graphfile import GraphFile | 119 from light9.rdfdb.graphfile import GraphFile |
120 from light9.rdfdb.patch import Patch, ALLSTMTS | 120 from light9.rdfdb.patch import Patch, ALLSTMTS |
121 from light9.rdfdb.rdflibpatch import patchQuads | 121 from light9.rdfdb.rdflibpatch import patchQuads |
122 | 122 from light9.rdfdb.file_vs_uri import correctToTopdirPrefix, fileForUri, uriFromFile |
123 from light9.rdfdb.patchsender import sendPatch | 123 from light9.rdfdb.patchsender import sendPatch |
124 from light9.rdfdb.patchreceiver import makePatchEndpointPutMethod | 124 from light9.rdfdb.patchreceiver import makePatchEndpointPutMethod |
125 | 125 |
126 from twisted.internet.inotify import INotify | 126 from twisted.internet.inotify import INotify |
127 from run_local import log | 127 from run_local import log |
163 """ | 163 """ |
164 find files, notice new files. | 164 find files, notice new files. |
165 | 165 |
166 This object watches directories. Each GraphFile watches its own file. | 166 This object watches directories. Each GraphFile watches its own file. |
167 """ | 167 """ |
168 def __init__(self, topDirsToWatch, patch, getSubgraph): | 168 def __init__(self, dirUriMap, patch, getSubgraph): |
169 self.topDirsToWatch = topDirsToWatch | 169 self.dirUriMap = dirUriMap # {abspath : uri prefix} |
170 self.patch, self.getSubgraph = patch, getSubgraph | 170 self.patch, self.getSubgraph = patch, getSubgraph |
171 | 171 |
172 # files from cwd become uris starting with this. *should* be | |
173 # building uris from the show uri in $LIGHT9_SHOW/URI | |
174 # instead. Who wants to keep their data in the same dir tree | |
175 # as the source code?! | |
176 self.topUri = URIRef("http://light9.bigasterisk.com/") | |
177 | |
178 self.graphFiles = {} # context uri : GraphFile | 172 self.graphFiles = {} # context uri : GraphFile |
179 | 173 |
180 self.notifier = INotify() | 174 self.notifier = INotify() |
181 self.notifier.startReading() | 175 self.notifier.startReading() |
182 | 176 |
183 self.findAndLoadFiles() | 177 self.findAndLoadFiles() |
184 | 178 |
185 def findAndLoadFiles(self): | 179 def findAndLoadFiles(self): |
186 self.initialLoad = True | 180 self.initialLoad = True |
187 try: | 181 try: |
188 for topdir in self.topDirsToWatch: | 182 for topdir in self.dirUriMap: |
189 for dirpath, dirnames, filenames in os.walk(topdir): | 183 for dirpath, dirnames, filenames in os.walk(topdir): |
190 for base in filenames: | 184 for base in filenames: |
191 self.watchFile(os.path.join(dirpath, base)) | 185 self.watchFile(os.path.join(dirpath, base)) |
192 self.notifier.watch(FilePath(dirpath), autoAdd=True, | 186 self.notifier.watch(FilePath(dirpath), autoAdd=True, |
193 callbacks=[self.dirChange]) | 187 callbacks=[self.dirChange]) |
207 FilePath) because we use its exact relative form in the | 201 FilePath) because we use its exact relative form in the |
208 context URI | 202 context URI |
209 """ | 203 """ |
210 if not os.path.isfile(inFile): | 204 if not os.path.isfile(inFile): |
211 return | 205 return |
212 if not any(inFile.startswith(prefix) for prefix in self.topDirsToWatch): | 206 |
213 for prefix in self.topDirsToWatch: | 207 inFile = correctToTopdirPrefix(self.dirUriMap, inFile) |
214 prefixAbs = os.path.abspath(prefix) | |
215 if inFile.startswith(prefixAbs): | |
216 inFile = prefix + inFile[len(prefixAbs):] | |
217 break | |
218 else: | |
219 raise ValueError("can't correct %s to start with one of %s" % | |
220 (inFile, self.topDirsToWatch)) | |
221 if os.path.splitext(inFile)[1] not in ['.n3']: | 208 if os.path.splitext(inFile)[1] not in ['.n3']: |
222 return | 209 return |
223 | 210 |
224 # an n3 file with rules makes it all the way past this reading | 211 # an n3 file with rules makes it all the way past this reading |
225 # and the serialization. Then, on the receiving side, a | 212 # and the serialization. Then, on the receiving side, a |
233 # read into one file called config.n3. New versions won't read | 220 # read into one file called config.n3. New versions won't read |
234 # it. | 221 # it. |
235 if inFile.endswith("config.n3"): | 222 if inFile.endswith("config.n3"): |
236 return | 223 return |
237 | 224 |
238 ctx = self.uriFromFile(inFile) | 225 ctx = uriFromFile(self.dirUriMap, inFile) |
239 gf = GraphFile(self.notifier, inFile, ctx, | 226 gf = GraphFile(self.notifier, inFile, ctx, |
240 self.patch, self.getSubgraph) | 227 self.patch, self.getSubgraph) |
241 self.graphFiles[ctx] = gf | 228 self.graphFiles[ctx] = gf |
242 log.info("%s do initial read", inFile) | 229 log.info("%s do initial read", inFile) |
243 gf.reread() | 230 gf.reread() |
254 graph is still a reasonable thing to do, though. | 241 graph is still a reasonable thing to do, though. |
255 """ | 242 """ |
256 g = self.getSubgraph(ctx) | 243 g = self.getSubgraph(ctx) |
257 | 244 |
258 if ctx not in self.graphFiles: | 245 if ctx not in self.graphFiles: |
259 outFile = self.fileForUri(ctx) | 246 outFile = fileForUri(self.dirUriMap, ctx) |
260 log.info("starting new file %r", outFile) | 247 log.info("starting new file %r", outFile) |
261 self.graphFiles[ctx] = GraphFile(self.notifier, outFile, ctx, | 248 self.graphFiles[ctx] = GraphFile(self.notifier, outFile, ctx, |
262 self.patch, self.getSubgraph) | 249 self.patch, self.getSubgraph) |
263 | 250 |
264 def dirtyFiles(self, ctxs): | 251 def dirtyFiles(self, ctxs): |
272 """ | 259 """ |
273 for ctx in ctxs: | 260 for ctx in ctxs: |
274 g = self.getSubgraph(ctx) | 261 g = self.getSubgraph(ctx) |
275 self.graphFiles[ctx].dirty(g) | 262 self.graphFiles[ctx].dirty(g) |
276 | 263 |
277 def uriFromFile(self, filename): | |
278 assert filename.endswith('.n3'), filename | |
279 if not any(filename.startswith(t) for t in self.topDirsToWatch): | |
280 raise ValueError("filename %s doesn't start with any of %s" % | |
281 (filename, self.topDirsToWatch)) | |
282 return URIRef(self.topUri + filename[:-len('.n3')]) | |
283 | |
284 def fileForUri(self, ctx): | |
285 assert isinstance(ctx, URIRef), ctx | |
286 if not ctx.startswith(self.topUri): | |
287 raise ValueError("don't know what filename to use for %s" % ctx) | |
288 return ctx[len(self.topUri):] + ".n3" | |
289 | |
290 | 264 |
291 class Db(object): | 265 class Db(object): |
292 """ | 266 """ |
293 the master graph, all the connected clients, all the files we're watching | 267 the master graph, all the connected clients, all the files we're watching |
294 """ | 268 """ |
295 def __init__(self, topDirsToWatch): | 269 def __init__(self, dirUriMap): |
296 | 270 |
297 self.clients = [] | 271 self.clients = [] |
298 self.graph = ConjunctiveGraph() | 272 self.graph = ConjunctiveGraph() |
299 | 273 |
300 self.watchedFiles = WatchedFiles(topDirsToWatch, | 274 self.watchedFiles = WatchedFiles(dirUriMap, |
301 self.patch, self.getSubgraph) | 275 self.patch, self.getSubgraph) |
302 | 276 |
303 self.summarizeToLog() | 277 self.summarizeToLog() |
304 | 278 |
305 def patch(self, p, dueToFileChange=False): | 279 def patch(self, p, dueToFileChange=False): |
442 help="logging.DEBUG") | 416 help="logging.DEBUG") |
443 (options, args) = parser.parse_args() | 417 (options, args) = parser.parse_args() |
444 | 418 |
445 log.setLevel(logging.DEBUG if options.verbose else logging.INFO) | 419 log.setLevel(logging.DEBUG if options.verbose else logging.INFO) |
446 | 420 |
447 db = Db(topDirsToWatch=[os.environ['LIGHT9_SHOW']]) | 421 db = Db(dirUriMap={os.environ['LIGHT9_SHOW'].rstrip('/') + '/': |
422 URIRef('http://light9.bigasterisk.com/show/dance2014/')}) | |
448 | 423 |
449 from twisted.python import log as twlog | 424 from twisted.python import log as twlog |
450 twlog.startLogging(sys.stdout) | 425 twlog.startLogging(sys.stdout) |
451 | 426 |
452 port = 8051 | 427 port = 8051 |