# HG changeset patch # User Goffi # Date 1700661374 -3600 # Node ID 85f5e6225aa166d15a8ec28ff951eb354be218bb # Parent 9162d3480b9e4cae175938d3f10c78314c429bf6 plugin XEP-0313: better error logging + store last stanza ID when retrieving archives + small improvments diff -r 9162d3480b9e -r 85f5e6225aa1 libervia/backend/plugins/plugin_xep_0313.py --- a/libervia/backend/plugins/plugin_xep_0313.py Wed Nov 22 14:53:07 2023 +0100 +++ b/libervia/backend/plugins/plugin_xep_0313.py Wed Nov 22 14:56:14 2023 +0100 @@ -18,23 +18,25 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from datetime import datetime +import uuid + +from dateutil import tz +from twisted.internet import defer +from twisted.words.protocols.jabber import jid +from twisted.words.protocols.jabber.error import StanzaError +from wokkel import disco +from wokkel import data_form +from wokkel import rsm +from wokkel import mam +from zope.interface import implementer + +from libervia.backend.core import exceptions from libervia.backend.core.constants import Const as C from libervia.backend.core.i18n import _ from libervia.backend.core.log import getLogger -from libervia.backend.core import exceptions +from libervia.backend.tools import xml_tools from libervia.backend.tools.common import data_format -from twisted.words.protocols.jabber import jid -from twisted.internet import defer -from zope.interface import implementer -from datetime import datetime -from dateutil import tz -from wokkel import disco -from wokkel import data_form -import uuid - -# XXX: mam and rsm come from sat_tmp.wokkel -from wokkel import rsm -from wokkel import mam log = getLogger(__name__) @@ -99,8 +101,21 @@ complete = False count = 0 while not complete: - mam_data = await self.get_archives(client, mam_req, - service=client.jid.userhostJID()) + try: + mam_data = await self.get_archives(client, mam_req, + service=client.jid.userhostJID()) + except StanzaError as e: + log.warning( + f"Can't retrieve MAM archives: {e}\n" + f"{xml_tools.pp_elt(mam_req.toElement())}\n" + f"{xml_tools.pp_elt(e.stanza)}" + ) + return + except Exception as e: + log.exception( + f"Can't retrieve retrieve MAM archive" + ) + return elt_list, rsm_response, mam_response = mam_data complete = mam_response["complete"] # we update MAM request for next iteration @@ -112,7 +127,7 @@ else: count += len(elt_list) - for mess_elt in elt_list: + for idx, mess_elt in enumerate(elt_list): try: fwd_message_elt = self.get_message_from_result( client, mess_elt, mam_req) @@ -152,6 +167,19 @@ log.error( "can't add message to history: {e}\n{xml}" .format(e=e, xml=mess_elt.toXml())) + if complete and idx == len(elt_list) - 1: + # We are at the last message from archive, we store the ID to not + # ask again the same messages next time. + try: + stanza_id = mess_elt.result["id"] + await self.host.memory.storage.set_private_value( + namespace=mam.NS_MAM, + key=KEY_LAST_STANZA_ID, + value=stanza_id, + profile=client.profile + ) + except Exception: + log.exception("Can't store last stanza ID") if not count: log.info(_("We have received no message while offline")) @@ -163,7 +191,7 @@ defer.ensureDeferred(self.resume(client)) def get_handler(self, client): - mam_client = client._mam = SatMAMClient(self) + mam_client = client._mam = LiberviaMAMClient(self) return mam_client def parse_extra(self, extra, with_rsm=True): @@ -240,7 +268,7 @@ xml=mess_elt.toXml())) raise exceptions.DataError("Invalid element") service_jid = client.jid.userhostJID() if service is None else service - mess_from = mess_elt["from"] + mess_from = mess_elt.getAttribute("from") or client.jid.userhostJID() # 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 @@ -420,6 +448,9 @@ to retrieve missing history on next connection @param message_elt(domish.Element): with a stanza-id """ + if message_elt.getAttribute("type") == C.MESS_TYPE_GROUPCHAT: + # groupchat message MAM is handled by XEP-0045 + return service_jid = client.jid.userhostJID() stanza_id = self._sid.get_stanza_id(message_elt, service_jid) if stanza_id is None: @@ -436,7 +467,7 @@ @implementer(disco.IDisco) -class SatMAMClient(mam.MAMClient): +class LiberviaMAMClient(mam.MAMClient): def __init__(self, plugin_parent): self.plugin_parent = plugin_parent