XEP-0153: API changes

This commit is contained in:
mathieui 2021-02-14 12:00:25 +01:00
parent e24e2f58d4
commit ab87b25030
2 changed files with 62 additions and 29 deletions

View File

@ -9,6 +9,42 @@ XEP-0153: vCard-Based Avatars
:exclude-members: session_bind, plugin_init, plugin_end :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 Stanza elements
--------------- ---------------

View File

@ -5,7 +5,7 @@
# See the file LICENSE for copying permission. # See the file LICENSE for copying permission.
import hashlib import hashlib
import logging import logging
from asyncio import Future, ensure_future from asyncio import Future
from typing import ( from typing import (
Dict, Dict,
Optional, Optional,
@ -13,7 +13,7 @@ from typing import (
from slixmpp import JID from slixmpp import JID
from slixmpp.stanza import Presence 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.xmlstream import register_stanza_plugin, ElementBase
from slixmpp.plugins.base import BasePlugin from slixmpp.plugins.base import BasePlugin
from slixmpp.plugins.xep_0153 import stanza, VCardTempUpdate 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_chat', self._recv_presence)
self.xmpp.del_event_handler('presence_away', self._recv_presence) self.xmpp.del_event_handler('presence_away', self._recv_presence)
@future_wrapper
def set_avatar(self, jid: Optional[JID] = None, def set_avatar(self, jid: Optional[JID] = None,
avatar: Optional[bytes] = None, avatar: Optional[bytes] = None,
mtype: Optional[str] = None, **iqkwargs) -> Future: mtype: Optional[str] = None, **iqkwargs) -> Future:
@ -97,10 +96,10 @@ class XEP_0153(BasePlugin):
except IqTimeout as exc: except IqTimeout as exc:
timeout_cb(exc) timeout_cb(exc)
raise raise
self.api['reset_hash'](jid) await self.api['reset_hash'](jid)
self.xmpp.roster[jid].send_last_presence() 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): async def _start(self, event):
try: try:
@ -110,22 +109,22 @@ class XEP_0153(BasePlugin):
new_hash = '' new_hash = ''
else: else:
new_hash = hashlib.sha1(data).hexdigest() 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: except XMPPError:
log.debug('Could not retrieve vCard for %s', self.xmpp.boundjid.bare) 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): if not isinstance(stanza, Presence):
return stanza return stanza
if stanza['type'] not in ('available', 'dnd', 'chat', 'away', 'xa'): if stanza['type'] not in ('available', 'dnd', 'chat', 'away', 'xa'):
return stanza 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 stanza['vcard_temp_update']['photo'] = current_hash
return stanza return stanza
def _recv_presence(self, pres: Presence): async def _recv_presence(self, pres: Presence):
try: try:
if pres.get_plugin('muc', check=True): if pres.get_plugin('muc', check=True):
# Don't process vCard avatars for MUC occupants # Don't process vCard avatars for MUC occupants
@ -135,7 +134,7 @@ class XEP_0153(BasePlugin):
pass pass
if not pres.match('presence/vcard_temp_update'): 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 return
data = pres['vcard_temp_update']['photo'] data = pres['vcard_temp_update']['photo']
@ -145,17 +144,18 @@ 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) own_jid = (jid.bare == self.xmpp.boundjid.bare)
if self.xmpp.is_component: if self.xmpp.is_component:
own_jid = (jid.domain == self.xmpp.boundjid.domain) 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: if own_jid:
self.xmpp.roster[jid].send_last_presence() self.xmpp.roster[jid].send_last_presence()
def callback(iq): try:
if iq['type'] == 'error': 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) log.debug('Could not retrieve vCard for %s', jid)
return return
try: try:
@ -168,10 +168,7 @@ class XEP_0153(BasePlugin):
else: else:
new_hash = hashlib.sha1(data).hexdigest() new_hash = hashlib.sha1(data).hexdigest()
self.api['set_hash'](jid, args=new_hash) await self.api['set_hash'](jid, args=new_hash)
self.xmpp['xep_0054'].get_vcard(jid=jid.bare, ifrom=ifrom,
callback=callback)
def _get_hash(self, jid: JID, node: str, ifrom: JID, args: Dict): def _get_hash(self, jid: JID, node: str, ifrom: JID, args: Dict):
return self._hashes.get(jid.bare, None) return self._hashes.get(jid.bare, None)