Changeset - e703b3434dbd
[Not reviewed]
bin/effecteval
Show inline comments
 
@@ -15,24 +15,25 @@ from light9.curvecalc.curve import Curve
 
from light9.effecteval.effect import EffectNode
 
from light9.effecteval.effectloop import makeEffectLoop
 
from light9.greplin_cyclone import StatsForCyclone
 
from light9.namespaces import L9, RDF, RDFS
 
from light9.rdfdb.patch import Patch
 
from light9.rdfdb.syncedgraph import SyncedGraph
 
from greplin import scales
 

	
 
from lib.cycloneerr import PrettyErrorHandler
 

	
 
class EffectEdit(PrettyErrorHandler, cyclone.web.RequestHandler):
 
    def get(self):
 
        self.set_header('Content-Type', 'text/html')        
 
        self.write(open("light9/effecteval/effect.html").read())
 
    def delete(self):
 
        graph = self.settings.graph
 
        uri = URIRef(self.get_argument('uri'))
 
        with graph.currentState(tripleFilter=(None, L9['effect'], uri)) as g:
 
            song = ctx = list(g.subjects(L9['effect'], uri))[0]
 
        self.settings.graph.patch(Patch(delQuads=[
 
            (song, L9['effect'], uri, ctx),
 
            ]))
 
        
 
def clamp(x, lo, hi):
 
    return max(lo, min(hi, x))
bin/homepageConfig
Show inline comments
 
@@ -9,17 +9,28 @@ from twisted.internet import reactor
 

	
 
graph = SyncedGraph(networking.rdfdb.url, "homepageConfig")
 

	
 
@graph.initiallySynced.addCallback
 
def printConfig(result):
 
    with graph.currentState() as current:
 
        netHome = current.value(showconfig.showUri(), L9['networking'])
 
        for role, server in current.predicate_objects(netHome):
 
            if not server.startswith('http'):
 
                continue
 
            path = current.value(role, L9['urlPath'])
 
            server = server.rstrip('/')
 
            print "location /%(path)s { proxy_pass %(server)s; rewrite /[^/]+/(.*) /$1 break; }" % vars()
 
            print """
 
            location /%(path)s {
 

	
 
              # for websocket
 
              proxy_http_version 1.1;
 
              proxy_set_header Upgrade $http_upgrade;
 
              proxy_set_header Connection "upgrade";
 
              proxy_set_header Host $host;
 

	
 
              proxy_pass %(server)s;
 
              rewrite /[^/]+/(.*) /$1 break;
 
            }""" % vars()
 

	
 
    reactor.stop()
 

	
 
reactor.run()
bin/subserver
Show inline comments
 
@@ -106,25 +106,25 @@ def newestImage(subject):
 
        if created > newest[0]:
 
            newest = (created, img)
 
    return newest[1]
 
        
 
if __name__ == "__main__":
 
    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)
 

	
 
    graph = SyncedGraph(networking.rdfdb.url, "subserver")
 
    graph = SyncedGraph(networking.rdfdb.url, "subServer")
 

	
 
    d = {}
 
    def updateSubs():
 
        subs = []
 
        for sub in sorted(graph.subjects(RDF.type, L9['Submaster'])):
 
            rec = {'uri' : sub}
 
            rec['isLocal'] = graph.contains((sub, RDF.type,
 
                                             L9['LocalSubmaster']))
 
            rec['label'] = graph.label(sub)
 
            rec['img'] = newestImage(sub)
 
            subs.append(rec)
 
        
 
@@ -137,23 +137,23 @@ if __name__ == "__main__":
 
            d['chases'].append({
 
                'uri': chase,
 
                'label': fakeLabel,
 
            })
 
        
 
        sendToLiveClients(d=d)
 
    def onNewClient():
 
        sendToLiveClients(d=d)
 
        
 
    graph.addHandler(updateSubs)
 
    
 
    
 
    port = 8052
 
    port = networking.subServer.port
 
    reactor.listenTCP(port, cyclone.web.Application(handlers=[
 
        (r'/live', Live),
 
        (r'/effectsUpdates', EffectsUpdates),
 
        (r'/snapshot', Snapshot),
 
        (r'/(.*)', Static,
 
         {"path" : "light9/subserver",
 
          "default_filename" : "index.jade"}),
 
        ], debug=True, graph=graph, onNewClient=onNewClient))
 
    log.info("serving on %s" % port)
 
    reactor.run()
light9/effecteval/effect.coffee
Show inline comments
 
