Mercurial > libervia-backend
comparison sat/plugins/plugin_xep_0054.py @ 3277:cf07641b764d
plugin identity: fixed infinite loop on nicknames update
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 18 May 2020 23:52:34 +0200 |
parents | 7aa01e262e05 |
children | 8de63fe6b5c9 |
comparison
equal
deleted
inserted
replaced
3276:81c8910db91f | 3277:cf07641b764d |
---|---|
46 try: | 46 try: |
47 from twisted.words.protocols.xmlstream import XMPPHandler | 47 from twisted.words.protocols.xmlstream import XMPPHandler |
48 except ImportError: | 48 except ImportError: |
49 from wokkel.subprotocols import XMPPHandler | 49 from wokkel.subprotocols import XMPPHandler |
50 | 50 |
51 IMPORT_NAME = "XEP-0054" | |
51 | 52 |
52 PLUGIN_INFO = { | 53 PLUGIN_INFO = { |
53 C.PI_NAME: "XEP 0054 Plugin", | 54 C.PI_NAME: "XEP 0054 Plugin", |
54 C.PI_IMPORT_NAME: "XEP-0054", | 55 C.PI_IMPORT_NAME: IMPORT_NAME, |
55 C.PI_TYPE: "XEP", | 56 C.PI_TYPE: "XEP", |
56 C.PI_PROTOCOLS: ["XEP-0054", "XEP-0153"], | 57 C.PI_PROTOCOLS: ["XEP-0054", "XEP-0153"], |
57 C.PI_DEPENDENCIES: ["IDENTITY"], | 58 C.PI_DEPENDENCIES: ["IDENTITY"], |
58 C.PI_RECOMMENDATIONS: [], | 59 C.PI_RECOMMENDATIONS: [], |
59 C.PI_MAIN: "XEP_0054", | 60 C.PI_MAIN: "XEP_0054", |
79 | 80 |
80 def __init__(self, host): | 81 def __init__(self, host): |
81 log.info(_("Plugin XEP_0054 initialization")) | 82 log.info(_("Plugin XEP_0054 initialization")) |
82 self.host = host | 83 self.host = host |
83 self._i = host.plugins['IDENTITY'] | 84 self._i = host.plugins['IDENTITY'] |
84 self._i.register('avatar', self.getAvatar, self.setAvatar) | 85 self._i.register(IMPORT_NAME, 'avatar', self.getAvatar, self.setAvatar) |
85 self._i.register('nicknames', self.getNicknames, self.setNicknames) | 86 self._i.register(IMPORT_NAME, 'nicknames', self.getNicknames, self.setNicknames) |
86 host.trigger.add("presence_available", self.presenceAvailableTrigger) | 87 host.trigger.add("presence_available", self.presenceAvailableTrigger) |
87 | 88 |
88 def getHandler(self, client): | 89 def getHandler(self, client): |
89 return XEP_0054_handler(self) | 90 return XEP_0054_handler(self) |
90 | 91 |
104 async def profileConnecting(self, client): | 105 async def profileConnecting(self, client): |
105 client._xep_0054_avatar_hashes = persistent.PersistentDict( | 106 client._xep_0054_avatar_hashes = persistent.PersistentDict( |
106 NS_VCARD, client.profile) | 107 NS_VCARD, client.profile) |
107 await client._xep_0054_avatar_hashes.load() | 108 await client._xep_0054_avatar_hashes.load() |
108 | 109 |
109 def getCache(self, client, entity_jid, name): | |
110 """return cached value for jid | |
111 | |
112 @param entity_jid(jid.JID): target contact | |
113 @param name(unicode): name of the value ('nick' or 'avatar') | |
114 @return(unicode, None): wanted value or None""" | |
115 entity_jid = self._i.getIdentityJid(client, entity_jid) | |
116 try: | |
117 data = self.host.memory.getEntityData(client, entity_jid, [name]) | |
118 except exceptions.UnknownEntityError: | |
119 return None | |
120 return data.get(name) | |
121 | |
122 def savePhoto(self, client, photo_elt, entity_jid): | 110 def savePhoto(self, client, photo_elt, entity_jid): |
123 """Parse a <PHOTO> photo_elt and save the picture""" | 111 """Parse a <PHOTO> photo_elt and save the picture""" |
124 # XXX: this method is launched in a separate thread | 112 # XXX: this method is launched in a separate thread |
125 try: | 113 try: |
126 mime_type = str(next(photo_elt.elements(NS_VCARD, "TYPE"))) | 114 mime_type = str(next(photo_elt.elements(NS_VCARD, "TYPE"))) |
182 vcard_dict["fullname"] = str(elem) | 170 vcard_dict["fullname"] = str(elem) |
183 elif elem.name == "NICKNAME": | 171 elif elem.name == "NICKNAME": |
184 nickname = vcard_dict["nickname"] = str(elem) | 172 nickname = vcard_dict["nickname"] = str(elem) |
185 await self._i.update( | 173 await self._i.update( |
186 client, | 174 client, |
175 IMPORT_NAME, | |
187 "nicknames", | 176 "nicknames", |
188 [nickname], | 177 [nickname], |
189 entity_jid | 178 entity_jid |
190 ) | 179 ) |
191 elif elem.name == "URL": | 180 elif elem.name == "URL": |
214 | 203 |
215 if avatar_hash: | 204 if avatar_hash: |
216 avatar_cache = self.host.common_cache.getMetadata(avatar_hash) | 205 avatar_cache = self.host.common_cache.getMetadata(avatar_hash) |
217 await self._i.update( | 206 await self._i.update( |
218 client, | 207 client, |
208 IMPORT_NAME, | |
219 "avatar", | 209 "avatar", |
220 { | 210 { |
221 'path': avatar_cache['path'], | 211 'path': avatar_cache['path'], |
222 'media_type': avatar_cache['mime_type'], | 212 'media_type': avatar_cache['mime_type'], |
223 'cache_uid': avatar_hash | 213 'cache_uid': avatar_hash |
224 }, | 214 }, |
225 entity_jid | 215 entity_jid |
226 ) | 216 ) |
227 else: | 217 else: |
228 await self._i.update(client, "avatar", None, entity_jid) | 218 await self._i.update( |
219 client, IMPORT_NAME, "avatar", None, entity_jid) | |
229 else: | 220 else: |
230 log.debug("FIXME: [{}] VCard_elt tag is not managed yet".format(elem.name)) | 221 log.debug("FIXME: [{}] VCard_elt tag is not managed yet".format(elem.name)) |
231 | 222 |
232 return vcard_dict | 223 return vcard_dict |
233 | 224 |
286 entity_jid = self._i.getIdentityJid(client, entity_jid) | 277 entity_jid = self._i.getIdentityJid(client, entity_jid) |
287 log.debug(f"Asking for {entity_jid}'s VCard") | 278 log.debug(f"Asking for {entity_jid}'s VCard") |
288 try: | 279 try: |
289 vcard_elt = await self.getVCardElement(client, entity_jid) | 280 vcard_elt = await self.getVCardElement(client, entity_jid) |
290 except exceptions.DataError: | 281 except exceptions.DataError: |
291 self._i.update(client, "avatar", None, entity_jid) | 282 self._i.update(client, IMPORT_NAME, "avatar", IMPORT_NAME, None, entity_jid) |
292 except Exception as e: | 283 except Exception as e: |
293 log.warning(_( | 284 log.warning(_( |
294 "Can't get vCard for {entity_jid}: {e}" | 285 "Can't get vCard for {entity_jid}: {e}" |
295 ).format(entity_jid=entity_jid, e=e)) | 286 ).format(entity_jid=entity_jid, e=e)) |
296 else: | 287 else: |
311 except KeyError: | 302 except KeyError: |
312 log.debug(f"avatar for {entity_jid} is not in cache, we retrieve it") | 303 log.debug(f"avatar for {entity_jid} is not in cache, we retrieve it") |
313 vcard = await self.getCard(client, entity_jid) | 304 vcard = await self.getCard(client, entity_jid) |
314 if vcard is None: | 305 if vcard is None: |
315 return None | 306 return None |
316 avatar_hash = hashes_cache[entity_jid.full()] | 307 try: |
308 avatar_hash = hashes_cache[entity_jid.full()] | |
309 except KeyError: | |
310 if 'avatar' in vcard: | |
311 raise exceptions.InternalError( | |
312 "No avatar hash while avatar is found in vcard") | |
313 return None | |
317 | 314 |
318 if not avatar_hash: | 315 if not avatar_hash: |
319 return None | 316 return None |
320 | 317 |
321 avatar_cache = self.host.common_cache.getMetadata(avatar_hash) | 318 avatar_cache = self.host.common_cache.getMetadata(avatar_hash) |
505 | 502 |
506 await hashes_cache.aset(entity_jid.full(), new_hash) | 503 await hashes_cache.aset(entity_jid.full(), new_hash) |
507 | 504 |
508 if not new_hash: | 505 if not new_hash: |
509 await self.plugin_parent._i.update( | 506 await self.plugin_parent._i.update( |
510 client, "avatar", None, entity_jid) | 507 client, IMPORT_NAME, "avatar", None, entity_jid) |
511 # the avatar has been removed, no need to go further | 508 # the avatar has been removed, no need to go further |
512 return | 509 return |
513 | 510 |
514 avatar_cache = self.host.common_cache.getMetadata(new_hash) | 511 avatar_cache = self.host.common_cache.getMetadata(new_hash) |
515 if avatar_cache is not None: | 512 if avatar_cache is not None: |
516 log.debug( | 513 log.debug( |
517 f"New avatar found for [{entity_jid}], it's already in cache, we use it" | 514 f"New avatar found for [{entity_jid}], it's already in cache, we use it" |
518 ) | 515 ) |
519 await self.plugin_parent._i.update( | 516 await self.plugin_parent._i.update( |
520 client, | 517 client, |
521 "avatar", | 518 IMPORT_NAME, "avatar", |
522 { | 519 { |
523 'path': avatar_cache['path'], | 520 'path': avatar_cache['path'], |
524 'media_type': avatar_cache['mime_type'], | 521 'media_type': avatar_cache['mime_type'], |
525 'cache_uid': new_hash, | 522 'cache_uid': new_hash, |
526 }, | 523 }, |