plugin XEP-0277, groupblog: fixes namespace issue of the items that are received from an event + trap some errors

This commit is contained in:
souliane 2014-10-06 17:25:41 +02:00
commit 97630ccab9

View file

@ -112,26 +112,30 @@ class XEP_0277(object):
@return: microblog data (dictionary)"""
def xpath(elt, path):
"""Return the XPATH result of an entry element or its descendance, works with both:
- no namespace, that means it is inherited from the parent item node --> NS_PUBSUB
- empty namespace
XXX: check why the received entries have no namespace when they are retrieved
from self.host.plugins["XEP-0060"].getItems and they have an empty namespace
when they are received with an event.
"""
result = elt.xpath(path)
if len(result) > 0:
return result
return elt.xpath('/'.join(['ns:%s' % tag for tag in path.split('/')]), namespaces={'ns': NS_PUBSUB})
"""Return the XPATH result of an entry element or its descendance."""
# XXX: use a wildcard to work with all and even undefined namespaces
return elt.xpath('/'.join(["*[local-name() = '%s']" % tag for tag in path.split('/')]))
# convert a date string to float without dealing with the date format
date2float = lambda elt, path: unicode(date.rfc3339.tf_from_timestamp(xpath(elt, path)[0].text))
def date2float(elt, path):
"""Convert a date string to float without dealing with the date format."""
return unicode(date.rfc3339.tf_from_timestamp(xpath(elt, path)[0].text))
item_elt = etree.fromstring(item.toXml().encode('utf-8'))
item_id = item_elt.get('id', '')
# XXX: when you raise an exception from inline callbacks, do defer.returnValue(Exception())
# to make it catchable by an eventual errback. If you do raise Exception, raise Exception()
# or defer.returnValue(Exception), it will explode and then the normal callback is ran.
if item.uri not in (NS_PUBSUB, NS_PUBSUB + "#event"):
log.error(_("Unsupported namespace {ns} in pubsub item {id}").format(ns=item.uri, id=item_id))
defer.returnValue(exceptions.DataError())
try:
entry_elt = xpath(item_elt, 'entry')[0]
except IndexError:
raise exceptions.DataError(_('No entry found in the pubsub item %s') % item_elt.get('id', ''))
log.error(_('No atom entry found in the pubsub item %s') % item_id)
defer.returnValue(exceptions.DataError())
microblog_data = {}
@ -154,8 +158,8 @@ class XEP_0277(object):
microblog_data['updated'] = date2float(entry_elt, 'updated')
assert('title' in microblog_data) # has been processed already
except IndexError:
log.error(_("Atom entry %s misses a required element") % item_elt.get('id', ''))
raise exceptions.DataError
log.error(_("Atom entry of pubsub item %s misses a required element") % item_id)
defer.returnValue(exceptions.DataError())
if 'content' not in microblog_data: # use the atom title data as the microblog body content
microblog_data['content'] = microblog_data['title']
@ -180,7 +184,7 @@ class XEP_0277(object):
microblog_data['comments_service'] = service.full()
microblog_data['comments_node'] = node
except (exceptions.DataError, RuntimeError, KeyError):
log.warning(_("Can't parse the link element of pubsub entry %s") % microblog_data['id'])
log.warning(_("Can't parse the link element of atom entry %s") % microblog_data['id'])
except:
pass
try:
@ -189,7 +193,7 @@ class XEP_0277(object):
try: # XXX: workaround for Jappix behaviour
microblog_data['author'] = xpath(entry_elt, 'author/nick')[0].text
except IndexError:
log.warning(_("Can't find author element in pubsub entry %s") % microblog_data['id'])
log.warning(_("Can't find author element in atom entry %s") % microblog_data['id'])
defer.returnValue(microblog_data)
@ -221,17 +225,12 @@ class XEP_0277(object):
return self.__getDomishInnerContent(elt)
def microblogCB(self, itemsEvent, profile):
d = defer.Deferred()
"""Callback to "MICROBLOG" PEP event."""
def manageItem(microblog_data):
self.host.bridge.personalEvent(itemsEvent.sender.full(), "MICROBLOG", microblog_data, profile)
for item in itemsEvent.items:
d.addCallback(lambda ignore: self.item2mbdata(item))
d.addCallback(manageItem)
d.callback(None)
return d
self.item2mbdata(item).addCallbacks(manageItem, lambda failure: None)
@defer.inlineCallbacks
def data2entry(self, data, profile):
@ -317,18 +316,9 @@ class XEP_0277(object):
@param max_items: how many microblogs we want to get
@param profile_key: profile key
"""
def resultToArray(result):
ret = []
for (success, value) in result:
if success:
ret.append(value)
else:
log.error('Error while getting last microblog')
return ret
d = self.host.plugins["XEP-0060"].getItems(jid.JID(pub_jid), NS_MICROBLOG, max_items=max_items, profile_key=profile_key)
d.addCallback(lambda items: defer.DeferredList(map(self.item2mbdata, items)))
d.addCallback(resultToArray)
d.addCallback(lambda items: defer.DeferredList(map(self.item2mbdata, items), consumeErrors=True))
d.addCallback(lambda result: [value for (success, value) in result if success])
return d
def setMicroblogAccess(self, access="presence", profile_key=C.PROF_KEY_NONE):