Mercurial > libervia-backend
comparison sat/plugins/plugin_exp_pubsub_hook.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 26edcf3a30eb |
children | 003b8b4b56a7 |
comparison
equal
deleted
inserted
replaced
2623:49533de4540b | 2624:56f94936df1e |
---|---|
22 from sat.core import exceptions | 22 from sat.core import exceptions |
23 from sat.core.log import getLogger | 23 from sat.core.log import getLogger |
24 from sat.memory import persistent | 24 from sat.memory import persistent |
25 from twisted.words.protocols.jabber import jid | 25 from twisted.words.protocols.jabber import jid |
26 from twisted.internet import defer | 26 from twisted.internet import defer |
27 | |
27 log = getLogger(__name__) | 28 log = getLogger(__name__) |
28 | 29 |
29 NS_PUBSUB_HOOK = 'PUBSUB_HOOK' | 30 NS_PUBSUB_HOOK = "PUBSUB_HOOK" |
30 | 31 |
31 PLUGIN_INFO = { | 32 PLUGIN_INFO = { |
32 C.PI_NAME: "PubSub Hook", | 33 C.PI_NAME: "PubSub Hook", |
33 C.PI_IMPORT_NAME: NS_PUBSUB_HOOK, | 34 C.PI_IMPORT_NAME: NS_PUBSUB_HOOK, |
34 C.PI_TYPE: "EXP", | 35 C.PI_TYPE: "EXP", |
35 C.PI_PROTOCOLS: [], | 36 C.PI_PROTOCOLS: [], |
36 C.PI_DEPENDENCIES: ["XEP-0060"], | 37 C.PI_DEPENDENCIES: ["XEP-0060"], |
37 C.PI_MAIN: "PubsubHook", | 38 C.PI_MAIN: "PubsubHook", |
38 C.PI_HANDLER: "no", | 39 C.PI_HANDLER: "no", |
39 C.PI_DESCRIPTION: _("""Experimental plugin to launch on action on Pubsub notifications""") | 40 C.PI_DESCRIPTION: _( |
41 """Experimental plugin to launch on action on Pubsub notifications""" | |
42 ), | |
40 } | 43 } |
41 | 44 |
42 # python module | 45 # python module |
43 HOOK_TYPE_PYTHON = u'python' | 46 HOOK_TYPE_PYTHON = u"python" |
44 # python file path | 47 # python file path |
45 HOOK_TYPE_PYTHON_FILE = u'python_file' | 48 HOOK_TYPE_PYTHON_FILE = u"python_file" |
46 # python code directly | 49 # python code directly |
47 HOOK_TYPE_PYTHON_CODE = u'python_code' | 50 HOOK_TYPE_PYTHON_CODE = u"python_code" |
48 HOOK_TYPES = (HOOK_TYPE_PYTHON, HOOK_TYPE_PYTHON_FILE, HOOK_TYPE_PYTHON_CODE) | 51 HOOK_TYPES = (HOOK_TYPE_PYTHON, HOOK_TYPE_PYTHON_FILE, HOOK_TYPE_PYTHON_CODE) |
49 | 52 |
50 | 53 |
51 class PubsubHook(object): | 54 class PubsubHook(object): |
52 | |
53 def __init__(self, host): | 55 def __init__(self, host): |
54 log.info(_(u"PubSub Hook initialization")) | 56 log.info(_(u"PubSub Hook initialization")) |
55 self.host = host | 57 self.host = host |
56 self.node_hooks = {} # keep track of the number of hooks per node (for all profiles) | 58 self.node_hooks = {} # keep track of the number of hooks per node (for all profiles) |
57 host.bridge.addMethod("psHookAdd", ".plugin", | 59 host.bridge.addMethod( |
58 in_sign='ssssbs', out_sign='', | 60 "psHookAdd", ".plugin", in_sign="ssssbs", out_sign="", method=self._addHook |
59 method=self._addHook | 61 ) |
60 ) | 62 host.bridge.addMethod( |
61 host.bridge.addMethod("psHookRemove", ".plugin", | 63 "psHookRemove", |
62 in_sign='sssss', out_sign='i', | 64 ".plugin", |
63 method=self._removeHook | 65 in_sign="sssss", |
64 ) | 66 out_sign="i", |
65 host.bridge.addMethod("psHookList", ".plugin", | 67 method=self._removeHook, |
66 in_sign='s', out_sign='aa{ss}', | 68 ) |
67 method=self._listHooks | 69 host.bridge.addMethod( |
68 ) | 70 "psHookList", |
71 ".plugin", | |
72 in_sign="s", | |
73 out_sign="aa{ss}", | |
74 method=self._listHooks, | |
75 ) | |
69 | 76 |
70 @defer.inlineCallbacks | 77 @defer.inlineCallbacks |
71 def profileConnected(self, client): | 78 def profileConnected(self, client): |
72 hooks = client._hooks = persistent.PersistentBinaryDict(NS_PUBSUB_HOOK, client.profile) | 79 hooks = client._hooks = persistent.PersistentBinaryDict( |
80 NS_PUBSUB_HOOK, client.profile | |
81 ) | |
73 client._hooks_temporary = {} | 82 client._hooks_temporary = {} |
74 yield hooks.load() | 83 yield hooks.load() |
75 for node in hooks: | 84 for node in hooks: |
76 self._installNodeManager(client, node) | 85 self._installNodeManager(client, node) |
77 | 86 |
83 if node in self.node_hooks: | 92 if node in self.node_hooks: |
84 log.debug(_(u"node manager already set for {node}").format(node=node)) | 93 log.debug(_(u"node manager already set for {node}").format(node=node)) |
85 self.node_hooks[node] += 1 | 94 self.node_hooks[node] += 1 |
86 else: | 95 else: |
87 # first hook on this node | 96 # first hook on this node |
88 self.host.plugins['XEP-0060'].addManagedNode(node, items_cb=self._itemsReceived) | 97 self.host.plugins["XEP-0060"].addManagedNode( |
98 node, items_cb=self._itemsReceived | |
99 ) | |
89 self.node_hooks[node] = 0 | 100 self.node_hooks[node] = 0 |
90 log.info(_(u"node manager installed on {node}").format( | 101 log.info(_(u"node manager installed on {node}").format(node=node)) |
91 node = node)) | |
92 | 102 |
93 def _removeNodeManager(self, client, node): | 103 def _removeNodeManager(self, client, node): |
94 try: | 104 try: |
95 self.node_hooks[node] -= 1 | 105 self.node_hooks[node] -= 1 |
96 except KeyError: | 106 except KeyError: |
97 log.error(_(u"trying to remove a {node} without hook").format(node=node)) | 107 log.error(_(u"trying to remove a {node} without hook").format(node=node)) |
98 else: | 108 else: |
99 if self.node_hooks[node] == 0: | 109 if self.node_hooks[node] == 0: |
100 del self.node_hooks[node] | 110 del self.node_hooks[node] |
101 self.host.plugins['XEP-0060'].removeManagedNode(node, self._itemsReceived) | 111 self.host.plugins["XEP-0060"].removeManagedNode(node, self._itemsReceived) |
102 log.debug(_(u"hook removed")) | 112 log.debug(_(u"hook removed")) |
103 else: | 113 else: |
104 log.debug(_(u"node still needed for an other hook")) | 114 log.debug(_(u"node still needed for an other hook")) |
105 | 115 |
106 def installHook(self, client, service, node, hook_type, hook_arg, persistent): | 116 def installHook(self, client, service, node, hook_type, hook_arg, persistent): |
107 if hook_type not in HOOK_TYPES: | 117 if hook_type not in HOOK_TYPES: |
108 raise exceptions.DataError(_(u'{hook_type} is not handled').format(hook_type=hook_type)) | 118 raise exceptions.DataError( |
119 _(u"{hook_type} is not handled").format(hook_type=hook_type) | |
120 ) | |
109 if hook_type != HOOK_TYPE_PYTHON_FILE: | 121 if hook_type != HOOK_TYPE_PYTHON_FILE: |
110 raise NotImplementedError(_(u'{hook_type} hook type not implemented yet').format(hook_type=hook_type)) | 122 raise NotImplementedError( |
123 _(u"{hook_type} hook type not implemented yet").format( | |
124 hook_type=hook_type | |
125 ) | |
126 ) | |
111 self._installNodeManager(client, node) | 127 self._installNodeManager(client, node) |
112 hook_data = {'service': service, | 128 hook_data = {"service": service, "type": hook_type, "arg": hook_arg} |
113 'type': hook_type, | |
114 'arg': hook_arg | |
115 } | |
116 | 129 |
117 if persistent: | 130 if persistent: |
118 hooks_list = client._hooks.setdefault(node,[]) | 131 hooks_list = client._hooks.setdefault(node, []) |
119 hooks_list.append(hook_data) | 132 hooks_list.append(hook_data) |
120 client._hooks.force(node) | 133 client._hooks.force(node) |
121 else: | 134 else: |
122 hooks_list = client._hooks_temporary.setdefault(node,[]) | 135 hooks_list = client._hooks_temporary.setdefault(node, []) |
123 hooks_list.append(hook_data) | 136 hooks_list.append(hook_data) |
124 | 137 |
125 log.info(_(u"{persistent} hook installed on {node} for {profile}").format( | 138 log.info( |
126 persistent = _(u'persistent') if persistent else _(u'temporary'), | 139 _(u"{persistent} hook installed on {node} for {profile}").format( |
127 node = node, | 140 persistent=_(u"persistent") if persistent else _(u"temporary"), |
128 profile = client.profile)) | 141 node=node, |
142 profile=client.profile, | |
143 ) | |
144 ) | |
129 | 145 |
130 def _itemsReceived(self, client, itemsEvent): | 146 def _itemsReceived(self, client, itemsEvent): |
131 node = itemsEvent.nodeIdentifier | 147 node = itemsEvent.nodeIdentifier |
132 for hooks in (client._hooks, client._hooks_temporary): | 148 for hooks in (client._hooks, client._hooks_temporary): |
133 if node not in hooks: | 149 if node not in hooks: |
134 continue | 150 continue |
135 hooks_list = hooks[node] | 151 hooks_list = hooks[node] |
136 for hook_data in hooks_list[:]: | 152 for hook_data in hooks_list[:]: |
137 if hook_data['service'] != itemsEvent.sender.userhostJID(): | 153 if hook_data["service"] != itemsEvent.sender.userhostJID(): |
138 continue | 154 continue |
139 try: | 155 try: |
140 callback = hook_data['callback'] | 156 callback = hook_data["callback"] |
141 except KeyError: | 157 except KeyError: |
142 # first time we get this hook, we create the callback | 158 # first time we get this hook, we create the callback |
143 hook_type = hook_data['type'] | 159 hook_type = hook_data["type"] |
144 try: | 160 try: |
145 if hook_type == HOOK_TYPE_PYTHON_FILE: | 161 if hook_type == HOOK_TYPE_PYTHON_FILE: |
146 hook_globals = {} | 162 hook_globals = {} |
147 execfile(hook_data['arg'], hook_globals) | 163 execfile(hook_data["arg"], hook_globals) |
148 callback = hook_globals['hook'] | 164 callback = hook_globals["hook"] |
149 else: | 165 else: |
150 raise NotImplementedError(_(u'{hook_type} hook type not implemented yet').format( | 166 raise NotImplementedError( |
151 hook_type=hook_type)) | 167 _(u"{hook_type} hook type not implemented yet").format( |
168 hook_type=hook_type | |
169 ) | |
170 ) | |
152 except Exception as e: | 171 except Exception as e: |
153 log.warning(_(u"Can't load Pubsub hook at node {node}, it will be removed: {reason}").format( | 172 log.warning( |
154 node=node, reason=e)) | 173 _( |
174 u"Can't load Pubsub hook at node {node}, it will be removed: {reason}" | |
175 ).format(node=node, reason=e) | |
176 ) | |
155 hooks_list.remove(hook_data) | 177 hooks_list.remove(hook_data) |
156 continue | 178 continue |
157 | 179 |
158 for item in itemsEvent.items: | 180 for item in itemsEvent.items: |
159 try: | 181 try: |
160 callback(self.host, client, item) | 182 callback(self.host, client, item) |
161 except Exception as e: | 183 except Exception as e: |
162 log.warning(_(u"Error while running Pubsub hook for node {node}: {msg}").format( | 184 log.warning( |
163 node = node, | 185 _( |
164 msg = e)) | 186 u"Error while running Pubsub hook for node {node}: {msg}" |
187 ).format(node=node, msg=e) | |
188 ) | |
165 | 189 |
166 def _addHook(self, service, node, hook_type, hook_arg, persistent, profile): | 190 def _addHook(self, service, node, hook_type, hook_arg, persistent, profile): |
167 client = self.host.getClient(profile) | 191 client = self.host.getClient(profile) |
168 service = jid.JID(service) if service else client.jid.userhostJID() | 192 service = jid.JID(service) if service else client.jid.userhostJID() |
169 return self.addHook(client, service, unicode(node), unicode(hook_type), unicode(hook_arg), persistent) | 193 return self.addHook( |
194 client, | |
195 service, | |
196 unicode(node), | |
197 unicode(hook_type), | |
198 unicode(hook_arg), | |
199 persistent, | |
200 ) | |
170 | 201 |
171 def addHook(self, client, service, node, hook_type, hook_arg, persistent): | 202 def addHook(self, client, service, node, hook_type, hook_arg, persistent): |
172 r"""Add a hook which will be triggered on a pubsub notification | 203 r"""Add a hook which will be triggered on a pubsub notification |
173 | 204 |
174 @param service(jid.JID): service of the node | 205 @param service(jid.JID): service of the node |
208 """ | 239 """ |
209 removed = 0 | 240 removed = 0 |
210 for hooks in (client._hooks, client._hooks_temporary): | 241 for hooks in (client._hooks, client._hooks_temporary): |
211 if node in hooks: | 242 if node in hooks: |
212 for hook_data in hooks[node]: | 243 for hook_data in hooks[node]: |
213 if (service != hook_data[u'service'] | 244 if ( |
214 or hook_type is not None and hook_type != hook_data[u'type'] | 245 service != hook_data[u"service"] |
215 or hook_arg is not None and hook_arg != hook_data[u'arg']): | 246 or hook_type is not None |
247 and hook_type != hook_data[u"type"] | |
248 or hook_arg is not None | |
249 and hook_arg != hook_data[u"arg"] | |
250 ): | |
216 continue | 251 continue |
217 hooks[node].remove(hook_data) | 252 hooks[node].remove(hook_data) |
218 removed += 1 | 253 removed += 1 |
219 if not hooks[node]: | 254 if not hooks[node]: |
220 # no more hooks, we can remove the node | 255 # no more hooks, we can remove the node |
221 del hooks[node] | 256 del hooks[node] |
222 self._removeNodeManager(client, node) | 257 self._removeNodeManager(client, node) |
223 else: | 258 else: |
224 if hooks == client._hooks: | 259 if hooks == client._hooks: |
225 hooks.force(node) | 260 hooks.force(node) |
226 return removed | 261 return removed |
227 | 262 |
228 def _listHooks(self, profile): | 263 def _listHooks(self, profile): |
229 hooks_list = self.listHooks(self.host.getClient(profile)) | 264 hooks_list = self.listHooks(self.host.getClient(profile)) |
230 for hook in hooks_list: | 265 for hook in hooks_list: |
231 hook[u'service'] = hook[u'service'].full() | 266 hook[u"service"] = hook[u"service"].full() |
232 hook[u'persistent'] = C.boolConst(hook[u'persistent']) | 267 hook[u"persistent"] = C.boolConst(hook[u"persistent"]) |
233 return hooks_list | 268 return hooks_list |
234 | 269 |
235 def listHooks(self, client): | 270 def listHooks(self, client): |
236 """return list of registered hooks""" | 271 """return list of registered hooks""" |
237 hooks_list = [] | 272 hooks_list = [] |
238 for hooks in (client._hooks, client._hooks_temporary): | 273 for hooks in (client._hooks, client._hooks_temporary): |
239 persistent = hooks is client._hooks | 274 persistent = hooks is client._hooks |
240 for node, hooks_data in hooks.iteritems(): | 275 for node, hooks_data in hooks.iteritems(): |
241 for hook_data in hooks_data: | 276 for hook_data in hooks_data: |
242 hooks_list.append({u'service': hook_data[u'service'], | 277 hooks_list.append( |
243 u'node': node, | 278 { |
244 u'type': hook_data[u'type'], | 279 u"service": hook_data[u"service"], |
245 u'arg': hook_data[u'arg'], | 280 u"node": node, |
246 u'persistent': persistent | 281 u"type": hook_data[u"type"], |
247 }) | 282 u"arg": hook_data[u"arg"], |
283 u"persistent": persistent, | |
284 } | |
285 ) | |
248 return hooks_list | 286 return hooks_list |
249 |