qs = new QueryString()
 
model =
 
  toSave: 
 
    uri: ko.observable(qs.value('uri'))
 
    codeLines: ko.observableArray([])
 
  
 
socket = reconnectingWebSocket "ws://localhost:8070/effectUpdates" + window.location.search, (msg) ->
 
socket = reconnectingWebSocket "../effectUpdates" + window.location.search, (msg) ->
 
  console.log('effectData ' + JSON.stringify(msg))
 
  model.toSave.codeLines(msg.codeLines.map((x) -> {text: ko.observable(x)})) if msg.codeLines?
 

	
 
model.saveCode = ->
 
  $.ajax
 
    type: 'PUT'
 
    url: 'code'
 
    data: ko.toJS(model.toSave)
 

	
 
writeBack = ko.computed(model.saveCode)
 
  
 
ko.applyBindings(model)
light9/effecteval/effect.html
Show inline comments
 
<!doctype html>
 
<html>
 
  <head>
 
    <title>effect</title>
 
    <meta charset="utf-8" />
 
    <link rel="stylesheet" href="/style.css">
 

	
 
  </head>
 
  <body>
 
    <div id="status">starting...</div>
 

	
 
    <a href="./">Effects</a> / <a class="effect" data-bind="attr: {href: toSave.uri}, text: toSave.uri"></a>
 

	
 
    <div data-bind="foreach: toSave.codeLines">
 
      <div>
 
        code:
 
        <input type="text" size="160" data-bind="value: text"></input>
 
      </div>
 
    </div>
 
    
 
    <script src="/lib/jquery-2.1.1.min.js"></script>
 
    <script src="/lib/knockout-3.1.0.js"></script>
 
    <script src="/websocket.js"></script>
light9/effecteval/index.coffee
Show inline comments
 
@@ -12,25 +12,25 @@ model.drop = (uri, event) ->
 
model.focusSong = (song) ->
 
  window.location.search = '?song=' + song.uri
 

	
 
dropped = (songTargetUri, dropUri) ->
 
  $.post('songEffects', {uri: songTargetUri, drop: dropUri})
 

	
 
deleteEffect = (uri) ->
 
  $.ajax
 
    type: 'DELETE'
 
    url: 'effect?' + $.param({uri: uri})
 
  console.log("del", uri)
 
  
 
reconnectingWebSocket "ws://localhost:8070/songEffectsUpdates", (msg) ->
 
reconnectingWebSocket "songEffectsUpdates", (msg) ->
 
  for s in msg.songs
 
    for e in s.effects
 
      do (e) ->
 
        e.deleteEffect = -> deleteEffect(e.uri)
 

	
 

	
 
  m = window.location.search.match(/song=(http[^&]+)/)
 
  if m
 
    model.songs((s for s in msg.songs when s.uri == m[1]))
 
  else
 
    model.songs(msg.songs)
 
  
light9/effecteval/index.html
Show inline comments
 
<!doctype html>
 
<html>
 
  <head>
 
    <title>effecteval</title>
 
    <meta charset="utf-8" />
 
    <link rel="stylesheet" href="/style.css">
 
  </head>
 
  <body>
 
    <div id="status">starting...</div>
 
    <div><a href="stats">/stats</a></div>
 
    <h1>Effect instances</h1>
 
    <div><a href=".">View all songs</a></div>
 
    <!-- subscribe to a query of all effects and their songs -->
 
    <ul data-bind="foreach: songs">
 
      <li>
 
        <a class="song" data-bind="attr: {href: uri}, click: $root.focusSong">Song <span data-bind="text: label"></span></a>
 
        <ul>
 
          <!-- ko foreach: effects -->
 
          <li>
 
            <a class="effect" data-bind="attr: {href: 'effect?'+jQuery.param({uri: uri})}, text: label"></a> <button data-bind="click: deleteEffect">Delete</button>
 
          </li>
light9/networking.py
Show inline comments
 
@@ -26,24 +26,25 @@ class ServiceAddress(object):
 
        _, netloc, _, _, _, _ = urlparse(self._url())
 
        host, port = splitport(netloc)
 
        return host
 

	
 
    @property
 
    def url(self):
 
        return self._url()
 
    value = url
 
    
 
    def path(self, more):
 
        return self.url + str(more)
 

	
 
curveCalc = ServiceAddress(L9['curveCalc'])
 
dmxServer = ServiceAddress(L9['dmxServer'])
 
oscDmxServer = ServiceAddress(L9['oscDmxServer'])
 
