Changeset - 1ba1d46a70a2
[Not reviewed]
default
0 4 0
Drew Perttula - 8 years ago 2017-05-24 08:26:39
drewp@bigasterisk.com
put song: prefix into song files
Ignore-this: 50e8d3947e925aa3edff31ed9d893b50
4 files changed with 14 insertions and 8 deletions:
0 comments (0 inline, 0 general)
bin/effecteval
Show inline comments
 
@@ -59,24 +59,25 @@ class SongEffects(PrettyErrorHandler, cy
 

	
 
        try:
 
            song = URIRef(self.get_argument('uri'))
 
        except Exception: # which?
 
            song = yield currentSong()
 

	
 
        event = self.get_argument('event', default='default')
 
            
 
        log.info("adding to %s", song)
 

	
 
        p = yield songEffectPatch(self.settings.graph, dropped, song, event, ctx=song)
 
        self.settings.graph.patch(p)
 
        self.settings.graph.suggestPrefixes({'song': URIRef(song + '/')})
 
        
 
class SongEffectsUpdates(cyclone.websocket.WebSocketHandler):
 
    def connectionMade(self, *args, **kwargs):
 
        self.graph = self.settings.graph
 
        self.graph.addHandler(self.updateClient)
 
        
 
    def updateClient(self):
 
        # todo: abort if client is gone
 
        playlist = self.graph.value(showconfig.showUri(), L9['playList'])
 
        songs = list(self.graph.items(playlist))
 
        out = []
 
        for s in songs:
bin/rdfdb
Show inline comments
 
@@ -171,27 +171,28 @@ class WsClient(object):
 
        return "<WsClient %s>" % self.updateUri
 

	
 
    def sendPatch(self, p):
 
        self.sendMessage(p.makeJsonRepr())
 
        return defer.succeed(None)
 
        
 
class WatchedFiles(object):
 
    """
 
    find files, notice new files.
 

	
 
    This object watches directories. Each GraphFile watches its own file.
 
    """
 
    def __init__(self, dirUriMap, patch, getSubgraph):
 
    def __init__(self, dirUriMap, patch, getSubgraph, addlPrefixes=None):
 
        self.dirUriMap = dirUriMap # {abspath : uri prefix}
 
        self.patch, self.getSubgraph = patch, getSubgraph
 
        self.addlPrefixes = addlPrefixes
 
        
 
        self.graphFiles = {} # context uri : GraphFile
 
        
 
        self.notifier = INotify()
 
        self.notifier.startReading()
 
        
 
        self.findAndLoadFiles()
 

	
 
    def findAndLoadFiles(self):
 
        self.initialLoad = True
 
        try:
 
            for topdir in self.dirUriMap:
 
@@ -230,74 +231,76 @@ class WatchedFiles(object):
 
        # yet.
 
        if '-rules' in inFile:
 
            return
 

	
 
        # for legacy versions, compile all the config stuff you want
 
        # read into one file called config.n3. New versions won't read
 
        # it.
 
        if inFile.endswith("config.n3"):
 
            return
 
            
 
        ctx = uriFromFile(self.dirUriMap, inFile)
 
        gf = GraphFile(self.notifier, inFile, ctx,
 
                       self.patch, self.getSubgraph)
 
                       self.patch, self.getSubgraph,
 
                       addlPrefixes=self.addlPrefixes)
 
        self.graphFiles[ctx] = gf
 
        log.info("%s do initial read", inFile)
 
        gf.reread()
 

	
 
    def aboutToPatch(self, ctx):
 
        """
 
        warn us that a patch is about to come to this context. it's more
 
        straightforward to create the new file now
 

	
 
        this is meant to make the file before we add triples, so we
 
        wouldn't see the blank file and lose those triples. But it
 
        didn't work, so there are other measures that make us not lose
 
        the triples from a new file. Calling this before patching the
 
        graph is still a reasonable thing to do, though.
 
        """
 
        g = self.getSubgraph(ctx)
 

	
 
        if ctx not in self.graphFiles:
 
            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)
 
                                             self.patch, self.getSubgraph,
 
                                             addlPrefixes=self.addlPrefixes)
 

	
 
    def dirtyFiles(self, ctxs):
 
        """mark dirty the files that we watch in these contexts.
 

	
 
        the ctx might not be a file that we already read; it might be
 
        for a new file we have to create, or it might be for a
 
        transient context that we're not going to save
 

	
 
        if it's a ctx with no file, error
 
        """
 
        for ctx in ctxs:
 
            g = self.getSubgraph(ctx)
 
            self.graphFiles[ctx].dirty(g)
 

	
 
        
 
