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