musicPlayer = ServiceAddress(L9['musicPlayer'])
 
effectEval = ServiceAddress(L9['effectEval'])
 
keyboardComposer = ServiceAddress(L9['keyboardComposer'])
 
curveCalc = ServiceAddress(L9['curveCalc'])
 
vidref = ServiceAddress(L9['vidref'])
 
effectEval = ServiceAddress(L9['effectEval'])
 
musicPlayer = ServiceAddress(L9['musicPlayer'])
 
oscDmxServer = ServiceAddress(L9['oscDmxServer'])
 
picamserve = ServiceAddress(L9['picamserve'])
 
rdfdb = ServiceAddress(L9['rdfdb'])
 
subComposer = ServiceAddress(L9['subComposer'])
 
subServer = ServiceAddress(L9['subServer'])
 
vidref = ServiceAddress(L9['vidref'])
 

	
 
patchReceiverUpdateHost = ServiceAddress(L9['patchReceiverUpdateHost'])
light9/rdfdb/web/graphView.xhtml
Show inline comments
 
@@ -4,25 +4,25 @@
 
<html xmlns="http://www.w3.org/1999/xhtml">
 
  <head>
 
    <title>graphview</title>
 
    <link rel="stylesheet" type="text/css" href="/style.css"/>
 

	
 
  </head>
 
  <body>
 
    <!--
 
        this page is another graph client who maintains the whole
 
        graph all the time
 
    -->
 

	
 
    <p>status: <span id="status">starting...</span></p>
 
    <div id="status">starting...</div>
 

	
 
    <fieldset>
 
      <legend>Messages</legend>
 
      <div id="out"></div>
 
    </fieldset>
 

	
 
    <p>URI substring: <input type="text" id="uriSubstring"/></p>
 

	
 
    <table>
 
      <thead>
 
        <tr>
 
          <th>subject</th> <th>predicate</th> <th>object</th> <th>context</th>
light9/rdfdb/web/index.xhtml
Show inline comments
 
<?xml version="1.0" encoding="utf8"?>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
 
  <head>
 
    <title>rdfdb</title>
 
    <link rel="stylesheet" type="text/css" href="/style.css"/>
 
  </head>
 
  <body>
 
    <h1>rdfdb</h1>
 
    <p>status: <span id="status">starting...</span></p>
 
    <div id="status">starting...</div>
 
    
 
    <section>
 
      <h2>Edits</h2>
 
      <div id="patches"></div>
 
    </section>
 

	
 
    <p>Clients: <span id="clients"/></p>
 

	
 
    <fieldset>
 
      <legend>Messages</legend>
 
      <div id="out"></div>
 
    </fieldset>
 
@@ -43,19 +43,19 @@
 
              }
 
              if (d.patch !== undefined) {
 
                  $("#patches").prepend(
 
                      $("<fieldset>").addClass("patch")
 
                          .append($("<legend>").text("Patch"))
 
                          .append($("<div>").addClass("deletes").text(collapseCuries(d.patch.deletes)))
 
                          .append($("<div>").addClass("adds").text(collapseCuries(d.patch.adds)))
 
                  );
 
              }
 

	
 
              $('#out').append($('<div>').text(JSON.stringify(d)));
 
          }
 
          reconnectingWebSocket("ws://localhost:8051/live", onMessage);
 
          reconnectingWebSocket("live", onMessage);
 
      });
 
      // ]]>
 
    </script>
 

	
 
  </body>
 
</html>
light9/rdfdb/web/syncedgraph.js
Show inline comments
 
@@ -14,14 +14,14 @@ function SyncedGraph(label) {
 
    self.nodesWithSubstring = function (subString) {
 

	
 
    }
 
    self.quads = function (s, p, o, c) {
 
        // any args can be null for wildcard
 
    }
 

	
 

	
 
    function onMessage(d) {
 
        $('#out').append($('<div>').text(JSON.stringify(d)));
 
    }
 
    
 
    reconnectingWebSocket("ws://localhost:8051/liveSyncedGraph", onMessage);
 
    reconnectingWebSocket("liveSyncedGraph", onMessage);
 
}
light9/subcomposer/index.html
Show inline comments
 
