plugin XEP-0313: better error logging + store last stanza ID when retrieving archives + small improvments

This commit is contained in:
Goffi 2023-11-22 14:56:14 +01:00
commit f91c2be526

View file

@ -18,23 +18,25 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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 @@ class XEP_0313(object):
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 @@ class XEP_0313(object):
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 @@ class XEP_0313(object):
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 @@ class XEP_0313(object):
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 @@ class XEP_0313(object):
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 @@ class XEP_0313(object):
to retrieve missing history on next connection
@param message_elt(domish.Element): <message> 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 @@ class XEP_0313(object):
@implementer(disco.IDisco)
class SatMAMClient(mam.MAMClient):
class LiberviaMAMClient(mam.MAMClient):
def __init__(self, plugin_parent):
self.plugin_parent = plugin_parent