Mercurial > libervia-pubsub
diff sat_pubsub/mam.py @ 322:54d90c73b8b5
mam: various improvments:
- put common namespaces ton const
- VAL_RSM_MAX_DEFAULT can be None if default limit is not wanted
- ItemDate now has a 'date' attribute
- MAMService is MonkeyPatched the same way as PubSubService to handle PEP
- fixed error mapping in mam module
- PEP is handled
- properly manage date in a payload independent way
- when PEP is used, send privileged messages
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 05 Jan 2016 23:13:13 +0100 |
parents | cca47e9977a5 |
children | 8d939378f023 |
line wrap: on
line diff
--- a/sat_pubsub/mam.py Tue Jan 05 22:16:37 2016 +0100 +++ b/sat_pubsub/mam.py Tue Jan 05 23:13:13 2016 +0100 @@ -28,32 +28,44 @@ from zope.interface import implements from twisted.words.xish import domish +from twisted.python import log +from twisted.words.protocols.jabber import error from sat_pubsub import const -from sat_pubsub.backend import PubSubResourceFromBackend -from wokkel.pubsub import NS_PUBSUB_EVENT - -from dateutil import parser +from sat_pubsub import backend +from wokkel import pubsub -# TODO: change this when RSM and MAM are in wokkel -from sat.tmp.wokkel import rsm -from sat.tmp.wokkel import mam - -NS_CLIENT = 'jabber:client' +from wokkel import rsm +from wokkel import mam +from wokkel import delay class MAMResource(object): + implements(mam.IMAMResource) + _errorMap = backend.PubSubResourceFromBackend._errorMap - implements(mam.IMAMResource) + def __init__(self, backend_): + self.backend = backend_ + + def _mapErrors(self, failure): + # XXX: come from backend.PubsubResourceFromBackend + e = failure.trap(*self._errorMap.keys()) - def __init__(self, backend): - self.backend = backend + condition, pubsubCondition, feature = self._errorMap[e] + msg = failure.value.msg - def onArchiveRequest(self, mam, requestor): + if pubsubCondition: + exc = pubsub.PubSubError(condition, pubsubCondition, feature, msg) + else: + exc = error.StanzaError(condition, text=msg) + + raise exc + + def onArchiveRequest(self, mam_request, requestor): """ - @param mam: The MAM <query/> request. - @type mam: L{MAMQueryReques<wokkel.mam.MAMQueryRequest>} + @param mam_request: The MAM archive request. + @type mam_request: L{MAMQueryReques<wokkel.mam.MAMRequest>} @param requestor: JID of the requestor. @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>} @@ -62,42 +74,68 @@ @rtype: C{tuple} """ # FIXME: bad result ordering - ext_data = {} - if mam.form: - ext_data['filters'] = mam.form.fields.values() - if mam.rsm is None: - mam.rsm = rsm.RSMRequest(const.VAL_RSM_MAX_DEFAULT) - ext_data['rsm'] = mam.rsm + try: + pep = mam_request.delegated + except AttributeError: + pep = False + ext_data = {'pep': pep} + if mam_request.form: + ext_data['filters'] = mam_request.form.fields.values() + if mam_request.rsm is None: + if const.VAL_RSM_MAX_DEFAULT != None: + log.msg("MAM request without RSM limited to {}".format(const.VAL_RSM_MAX_DEFAULT)) + ext_data['rsm'] = rsm.RSMRequest(const.VAL_RSM_MAX_DEFAULT) + else: + ext_data['rsm'] = mam_request.rsm - d = self.backend.getItems(mam.node, requestor, mam.rsm.max, None, ext_data) + d = self.backend.getItemsData(mam_request.node, requestor, None, None, ext_data) def make_message(elt): # XXX: http://xmpp.org/extensions/xep-0297.html#sect-idp629952 (rule 3) - message = domish.Element((NS_CLIENT, "message")) - event = message.addElement((NS_PUBSUB_EVENT, "event")) + message = domish.Element((const.NS_CLIENT, "message")) + event = message.addElement((pubsub.NS_PUBSUB_EVENT, "event")) items = event.addElement('items') - items["node"] = mam.node + items["node"] = mam_request.node items.addChild(elt) return message - def cb(elts): + def cb(items_data): msg_data = [] rsm_elt = None - for elt in elts: - if elt.name == 'set' and elt.uri == rsm.NS_RSM: + for item_data in items_data: + if item_data.item.name == 'set' and item_data.item.uri == rsm.NS_RSM: assert rsm_elt is None - rsm_elt = elt - elif elt.name == 'item': - # FIXME: this is not good as it is dependant on payload - # TODO: remove this and use date field in database - date = parser.parse(''.join(elt.entry.published.children)) - msg_data.append([elt['id'], make_message(elt), date]) + rsm_elt = item_data.item + elif item_data.item.name == 'item': + msg_data.append([item_data.item['id'], make_message(item_data.item), item_data.date]) + else: + log.msg("WARNING: unknown element: {}".format(item_data.item.name)) + if pep: + # we need to send privileged message + # so me manage the sending ourself, and return + # an empty msg_data list to avoid double sending + for data in msg_data: + self.forwardPEPMessage(mam_request, requestor, *data) + msg_data = [] return (msg_data, rsm_elt) - d.addErrback(PubSubResourceFromBackend._mapErrors) + d.addErrback(self._mapErrors) d.addCallback(cb) return d + def forwardPEPMessage(self, mam_request, requestor, id_, elt, date): + msg = domish.Element((None, 'message')) + msg['from'] = self.backend.privilege.server_jid.full() + msg['to'] = requestor.full() + result = msg.addElement((mam.NS_MAM, 'result')) + if mam_request.query_id is not None: + result['queryid'] = mam_request.query_id + result['id'] = id_ + forward = result.addElement((const.NS_FORWARD, 'forwarded')) + forward.addChild(delay.Delay(date).toElement()) + forward.addChild(elt) + self.backend.privilege.sendMessage(msg) + def onPrefsGetRequest(self, requestor): """