author | ymh <ymh.work@gmail.com> |
Fri, 17 Apr 2015 15:20:46 +0200 | |
changeset 165 | 7dfdafb88968 |
parent 93 | 79ae42ad97d4 |
permissions | -rw-r--r-- |
0 | 1 |
# |
2 |
# See LICENCE for detail |
|
3 |
# Copyright (c) 2014 IRI |
|
4 |
# |
|
5 |
||
6 |
import json |
|
7 |
||
8 |
from autobahn.twisted.websocket import WebSocketServerFactory, \ |
|
9 |
WebSocketServerProtocol |
|
10 |
from autobahn.websocket import http |
|
11 |
||
12 |
from baseserver import BaseProtocol |
|
13 |
import utils |
|
14 |
||
15 |
class BroadcastServerProtocol(WebSocketServerProtocol): |
|
16 |
||
17 |
def onConnect(self, request): |
|
18 |
if request.params: |
|
19 |
self.factory.registerFilter(self, request.params) |
|
20 |
||
21 |
def onOpen(self): |
|
22 |
self.factory.register(self) |
|
23 |
||
24 |
def onMessage(self, payload, isBinary): |
|
25 |
if not isBinary: |
|
26 |
msg = "{} from {}".format(payload.decode('utf8'), self.peer) |
|
27 |
self.factory.broadcast(msg) |
|
28 |
||
29 |
def connectionLost(self, reason): |
|
30 |
WebSocketServerProtocol.connectionLost(self, reason) |
|
31 |
self.factory.unregister(self) |
|
32 |
||
33 |
||
34 |
class BroadcastServerFactory(WebSocketServerFactory): |
|
35 |
""" |
|
36 |
Simple broadcast server broadcasting any message it receives to all |
|
37 |
currently connected clients. |
|
38 |
""" |
|
39 |
||
40 |
def __init__(self, url, debug = False, debugCodePaths = False): |
|
41 |
WebSocketServerFactory.__init__(self, url, debug = debug, debugCodePaths = debugCodePaths) |
|
42 |
self.clients = [] |
|
43 |
self.filters = {} |
|
44 |
self.protocol = BroadcastServerProtocol |
|
45 |
||
46 |
def registerFilter(self, client, filter): |
|
47 |
print("registered filter {} for client {}".format(repr(filter),client.peer)) |
|
48 |
self.filters[client] = filter |
|
49 |
||
50 |
def register(self, client): |
|
51 |
if not client in self.clients: |
|
93
79ae42ad97d4
optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents:
76
diff
changeset
|
52 |
print("registered client {}".format(client.peer)) |
79ae42ad97d4
optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents:
76
diff
changeset
|
53 |
self.clients.append(client) |
0 | 54 |
|
55 |
def unregister(self, client): |
|
56 |
if client in self.clients: |
|
57 |
print("unregistered client {}".format(client.peer)) |
|
58 |
self.clients.remove(client) |
|
59 |
if client in self.filters: |
|
60 |
self.filters.pop(client, None) |
|
61 |
||
93
79ae42ad97d4
optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents:
76
diff
changeset
|
62 |
def broadcast(self, msg, filter_list): |
0 | 63 |
print("broadcasting prepared message '{}' ..".format(msg)) |
76
029cdbeebf03
filter pianoroll annotation by channel & event
ymh <ymh.work@gmail.com>
parents:
66
diff
changeset
|
64 |
preparedMsg = self.prepareMessage(msg) |
0 | 65 |
for c in self.clients: |
93
79ae42ad97d4
optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents:
76
diff
changeset
|
66 |
if all([ (k in filter_list and filter_list[k] in v) for k,v in self.filters.get(c, {}).items()]): |
0 | 67 |
c.sendPreparedMessage(preparedMsg) |
68 |
print("prepared message sent to {}".format(c.peer)) |
|
69 |
||
70 |
||
71 |
class AnnotationServerProtocol(WebSocketServerProtocol, BaseProtocol): |
|
72 |
||
73 |
def onConnect(self, request): |
|
74 |
event_ids = request.params.get('event', []) |
|
75 |
if not event_ids or not event_ids[0]: |
|
76 |
raise http.HttpException(400, "The event parameter is missing") |
|
77 |
self.event = event_ids[0] |
|
78 |
self._init_props(self.factory.ws_factory, self.factory.conn) |
|
79 |
||
66
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
80 |
def clean_annot(self, annot): |
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
81 |
if 'ts' in annot: |
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
82 |
annot['ts'] = annot['ts'].isoformat() |
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
83 |
if 'uuid' in annot: |
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
84 |
annot['uuid'] = str(annot['uuid']) |
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
85 |
|
0 | 86 |
#TODO: add error handling |
87 |
def onMessage(self, payload, isBinary): |
|
88 |
if isBinary: |
|
89 |
return |
|
90 |
msg = payload.decode('utf8') |
|
91 |
params_annot = json.loads(msg) |
|
92 |
||
93 |
params = { |
|
42
926f0426ce78
add event + event session + admin + category json management. Must rebuild database
ymh <ymh.work@gmail.com>
parents:
23
diff
changeset
|
94 |
'event_code': self.event, |
0 | 95 |
'channel' : utils.ANNOTATION_CHANNEL, |
96 |
'content' : params_annot |
|
97 |
} |
|
98 |
||
99 |
def error_callback(failure): |
|
23
16a1925df2df
add status to annotation creation. Improve error management for annotation creation
ymh <ymh.work@gmail.com>
parents:
0
diff
changeset
|
100 |
res = params.copy() |
66
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
101 |
self.clean_annot(res) |
23
16a1925df2df
add status to annotation creation. Improve error management for annotation creation
ymh <ymh.work@gmail.com>
parents:
0
diff
changeset
|
102 |
res['status'] = 'KO' |
16a1925df2df
add status to annotation creation. Improve error management for annotation creation
ymh <ymh.work@gmail.com>
parents:
0
diff
changeset
|
103 |
res['failure'] = str(failure) |
16a1925df2df
add status to annotation creation. Improve error management for annotation creation
ymh <ymh.work@gmail.com>
parents:
0
diff
changeset
|
104 |
self.sendMessage(json.dumps(res)) |
0 | 105 |
|
106 |
def annot_callback(res): |
|
66
658561ea9e65
export sync code in utils, and add button to synchronize annotation on eventsessionview
ymh <ymh.work@gmail.com>
parents:
42
diff
changeset
|
107 |
self.clean_annot(res) |
23
16a1925df2df
add status to annotation creation. Improve error management for annotation creation
ymh <ymh.work@gmail.com>
parents:
0
diff
changeset
|
108 |
res['status'] = 'OK' |
0 | 109 |
self.sendMessage(json.dumps(res)) |
110 |
||
111 |
||
112 |
defer = self.process_annotation(params) |
|
113 |
defer.addErrback(error_callback) |
|
114 |
defer.addCallback(annot_callback) |
|
115 |
||
116 |
||
117 |
class AnotationServerFactory(WebSocketServerFactory): |
|
118 |
||
119 |
def __init__(self, url, ws_factory, conn, debug = False, debugCodePaths = False): |
|
120 |
WebSocketServerFactory.__init__(self, url, debug = debug, debugCodePaths = debugCodePaths) |
|
121 |
self.ws_factory = ws_factory |
|
122 |
self.conn = conn |
|
123 |
self.clients = {} |
|
124 |
self.protocol = AnnotationServerProtocol |