annot-server/websockets.py
author rougeronj
Thu, 22 Jan 2015 09:26:43 +0100
changeset 111 a7b72620d227
parent 93 79ae42ad97d4
permissions -rw-r--r--
Add variable "wait". When this variable set, the annotsroll wait ignore some annotations, and wait before printing an otherone so there is no superposition. Can be passed as an options
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
#
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
# See LICENCE for detail
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
# Copyright (c) 2014 IRI
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
#
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
import json
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
from autobahn.twisted.websocket import WebSocketServerFactory, \
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
                                       WebSocketServerProtocol
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
from autobahn.websocket import http
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
from baseserver import BaseProtocol
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
import utils
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
class BroadcastServerProtocol(WebSocketServerProtocol):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
    def onConnect(self, request):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
        if request.params:
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
            self.factory.registerFilter(self, request.params)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    def onOpen(self):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
        self.factory.register(self)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    def onMessage(self, payload, isBinary):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
        if not isBinary:
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
            msg = "{} from {}".format(payload.decode('utf8'), self.peer)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
            self.factory.broadcast(msg)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
    def connectionLost(self, reason):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
        WebSocketServerProtocol.connectionLost(self, reason)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
        self.factory.unregister(self)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
class BroadcastServerFactory(WebSocketServerFactory):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    """
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
    Simple broadcast server broadcasting any message it receives to all
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
    currently connected clients.
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
    """
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
    def __init__(self, url, debug = False, debugCodePaths = False):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
        WebSocketServerFactory.__init__(self, url, debug = debug, debugCodePaths = debugCodePaths)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
        self.clients = []
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
        self.filters = {}
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
        self.protocol = BroadcastServerProtocol
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    def registerFilter(self, client, filter):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        print("registered filter {} for client {}".format(repr(filter),client.peer))
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
        self.filters[client] = filter
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
    def register(self, client):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
    def unregister(self, client):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
        if client in self.clients:
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
            print("unregistered client {}".format(client.peer))
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
            self.clients.remove(client)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
        if client in self.filters:
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
            self.filters.pop(client, None)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
                c.sendPreparedMessage(preparedMsg)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
                print("prepared message sent to {}".format(c.peer))
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
class AnnotationServerProtocol(WebSocketServerProtocol, BaseProtocol):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
    def onConnect(self, request):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
        event_ids = request.params.get('event', [])
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        if not event_ids or not event_ids[0]:
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
            raise http.HttpException(400, "The event parameter is missing")
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        self.event = event_ids[0]
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
        self._init_props(self.factory.ws_factory, self.factory.conn)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
    #TODO: add error handling
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
    def onMessage(self, payload, isBinary):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
        if isBinary:
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
            return
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
        msg = payload.decode('utf8')
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
        params_annot = json.loads(msg)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
            'channel' : utils.ANNOTATION_CHANNEL,
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
            'content' : params_annot
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
        }
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   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
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
            self.sendMessage(json.dumps(res))
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
        defer = self.process_annotation(params)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
        defer.addErrback(error_callback)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
        defer.addCallback(annot_callback)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
class AnotationServerFactory(WebSocketServerFactory):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
    def __init__(self, url, ws_factory, conn, debug = False, debugCodePaths = False):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
        WebSocketServerFactory.__init__(self, url, debug = debug, debugCodePaths = debugCodePaths)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
        self.ws_factory = ws_factory
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
        self.conn = conn
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
        self.clients = {}
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
        self.protocol = AnnotationServerProtocol