Passed
Push — master ( 3636b6...a47c1d )
by Olivier
02:42
created

asyncua.common.callback.CallbackService.__init__()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
"""
2
server side implementation of callback event 
3
"""
4
5
from collections import OrderedDict
6
from enum import Enum
7
import asyncio
8
9
10
class CallbackType(Enum):
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
    PreWrite = 4
23
    PostWrite = 5
24
    PreRead = 6
25
    PostRead = 7
26
27
28
class Callback(object):
29
    def __init__(self):
30
        self.__name = None
31
32
    def setName(self, name):
33
        self.__name = name
34
35
    def getName(self):
36
        return self.__name
37
38
39
class ServerItemCallback(Callback):
40
    def __init__(self, request_params, response_params, user=None):
41
        self.request_params = request_params
42
        self.response_params = response_params
43
        self.user = user
44
45
46
class CallbackSubscriberInterface(object):
47
    def getSubscribedEvents(self):
48
        raise NotImplementedError()
49
50
51
class CallbackService(object):
52
    def __init__(self):
53
        self._listeners = {}
54
55
    async def dispatch(self, eventName, event=None):
56
        if event is None:
57
            event = Callback()
58
        elif not isinstance(event, Callback):
59
            raise ValueError('Unexpected event type given')
60
        event.setName(eventName)
61
        if eventName not in self._listeners:
62
            return event
63
        for listener in self._listeners[eventName].values():
64
            await self.call_listener(event, listener)
65
66
        return event
67
68
    async def call_listener(self, event, listener):
69
        if asyncio.iscoroutinefunction(listener):
70
            await listener(event, self)
71
        else:
72
            listener(event, self)
73
74
    def addListener(self, eventName, listener, priority=0):
75
        if eventName not in self._listeners:
76
            self._listeners[eventName] = {}
77
        self._listeners[eventName][priority] = listener
78
        self._listeners[eventName] = OrderedDict(sorted(self._listeners[eventName].items(), key=lambda item: item[0]))
79
80
    def removeListener(self, eventName, listener=None):
81
        if eventName not in self._listeners:
82
            return
83
        if not listener:
84
            del self._listeners[eventName]
85
        else:
86
            for p, l in self._listeners[eventName].items():
87
                if l is listener:
88
                    self._listeners[eventName].pop(p)
89
                    return
90
91
    def addSubscriber(self, subscriber):
92
        if not isinstance(subscriber, CallbackSubscriberInterface):
93
            raise ValueError('Unexpected subscriber type given')
94
        for eventName, params in subscriber.getSubscribedEvents().items():
95
            if isinstance(params, str):
96
                self.addListener(eventName, getattr(subscriber, params))
97
            elif isinstance(params, list):
98
                if not params:
99
                    raise ValueError(f'Invalid params "{repr(params)}" for event "{str(eventName)}"')
100
                if len(params) <= 2 and isinstance(params[0], str):
101
                    priority = params[1] if len(params) > 1 else 0
102
                    self.addListener(eventName, getattr(subscriber, params[0]), priority)
103
                else:
104
                    for listener in params:
105
                        priority = listener[1] if len(listener) > 1 else 0
106
                        self.addListener(eventName, getattr(subscriber, listener[0]), priority)
107
            else:
108
                raise ValueError(f'Invalid params for event "{str(eventName)}"')
109