diff sat/plugins/plugin_xep_0045.py @ 2718:bb6adaa580ee

plugin XEP-0313, XEP-0045: loop MAM requests until whole archive is retrieved: - plugin xep-0313: new serialise method - : getArchives now returns an extra mam_response dict with "complete" and "stable" status - : MAMGet now return a new metadata dict before profile (with serialised RSM and MAM response)
author Goffi <goffi@goffi.org>
date Mon, 10 Dec 2018 20:34:45 +0100
parents b35c84ea73cf
children c6be5962752d
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0045.py	Mon Dec 10 20:34:45 2018 +0100
+++ b/sat/plugins/plugin_xep_0045.py	Mon Dec 10 20:34:45 2018 +0100
@@ -870,43 +870,56 @@
                                                       profile=client.profile)
         if last_mess:
             stanza_id = last_mess[0][-1][u'stanza_id']
-            rsm_req = rsm.RSMRequest(after=stanza_id)
+            rsm_req = rsm.RSMRequest(max_=100, after=stanza_id)
         else:
             log.info(u"We have no MAM archive for room {room_jid}.".format(
                 room_jid=room_jid))
-            rsm_req = rsm.RSMRequest(max_=20)
+            # we don't want the whole archive if we have no archive yet
+            # as it can be huge
+            rsm_req = rsm.RSMRequest(max_=50)
 
         mam_req = mam.MAMRequest(rsm_=rsm_req)
-        mam_data = yield self._mam.getArchives(client, mam_req,
-                                               service=room_jid)
-        elt_list, rsm_response = mam_data
+        complete = False
+        count = 0
+        while not complete:
+            mam_data = yield self._mam.getArchives(client, mam_req,
+                                                   service=room_jid)
+            elt_list, rsm_response, mam_response = mam_data
+            complete = mam_response[u"complete"]
+            # we update MAM request for next iteration
+            mam_req.rsm.after = rsm_response.last
+
+            if not elt_list:
+                break
+            else:
+                count += len(elt_list)
 
-        if not elt_list:
+                for mess_elt in elt_list:
+                    try:
+                        fwd_message_elt = self._mam.getMessageFromResult(
+                            client, mess_elt, mam_req, service=room_jid)
+                    except exceptions.DataError:
+                        continue
+                    if fwd_message_elt.getAttribute(u"to"):
+                        log.warning(
+                            u'Forwarded message element has a "to" attribute while it is '
+                            u'forbidden by specifications')
+                    fwd_message_elt[u"to"] = client.jid.full()
+                    mess_data = client.messageProt.parseMessage(fwd_message_elt)
+                    # we attache parsed message data to element, to avoid parsing
+                    # again in _addToHistory
+                    fwd_message_elt._mess_data = mess_data
+                    # and we inject to MUC workflow
+                    client._muc_client._onGroupChat(fwd_message_elt)
+
+        if not count:
             log.info(_(u"No message received while offline in {room_jid}".format(
                 room_jid=room_jid)))
         else:
             log.info(
-                _(u"We have received {num_mess} message(s) in {room_jid} while offline.")
-                .format(num_mess=len(elt_list), room_jid=room_jid))
-
-            for mess_elt in elt_list:
-                try:
-                    fwd_message_elt = self._mam.getMessageFromResult(
-                        client, mess_elt, mam_req, service=room_jid)
-                except exceptions.DataError:
-                    continue
-                if fwd_message_elt.getAttribute(u"to"):
-                    log.warning(
-                        u'Forwarded message element has a "to" attribute while it is '
-                        u'forbidden by specifications')
-                fwd_message_elt[u"to"] = client.jid.full()
-                mess_data = client.messageProt.parseMessage(fwd_message_elt)
-                # we attache parsed message data to element, to avoid parsing
-                # again in _addToHistory
-                fwd_message_elt._mess_data = mess_data
-                # and we inject to MUC workflow
-                client._muc_client._onGroupChat(fwd_message_elt)
-
+                _(u"We have received {num_mess} message(s) in {room_jid} while "
+                  u"offline.")
+                .format(num_mess=count, room_jid=room_jid))
 
         # for legacy history, the following steps are done in receivedSubject but for MAM
         # the order is different (we have to join then get MAM archive, so subject