class Db(object):
 
    """
 
    the master graph, all the connected clients, all the files we're watching
 
    """
 
    def __init__(self, dirUriMap):
 
    def __init__(self, dirUriMap, addlPrefixes=None):
 
      
 
        self.clients = []
 
        self.graph = ConjunctiveGraph()
 

	
 
        self.watchedFiles = WatchedFiles(dirUriMap,
 
                                         self.patch, self.getSubgraph)
 
                                         self.patch, self.getSubgraph, addlPrefixes)
 
        
 
        self.summarizeToLog()
 

	
 
    def patch(self, p, dueToFileChange=False):
 
        """
 
        apply this patch to the master graph then notify everyone about it
 

	
 
        dueToFileChange if this is a patch describing an edit we read
 
        *from* the file (such that we shouldn't write it back to the file)
 

	
 
        if p has a senderUpdateUri attribute, we won't send this patch
 
        back to the sender with that updateUri
 
@@ -457,25 +460,26 @@ class NoExts(cyclone.web.StaticFileHandl
 
if __name__ == "__main__":
 
    logging.basicConfig()
 
    log = logging.getLogger()
 

	
 
    parser = optparse.OptionParser()
 
    parser.add_option("-v", "--verbose", action="store_true",
 
                      help="logging.DEBUG")
 
    (options, args) = parser.parse_args()
 

	
 
    log.setLevel(logging.DEBUG if options.verbose else logging.INFO)
 

	
 
    db = Db(dirUriMap={os.environ['LIGHT9_SHOW'].rstrip('/') + '/':
 
                       showconfig.showUri() + '/'})
 
                       showconfig.showUri() + '/'},
 
            addlPrefixes={'show': URIRef(showconfig.showUri() + '/')})
 

	
 
    from twisted.python import log as twlog
 
    twlog.startLogging(sys.stdout)
 

	
 
    reactor.listenTCP(networking.rdfdb.port, cyclone.web.Application(handlers=[
 
        (r'/live', Live),
 
        (r'/graph', GraphResource),
 
        (r'/patches', Patches),
 
        (r'/graphClients', GraphClients),
 
        (r'/syncedGraph', WebsocketClient),
 

	
 
        (r'/(.*)', NoExts,
light9/rdfdb/graphfile.py
Show inline comments
 
@@ -54,45 +54,47 @@ def patchN3SerializerToUseLessWhitespace
 
        originalStatement(self, subject)
 
        return False         #  suppress blank line for 'minor' statements
 
    TurtleSerializer.statement = statement
 
    TurtleSerializer.predicateList = predicateList
 
    TurtleSerializer.objectList = objectList
 

	
 
patchN3SerializerToUseLessWhitespace()
 

	
 
class GraphFile(object):
 
    """
 
    one rdf file that we read from, write to, and notice external changes to
 
    """
 
    def __init__(self, notifier, path, uri, patch, getSubgraph):
 
    def __init__(self, notifier, path, uri, patch, getSubgraph, addlPrefixes=None):
 
        """
 
        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
 
        """
 
        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)
 
        
 
        if not os.path.exists(path):
 
            # can't start notify until file exists
 
            try:
 
                os.makedirs(os.path.dirname(path))
 
            except OSError:
 
                pass
 
            f = open(path, "w")
 
            f.write("#new\n")
 
            f.close()
 
            iolog.info("%s created", path)
 
            # this was supposed to cut out some extra reads but it
light9/rdfdb/syncedgraph.py
Show inline comments
 
@@ -117,25 +117,24 @@ class SyncedGraph(CurrentStateGraphApi, 
 
                       perfect=True)
 
        except ValueError as e:
 
            log.error(e)
 
            self.sendFailed(None)
 
            return
 
        log.debug('runDepsOnNewPatch')
 
        self.runDepsOnNewPatch(p)
 
        log.debug('sendPatch')
 
        self._sender.sendPatch(p).addErrback(self.sendFailed)
 
        log.debug('patch is done %s', debugKey)
 

	
 
    def suggestPrefixes(self, prefixes):
 
        song note edit should put song: to the song uri
 
        self.addlPrefixes.update(prefixes)
 

	
 
    def sendFailed(self, result):
 
        """
 
        we asked for a patch to be queued and sent to the master, and
 
        that ultimately failed because of a conflict
 
        """
 
        log.warn("sendFailed")
 
        self.resync()
 
        
 
        #i think we should receive back all the pending patches,
 
        #do a resync here,
0 comments (0 inline, 0 general)