@@ -35,25 +35,25 @@
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f2">f2</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f3">f3</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f4-pool-l">f4-pool-l</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f5-fill">f5-fill</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/sharlyn">sharlyn</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f7">f7</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f8-fill">f8-fill</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f9-pool-r">f9-pool-r</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f10">f10</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f11-blue">f11-blue</button>
 
    <button data-chan="http://light9.bigasterisk.com/theater/piedmont/channel/f12-purp">f12-purp</button>
 

	
 
    <script src="static/jquery-2.1.1.min.js"></script>
 
    <script src="/lib/jquery-2.1.1.min.js"></script>
 
    <script>
 
      $(document).on("click", "button", function (ev) {
 
          var chan = ev.target.getAttribute('data-chan');
 
          $.ajax({
 
              type: 'POST',
 
              url: 'toggle',
 
              data: {chan: chan}
 
          });
 
      });
 
    </script>
 
  </body>
 
</html>
light9/subcomposer/subcomposerweb.py
Show inline comments
 
@@ -2,25 +2,24 @@ import logging
 
import cyclone.web, cyclone.websocket, cyclone.httpclient
 
from lib.cycloneerr import PrettyErrorHandler
 
from light9 import networking
 
from rdflib import URIRef, Literal
 
from twisted.internet import reactor
 
log = logging.getLogger('web')
 

	
 
def init(graph, session, currentSub):
 
    SFH = cyclone.web.StaticFileHandler
 
    app = cyclone.web.Application(handlers=[
 
        (r'/()', SFH,
 
         {'path': 'light9/subcomposer', 'default_filename': 'index.html'}),
 
        (r'/static/(.*)', SFH, {'path': 'static/'}),
 
        (r'/toggle', Toggle),
 
    ], debug=True, graph=graph, currentSub=currentSub)
 
    reactor.listenTCP(networking.subComposer.port, app)
 
    log.info("listening on %s" % networking.subComposer.port)
 

	
 
class Toggle(PrettyErrorHandler, cyclone.web.RequestHandler):
 
    def post(self):
 
        chan = URIRef(self.get_argument('chan'))
 
        log.info("toggle %r", chan)
 
        sub = self.settings.currentSub()
 
        
 
        chanKey = Literal(chan.rsplit('/', 1)[1])
light9/subserver/effects.coffee
Show inline comments
 
@@ -24,23 +24,23 @@ class Model
 
    ]
 
  
 

	
 
model = new Model()
 

	
 
model.addToCurrentSong = (e) ->
 
  $.ajax({
 
    type: 'POST'
 
    url: '//localhost:8070/songEffects'
 
    data: {drop: e.uri}
 
  })
 

	
 
reconnectingWebSocket "ws://localhost:8052/effectsUpdates", (msg) ->
 
reconnectingWebSocket "../effectsUpdates", (msg) ->
 
  model.chases(msg.chases) if msg.chases?
 
  model.classes(msg.classes) if msg.classes?
 

	
 
# this sort of works to stop clicks in <input> from following the
 
# submaster hyperlink, but it may make certain clicks act wrong
 
$(document).on('click', 'a', (ev) ->
 
  return false if ev.target.tagName == 'INPUT'
 
)
 

	
 
ko.applyBindings(model)
 
\ No newline at end of file
light9/subserver/effects.jade
Show inline comments
 
doctype html
 
html
 
  head
 
    title effects
 
    link(rel='stylesheet', href='/style.css')
 
  body
 
    #status starting...
 
    h1 Effects
 
    p: a(href='.') Go to Submasters
 

	
 

	
 
    div(data-bind="foreach: moreExprs")
 
      div.resource.chase
 
        span(data-bind="text: label")
 
        | 
 
        a.resource(data-bind="attr: {href: $root.subtermLink(label, expr)}, text: expr")
 
    
 
    div(data-bind="foreach: chases")
 
      div.resource.chase
 
        | Chase
 
        a(data-bind="attr: {href: uri}, text: label")
 
        ul(data-bind="foreach: $parent.subtermExprs($data)")
light9/subserver/gui.coffee
Show inline comments
 
@@ -9,17 +9,17 @@ class Model
 
      type: "POST"
 
      data: {about: sub.uri}
 
    })
 

	
 
model = new Model()
 

	
 
# this sort of works to stop clicks in <input> from following the
 
# submaster hyperlink, but it may make certain clicks act wrong
 
$(document).on('click', 'a', (ev) ->
 
  return false if ev.target.tagName == 'INPUT'
 
)
 

	
 
reconnectingWebSocket "ws://localhost:8052/live", (msg) ->
 
reconnectingWebSocket "live", (msg) ->
 
  model.subs(msg.subs) if msg.subs?
 

	
 

	
 
ko.applyBindings(model)
 
