# HG changeset patch # User souliane # Date 1421352161 -3600 # Node ID d9939b4765261e997f565ce4b9d2ec01e782c7de # Parent ed2c718bfe031d8a3ad41ffe94fd57a1f76b56e1 tmp: update wokkel MAM implementation diff -r ed2c718bfe03 -r d9939b476526 src/tmp/wokkel/mam.py --- a/src/tmp/wokkel/mam.py Wed Jan 14 10:44:49 2015 +0100 +++ b/src/tmp/wokkel/mam.py Thu Jan 15 21:02:41 2015 +0100 @@ -11,15 +11,21 @@ """ from dateutil.tz import tzutc + from zope.interface import Interface, implements + from twisted.words.protocols.jabber.xmlstream import IQ, toResponse from twisted.words.xish import domish from twisted.words.protocols.jabber import jid +from twisted.python import log + from wokkel.subprotocols import IQHandlerMixin, XMPPHandler -from wokkel import disco, data_form +from wokkel import disco, data_form, delay + import rsm NS_MAM = 'urn:xmpp:mam:0' +NS_FORWARD = 'urn:xmpp:forward:0' FIELDS_REQUEST = "/iq[@type='get']/query[@xmlns='%s']" % NS_MAM ARCHIVE_REQUEST = "/iq[@type='set']/query[@xmlns='%s']" % NS_MAM @@ -68,6 +74,8 @@ node = None def __init__(self, form=None, rsm=None, node=None): + if form is not None: + assert(form.formType == 'submit') self.form = form self.rsm = rsm self.node = node @@ -315,15 +323,12 @@ class IMAMResource(Interface): - def onArchiveRequest(self, mam, rsm, requestor): + def onArchiveRequest(self, mam, requestor): """ @param mam: The MAM request. @type mam: L{MAMQueryReques} - @param rsm: The RSM request. - @type rsm: L{RSMRequest} - @param requestor: JID of the requestor. @type requestor: L{JID} @@ -387,7 +392,7 @@ }, } - extra_filters = [] + extra_filters = {} def __init__(self, resource): """ @@ -415,7 +420,7 @@ wokkel.data_form.Field. @type field: C{dict} """ - self.extra_filters.append(field) + self.extra_filters[field.var] = field def _onFieldsRequest(self, iq): """ @@ -440,21 +445,44 @@ self.xmlstream.send(response) mam_ = MAMQueryRequest.parse(iq.query) - try: - rsm_ = rsm.RSMRequest.parse(iq.query) - except rsm.RSMNotFoundError: - rsm_ = None requestor = jid.JID(iq['from']) - rsm_response = self.resource.onArchiveRequest(mam_, rsm_, requestor) + + # remove unsupported filters + unsupported_fields = [] + if mam_.form: + for key, field in mam_.form.fields.iteritems(): + if key not in self._legacyFilters and key not in self.extra_filters: + log.msg('Ignored unsupported MAM filter: %s' % field) + unsupported_fields.append(key) + for key in unsupported_fields: + del mam_.form.fields[key] - msg = domish.Element((None, 'message')) - fin = msg.addElement('fin', NS_MAM) - if iq.hasAttribute('queryid'): - fin['queryid'] = iq.query['queryid'] - if rsm_response is not None: - fin.addChild(rsm_response.toElement()) - self.xmlstream.send(msg) + def forward_message(id_, elt, date): + msg = domish.Element((None, 'message')) + msg['to'] = iq['from'] + result = msg.addElement('result', NS_MAM) + if iq.hasAttribute('queryid'): + result['queryid'] = iq.query['queryid'] + result['id'] = id_ + forward = result.addElement('forwarded', NS_FORWARD) + forward.addChild(delay.Delay(date).toElement()) + forward.addChild(elt) + self.xmlstream.send(msg) + def cb(result): + msg_data, rsm_elt = result + for data in msg_data: + forward_message(*data) + msg = domish.Element((None, 'message')) + msg['to'] = iq['from'] + fin = msg.addElement('fin', NS_MAM) + if iq.hasAttribute('queryid'): + fin['queryid'] = iq.query['queryid'] + if rsm_elt is not None: + fin.addChild(rsm_elt) + self.xmlstream.send(msg) + + self.resource.onArchiveRequest(mam_, requestor).addCallback(cb) iq.handled = True def _onPrefsGetRequest(self, iq): @@ -466,10 +494,12 @@ response = toResponse(iq, 'result') requestor = jid.JID(iq['from']) - prefs = self.resource.onPrefsGetRequest(requestor) - response.addChild(prefs.toElement()) - self.xmlstream.send(response) + def cb(prefs): + response.addChild(prefs.toElement()) + self.xmlstream.send(response) + + self.resource.onPrefsGetRequest(requestor).addCallback(cb) iq.handled = True def _onPrefsSetRequest(self, iq): @@ -482,10 +512,12 @@ prefs = MAMPrefs.parse(iq.prefs) requestor = jid.JID(iq['from']) - prefs = self.resource.onPrefsSetRequest(prefs, requestor) - response.addChild(prefs.toElement()) - self.xmlstream.send(response) + def cb(prefs): + response.addChild(prefs.toElement()) + self.xmlstream.send(response) + + self.resource.onPrefsSetRequest(prefs, requestor).addCallback(cb) iq.handled = True def getDiscoInfo(self, requestor, target, nodeIdentifier=''):