changeset 532:8d6f6d8a4719

clean up music client calls from curvecalc and musictime Ignore-this: 4fd58f13cedae44ba9a21534ea127292
author drewp@bigasterisk.com
date Sat, 12 Jun 2010 08:00:52 +0000
parents e8f6722a3881
children 846bc4712cf7
files bin/curvecalc bin/musictime bin/webcontrol light9/ascoltami/webapp.py light9/networking.py light9/showconfig.py
diffstat 6 files changed, 78 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/bin/curvecalc	Sat Jun 12 07:00:54 2010 +0000
+++ b/bin/curvecalc	Sat Jun 12 08:00:52 2010 +0000
@@ -17,8 +17,14 @@
 except ImportError:
     import louie as dispatcher 
 from twisted.internet import reactor,tksupport
+import jsonlib
 import twisted
-from twisted.web.xmlrpc import Proxy
+from twisted.web.client import Agent
+from twisted.internet.protocol import Protocol
+from twisted.internet.defer import Deferred     
+from zope.interface import implements
+from twisted.internet.defer import succeed
+from twisted.web.iweb import IBodyProducer
 from rdflib import Literal, URIRef, RDF, RDFS
 from rdflib.Graph import Graph
 import rdflib
@@ -37,33 +43,62 @@
 from light9.namespaces import L9
 import light9.Effects
 
+class GatherJson(Protocol):
+    """calls back the 'finished' deferred with the parsed json data we
+    received"""
+    def __init__(self, finished):
+        self.finished = finished
+        self.buf = ""
+
+    def dataReceived(self, bytes):
+        self.buf += bytes
+
+    def connectionLost(self, reason):
+        self.finished.callback(jsonlib.read(self.buf, use_float=True))
+
+class StringProducer(object):
+    # http://twistedmatrix.com/documents/current/web/howto/client.html
+    implements(IBodyProducer)
+
+    def __init__(self, body):
+        self.body = body
+        self.length = len(body)
+
+    def startProducing(self, consumer):
+        consumer.write(self.body)
+        return succeed(None)
+
+    def pauseProducing(self):
+        pass
+
+    def stopProducing(self):
+        pass
+
 class Music:
     def __init__(self):
-        self.player=None # xmlrpc Proxy to player
         self.recenttime=0
-
+        self.player = Agent(reactor)
         dispatcher.connect(self.seekplay_or_pause,"music seek")
         
     def current_time(self):
         """return deferred which gets called with the current time"""
-        if self.player is None:
-            print "connect to player"
-            self.player = Proxy(networking.musicUrl())
-#            d = self.player.callRemote("songlength")
-#            d.addCallback(lambda l: dispatcher.send("max time",maxtime=l))
-#            d = self.player.callRemote("songname")
-#            d.addCallback(lambda n: dispatcher.send("songname",name=n))
-        d = self.player.callRemote('gettime')
-        def sendtime(t):
-            dispatcher.send("input time",val=t)
-            return t # pass along to the real receiver
-        def error(e):
-            pass#self.player=None
-        d.addCallback(sendtime)
+        d = self.player.request("GET", networking.musicUrl() + "time")
+        d.addCallback(self._timeReturned)
         return d
+
+    def _timeReturned(self, response):
+        done = Deferred()
+        done.addCallback(self._bodyReceived)
+        response.deliverBody(GatherJson(done))
+        return done
+
+    def _bodyReceived(self, data):
+        dispatcher.send("input time",val=data['t'])
+        return data['t'] # pass along to the real receiver
     
     def seekplay_or_pause(self,t):
