Implemented playlist, removed version from node protocol.
[blynken.git] / server / server.py
blobb3541f97d437ac1ab56d626474bc45c701f34cd5
1 #!/usr/bin/env python
2 from __future__ import with_statement
3 from projector import DummyProjector
4 from blinken_handler import BlinkenHandler
5 from control_handler import ControlHandler
6 from my_threading import Thread, schedule, ThreadingMixIn, Lock
7 from SocketServer import TCPServer
9 __all__ = ['BlinkenServer']
11 class Server(ThreadingMixIn, TCPServer):
12 allow_reuse_address = True
14 class BlinkenServer(Server):
15 is_running = True
16 current = DummyProjector()
17 blinken_port = 10000
18 control_port = 10001
20 def __init__(self):
21 self._next = []
22 self._force_next = False
23 self._blinken = Server(('', self.blinken_port), BlinkenHandler)
24 self._blinken.connections = {}
25 self._blinken.lock = Lock()
26 self._blinken.close_request = lambda request : None
28 Server.__init__(self, ('', self.control_port), ControlHandler)
30 self._idles = {'dummy' : DummyProjector()}
31 self._movies = {}
33 Thread(self._serve_nodes)()
34 Thread(self._blinken.serve_forever)()
35 Thread(self.serve_forever)()
37 def set_projector(self, projector):
38 self._force_next = True
39 self._next.insert(0, projector)
41 def enqueue_projector(self, projector):
42 self._next.append(projector)
44 def _projectors(self):
45 import random
46 while True:
47 if not self._next:
48 self._is_idling = True
49 yield random.choice(self._idles.values())
50 else:
51 self._is_idling = False
52 proj = self.next.pop(0)
53 yield next_proj
55 def _serve_nodes(self):
56 for projector in self._projectors():
57 for frame in projector:
58 to_clean = []
59 with self._blinken.lock:
60 for pixel, socket in self._blinken.connections.iteritems():
61 try:
62 socket.send(("on" if pixel in frame else "off") + "\r\n")
63 except:
64 to_clean.append(pixel)
66 for i in to_clean:
67 del self._blinken.connections[i]
69 if self._force_next or self._next and self._is_idling:
70 self._force_next = False
71 break
73 schedule()
76 if __name__ == '__main__':
77 server = BlinkenServer()
78 try:
79 import stackless
80 stackless.run()
81 except ImportError:
82 pass