changeset 3101:ab7e8ade848a

plugin XEP-0045: added room statuses to metadata: room statuses are now sent with other metadata on bridge signals, and saved in Room instance. They give useful data on the room, for instance they can be used to know if a full jid is used in this room.
author Goffi <goffi@goffi.org>
date Mon, 30 Dec 2019 20:44:02 +0100
parents cea52c9ddfd9
children 7574f795bd1e
files sat/plugins/plugin_xep_0045.py sat_frontends/primitivus/chat.py sat_frontends/quick_frontend/quick_app.py sat_frontends/quick_frontend/quick_chat.py
diffstat 4 files changed, 29 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0045.py	Sat Dec 28 20:02:18 2019 +0100
+++ b/sat/plugins/plugin_xep_0045.py	Mon Dec 30 20:44:02 2019 +0100
@@ -92,7 +92,7 @@
         # return same arguments as mucRoomJoined + a boolean set to True is the room was
         # already joined (first argument)
         host.bridge.addMethod(
-            "mucJoin", ".plugin", in_sign='ssa{ss}s', out_sign='(bsa{sa{ss}}sss)',
+            "mucJoin", ".plugin", in_sign='ssa{ss}s', out_sign='(bsa{sa{ss}}ssass)',
             method=self._join, async_=True)
         host.bridge.addMethod(
             "mucNick", ".plugin", in_sign='sss', out_sign='', method=self._nick)
@@ -107,7 +107,7 @@
         host.bridge.addMethod(
             "mucSubject", ".plugin", in_sign='sss', out_sign='', method=self._subject)
         host.bridge.addMethod(
-            "mucGetRoomsJoined", ".plugin", in_sign='s', out_sign='a(sa{sa{ss}}ss)',
+            "mucGetRoomsJoined", ".plugin", in_sign='s', out_sign='a(sa{sa{ss}}ssas)',
             method=self._getRoomsJoined)
         host.bridge.addMethod(
             "mucGetUniqueRoomName", ".plugin", in_sign='ss', out_sign='s',
@@ -128,7 +128,7 @@
             "mucRoomPrepareJoin", ".plugin", signature='ss')
         # args: room_jid, occupants, user_nick, subject, profile
         host.bridge.addSignal(
-            "mucRoomJoined", ".plugin", signature='sa{sa{ss}}sss')
+            "mucRoomJoined", ".plugin", signature='sa{sa{ss}}ssass')
         # args: room_jid, profile
         host.bridge.addSignal(
             "mucRoomLeft", ".plugin", signature='ss')
@@ -241,6 +241,7 @@
             XEP_0045._getOccupants(room),
             room.nick,
             room.subject,
+            [s.name for s in room.statuses],
             profile
             ]
 
@@ -331,7 +332,14 @@
         result = []
         for room in list(client._muc_client.joined_rooms.values()):
             if room.state == ROOM_STATE_LIVE:
-                result.append((room.roomJID.userhost(), self._getOccupants(room), room.nick, room.subject))
+                result.append(
+                    (room.roomJID.userhost(),
+                     self._getOccupants(room),
+                     room.nick,
+                     room.subject,
+                     [s.name for s in room.statuses],
+                    )
+                )
         return result
 
     def _getRoomNick(self, room_jid_s, profile_key=C.PROF_KEY_NONE):
@@ -1087,6 +1095,15 @@
                 return
             user = muc.User(nick, presence.entity)
 
+        # we want to keep statuses with room
+        # XXX: presence if broadcasted, and we won't have status code
+        #      like 110 (REALJID_PUBLIC) after first <presence/> received
+        #      so we keep only the initial <presence> (with SELF_PRESENCE),
+        #      thus we check if attribute already exists
+        if (not hasattr(room, 'statuses')
+            and muc.STATUS_CODE.SELF_PRESENCE in presence.mucStatuses):
+            room.statuses = presence.mucStatuses
+
         # Update user data
         user.role = presence.role
         user.affiliation = presence.affiliation
--- a/sat_frontends/primitivus/chat.py	Sat Dec 28 20:02:18 2019 +0100
+++ b/sat_frontends/primitivus/chat.py	Mon Dec 30 20:44:02 2019 +0100
@@ -283,7 +283,7 @@
 
 class Chat(PrimitivusWidget, quick_chat.QuickChat):
     def __init__(self, host, target, type_=C.CHAT_ONE2ONE, nick=None, occupants=None,
-                 subject=None, profiles=None):
+                 subject=None, statuses=None, profiles=None):
         self.filters = []  # list of filter callbacks to apply
         self.mess_walker = urwid.SimpleListWalker([])
         self.mess_widgets = urwid.ListBox(self.mess_walker)
@@ -292,7 +292,8 @@
         self.pile = urwid.Pile([self.chat_colums])
         PrimitivusWidget.__init__(self, self.pile, target)
         quick_chat.QuickChat.__init__(
-            self, host, target, type_, nick, occupants, subject, profiles=profiles
+            self, host, target, type_, nick, occupants, subject, statuses,
+            profiles=profiles
         )
 
         # we must adapt the behaviour with the type
--- a/sat_frontends/quick_frontend/quick_app.py	Sat Dec 28 20:02:18 2019 +0100
+++ b/sat_frontends/quick_frontend/quick_app.py	Mon Dec 30 20:44:02 2019 +0100
@@ -859,7 +859,8 @@
 
         self.callListeners("presence", entity, show, priority, statuses, profile=profile)
 
-    def mucRoomJoinedHandler(self, room_jid_s, occupants, user_nick, subject, profile):
+    def mucRoomJoinedHandler(
+            self, room_jid_s, occupants, user_nick, subject, statuses, profile):
         """Called when a MUC room is joined"""
         log.debug(
             "Room [{room_jid}] joined by {profile}, users presents:{users}".format(
@@ -875,6 +876,7 @@
             nick=user_nick,
             occupants=occupants,
             subject=subject,
+            statuses=statuses,
             profile=profile,
         )
 
--- a/sat_frontends/quick_frontend/quick_chat.py	Sat Dec 28 20:02:18 2019 +0100
+++ b/sat_frontends/quick_frontend/quick_chat.py	Mon Dec 30 20:44:02 2019 +0100
@@ -264,7 +264,7 @@
     visible_states = ["chat_state"]  # FIXME: to be removed, used only in quick_games
 
     def __init__(self, host, target, type_=C.CHAT_ONE2ONE, nick=None, occupants=None,
-                 subject=None, profiles=None):
+                 subject=None, statuses=None, profiles=None):
         """
         @param type_: can be C.CHAT_ONE2ONE for single conversation or C.CHAT_GROUP for
                       chat à la IRC
@@ -299,6 +299,7 @@
         self.messages = OrderedDict()  # key: uid, value: Message instance
         self.games = {}  # key=game name (unicode), value=instance of quick_games.RoomGame
         self.subject = subject
+        self.statuses = set(statuses or [])
         lt = time.localtime()
         self.day_change = (
             lt.tm_year,