-        self.player.callRemote('seekplay_or_pause',t)
+        d = self.player.request("POST",
+                                networking.musicUrl() + "seekPlayOrPause", bodyProducer=StringProducer(jsonlib.write({"t" : t})))
 
 class Expr(object):
     """singleton, provides functions for use in subterm expressions,
@@ -241,7 +276,6 @@
         self.later = reactor.callLater(1,self.update)
         
     def update2(self,t):
-
         # spot alsa soundcard offset is always 0, we get times about a
         # second ahead of what's really getting played
         #t = t - .7
--- a/bin/musictime	Sat Jun 12 07:00:54 2010 +0000
+++ b/bin/musictime	Sat Jun 12 08:00:52 2010 +0000
@@ -3,17 +3,19 @@
 import light9.networking
 
 import Tkinter as tk
-import xmlrpclib, socket, time
+import time
+import restkit, jsonlib
 
 class MusicTime:
     def __init__(self, url):
-        self.player = xmlrpclib.Server(url)
+        self.player = restkit.Resource(url)
     def get_music_time(self):
         playtime = None
         while not playtime:
             try:
-                playtime = self.player.gettime()
-            except socket.error, e:
+                playtime = jsonlib.read(self.player.get("time").body,
+                                        use_float=True)['t']
+            except restkit.RequestError, e:
                 print "Server error %s, waiting" % e
                 time.sleep(2)
         return playtime
--- a/bin/webcontrol	Sat Jun 12 07:00:54 2010 +0000
+++ b/bin/webcontrol	Sat Jun 12 08:00:52 2010 +0000
@@ -16,6 +16,7 @@
 from nevow import rend, static, loaders, inevow, url, tags as T
 from rdflib import URIRef
 from louie.robustapply import robust_apply
+sys.path.append(".")
 from light9 import showconfig, networking
 from light9.namespaces import L9
 from urllib import urlencode
--- a/light9/ascoltami/webapp.py	Sat Jun 12 07:00:54 2010 +0000
+++ b/light9/ascoltami/webapp.py	Sat Jun 12 08:00:52 2010 +0000
@@ -1,6 +1,6 @@
 import web, jsonlib
 from twisted.python.util import sibpath
-from light9.namespaces import L9, MUS
+from light9.namespaces import L9
 
 player = None
 graph = None
@@ -9,6 +9,8 @@
 class root(object):
     def GET(self):
         web.header("Content-type", "application/xhtml+xml")
+        # todo: use a template; embed the show name and the intro/post
+        # times into the page
         return open(sibpath(__file__, "index.html")).read()
 
 class timeResource(object):
@@ -49,6 +51,15 @@
         """post a uri of song to switch to (and start playing)"""
         player.setSong(web.data())
         return "ok"
+    
+class seekPlayOrPause(object):
+    def POST(self):
+        data = jsonlib.read(web.data(), use_float=True)
+        if player.isPlaying():
+            player.pause()
+        else:
+            player.seek(data['t'])
+            player.resume()
 
 def makeApp(thePlayer, theGraph, theShow):
     global player, graph, show
@@ -58,7 +69,7 @@
             "/time", "timeResource",
             "/song", "songResource",
             "/songs", "songs",
-            "/api/position", "timeResource", # old
+            "/seekPlayOrPause", "seekPlayOrPause",
             )
 
     app = web.application(urls, globals(), autoreload=False)
--- a/light9/networking.py	Sat Jun 12 07:00:54 2010 +0000
+++ b/light9/networking.py	Sat Jun 12 08:00:52 2010 +0000
@@ -11,12 +11,8 @@
 def dmxServerPort():
     return 8030
     
-def musicUrl(api='xmlrpc'):
-    site = "http://dash:%s/" % musicPort()
-    if api == 'rest':
-        return site + "api/"
-    else:
-        return site + "RPC2"
+def musicUrl():
+    return "http://dash:%s/" % musicPort()
 
 def musicPort():
     return 8040
--- a/light9/showconfig.py	Sat Jun 12 07:00:54 2010 +0000
+++ b/light9/showconfig.py	Sat Jun 12 08:00:52 2010 +0000
@@ -80,8 +80,9 @@
     showPath = graph.value(song, L9['showPath'])
     if not showPath:
         raise ValueError("no mpd path found for subject=%r" % song)
-    songFullPath = path.join(findMpdHome(), showPath)
-    return songFullPath
+    if showPath.startswith("file://"):
+        showPath = showPath[7:]
+    return showPath
 
 def songFilenameFromURI(uri):
     """