Philipp Hörist pushed to branch master at gajim / gajim
Commits: cef5b04d by Philipp Hörist at 2019-02-02T23:08:28Z Refactor UserAvatar
- Simplify modules because nbxmpp handles more stuff
- - - - -
1 changed file:
- gajim/common/modules/user_avatar.py
Changes:
===================================== gajim/common/modules/user_avatar.py ===================================== @@ -15,134 +15,67 @@ # XEP-0084: User Avatar
import logging -import base64 -import binascii
import nbxmpp
from gajim.common import app -from gajim.common.const import PEPEventType -from gajim.common.exceptions import StanzaMalformed -from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData +from gajim.common.modules.base import BaseModule +from gajim.common.modules.util import event_node
log = logging.getLogger('gajim.c.m.user_avatar')
-class UserAvatarData(AbstractPEPData): +class UserAvatar(BaseModule):
- type_ = PEPEventType.AVATAR + _nbxmpp_extends = 'UserAvatar' + _nbxmpp_methods = [ + 'request_avatar' + ]
+ def __init__(self, con): + BaseModule.__init__(self, con) + self._register_pubsub_handler(self._avatar_metadata_received)
-class UserAvatar(AbstractPEPModule): + @event_node(nbxmpp.NS_AVATAR_METADATA) + def _avatar_metadata_received(self, _con, _stanza, properties): + data = properties.pubsub_event.data + empty = properties.pubsub_event.empty + jid = str(properties.jid) + own_jid = self._con.get_own_jid().getBare()
- name = 'user-avatar' - namespace = 'urn:xmpp:avatar:metadata' - pep_class = UserAvatarData - store_publish = False - _log = log - - def get_pubsub_avatar(self, jid, item_id): - log.info('Request: %s %s', jid, item_id) - self._con.get_module('PubSub').send_pb_retrieve( - jid, 'urn:xmpp:avatar:data', item_id, self._avatar_received) - - def _validate_avatar_node(self, stanza): - jid = stanza.getFrom() - if jid is None: - jid = self._con.get_own_jid().getStripped() - else: - jid = jid.getStripped() - - if nbxmpp.isErrorNode(stanza): - raise StanzaMalformed(stanza.getErrorMsg()) - - pubsub_node = stanza.getTag('pubsub') - if pubsub_node is None: - raise StanzaMalformed('No pubsub node', stanza) - - items_node = pubsub_node.getTag('items') - if items_node is None: - raise StanzaMalformed('No items node', stanza) - - if items_node.getAttr('node') != 'urn:xmpp:avatar:data': - raise StanzaMalformed('Wrong namespace', stanza) - - item = items_node.getTag('item') - if item is None: - raise StanzaMalformed('No item node', stanza) - - sha = item.getAttr('id') - data_tag = item.getTag('data', namespace='urn:xmpp:avatar:data') - if sha is None or data_tag is None: - raise StanzaMalformed('No id attr or data node found', stanza) - - data = data_tag.getData() - if data is None: - raise StanzaMalformed('Data node empty', stanza) - - data = base64.b64decode(data.encode('utf-8')) - - return jid, sha, data - - def _avatar_received(self, _con, stanza): - try: - jid, sha, data = self._validate_avatar_node(stanza) - except (StanzaMalformed, binascii.Error) as error: - log.warning('Error: %s %s', stanza.getFrom(), error) - return - - log.info('Received Avatar: %s %s', jid, sha) - app.interface.save_avatar(data) - - if self._con.get_own_jid().bareMatch(jid): - app.config.set_per('accounts', self._account, 'avatar_sha', sha) - else: - own_jid = self._con.get_own_jid().getStripped() - app.logger.set_avatar_sha(own_jid, jid, sha) - - app.contacts.set_avatar(self._account, jid, sha) - app.interface.update_avatar(self._account, jid) - - def _extract_info(self, item): - metadata = item.getTag('metadata', namespace=self.namespace) - if metadata is None: - raise StanzaMalformed('No metadata node') - - info = metadata.getTags('info', one=True) - if not info: - return None - - avatar = info.getAttrs() - return avatar or None - - def _notification_received(self, jid, user_pep): - avatar = user_pep.data - own_jid = self._con.get_own_jid() - if avatar is None: + if empty: # Remove avatar log.info('Remove: %s', jid) - app.contacts.set_avatar(self._account, str(jid), None) - app.logger.set_avatar_sha(own_jid.getStripped(), str(jid), None) - app.interface.update_avatar(self._account, str(jid)) + app.contacts.set_avatar(self._account, jid, None) + app.logger.set_avatar_sha(own_jid, jid, None) + app.interface.update_avatar(self._account, jid) else: - if own_jid.bareMatch(jid): + if properties.is_self_message: sha = app.config.get_per( 'accounts', self._account, 'avatar_sha') else: - sha = app.contacts.get_avatar_sha(self._account, str(jid)) + sha = app.contacts.get_avatar_sha(self._account, jid)
- if sha == avatar['id']: - log.info('Avatar already known: %s %s', - jid, avatar['id']) + if sha == data.id: + log.info('Avatar already known: %s %s', jid, data.id) return - self.get_pubsub_avatar(jid, avatar['id'])
- def _build_node(self, data): - raise NotImplementedError + log.info('Request: %s %s', jid, data.id) + self._nbxmpp('UserAvatar').request_avatar( + jid, data.id, callback=self._avatar_received) + + def _avatar_received(self, result): + log.info('Received Avatar: %s %s', result.jid, result.sha) + app.interface.save_avatar(result.data) + + if self._con.get_own_jid().bareMatch(result.jid): + app.config.set_per('accounts', self._account, 'avatar_sha', result.sha) + else: + own_jid = self._con.get_own_jid().getBare() + app.logger.set_avatar_sha(own_jid, str(result.jid), result.sha)
- def send(self, data): - # Not implemented yet - return + app.contacts.set_avatar(self._account, str(result.jid), result.sha) + app.interface.update_avatar(self._account, str(result.jid))
def get_instance(*args, **kwargs):
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/cef5b04d82b9c3c9ab57379102511916f17...