changeset 4155:453e53dfc50e

plugin XEP-0045: user normal workflow for history + `get_room_user_jid` method: - workflow is now using the normal messages workflow even for history message: previous workflow was dedicated to MUC and only adding message to history, resulting in other plugins being skipped. - new `get_room_user_jid` helps to retrieve easily the JID currently used in a joined room.
author Goffi <goffi@goffi.org>
date Wed, 22 Nov 2023 15:00:57 +0100
parents 85f5e6225aa1
children 2729d424dee7
files libervia/backend/plugins/plugin_xep_0045.py
diffstat 1 files changed, 19 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/libervia/backend/plugins/plugin_xep_0045.py	Wed Nov 22 14:56:14 2023 +0100
+++ b/libervia/backend/plugins/plugin_xep_0045.py	Wed Nov 22 15:00:57 2023 +0100
@@ -175,7 +175,7 @@
 
     def message_received_trigger(self, client, message_elt, post_treat):
         if message_elt.getAttribute("type") == C.MESS_TYPE_GROUPCHAT:
-            if message_elt.subject or message_elt.delay:
+            if message_elt.subject:
                 return False
             from_jid = jid.JID(message_elt['from'])
             room_jid = from_jid.userhostJID()
@@ -256,6 +256,22 @@
                 return peer_jid.userhostJID()
         return peer_jid
 
+    def get_room_user_jid(self, client: SatXMPPEntity, room_jid: jid.JID) -> jid.JID:
+        """Get the nick used in the room
+
+        @param room_jid: jid of the room to use
+        @return: JID used in room
+
+        @raise exceptions.NotFound: this room has not been joined
+        @raise exceptions.InternalError: invalid room_jid
+        """
+        # FIXME: doesn't check if room is anonymous or not
+        # TODO: check if room is (semi)anonymous
+        if room_jid.resource:
+            raise exceptions.InternalError(f"{room_jid} should not have a ressource.")
+        room = self.get_room(client, room_jid)
+        return jid.JID(tuple=(room_jid.user, room_jid.host, room.nick))
+
     def _get_room_joined_args(self, room, profile):
         return [
             room.roomJID.userhost(),
@@ -1067,7 +1083,7 @@
                                                        service=room_jid)
             except xmpp_error.StanzaError as e:
                 if last_mess and e.condition == 'item-not-found':
-                    log.info(
+                    log.warning(
                         f"requested item (with id {stanza_id!r}) can't be found in "
                         f"history of {room_jid}, history has probably been purged on "
                         f"server.")
@@ -1099,18 +1115,7 @@
                             'Forwarded message element has a "to" attribute while it is '
                             'forbidden by specifications')
                     fwd_message_elt["to"] = client.jid.full()
-                    try:
-                        mess_data = client.messageProt.parse_message(fwd_message_elt)
-                    except Exception as e:
-                        log.error(
-                            f"Can't parse message, ignoring it: {e}\n"
-                            f"{fwd_message_elt.toXml()}"
-                        )
-                        continue
-                    # we attache parsed message data to element, to avoid parsing
-                    # again in _add_to_history
-                    fwd_message_elt._mess_data = mess_data
-                    # and we inject to MUC workflow
+                    client.messageProt.onMessage(fwd_message_elt)
                     client._muc_client._onGroupChat(fwd_message_elt)
 
         if not count:
@@ -1352,59 +1357,6 @@
     def receivedGroupChat(self, room, user, body):
         log.debug('receivedGroupChat: room=%s user=%s body=%s' % (room.roomJID.full(), user, body))
 
-    def _add_to_history(self, __, user, message):
-        try:
-            # message can be already parsed (with MAM), in this case mess_data
-            # it attached to the element
-            mess_data = message.element._mess_data
-        except AttributeError:
-            mess_data = self.client.messageProt.parse_message(message.element)
-        if mess_data['message'] or mess_data['subject']:
-            return defer.ensureDeferred(
-                self.host.memory.add_to_history(self.client, mess_data)
-            )
-        else:
-            return defer.succeed(None)
-
-    def _add_to_history_eb(self, failure):
-        failure.trap(exceptions.CancelError)
-
-    def receivedHistory(self, room, user, message):
-        """Called when history (backlog) message are received
-
-        we check if message is not already in our history
-        and add it if needed
-        @param room(muc.Room): room instance
-        @param user(muc.User, None): the user that sent the message
-            None if the message come from the room
-        @param message(muc.GroupChat): the parsed message
-        """
-        if room.state != ROOM_STATE_SELF_PRESENCE:
-            log.warning(_(
-                "received history in unexpected state in room {room} (state: "
-                "{state})").format(room = room.roomJID.userhost(),
-                                    state = room.state))
-            if not hasattr(room, "_history_d"):
-                # XXX: this hack is due to buggy behaviour seen in the wild because of the
-                #      "mod_delay" prosody module being activated. This module add an
-                #      unexpected <delay> elements which break our workflow.
-                log.warning(_("storing the unexpected message anyway, to avoid loss"))
-                # we have to restore URI which are stripped by wokkel parsing
-                for c in message.element.elements():
-                    if c.uri is None:
-                        c.uri = C.NS_CLIENT
-                mess_data = self.client.messageProt.parse_message(message.element)
-                message.element._mess_data = mess_data
-                self._add_to_history(None, user, message)
-                if mess_data['message'] or mess_data['subject']:
-                    self.host.bridge.message_new(
-                        *self.client.message_get_bridge_args(mess_data),
-                        profile=self.client.profile
-                    )
-                return
-        room._history_d.addCallback(self._add_to_history, user, message)
-        room._history_d.addErrback(self._add_to_history_eb)
-
     ## subject ##
 
     def groupChatReceived(self, message):
@@ -1427,8 +1379,6 @@
             self.receivedSubject(room, user, message.subject)
         elif message.delay is None:
             self.receivedGroupChat(room, user, message)
-        else:
-            self.receivedHistory(room, user, message)
 
     def subject(self, room, subject):
         return muc.MUCClientProtocol.subject(self, room, subject)