Refactor getting avatars from pubsub
- use SendAndCallForResponse instead of triggering an Event - validate iq result even more, it didnt print iq errors before
This commit is contained in:
parent
7b1bdc5591
commit
7479bd8bd6
|
@ -24,8 +24,6 @@
|
|||
from calendar import timegm
|
||||
import datetime
|
||||
import hashlib
|
||||
import binascii
|
||||
import base64
|
||||
import hmac
|
||||
import logging
|
||||
import sys
|
||||
|
@ -604,48 +602,6 @@ class PubsubBookmarksReceivedEvent(nec.NetworkIncomingEvent, BookmarksHelper):
|
|||
self.parse_bookmarks()
|
||||
return True
|
||||
|
||||
class PubsubAvatarReceivedEvent(nec.NetworkIncomingEvent):
|
||||
name = 'pubsub-avatar-received'
|
||||
base_network_events = ['pubsub-received']
|
||||
|
||||
def __init__(self, name, base_event):
|
||||
'''
|
||||
Pre-Generated attributes on self:
|
||||
|
||||
:conn: Connection instance
|
||||
:jid: The from jid
|
||||
:pubsub_node: The 'pubsub' node
|
||||
:items_node: The 'items' node
|
||||
'''
|
||||
self._set_base_event_vars_as_attributes(base_event)
|
||||
|
||||
def generate(self):
|
||||
if self.items_node.getAttr('node') != 'urn:xmpp:avatar:data':
|
||||
return
|
||||
item = self.items_node.getTag('item')
|
||||
if not item:
|
||||
log.warning('Received malformed avatar data via pubsub')
|
||||
log.debug(self.stanza)
|
||||
return
|
||||
self.sha = item.getAttr('id')
|
||||
data_tag = item.getTag('data', namespace='urn:xmpp:avatar:data')
|
||||
if self.sha is None or data_tag is None:
|
||||
log.warning('Received malformed avatar data via pubsub')
|
||||
log.debug(self.stanza)
|
||||
return
|
||||
self.data = data_tag.getData()
|
||||
if self.data is None:
|
||||
log.warning('Received malformed avatar data via pubsub')
|
||||
log.debug(self.stanza)
|
||||
return
|
||||
try:
|
||||
self.data = base64.b64decode(self.data.encode('utf-8'))
|
||||
except binascii.Error as err:
|
||||
log.debug('Received malformed avatar data via pubsub: %s' % err)
|
||||
return
|
||||
|
||||
return True
|
||||
|
||||
class SearchFormReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
||||
name = 'search-form-received'
|
||||
base_network_events = []
|
||||
|
|
|
@ -147,3 +147,13 @@ class PluginsystemError(Exception):
|
|||
|
||||
def __str__(self):
|
||||
return self.text
|
||||
|
||||
class StanzaMalformed(Exception):
|
||||
"""
|
||||
Malfromed Stanza
|
||||
"""
|
||||
def __init__(self, message, stanza=''):
|
||||
Exception.__init__(self, message, stanza)
|
||||
self._msg = '{}\n{}'.format(message, stanza)
|
||||
def __str__(self):
|
||||
return self._msg
|
||||
|
|
|
@ -509,8 +509,8 @@ class AvatarNotificationPEP(AbstractPEP):
|
|||
jid, self.avatar['id'])
|
||||
return
|
||||
app.log('avatar').info('Request (Pubsub): %s', jid)
|
||||
con.send_pb_retrieve(jid, 'urn:xmpp:avatar:data',
|
||||
self.avatar['id'])
|
||||
con.get_pubsub_avatar(jid, 'urn:xmpp:avatar:data',
|
||||
self.avatar['id'])
|
||||
|
||||
|
||||
SUPPORTED_PERSONAL_USER_EVENTS = [
|
||||
|
|
|
@ -21,16 +21,18 @@
|
|||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
|
||||
import nbxmpp
|
||||
from gajim.common import app
|
||||
#TODO: Doesn't work
|
||||
#from common.connection_handlers import PEP_CONFIG
|
||||
PEP_CONFIG = 'pep_config'
|
||||
from gajim.common import ged
|
||||
from gajim.common.nec import NetworkEvent
|
||||
from gajim.common.connection_handlers_events import PubsubReceivedEvent
|
||||
from gajim.common.connection_handlers_events import PubsubBookmarksReceivedEvent
|
||||
from gajim.common.connection_handlers_events import PubsubAvatarReceivedEvent
|
||||
from gajim.common.exceptions import StanzaMalformed
|
||||
|
||||
import logging
|
||||
log = logging.getLogger('gajim.c.pubsub')
|
||||
|
@ -39,11 +41,8 @@ class ConnectionPubSub:
|
|||
def __init__(self):
|
||||
self.__callbacks = {}
|
||||
app.nec.register_incoming_event(PubsubBookmarksReceivedEvent)
|
||||
app.nec.register_incoming_event(PubsubAvatarReceivedEvent)
|
||||
app.ged.register_event_handler('pubsub-bookmarks-received',
|
||||
ged.CORE, self._nec_pubsub_bookmarks_received)
|
||||
app.ged.register_event_handler('pubsub-avatar-received',
|
||||
ged.CORE, self._nec_pubsub_avatar_received)
|
||||
|
||||
def cleanup(self):
|
||||
app.ged.remove_event_handler('pubsub-bookmarks-received',
|
||||
|
@ -103,22 +102,35 @@ class ConnectionPubSub:
|
|||
|
||||
self.connection.send(query)
|
||||
|
||||
@staticmethod
|
||||
def get_pb_retrieve_iq(jid, node, item_id=None):
|
||||
"""
|
||||
Get IQ to query items from a node
|
||||
"""
|
||||
query = nbxmpp.Iq('get', to=jid)
|
||||
r = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
|
||||
r = r.addChild('items', {'node': node})
|
||||
if item_id is not None:
|
||||
r.addChild('item', {'id': item_id})
|
||||
return query
|
||||
|
||||
def send_pb_retrieve(self, jid, node, item_id=None, cb=None, *args, **kwargs):
|
||||
"""
|
||||
Get items from a node
|
||||
"""
|
||||
if not self.connection or self.connected < 2:
|
||||
return
|
||||
query = nbxmpp.Iq('get', to=jid)
|
||||
r = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
|
||||
r = r.addChild('items', {'node': node})
|
||||
if item_id is not None:
|
||||
r.addChild('item', {'id': item_id})
|
||||
query = self.get_pb_retrieve_iq(jid, node, item_id)
|
||||
id_ = self.connection.send(query)
|
||||
|
||||
if cb:
|
||||
self.__callbacks[id_] = (cb, args, kwargs)
|
||||
|
||||
def get_pubsub_avatar(self, jid, node, item_id):
|
||||
query = self.get_pb_retrieve_iq(jid, node, item_id)
|
||||
self.connection.SendAndCallForResponse(
|
||||
query, self._nec_pubsub_avatar_received, {'jid': jid})
|
||||
|
||||
def send_pb_retract(self, jid, node, id_):
|
||||
"""
|
||||
Delete item from a node
|
||||
|
@ -211,25 +223,62 @@ class ConnectionPubSub:
|
|||
# We got bookmarks from pubsub, now get those from xml to merge them
|
||||
self.get_bookmarks(storage_type='xml')
|
||||
|
||||
def _nec_pubsub_avatar_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
return
|
||||
|
||||
if obj.jid is None:
|
||||
def _validate_avatar_node(self, stanza):
|
||||
jid = stanza.getFrom()
|
||||
if jid is None:
|
||||
jid = self.get_own_jid().getStripped()
|
||||
else:
|
||||
jid = obj.jid.getStripped()
|
||||
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 _nec_pubsub_avatar_received(self, conn, stanza, jid):
|
||||
try:
|
||||
jid, sha, data = self._validate_avatar_node(stanza)
|
||||
except (StanzaMalformed, binascii.Error) as error:
|
||||
app.log('avatar').warning(
|
||||
'Error loading Avatar (Pubsub): %s %s', jid, error)
|
||||
return
|
||||
|
||||
app.log('avatar').info(
|
||||
'Received Avatar (Pubsub): %s %s', jid, obj.sha)
|
||||
app.interface.save_avatar(obj.data)
|
||||
'Received Avatar (Pubsub): %s %s', jid, sha)
|
||||
app.interface.save_avatar(data)
|
||||
|
||||
if self.get_own_jid().bareMatch(jid):
|
||||
app.config.set_per('accounts', self.name, 'avatar_sha', obj.sha)
|
||||
app.config.set_per('accounts', self.name, 'avatar_sha', sha)
|
||||
else:
|
||||
own_jid = self.get_own_jid().getStripped()
|
||||
app.logger.set_avatar_sha(own_jid, jid, obj.sha)
|
||||
app.contacts.set_avatar(self.name, jid, obj.sha)
|
||||
app.logger.set_avatar_sha(own_jid, jid, sha)
|
||||
app.contacts.set_avatar(self.name, jid, sha)
|
||||
|
||||
app.interface.update_avatar(self.name, jid)
|
||||
|
||||
|
|
Loading…
Reference in New Issue