annotate sat/plugins/plugin_exp_pubsub_hook.py @ 3011:93da7c6f8e0c

plugin XEP-0198: retrieve missing messages + send buffered ones on hot reconnection: Missing one2one messages are now retrieved with MAM on hot reconnection, and buffered ones (which have most probably not been received by the server) are resent at the end of the reconnection workflow. IQ results are not re-sent on hot reconnection, as they don't make sense anymore with a new session. fix 330
author Goffi <goffi@goffi.org>
date Wed, 17 Jul 2019 09:28:35 +0200
parents 003b8b4b56a7
children ab2696e34d29
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python2
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # SAT plugin for Pubsub Hooks
2771
003b8b4b56a7 date update
Goffi <goffi@goffi.org>
parents: 2624
diff changeset
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from sat.core.i18n import _
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.constants import Const as C
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core import exceptions
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.core.log import getLogger
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat.memory import persistent
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from twisted.words.protocols.jabber import jid
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from twisted.internet import defer
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
27
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 log = getLogger(__name__)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
30 NS_PUBSUB_HOOK = "PUBSUB_HOOK"
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 PLUGIN_INFO = {
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 C.PI_NAME: "PubSub Hook",
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 C.PI_IMPORT_NAME: NS_PUBSUB_HOOK,
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 C.PI_TYPE: "EXP",
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 C.PI_PROTOCOLS: [],
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 C.PI_DEPENDENCIES: ["XEP-0060"],
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 C.PI_MAIN: "PubsubHook",
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 C.PI_HANDLER: "no",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
40 C.PI_DESCRIPTION: _(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
41 """Experimental plugin to launch on action on Pubsub notifications"""
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
42 ),
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 }
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
45 #  python module
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
46 HOOK_TYPE_PYTHON = u"python"
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 # python file path
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
48 HOOK_TYPE_PYTHON_FILE = u"python_file"
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 # python code directly
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
50 HOOK_TYPE_PYTHON_CODE = u"python_code"
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 HOOK_TYPES = (HOOK_TYPE_PYTHON, HOOK_TYPE_PYTHON_FILE, HOOK_TYPE_PYTHON_CODE)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 class PubsubHook(object):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 def __init__(self, host):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 log.info(_(u"PubSub Hook initialization"))
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 self.host = host
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 self.node_hooks = {} # keep track of the number of hooks per node (for all profiles)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
59 host.bridge.addMethod(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
60 "psHookAdd", ".plugin", in_sign="ssssbs", out_sign="", method=self._addHook
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
61 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
62 host.bridge.addMethod(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
63 "psHookRemove",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
64 ".plugin",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
65 in_sign="sssss",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
66 out_sign="i",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
67 method=self._removeHook,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
68 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
69 host.bridge.addMethod(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
70 "psHookList",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
71 ".plugin",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
72 in_sign="s",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
73 out_sign="aa{ss}",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
74 method=self._listHooks,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
75 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
76
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 @defer.inlineCallbacks
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 def profileConnected(self, client):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
79 hooks = client._hooks = persistent.PersistentBinaryDict(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
80 NS_PUBSUB_HOOK, client.profile
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
81 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 client._hooks_temporary = {}
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 yield hooks.load()
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 for node in hooks:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 self._installNodeManager(client, node)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
86
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 def profileDisconnected(self, client):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 for node in client._hooks:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 self._removeNodeManager(client, node)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
90
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 def _installNodeManager(self, client, node):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 if node in self.node_hooks:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 log.debug(_(u"node manager already set for {node}").format(node=node))
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 self.node_hooks[node] += 1
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 else:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 # first hook on this node
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
97 self.host.plugins["XEP-0060"].addManagedNode(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
98 node, items_cb=self._itemsReceived
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
99 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 self.node_hooks[node] = 0
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
101 log.info(_(u"node manager installed on {node}").format(node=node))
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
102
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 def _removeNodeManager(self, client, node):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 try:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
105 self.node_hooks[node] -= 1
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 except KeyError:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
107 log.error(_(u"trying to remove a {node} without hook").format(node=node))
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
108 else:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 if self.node_hooks[node] == 0:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 del self.node_hooks[node]
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
111 self.host.plugins["XEP-0060"].removeManagedNode(node, self._itemsReceived)
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 log.debug(_(u"hook removed"))
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 else:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 log.debug(_(u"node still needed for an other hook"))
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
115
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 def installHook(self, client, service, node, hook_type, hook_arg, persistent):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 if hook_type not in HOOK_TYPES:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
118 raise exceptions.DataError(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
119 _(u"{hook_type} is not handled").format(hook_type=hook_type)
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
120 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 if hook_type != HOOK_TYPE_PYTHON_FILE:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
122 raise NotImplementedError(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
123 _(u"{hook_type} hook type not implemented yet").format(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
124 hook_type=hook_type
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
125 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
126 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
127 self._installNodeManager(client, node)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
128 hook_data = {"service": service, "type": hook_type, "arg": hook_arg}
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
129
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
130 if persistent:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
131 hooks_list = client._hooks.setdefault(node, [])
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 hooks_list.append(hook_data)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 client._hooks.force(node)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
135 hooks_list = client._hooks_temporary.setdefault(node, [])
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 hooks_list.append(hook_data)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
137
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
138 log.info(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
139 _(u"{persistent} hook installed on {node} for {profile}").format(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
140 persistent=_(u"persistent") if persistent else _(u"temporary"),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
141 node=node,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
142 profile=client.profile,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
143 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
144 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
145
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 def _itemsReceived(self, client, itemsEvent):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
147 node = itemsEvent.nodeIdentifier
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 for hooks in (client._hooks, client._hooks_temporary):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 if node not in hooks:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 continue
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 hooks_list = hooks[node]
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 for hook_data in hooks_list[:]:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
153 if hook_data["service"] != itemsEvent.sender.userhostJID():
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 continue
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
155 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
156 callback = hook_data["callback"]
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 except KeyError:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 # first time we get this hook, we create the callback
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
159 hook_type = hook_data["type"]
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
160 try:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 if hook_type == HOOK_TYPE_PYTHON_FILE:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 hook_globals = {}
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
163 execfile(hook_data["arg"], hook_globals)
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
164 callback = hook_globals["hook"]
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
165 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
166 raise NotImplementedError(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
167 _(u"{hook_type} hook type not implemented yet").format(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
168 hook_type=hook_type
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
169 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
170 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 except Exception as e:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
172 log.warning(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
173 _(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
174 u"Can't load Pubsub hook at node {node}, it will be removed: {reason}"
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
175 ).format(node=node, reason=e)
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
176 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 hooks_list.remove(hook_data)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 continue
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
179
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 for item in itemsEvent.items:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 try:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 callback(self.host, client, item)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 except Exception as e:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
184 log.warning(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
185 _(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
186 u"Error while running Pubsub hook for node {node}: {msg}"
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
187 ).format(node=node, msg=e)
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
188 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
189
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 def _addHook(self, service, node, hook_type, hook_arg, persistent, profile):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 client = self.host.getClient(profile)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 service = jid.JID(service) if service else client.jid.userhostJID()
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
193 return self.addHook(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
194 client,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
195 service,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
196 unicode(node),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
197 unicode(hook_type),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
198 unicode(hook_arg),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
199 persistent,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
200 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
201
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 def addHook(self, client, service, node, hook_type, hook_arg, persistent):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 r"""Add a hook which will be triggered on a pubsub notification
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
204
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 @param service(jid.JID): service of the node
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 @param node(unicode): Pubsub node
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 @param hook_type(unicode): type of the hook, one of:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 - HOOK_TYPE_PYTHON: a python module (must be in path)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 module must have a "hook" method which will be called
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 - HOOK_TYPE_PYTHON_FILE: a python file
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 file must have a "hook" method which will be called
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 - HOOK_TYPE_PYTHON_CODE: direct python code
2444
30278ea1ca7c plugin XEP-0060: added node watching methods to bridge:
Goffi <goffi@goffi.org>
parents: 2307
diff changeset
213 /!\ Python hooks will be executed in SàT context,
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 with host, client and item as arguments, it means that:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 - they can do whatever they wants, so don't run untrusted hooks
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 - they MUST NOT BLOCK, they are run in Twisted async environment and blocking would block whole SàT process
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 - item are domish.Element
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 @param hook_arg(unicode): argument of the hook, depending on the hook_type
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 can be a module path, file path, python code
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 """
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 assert service is not None
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 return self.installHook(client, service, node, hook_type, hook_arg, persistent)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
223
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 def _removeHook(self, service, node, hook_type, hook_arg, profile):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 client = self.host.getClient(profile)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 service = jid.JID(service) if service else client.jid.userhostJID()
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 return self.removeHook(client, service, node, hook_type or None, hook_arg or None)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
228
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 def removeHook(self, client, service, node, hook_type=None, hook_arg=None):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 """Remove a persistent or temporaty root
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
231
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 @param service(jid.JID): service of the node
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 @param node(unicode): Pubsub node
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 @param hook_type(unicode, None): same as for [addHook]
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 match all if None
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 @param hook_arg(unicode, None): same as for [addHook]
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 match all if None
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 @return(int): number of hooks removed
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 """
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 removed = 0
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 for hooks in (client._hooks, client._hooks_temporary):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 if node in hooks:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 for hook_data in hooks[node]:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
244 if (
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
245 service != hook_data[u"service"]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
246 or hook_type is not None
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
247 and hook_type != hook_data[u"type"]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
248 or hook_arg is not None
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
249 and hook_arg != hook_data[u"arg"]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
250 ):
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 continue
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 hooks[node].remove(hook_data)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 removed += 1
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 if not hooks[node]:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
255 #  no more hooks, we can remove the node
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 del hooks[node]
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
257 self._removeNodeManager(client, node)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 else:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 if hooks == client._hooks:
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
260 hooks.force(node)
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 return removed
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
262
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 def _listHooks(self, profile):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 hooks_list = self.listHooks(self.host.getClient(profile))
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 for hook in hooks_list:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
266 hook[u"service"] = hook[u"service"].full()
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
267 hook[u"persistent"] = C.boolConst(hook[u"persistent"])
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 return hooks_list
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
269
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 def listHooks(self, client):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 """return list of registered hooks"""
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 hooks_list = []
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
273 for hooks in (client._hooks, client._hooks_temporary):
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 persistent = hooks is client._hooks
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
275 for node, hooks_data in hooks.iteritems():
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
276 for hook_data in hooks_data:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
277 hooks_list.append(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
278 {
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
279 u"service": hook_data[u"service"],
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
280 u"node": node,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
281 u"type": hook_data[u"type"],
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
282 u"arg": hook_data[u"arg"],
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
283 u"persistent": persistent,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
284 }
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
285 )
2307
8fa7edd0da24 plugin Pubsub Hook: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
286 return hooks_list