comparison sat/plugins/plugin_xep_0115.py @ 2624:56f94936df1e

code style reformatting using black
author Goffi <goffi@goffi.org>
date Wed, 27 Jun 2018 20:14:46 +0200
parents e70023e84974
children 378188abe941
comparison
equal deleted inserted replaced
2623:49533de4540b 2624:56f94936df1e
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 from sat.core.i18n import _ 20 from sat.core.i18n import _
21 from sat.core.constants import Const as C 21 from sat.core.constants import Const as C
22 from sat.core.log import getLogger 22 from sat.core.log import getLogger
23
23 log = getLogger(__name__) 24 log = getLogger(__name__)
24 from twisted.words.xish import domish 25 from twisted.words.xish import domish
25 from twisted.words.protocols.jabber import jid 26 from twisted.words.protocols.jabber import jid
26 from twisted.internet import defer, error 27 from twisted.internet import defer, error
27 from zope.interface import implements 28 from zope.interface import implements
30 try: 31 try:
31 from twisted.words.protocols.xmlstream import XMPPHandler 32 from twisted.words.protocols.xmlstream import XMPPHandler
32 except ImportError: 33 except ImportError:
33 from wokkel.subprotocols import XMPPHandler 34 from wokkel.subprotocols import XMPPHandler
34 35
35 PRESENCE = '/presence' 36 PRESENCE = "/presence"
36 NS_ENTITY_CAPABILITY = 'http://jabber.org/protocol/caps' 37 NS_ENTITY_CAPABILITY = "http://jabber.org/protocol/caps"
37 NS_CAPS_OPTIMIZE = 'http://jabber.org/protocol/caps#optimize' 38 NS_CAPS_OPTIMIZE = "http://jabber.org/protocol/caps#optimize"
38 CAPABILITY_UPDATE = PRESENCE + '/c[@xmlns="' + NS_ENTITY_CAPABILITY + '"]' 39 CAPABILITY_UPDATE = PRESENCE + '/c[@xmlns="' + NS_ENTITY_CAPABILITY + '"]'
39 40
40 PLUGIN_INFO = { 41 PLUGIN_INFO = {
41 C.PI_NAME: "XEP 0115 Plugin", 42 C.PI_NAME: "XEP 0115 Plugin",
42 C.PI_IMPORT_NAME: "XEP-0115", 43 C.PI_IMPORT_NAME: "XEP-0115",
44 C.PI_MODES: C.PLUG_MODE_BOTH, 45 C.PI_MODES: C.PLUG_MODE_BOTH,
45 C.PI_PROTOCOLS: ["XEP-0115"], 46 C.PI_PROTOCOLS: ["XEP-0115"],
46 C.PI_DEPENDENCIES: [], 47 C.PI_DEPENDENCIES: [],
47 C.PI_MAIN: "XEP_0115", 48 C.PI_MAIN: "XEP_0115",
48 C.PI_HANDLER: "yes", 49 C.PI_HANDLER: "yes",
49 C.PI_DESCRIPTION: _("""Implementation of entity capabilities""") 50 C.PI_DESCRIPTION: _("""Implementation of entity capabilities"""),
50 } 51 }
51 52
52 53
53 class XEP_0115(object): 54 class XEP_0115(object):
54 cap_hash = None # capabilities hash is class variable as it is common to all profiles 55 cap_hash = None # capabilities hash is class variable as it is common to all profiles
73 client._caps_sent = False 74 client._caps_sent = False
74 else: 75 else:
75 log.warning(_(u"Caps optimisation not available")) 76 log.warning(_(u"Caps optimisation not available"))
76 77
77 # hash generation 78 # hash generation
78 _infos = yield client.discoHandler.info(client.jid, client.jid, '') 79 _infos = yield client.discoHandler.info(client.jid, client.jid, "")
79 disco_infos = disco.DiscoInfo() 80 disco_infos = disco.DiscoInfo()
80 for item in _infos: 81 for item in _infos:
81 disco_infos.append(item) 82 disco_infos.append(item)
82 cap_hash = client._caps_hash = self.host.memory.disco.generateHash(disco_infos) 83 cap_hash = client._caps_hash = self.host.memory.disco.generateHash(disco_infos)
83 log.info(u"Our capability hash has been generated: [{cap_hash}]".format( 84 log.info(
84 cap_hash = cap_hash)) 85 u"Our capability hash has been generated: [{cap_hash}]".format(
86 cap_hash=cap_hash
87 )
88 )
85 log.debug(u"Generating capability domish.Element") 89 log.debug(u"Generating capability domish.Element")
86 c_elt = domish.Element((NS_ENTITY_CAPABILITY, 'c')) 90 c_elt = domish.Element((NS_ENTITY_CAPABILITY, "c"))
87 c_elt['hash'] = 'sha-1' 91 c_elt["hash"] = "sha-1"
88 c_elt['node'] = C.APP_URL 92 c_elt["node"] = C.APP_URL
89 c_elt['ver'] = cap_hash 93 c_elt["ver"] = cap_hash
90 client._caps_elt = c_elt 94 client._caps_elt = c_elt
91 if client._caps_optimize: 95 if client._caps_optimize:
92 client._caps_sent = False 96 client._caps_sent = False
93 if cap_hash not in self.host.memory.disco.hashes: 97 if cap_hash not in self.host.memory.disco.hashes:
94 self.host.memory.disco.hashes[cap_hash] = disco_infos 98 self.host.memory.disco.hashes[cap_hash] = disco_infos
95 self.host.memory.updateEntityData(client.jid, C.ENTITY_CAP_HASH, cap_hash, profile_key=client.profile) 99 self.host.memory.updateEntityData(
100 client.jid, C.ENTITY_CAP_HASH, cap_hash, profile_key=client.profile
101 )
96 102
97 def _presenceAddElt(self, client, obj): 103 def _presenceAddElt(self, client, obj):
98 if client._caps_optimize: 104 if client._caps_optimize:
99 if client._caps_sent: 105 if client._caps_sent:
100 return 106 return
118 self.profile = profile 124 self.profile = profile
119 125
120 def connectionInitialized(self): 126 def connectionInitialized(self):
121 self.xmlstream.addObserver(CAPABILITY_UPDATE, self.update) 127 self.xmlstream.addObserver(CAPABILITY_UPDATE, self.update)
122 128
123 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): 129 def getDiscoInfo(self, requestor, target, nodeIdentifier=""):
124 return [disco.DiscoFeature(NS_ENTITY_CAPABILITY), disco.DiscoFeature(NS_CAPS_OPTIMIZE)] 130 return [
125 131 disco.DiscoFeature(NS_ENTITY_CAPABILITY),
126 def getDiscoItems(self, requestor, target, nodeIdentifier=''): 132 disco.DiscoFeature(NS_CAPS_OPTIMIZE),
133 ]
134
135 def getDiscoItems(self, requestor, target, nodeIdentifier=""):
127 return [] 136 return []
128 137
129 def update(self, presence): 138 def update(self, presence):
130 """ 139 """
131 Manage the capabilities of the entity 140 Manage the capabilities of the entity
132 141
133 Check if we know the version of this capabilities and get the capabilities if necessary 142 Check if we know the version of this capabilities and get the capabilities if necessary
134 """ 143 """
135 from_jid = jid.JID(presence['from']) 144 from_jid = jid.JID(presence["from"])
136 c_elem = presence.elements(NS_ENTITY_CAPABILITY, 'c').next() 145 c_elem = presence.elements(NS_ENTITY_CAPABILITY, "c").next()
137 try: 146 try:
138 c_ver = c_elem['ver'] 147 c_ver = c_elem["ver"]
139 c_hash = c_elem['hash'] 148 c_hash = c_elem["hash"]
140 c_node = c_elem['node'] 149 c_node = c_elem["node"]
141 except KeyError: 150 except KeyError:
142 log.warning(_(u'Received invalid capabilities tag: %s') % c_elem.toXml()) 151 log.warning(_(u"Received invalid capabilities tag: %s") % c_elem.toXml())
143 return 152 return
144 153
145 if c_ver in self.host.memory.disco.hashes: 154 if c_ver in self.host.memory.disco.hashes:
146 # we already know the hash, we update the jid entity 155 # we already know the hash, we update the jid entity
147 log.debug(u"hash [%(hash)s] already in cache, updating entity [%(jid)s]" % {'hash': c_ver, 'jid': from_jid.full()}) 156 log.debug(
148 self.host.memory.updateEntityData(from_jid, C.ENTITY_CAP_HASH, c_ver, profile_key=self.profile) 157 u"hash [%(hash)s] already in cache, updating entity [%(jid)s]"
158 % {"hash": c_ver, "jid": from_jid.full()}
159 )
160 self.host.memory.updateEntityData(
161 from_jid, C.ENTITY_CAP_HASH, c_ver, profile_key=self.profile
162 )
149 return 163 return
150 164
151 if c_hash != 'sha-1': # unknown hash method 165 if c_hash != "sha-1": # unknown hash method
152 log.warning(_(u'Unknown hash method for entity capabilities: [%(hash_method)s] (entity: %(jid)s, node: %(node)s)') % {'hash_method':c_hash, 'jid': from_jid, 'node': c_node}) 166 log.warning(
167 _(
168 u"Unknown hash method for entity capabilities: [%(hash_method)s] (entity: %(jid)s, node: %(node)s)"
169 )
170 % {"hash_method": c_hash, "jid": from_jid, "node": c_node}
171 )
153 172
154 def cb(dummy): 173 def cb(dummy):
155 computed_hash = self.host.memory.getEntityDatum(from_jid, C.ENTITY_CAP_HASH, self.profile) 174 computed_hash = self.host.memory.getEntityDatum(
175 from_jid, C.ENTITY_CAP_HASH, self.profile
176 )
156 if computed_hash != c_ver: 177 if computed_hash != c_ver:
157 log.warning(_(u'Computed hash differ from given hash:\ngiven: [%(given_hash)s]\ncomputed: [%(computed_hash)s]\n(entity: %(jid)s, node: %(node)s)') % {'given_hash':c_ver, 'computed_hash': computed_hash, 'jid': from_jid, 'node': c_node}) 178 log.warning(
179 _(
180 u"Computed hash differ from given hash:\ngiven: [%(given_hash)s]\ncomputed: [%(computed_hash)s]\n(entity: %(jid)s, node: %(node)s)"
181 )
182 % {
183 "given_hash": c_ver,
184 "computed_hash": computed_hash,
185 "jid": from_jid,
186 "node": c_node,
187 }
188 )
158 189
159 def eb(failure): 190 def eb(failure):
160 if isinstance(failure.value, error.ConnectionDone): 191 if isinstance(failure.value, error.ConnectionDone):
161 return 192 return
162 msg = failure.value.condition if hasattr(failure.value, 'condition') else failure.getErrorMessage() 193 msg = (
163 log.error(_(u"Couldn't retrieve disco info for {jid}: {error}").format(jid=from_jid.full(), error=msg)) 194 failure.value.condition
195 if hasattr(failure.value, "condition")
196 else failure.getErrorMessage()
197 )
198 log.error(
199 _(u"Couldn't retrieve disco info for {jid}: {error}").format(
200 jid=from_jid.full(), error=msg
201 )
202 )
164 203
165 d = self.host.getDiscoInfos(self.parent, from_jid) 204 d = self.host.getDiscoInfos(self.parent, from_jid)
166 d.addCallbacks(cb, eb) 205 d.addCallbacks(cb, eb)
167 # TODO: me must manage the full algorithm described at XEP-0115 #5.4 part 3 206 # TODO: me must manage the full algorithm described at XEP-0115 #5.4 part 3