\ No newline at end of file
light9/subserver/index.jade
Show inline comments
 
doctype html
 
html
 
  head
 
    title subs
 
    link(rel='stylesheet', href='/style.css')
 
  body
 
    #status starting...
 
    h1 Submasters
 
    p: a(href='effects') Go to Effects
 

	
 
    div
 
      input(type='checkbox', data-bind='checked: showLocal', id='showLocal')
 
      label(for='showLocal') show local
 
    
 
    div(data-bind="foreach: subs")
 
      // ko if: $parent.showLocal() || !isLocal
 
      a.resource.sub(data-bind="css: {local: isLocal}, attr: {href: uri}")
 
        div(data-bind="if: isLocal") (local)
 
        div
 
          | Label
 
          input(type="text", data-bind="value: label")
light9/web/websocket.js
Show inline comments
 
/*
 
  url is now relative to the window location
 
*/
 
function reconnectingWebSocket(url, onMessage) {
 
    var pong = 0;
 
    
 
    var fullUrl = (
 
        "ws://"
 
            + window.location.host
 
            + window.location.pathname
 
            + (window.location.pathname.match(/\/$/) ? "" : "/")
 
            + url);
 
    function connect() {
 
        var ws = new WebSocket(url);
 
        var ws = new WebSocket(fullUrl);
 
        
 
        ws.onopen = function() {   $("#status").text("connected"); };
 
        ws.onerror = function(e) { $("#status").text("error: "+e); };
 
        ws.onclose = function() {  
 
            pong = 1 - pong;
 
            $("#status").text("disconnected (retrying "+(pong ? "😼":"😺")+")"); 
 
            // this should be under a requestAnimationFrame to
 
            // save resources
 
            setTimeout(connect, 2000);
 
        };
 
        ws.onmessage = function (evt) {
 
            onMessage(JSON.parse(evt.data));
 
        };
 
    }
 
    connect();
 
}
 
\ No newline at end of file
 
}
show/dance2014/networking.n3
Show inline comments
 
@prefix : <http://light9.bigasterisk.com/> .
 
@prefix show: <http://light9.bigasterisk.com/show/> .
 
@prefix sh: <http://light9.bigasterisk.com/show/dance2014/> .
 

	
 
show:dance2014 :networking sh:netHome .
 
sh:netHome
 
  :patchReceiverUpdateHost "localhost";
 
  :curveCalc        <http://dash:8060/>;
 
  :dmxServer        <http://dash:8030/>;
 
  :effectEval       <http://dash:8070/>;
 
  :keyboardComposer <http://dash:8050/>;
 
  :musicPlayer      <http://dash:8040/>;
 
  :oscDmxServer     <udp://dash:9050/>;
 
  :picamserve       <http://10.2.0.3:8001/>;
 
  :rdfdb            <http://localhost:8051/>;
 
  :effectEval       <http://plus:8070/>;
 
  :musicPlayer      <http://plus:8040/>;
 
  :dmxServer        <http://plus:8030/>;
 
  :oscDmxServer     <udp://plus:9050/>;
 
  :curveCalc        <http://plus:8060/>;
 
  :keyboardComposer <http://plus:8050/>;
 
  :subComposer <http://plus:8054/>;
 
  :picamserve       <http://10.2.0.3:8001/>;
 
  :subComposer      <http://dash:8055/>;
 
  :subServer        <http://dash:8052/>;
 
  :vidref           <http://dash:8053/> .
 

	
 
:rdfdb            :urlPath "rdfdb" .
 
:effectEval       :urlPath "effectEval" .
 
:musicPlayer      :urlPath "ascoltami" .
 
:curveCalc        :urlPath "curveCalc" .
 
:dmxServer        :urlPath "dmxServer" .
 
:oscDmxServer     :urlPath "oscDmxServer" .
 
:curveCalc        :urlPath "curveCalc" .
 
:effectEval       :urlPath "effectEval" .
 
:keyboardComposer :urlPath "keyboardComposer" .
 
:subComposer      :urlPath "subComposer" .
 
:musicPlayer      :urlPath "ascoltami" .
 
:picamserve       :urlPath "picamserve" .
 
:vidref           :urlPath "vidref" .
 
:rdfdb            :urlPath "rdfdb" .
 
:subComposer      :urlPath "subComposer" .
 
:subServer        :urlPath "subServer" .
 
:vidref           :urlPath "vidref" .
 
\ No newline at end of file
0 comments (0 inline, 0 general)