diff options
author | mathieui <mathieui@mathieui.net> | 2021-02-14 12:00:25 +0100 |
---|---|---|
committer | mathieui <mathieui@mathieui.net> | 2021-02-26 00:08:56 +0100 |
commit | ab87b2503042ec9cf226574fa68af1b5b9809cc7 (patch) | |
tree | 285f4c588de15d37a5d7be361a6d46bc640dfde3 | |
parent | e24e2f58d4e9c71ef005a4dfe88abac7bff1cc6b (diff) | |
download | slixmpp-ab87b2503042ec9cf226574fa68af1b5b9809cc7.tar.gz slixmpp-ab87b2503042ec9cf226574fa68af1b5b9809cc7.tar.bz2 slixmpp-ab87b2503042ec9cf226574fa68af1b5b9809cc7.tar.xz slixmpp-ab87b2503042ec9cf226574fa68af1b5b9809cc7.zip |
XEP-0153: API changes
-rw-r--r-- | docs/api/plugins/xep_0153.rst | 36 | ||||
-rw-r--r-- | slixmpp/plugins/xep_0153/vcard_avatar.py | 57 |
2 files changed, 63 insertions, 30 deletions
diff --git a/docs/api/plugins/xep_0153.rst b/docs/api/plugins/xep_0153.rst index 00e22098..bdcbc07c 100644 --- a/docs/api/plugins/xep_0153.rst +++ b/docs/api/plugins/xep_0153.rst @@ -9,6 +9,42 @@ XEP-0153: vCard-Based Avatars :exclude-members: session_bind, plugin_init, plugin_end +Internal API methods +-------------------- + +The internal API is used here to maintain an in-memory JID→avatar hash +cache. + +.. glossary:: + + set_hash + - **jid**: :class:`~.JID` of whom to retrieve the last activity + - **node**: unused + - **ifrom**: unused + - **args**: ``str``, avatar hash + + Set the avatar hash for a JID. + + reset_hash + - **jid**: :class:`~.JID` of whom to retrieve the last activity + - **node**: unused + - **ifrom**: :class:`~.JID` of the entity requesting the reset. + - **args**: unused + - **returns** + information. + + Reset the avatar hash for a JID. This downloads the vcard and computes + the hash. + + get_hash + - **jid**: :class:`~.JID` of whom to retrieve the last activity + - **node**: unused + - **ifrom**: unused + - **args**: unused + - **returns**: ``Optional[str]``, the avatar hash + + Get the avatar hash for a JID. + Stanza elements --------------- diff --git a/slixmpp/plugins/xep_0153/vcard_avatar.py b/slixmpp/plugins/xep_0153/vcard_avatar.py index 56bf899a..e2d98b0a 100644 --- a/slixmpp/plugins/xep_0153/vcard_avatar.py +++ b/slixmpp/plugins/xep_0153/vcard_avatar.py @@ -5,7 +5,7 @@ # See the file LICENSE for copying permission. import hashlib import logging -from asyncio import Future, ensure_future +from asyncio import Future from typing import ( Dict, Optional, @@ -13,7 +13,7 @@ from typing import ( from slixmpp import JID from slixmpp.stanza import Presence -from slixmpp.exceptions import XMPPError, IqTimeout +from slixmpp.exceptions import XMPPError, IqTimeout, IqError from slixmpp.xmlstream import register_stanza_plugin, ElementBase from slixmpp.plugins.base import BasePlugin from slixmpp.plugins.xep_0153 import stanza, VCardTempUpdate @@ -59,7 +59,6 @@ class XEP_0153(BasePlugin): self.xmpp.del_event_handler('presence_chat', self._recv_presence) self.xmpp.del_event_handler('presence_away', self._recv_presence) - @future_wrapper def set_avatar(self, jid: Optional[JID] = None, avatar: Optional[bytes] = None, mtype: Optional[str] = None, **iqkwargs) -> Future: @@ -97,10 +96,10 @@ class XEP_0153(BasePlugin): except IqTimeout as exc: timeout_cb(exc) raise - self.api['reset_hash'](jid) + await self.api['reset_hash'](jid) self.xmpp.roster[jid].send_last_presence() - return ensure_future(get_and_set_avatar(), loop=self.xmpp.loop) + return self.xmpp.wrap(get_and_set_avatar()) async def _start(self, event): try: @@ -110,22 +109,22 @@ class XEP_0153(BasePlugin): new_hash = '' else: new_hash = hashlib.sha1(data).hexdigest() - self.api['set_hash'](self.xmpp.boundjid, args=new_hash) + await self.api['set_hash'](self.xmpp.boundjid, args=new_hash) except XMPPError: log.debug('Could not retrieve vCard for %s', self.xmpp.boundjid.bare) - def _update_presence(self, stanza: ElementBase) -> ElementBase: + async def _update_presence(self, stanza: ElementBase) -> ElementBase: if not isinstance(stanza, Presence): return stanza if stanza['type'] not in ('available', 'dnd', 'chat', 'away', 'xa'): return stanza - current_hash = self.api['get_hash'](stanza['from']) + current_hash = await self.api['get_hash'](stanza['from']) stanza['vcard_temp_update']['photo'] = current_hash return stanza - def _recv_presence(self, pres: Presence): + async def _recv_presence(self, pres: Presence): try: if pres.get_plugin('muc', check=True): # Don't process vCard avatars for MUC occupants @@ -135,7 +134,7 @@ class XEP_0153(BasePlugin): pass if not pres.match('presence/vcard_temp_update'): - self.api['set_hash'](pres['from'], args=None) + await self.api['set_hash'](pres['from'], args=None) return data = pres['vcard_temp_update']['photo'] @@ -145,33 +144,31 @@ class XEP_0153(BasePlugin): # ================================================================= - def _reset_hash(self, jid: JID, node: str, ifrom: JID, args: Dict): + async def _reset_hash(self, jid: JID, node: str, ifrom: JID, args: Dict): own_jid = (jid.bare == self.xmpp.boundjid.bare) if self.xmpp.is_component: own_jid = (jid.domain == self.xmpp.boundjid.domain) - self.api['set_hash'](jid, args=None) + await self.api['set_hash'](jid, args=None) if own_jid: self.xmpp.roster[jid].send_last_presence() - def callback(iq): - if iq['type'] == 'error': - log.debug('Could not retrieve vCard for %s', jid) - return - try: - data = iq['vcard_temp']['PHOTO']['BINVAL'] - except ValueError: - log.debug('Invalid BINVAL in vCard’s PHOTO for %s:', jid, exc_info=True) - data = None - if not data: - new_hash = '' - else: - new_hash = hashlib.sha1(data).hexdigest() - - self.api['set_hash'](jid, args=new_hash) - - self.xmpp['xep_0054'].get_vcard(jid=jid.bare, ifrom=ifrom, - callback=callback) + try: + iq = await self.xmpp['xep_0054'].get_vcard(jid=jid.bare, ifrom=ifrom) + except (IqError, IqTimeout): + log.debug('Could not retrieve vCard for %s', jid) + return + try: + data = iq['vcard_temp']['PHOTO']['BINVAL'] + except ValueError: + log.debug('Invalid BINVAL in vCard’s PHOTO for %s:', jid, exc_info=True) + data = None + if not data: + new_hash = '' + else: + new_hash = hashlib.sha1(data).hexdigest() + + await self.api['set_hash'](jid, args=new_hash) def _get_hash(self, jid: JID, node: str, ifrom: JID, args: Dict): return self._hashes.get(jid.bare, None) |