Completed
Push — master ( 641228...9a97a0 )
by Olivier
06:26 queued 02:23
created

CallbackDispatcher   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 51
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 51
rs 10
wmc 25

5 Methods

Rating   Name   Duplication   Size   Complexity  
C addSubscriber() 0 18 11
A __init__() 0 2 1
B dispatch() 0 11 5
B removeListener() 0 10 5
A addListener() 0 5 3
1
2
"""
3
server side implementation of callback event 
4
"""
5
6
from collections import OrderedDict
7
from enum import Enum
8
9
class CallbackType(Enum):
10
11
    '''
12
    The possible types of a Callback type.
13
14
    :ivar Null:
15
    :ivar MonitoredItem:
16
17
    '''
18
    Null = 0
19
    ItemSubscriptionCreated = 1
20
    ItemSubscriptionModified = 2
21
    ItemSubscriptionDeleted= 3
22
   
23
24
25
class Callback(object):
26
    def __init__(self):
27
        self.__name = None
28
29
    def setName(self, name):
30
        self.__name = name
31
32
    def getName(self):
33
        return self.__name
34
35
36
class ServerItemCallback(Callback):
37
    def __init__(self, request_params, response_params):
38
        self.request_params = request_params
39
        self.response_params = response_params
40
        
41
42
class CallbackSubscriberInterface(object):
43
    def getSubscribedEvents(self):
44
        raise NotImplementedError()
45
46
47
class CallbackDispatcher(object):
48
    def __init__(self):
49
        self._listeners = {}
50
51
    def dispatch(self, eventName, event=None):
52
        if event is None:
53
            event = Callback()
54
        elif not isinstance(event, Callback):
55
            raise ValueError('Unexpected event type given')
56
        event.setName(eventName)
57
        if eventName not in self._listeners:
58
            return event
59
        for listener in self._listeners[eventName].values():
60
            listener(event, self)
61
        return event
62
63
    def addListener(self, eventName, listener, priority=0):
64
        if eventName not in self._listeners:
65
            self._listeners[eventName] = {}
66
        self._listeners[eventName][priority] = listener
67
        self._listeners[eventName] = OrderedDict(sorted(self._listeners[eventName].items(), key=lambda item: item[0]))
68
69
    def removeListener(self, eventName, listener=None):
70
        if eventName not in self._listeners:
71
            return
72
        if not listener:
73
            del self._listeners[eventName]
74
        else:
75
            for p, l in self._listeners[eventName].items():
76
                if l is listener:
77
                    self._listeners[eventName].pop(p)
78
                    return
79
80
    def addSubscriber(self, subscriber):
81
        if not isinstance(subscriber, CallbackSubscriberInterface):
82
            raise ValueError('Unexpected subscriber type given')
83
        for eventName, params in subscriber.getSubscribedEvents().items():
84
            if isinstance(params, str):
85
                self.addListener(eventName, getattr(subscriber, params))
86
            elif isinstance(params, list):
87
                if not params:
88
                    raise ValueError('Invalid params "%r" for event "%s"' % (params, eventName))
89
                if len(params) <= 2 and isinstance(params[0], str):
90
                    priority = params[1] if len(params) > 1 else 0
91
                    self.addListener(eventName, getattr(subscriber, params[0]), priority)
92
                else:
93
                    for listener in params:
94
                        priority = listener[1] if len(listener) > 1 else 0
95
                        self.addListener(eventName, getattr(subscriber, listener[0]), priority)
96
            else:
97
                raise ValueError('Invalid params for event "%s"' % eventName)
98
99
100