Changeset - 33a5a98e9bf1
[Not reviewed]
default
0 3 3
drewp@bigasterisk.com - 12 years ago 2013-06-10 23:03:57
drewp@bigasterisk.com
start subserver webapp with websockets, cyclone, jade, coffee
Ignore-this: d0e47882e0f3edb2bcea660e612d364
6 files changed with 127 insertions and 20 deletions:
0 comments (0 inline, 0 general)
bin/subserver
Show inline comments
 
# keep the database of submasters, and mix up the current client
 
# requests into dmx levels for dmxserver
 
#!bin/python
 
"""
 
live web display of all existing subs with pictures, mainly for
 
dragging them into CC
 
"""
 
from run_local import log
 
from twisted.internet import reactor
 
import twisted.internet.error
 
import sys, optparse, logging, json, os, subprocess
 
import cyclone.web, cyclone.httpclient, cyclone.websocket
 
from light9.rdfdb.syncedgraph import SyncedGraph
 
import pyjade.utils
 

	
 
class SubServe:
 
    """call the server with these messages"""
 
try:
 
    import sys
 
    sys.path.append("../homeauto/lib")
 
    sys.path.append("/home/drewp/projects/homeauto/lib")
 
    from cycloneerr import PrettyErrorHandler
 
except ImportError:
 
    class PrettyErrorHandler(object):
 
        pass
 
        
 
liveClients = set()
 
def sendToLiveClients(d=None, asJson=None):
 
    j = asJson or json.dumps(d)
 
    for c in liveClients:
 
        c.sendMessage(j)
 

	
 
class Live(cyclone.websocket.WebSocketHandler):
 
    def connectionMade(self, *args, **kwargs):
 
        log.info("websocket opened")
 
        liveClients.add(self)
 
        self.settings.onNewClient()
 

	
 
    def connectionLost(self, reason):
 
        log.info("websocket closed")
 
        liveClients.remove(self)
 

	
 
    def messageReceived(self, message):
 
        log.info("got message %s" % message)
 
        self.sendMessage(message)
 
    
 
    def allSubs(self):
 
        """list of all the known subs"""
 
class Static(PrettyErrorHandler, cyclone.web.StaticFileHandler):
 
    # .xhtml pages can be get() without .xhtml on them
 
    def get(self, path, *args, **kw):
 
        if path == '':
 
            return self.respondStaticJade("light9/subserver/index.jade")
 

	
 
        if path == 'gui.js':
 
            return self.responseStaticCoffee('light9/subserver/gui.coffee')
 
            
 
        oddlyPlaced = {
 
            "websocket.js":        "light9/rdfdb/web/websocket.js",
 
            "jquery-1.7.2.min.js": "light9/rdfdb/web/lib/jquery-1.7.2.min.js",
 
        }
 
        if path in oddlyPlaced:
 
            self.write(open(oddlyPlaced[path]).read())
 
            return
 

	
 
        cyclone.web.StaticFileHandler.get(self, path, *args, **kw)
 

	
 
    def respondStaticJade(self, src):
 
        html = pyjade.utils.process(open(src).read())
 
        self.write(html)
 

	
 
    def output(self,levels):
 
        """pass a dict of {sub : level} mappings"""
 
    def responseStaticCoffee(self, src):
 
        self.write(subprocess.check_output([
 
            '/usr/bin/coffee', '--compile', '--print', src]))
 
        
 
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)
 

	
 
def editsub
 
    graph = SyncedGraph("subserver")
 

	
 
    d = {}
 
    def updateSubs():
 
        d.clear()
 
        d.update({'subs':['a', 'b']})
 
        sendToLiveClients(d=d)
 
    def onNewClient():
 
        sendToLiveClients(d=d)
 
        
 
    graph.addHandler(updateSubs)
 

	
 

	
 
class SubClient:
 
    """each client can receive these messages"""
 
    
 
    def subAdded(self,newsub):
 
        """sub was just added to the db"""
 

	
 
    def subRemove(self,pastsub):
 
        """this sub is about to be removed from the db"""
 

	
 
    def subChange(self,sub):
 
        """this is a new version of an existing sub"""
 
    port = 8052
 
    reactor.listenTCP(port, cyclone.web.Application(handlers=[
 
        (r'/live', Live),
 
        (r'/(.*)', Static,
 
         {"path" : "light9/subserver",
 
          "default_filename" : "index.jade"}),
 
        ], debug=True, graph=graph, onNewClient=onNewClient))
 
    log.info("serving on %s" % port)
 
    reactor.run()
light9/subserver/gui.coffee
Show inline comments
 
new file 100644
 

	
 
class Model
 
  constructor: ->
 
    @subs = ko.observable([])
 

	
 
model = new Model()
 

	
 
reconnectingWebSocket "ws://localhost:8052/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
 
new file 100644
 
doctype html
 
html
 
  head
 
    title subserver
 
    link(rel='stylesheet', href='style.css')
 
  body
 
    h1 subserver
 

	
 
    div(data-bind="foreach: subs")
 
      div(data-bind="text: JSON.stringify($data)")
 

	
 
    script(src="jquery-1.7.2.min.js")
 
    script(src="knockout-2.2.1.js")
 
    script(src="websocket.js")
 
    script(src="gui.js")
 
\ No newline at end of file
light9/subserver/style.css
Show inline comments
 
new file 100644
 
body {
 
  font-family: sans;
 
}
 
\ No newline at end of file
makefile
Show inline comments
 
@@ -50,3 +50,6 @@ bin/ascoltami2: gst_packages link_to_sys
 

	
 
gst_packages:
 
	sudo aptitude install python-gi gir1.2-gst-plugins-base-1.0 libgirepository-1.0-1 gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-pulseaudio
 

	
 
packages:
 
	sudo aptitude install coffeescript
pydeps
Show inline comments
 
@@ -13,3 +13,4 @@ ipdb==0.7
 
# waiting for https://github.com/xolox/python-coloredlogs/pull/1
 
git+git://github.com/drewp/python-coloredlogs@9803112ddf7d4cd7dd001912ad1aa482fb8383f6
 
genshi==0.7
 
pyjade==2.0.2
0 comments (0 inline, 0 general)