XEP-0153: API changes
This commit is contained in:
parent
e24e2f58d4
commit
ab87b25030
2 changed files with 62 additions and 29 deletions
|
@ -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
|
||||
---------------
|
||||
|
||||
|
|
|
@ -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()
|
||||
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()
|
||||
|
||||
self.api['set_hash'](jid, args=new_hash)
|
||||
|
||||
self.xmpp['xep_0054'].get_vcard(jid=jid.bare, ifrom=ifrom,
|
||||
callback=callback)
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue