annotate bin/effecteval @ 1044:a2081b9adfe4

effecteval now takes dropped subs and makes new effects out of them Ignore-this: 69423eca1858291f486dd2a202d3732a
author Drew Perttula <drewp@bigasterisk.com>
date Wed, 28 May 2014 07:37:36 +0000
parents aa45e5379c5a
children be016cd5e5c5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
1 #!bin/python
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
2 from run_local import log
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
3 from twisted.internet import reactor, task
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
4 from twisted.internet.defer import inlineCallbacks
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
5 import cyclone.web, cyclone.websocket, cyclone.httpclient
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
6 import sys, optparse, logging, subprocess, json, re, time, traceback
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
7 from rdflib import URIRef, RDF, Literal
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
8
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
9 sys.path.append(".")
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
10 from light9 import networking, showconfig, Submaster, dmxclient
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
11 from light9.rdfdb.syncedgraph import SyncedGraph
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
12 from light9.curvecalc.curve import Curve
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
13 from light9.namespaces import L9, DCTERMS, RDF
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
14 from light9.rdfdb.patch import Patch
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
15
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
16 sys.path.append("/my/proj/homeauto/lib")
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
17 sys.path.append("/home/drewp/projects/homeauto/lib")
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
18 from cycloneerr import PrettyErrorHandler
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
19
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
20 class EffectEdit(cyclone.web.RequestHandler):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
21 def get(self):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
22 self.write(open("light9/effecteval/effect.html").read())
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
23
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
24 class SongEffects(PrettyErrorHandler, cyclone.web.RequestHandler):
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
25 def post(self):
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
26 song = URIRef(self.get_argument('uri'))
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
27 drop = URIRef(self.get_argument('drop'))
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
28 ctx = song
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
29 now = time.time()
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
30 effect = song + "/effect/e-%f" % now
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
31 curve = song + "/curve/c-%f" % now
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
32 self.settings.graph.patch(Patch(addQuads=[
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
33 (song, L9['effect'], effect, ctx),
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
34 (effect, RDF.type, L9['Effect'], ctx),
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
35 (effect, L9['code'],
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
36 Literal('out = sub(%s, intensity=%s)' % (drop.n3(), curve.n3())),
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
37 ctx),
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
38 (curve, RDF.type, L9['Curve'], ctx),
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
39 (curve, L9['points'], Literal('0 0'), ctx),
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
40 ]))
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
41
1043
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
42 class SongEffectsUpdates(cyclone.websocket.WebSocketHandler):
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
43 def connectionMade(self, *args, **kwargs):
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
44 self.graph = self.settings.graph
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
45 self.graph.addHandler(self.updateClient)
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
46
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
47 def updateClient(self):
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
48 # todo: abort if client is gone
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
49 playlist = self.graph.value(showconfig.showUri(), L9['playList'])
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
50 songs = list(self.graph.items(playlist))
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
51 out = []
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
52 for s in songs:
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
53 out.append({'uri': s, 'label': self.graph.label(s)})
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
54 out[-1]['effects'] = sorted(self.graph.objects(s, L9['effect']))
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
55 self.sendMessage({'songs': out})
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
56
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
57
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
58 class EffectUpdates(cyclone.websocket.WebSocketHandler):
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
59 """
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
60 stays alive for the life of the effect page
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
61 """
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
62 def connectionMade(self, *args, **kwargs):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
63 log.info("websocket opened")
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
64 self.uri = URIRef(self.get_argument('uri'))
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
65 self.sendMessage({'hello': repr(self)})
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
66
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
67 self.graph = self.settings.graph
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
68 self.graph.addHandler(self.updateClient)
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
69
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
70 def updateClient(self):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
71 # todo: if client has dropped, abort and don't get any more
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
72 # graph updates
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
73 self.sendMessage({'code': self.graph.value(self.uri, L9['code'])})
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
74
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
75 def connectionLost(self, reason):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
76 log.info("websocket closed")
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
77
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
78 def messageReceived(self, message):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
79 log.info("got message %s" % message)
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
80 # write a patch back to the graph
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
81
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
82 def uriFromCode(s):
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
83 # i thought this was something a graph could do with its namespace manager
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
84 if s.startswith('sub:'):
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
85 return URIRef('http://light9.bigasterisk.com/show/dance2014/sub/' + s[4:])
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
86 if s.startswith('song1:'):
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
87 return URIRef('http://ex/effect/song1/' + s[6:])
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
88 if (s[0], s[-1]) == ('<', '>'):
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
89 return URIRef(s[1:-1])
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
90 raise NotImplementedError
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
91
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
92 class EffectNode(object):
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
93 def __init__(self, graph, uri):
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
94 self.graph, self.uri = graph, uri
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
95 self.graph.addHandler(self.prepare)
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
96
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
97 def prepare(self):
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
98 self.code = self.graph.value(self.uri, L9['code'])
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
99 m = re.match(r'^out = sub\((.*?), intensity=(.*?)\)', self.code)
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
100 if not m:
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
101 raise NotImplementedError
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
102 subUri = uriFromCode(m.group(1))
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
103 subs = Submaster.get_global_submasters(self.graph)
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
104 self.sub = subs.get_sub_by_uri(subUri)
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
105
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
106 intensityCurve = uriFromCode(m.group(2))
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
107 self.curve = Curve()
1043
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
108
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
109 # read from disk ok? how do we know to reread? start with
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
110 # mtime. the mtime check could be done occasionally so on
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
111 # average we read at most one curve's mtime per effectLoop.
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
112
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
113 pts = self.graph.value(intensityCurve, L9['points'])
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
114 if pts is None:
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
115 log.info("curve %r has no points" % intensityCurve)
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
116 else:
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
117 self.curve.set_from_string(pts)
1043
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
118
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
119
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
120 def eval(self, songTime):
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
121 # consider http://waxeye.org/ for a parser that can be used in py and js
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
122 level = self.curve.eval(songTime)
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
123 scaledSubs = self.sub * level
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
124 return scaledSubs
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
125
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
126
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
127 class EffectEval(PrettyErrorHandler, cyclone.web.RequestHandler):
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
128 @inlineCallbacks
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
129 def get(self):
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
130 # return dmx list for that effect
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
131 uri = URIRef(self.get_argument('uri'))
1027
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
132 response = yield cyclone.httpclient.fetch(
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
133 networking.musicPlayer.path('time'))
a38414bd3929 hacking on effecteval
Drew Perttula <drewp@bigasterisk.com>
parents: 1019
diff changeset
134 songTime = json.loads(response.body)['t']
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
135
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
136 node = EffectNode(self.settings.graph, uri)
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
137 outSub = node.eval(songTime)
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
138 self.write(json.dumps(outSub.get_dmx_list()))
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
139
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
140
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
141 # Completely not sure where the effect background loop should
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
142 # go. Another process could own it, and get this request repeatedly:
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
143 class SongEffectsEval(PrettyErrorHandler, cyclone.web.RequestHandler):
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
144 def get(self):
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
145 song = URIRef(self.get_argument('song'))
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
146 effects = effectsForSong(self.settings.graph, song)
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
147 raise NotImplementedError
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
148 self.write(maxDict(effectDmxDict(e) for e in effects))
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
149 # return dmx dict for all effects in the song, already combined
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
150
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
151 # Or, we could own that loop, like this:
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
152 @inlineCallbacks
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
153 def effectLoop(graph):
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
154 t1 = time.time()
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
155 try:
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
156 response = json.loads((yield cyclone.httpclient.fetch(
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
157 networking.musicPlayer.path('time'))).body)
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
158 if response['song'] is not None:
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
159 song = URIRef(response['song'])
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
160 songTime = response['t']
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
161 # Possibilities to make this shut up about graph copies:
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
162 # - implement the cheap readonly currentState response
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
163 # - do multiple little currentState calls (in this code) over just
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
164 # the required triples
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
165 # - use addHandler instead and only fire dmx when there is a data
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
166 # change (and also somehow call it when there is a time change)
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
167
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
168 outSubs = []
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
169 with graph.currentState(tripleFilter=(song, L9['effect'], None)) as g:
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
170 for effectUri in g.objects(song, L9['effect']):
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
171 # these should be built once, not per (frequent) update
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
172 node = EffectNode(graph, effectUri)
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
173 outSubs.append(node.eval(songTime))
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
174 out = Submaster.sub_maxes(*outSubs)
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
175 # out.get_levels() for a more readable view
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
176 dmx = out.get_dmx_list()
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
177
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
178 if log.isEnabledFor(logging.DEBUG):
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
179 log.debug("send dmx: %r", out.get_levels())
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
180 yield dmxclient.outputlevels(dmx, twisted=True)
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
181 except Exception:
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
182 traceback.print_exc()
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
183 time.sleep(1)
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
184
1033
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
185 loopTime = time.time() - t1
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
186 log.debug('loopTime %.1f ms', 1000 * loopTime)
b5ee7aa9341a effecteval now runs effects in the background, following the current song, and sends dmx output
Drew Perttula <drewp@bigasterisk.com>
parents: 1027
diff changeset
187
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
188 class App(object):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
189 def __init__(self, show):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
190 self.show = show
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
191 self.graph = SyncedGraph("effectEval")
1043
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
192 self.graph.initiallySynced.addCallback(self.launch)
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
193
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
194 def launch(self, *args):
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
195 task.LoopingCall(effectLoop, self.graph).start(1)
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
196 SFH = cyclone.web.StaticFileHandler
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
197 self.cycloneApp = cyclone.web.Application(handlers=[
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
198 (r'/()', SFH,
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
199 {'path': 'light9/effecteval', 'default_filename': 'index.html'}),
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
200 (r'/effect', EffectEdit),
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
201 (r'/(websocket\.js)', SFH, {'path': 'light9/rdfdb/web/'}),
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
202 (r'/effect\.js', StaticCoffee, {'src': 'light9/effecteval/effect.coffee'}),
1041
a4632a7b2e17 upgrade knockout and jquery, simplify the static/ dirs for all web services
Drew Perttula <drewp@bigasterisk.com>
parents: 1033
diff changeset
203 (r'/index\.js', StaticCoffee, {'src': 'light9/effecteval/index.coffee'}),
a4632a7b2e17 upgrade knockout and jquery, simplify the static/ dirs for all web services
Drew Perttula <drewp@bigasterisk.com>
parents: 1033
diff changeset
204 (r'/effectUpdates', EffectUpdates),
a4632a7b2e17 upgrade knockout and jquery, simplify the static/ dirs for all web services
Drew Perttula <drewp@bigasterisk.com>
parents: 1033
diff changeset
205 (r'/songEffectsUpdates', SongEffectsUpdates),
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
206 (r'/static/(.*)', SFH, {'path': 'static/'}),
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
207 (r'/effect/eval', EffectEval),
1044
a2081b9adfe4 effecteval now takes dropped subs and makes new effects out of them
Drew Perttula <drewp@bigasterisk.com>
parents: 1043
diff changeset
208 (r'/songEffects', SongEffects),
1019
5939fce98fad notes for next step
drewp@bigasterisk.com
parents: 1018
diff changeset
209 (r'/songEffects/eval', SongEffectsEval),
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
210 ], debug=True, graph=self.graph)
1043
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
211 reactor.listenTCP(networking.effectEval.port, self.cycloneApp)
aa45e5379c5a effecteval improvements. displays current song+effect tree
Drew Perttula <drewp@bigasterisk.com>
parents: 1041
diff changeset
212 log.info("listening on %s" % networking.effectEval.port)
1018
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
213
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
214 class StaticCoffee(PrettyErrorHandler, cyclone.web.RequestHandler):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
215 def initialize(self, src):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
216 super(StaticCoffee, self).initialize()
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
217 self.src = src
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
218 def get(self):
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
219 self.set_header('Content-Type', 'application/javascript')
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
220 self.write(subprocess.check_output([
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
221 '/usr/bin/coffee', '--compile', '--print', self.src]))
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
222
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
223
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
224 if __name__ == "__main__":
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
225 parser = optparse.OptionParser()
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
226 parser.add_option('--show',
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
227 help='show URI, like http://light9.bigasterisk.com/show/dance2008',
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
228 default=showconfig.showUri())
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
229 parser.add_option("-v", "--verbose", action="store_true",
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
230 help="logging.DEBUG")
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
231 parser.add_option("--twistedlog", action="store_true",
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
232 help="twisted logging")
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
233 (options, args) = parser.parse_args()
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
234
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
235 log.setLevel(logging.DEBUG if options.verbose else logging.INFO)
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
236
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
237 if not options.show:
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
238 raise ValueError("missing --show http://...")
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
239
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
240 app = App(URIRef(options.show))
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
241 if options.twistedlog:
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
242 from twisted.python import log as twlog
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
243 twlog.startLogging(sys.stderr)
e28a443bd153 initial effecteval that can propagate changes from the graph to a web page
drewp@bigasterisk.com
parents:
diff changeset
244 reactor.run()