# HG changeset patch # User Goffi # Date 1544201023 -3600 # Node ID 19000c506d0c7ded06f5843ea91c96589544c944 # Parent c3f59c1dcb0a553baf09a480d3f29bfd6f474303 plugin XEP-0313: improvments to prepare MUC MAM: - discard groupchat message when retrieving last stanza_id on connection - service can be specified in getMessageFromResult - service is also used when using getArchives from bridge diff -r c3f59c1dcb0a -r 19000c506d0c sat/plugins/plugin_xep_0313.py --- a/sat/plugins/plugin_xep_0313.py Sat Dec 01 14:40:32 2018 +0100 +++ b/sat/plugins/plugin_xep_0313.py Fri Dec 07 17:43:43 2018 +0100 @@ -71,18 +71,17 @@ @defer.inlineCallbacks def profileConnected(self, client): last_mess = yield self.host.memory.historyGet( - None, None, limit=1, filters={u'last_stanza_id': True}, + None, None, limit=1, filters={u'not_types': C.MESS_TYPE_GROUPCHAT, + u'last_stanza_id': True}, profile=client.profile) if not last_mess: log.info(_(u"It seems that we have no MAM history yet")) return stanza_id = last_mess[0][-1][u'stanza_id'] - # XXX: test - # stanza_id = "IIheJOfiIhkPYkw6" rsm_req = rsm.RSMRequest(after=stanza_id) mam_req = mam.MAMRequest(rsm_=rsm_req) mam_data = yield self.getArchives(client, mam_req, - service=client.jid.userhostJID()) + service=client.jid.userhostJID()) elt_list, rsm_response = mam_data if not elt_list: log.info(_(u"We have received no message while offline")) @@ -154,21 +153,28 @@ return mam.MAMRequest(**mam_args) if mam_args else None - def getMessageFromResult(self, client, mess_elt, mam_req): + def getMessageFromResult(self, client, mess_elt, mam_req, service=None): """Extract usable from MAM query result The message will be validated, and stanza-id/delay will be added if necessary. @param mess_elt(domish.Element): result element wrapping the message to retrieve @param mam_req(mam.MAMRequest): request used + @param service(jid.JID, None): MAM service where the request has been sent + None if it's user server @return (domish.Element): that can be used directly with onMessage """ if mess_elt.name != u"message": log.warning(u"unexpected stanza in archive: {xml}".format( xml=mess_elt.toXml())) raise exceptions.DataError(u"Invalid element") + service_jid = client.jid.userhostJID() if service is None else service mess_from = mess_elt[u"from"] - if mess_from != client.jid.host and mess_from != client.jid.userhost(): + # we check that the message has been sent by the right service + # if service is None (i.e. message expected from our own server) + # from can be server jid or user's bare jid + if (mess_from != service_jid.full() + and not (service is None and mess_from == client.jid.host)): log.error(u"Message is not from our server, something went wrong: " u"{xml}".format(xml=mess_elt.toXml())) raise exceptions.DataError(u"Invalid element") @@ -191,7 +197,7 @@ .format(query_id=mam.query_id, xml=mess_elt.toXml())) raise exceptions.DataError(u"Invalid element") stanza_id = self._sid.getStanzaId(fwd_message_elt, - client.jid.userhostJID()) + service_jid) if stanza_id is None: # not stanza-id element is present, we add one so message # will be archived with it, and we won't request several times @@ -202,7 +208,7 @@ log.warning(u'Invalid MAM result: missing "id" attribute: {xml}' .format(xml=result_elt.toXml())) raise exceptions.DataError(u"Invalid element") - self._sid.addStanzaId(client, fwd_message_elt, stanza_id) + self._sid.addStanzaId(client, fwd_message_elt, stanza_id, by=service_jid) if delay_elt is not None: fwd_message_elt.addChild(delay_elt) @@ -247,11 +253,12 @@ return (elt_list, rsm_response) - def serializeArchiveResult(self, data, client, mam_req): + def serializeArchiveResult(self, data, client, mam_req, service): elt_list, rsm_response = data mess_list = [] for elt in elt_list: - fwd_message_elt = self.getMessageFromResult(client, elt, mam_req) + fwd_message_elt = self.getMessageFromResult(client, elt, mam_req, + service=service) mess_data = client.messageProt.parseMessage(fwd_message_elt) mess_list.append(client.messageGetBridgeArgs(mess_data)) return mess_list, client.profile @@ -263,7 +270,7 @@ mam_req = self.parseExtra(extra) d = self.getArchives(client, mam_req, service=service) - d.addCallback(self.serializeArchiveResult, client, mam_req) + d.addCallback(self.serializeArchiveResult, client, mam_req, service) return d def getArchives(self, client, query, service=None, message_cb=None):