1
- # Copyright 2017, Optimizely
1
+ # Copyright 2017-2019 , Optimizely
2
2
# Licensed under the Apache License, Version 2.0 (the "License");
3
3
# you may not use this file except in compliance with the License.
4
4
# You may obtain a copy of the License at
11
11
# See the License for the specific language governing permissions and
12
12
# limitations under the License.
13
13
14
- from functools import reduce
15
-
16
14
from .helpers import enums
15
+ from . import logger as optimizely_logger
16
+
17
+
18
+ NOTIFICATION_TYPES = tuple (getattr (enums .NotificationTypes , attr )
19
+ for attr in dir (enums .NotificationTypes )
20
+ if not attr .startswith ('__' ))
17
21
18
22
19
23
class NotificationCenter (object ):
20
- """ Class encapsulating Broadcast Notifications. The enums.NotifcationTypes includes predefined notifications."""
24
+ """ Class encapsulating methods to manage notifications and their listeners.
25
+ The enums.NotificationTypes includes predefined notifications."""
21
26
22
- def __init__ (self , logger ):
23
- self .notification_id = 1
24
- self .notifications = {}
25
- for ( attr , value ) in enums . NotificationTypes . __dict__ . items () :
26
- self .notifications [ value ] = []
27
- self .logger = logger
27
+ def __init__ (self , logger = None ):
28
+ self .listener_id = 1
29
+ self .notification_listeners = {}
30
+ for notification_type in NOTIFICATION_TYPES :
31
+ self .notification_listeners [ notification_type ] = []
32
+ self .logger = optimizely_logger . adapt_logger ( logger or optimizely_logger . NoOpLogger ())
28
33
29
34
def add_notification_listener (self , notification_type , notification_callback ):
30
- """ Add a notification callback to the notification center.
35
+ """ Add a notification callback to the notification center for a given notification type .
31
36
32
37
Args:
33
- notification_type: A string representing the notification type from . helpers.enums.NotificationTypes
34
- notification_callback: closure of function to call when event is triggered.
38
+ notification_type: A string representing the notification type from helpers.enums.NotificationTypes
39
+ notification_callback: Closure of function to call when event is triggered.
35
40
36
41
Returns:
37
- Integer notification id used to remove the notification or -1 if the notification has already been added.
42
+ Integer notification ID used to remove the notification or
43
+ -1 if the notification listener has already been added or
44
+ if the notification type is invalid.
38
45
"""
39
46
40
- if notification_type not in self .notifications :
41
- self .notifications [notification_type ] = [(self .notification_id , notification_callback )]
42
- else :
43
- if reduce (lambda a , b : a + 1 ,
44
- filter (lambda tup : tup [1 ] == notification_callback , self .notifications [notification_type ]),
45
- 0 ) > 0 :
46
- return - 1
47
- self .notifications [notification_type ].append ((self .notification_id , notification_callback ))
47
+ if notification_type not in NOTIFICATION_TYPES :
48
+ self .logger .error ('Invalid notification_type: {} provided. Not adding listener.' .format (notification_type ))
49
+ return - 1
48
50
49
- ret_val = self .notification_id
51
+ for _ , listener in self .notification_listeners [notification_type ]:
52
+ if listener == notification_callback :
53
+ self .logger .error ('Listener has already been added. Not adding it again.' )
54
+ return - 1
50
55
51
- self .notification_id += 1
56
+ self .notification_listeners [notification_type ].append ((self .listener_id , notification_callback ))
57
+ current_listener_id = self .listener_id
58
+ self .listener_id += 1
52
59
53
- return ret_val
60
+ return current_listener_id
54
61
55
62
def remove_notification_listener (self , notification_id ):
56
63
""" Remove a previously added notification callback.
@@ -62,40 +69,61 @@ def remove_notification_listener(self, notification_id):
62
69
The function returns boolean true if found and removed, false otherwise.
63
70
"""
64
71
65
- for v in self .notifications .values ():
66
- toRemove = list (filter (lambda tup : tup [0 ] == notification_id , v ))
67
- if len (toRemove ) > 0 :
68
- v .remove (toRemove [0 ])
72
+ for listener in self .notification_listeners .values ():
73
+ listener_to_remove = list (filter (lambda tup : tup [0 ] == notification_id , listener ))
74
+ if len (listener_to_remove ) > 0 :
75
+ listener .remove (listener_to_remove [0 ])
69
76
return True
70
77
71
78
return False
72
79
73
- def clear_all_notifications (self ):
74
- """ Remove all notifications """
75
- for key in self .notifications .keys ():
76
- self .notifications [key ] = []
80
+ def clear_notification_listeners (self , notification_type ):
81
+ """ Remove notification listeners for a certain notification type.
82
+
83
+ Args:
84
+ notification_type: String denoting notification type.
85
+ """
86
+
87
+ if notification_type not in NOTIFICATION_TYPES :
88
+ self .logger .error ('Invalid notification_type: {} provided. Not removing any listener.' .format (notification_type ))
89
+ self .notification_listeners [notification_type ] = []
77
90
78
91
def clear_notifications (self , notification_type ):
79
- """ Remove notifications for a certain notification type
92
+ """ (DEPRECATED since 3.2.0, use clear_notification_listeners)
93
+ Remove notification listeners for a certain notification type.
80
94
81
95
Args:
82
96
notification_type: key to the list of notifications .helpers.enums.NotificationTypes
83
97
"""
98
+ self .clear_notification_listeners (notification_type )
84
99
85
- self .notifications [notification_type ] = []
100
+ def clear_all_notification_listeners (self ):
101
+ """ Remove all notification listeners. """
102
+ for notification_type in self .notification_listeners .keys ():
103
+ self .clear_notification_listeners (notification_type )
104
+
105
+ def clear_all_notifications (self ):
106
+ """ (DEPRECATED since 3.2.0, use clear_all_notification_listeners)
107
+ Remove all notification listeners. """
108
+ self .clear_all_notification_listeners ()
86
109
87
110
def send_notifications (self , notification_type , * args ):
88
111
""" Fires off the notification for the specific event. Uses var args to pass in a
89
112
arbitrary list of parameter according to which notification type was fired.
90
113
91
114
Args:
92
115
notification_type: Type of notification to fire (String from .helpers.enums.NotificationTypes)
93
- args: variable list of arguments to the callback.
116
+ args: Variable list of arguments to the callback.
94
117
"""
95
118
96
- if notification_type in self .notifications :
97
- for notification_id , callback in self .notifications [notification_type ]:
119
+ if notification_type not in NOTIFICATION_TYPES :
120
+ self .logger .error ('Invalid notification_type: {} provided. '
121
+ 'Not triggering any notification.' .format (notification_type ))
122
+ return
123
+
124
+ if notification_type in self .notification_listeners :
125
+ for notification_id , callback in self .notification_listeners [notification_type ]:
98
126
try :
99
127
callback (* args )
100
128
except :
101
- self .logger .exception ('Problem calling notify callback!' )
129
+ self .logger .exception ('Unknown problem when sending "{}" type notification.' . format ( notification_type ) )
0 commit comments