From efe52d755dfed5c7603a9aa8770b25346d3895d1 Mon Sep 17 00:00:00 2001 From: Goffi Date: Mon, 30 Dec 2019 20:44:02 +0100 Subject: [PATCH] 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. --- sat/plugins/plugin_xep_0045.py | 25 ++++++++++++++++++---- sat_frontends/primitivus/chat.py | 5 +++-- sat_frontends/quick_frontend/quick_app.py | 4 +++- sat_frontends/quick_frontend/quick_chat.py | 3 ++- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/sat/plugins/plugin_xep_0045.py b/sat/plugins/plugin_xep_0045.py index 857ffe68..668cae27 100644 --- a/sat/plugins/plugin_xep_0045.py +++ b/sat/plugins/plugin_xep_0045.py @@ -92,7 +92,7 @@ class XEP_0045(object): # 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 @@ class XEP_0045(object): 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 @@ class XEP_0045(object): "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 @@ class XEP_0045(object): XEP_0045._getOccupants(room), room.nick, room.subject, + [s.name for s in room.statuses], profile ] @@ -331,7 +332,14 @@ class XEP_0045(object): 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 @@ class SatMUCClient(muc.MUCClient): 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 received + # so we keep only the initial (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 diff --git a/sat_frontends/primitivus/chat.py b/sat_frontends/primitivus/chat.py index cfc6ec64..6b1e8873 100644 --- a/sat_frontends/primitivus/chat.py +++ b/sat_frontends/primitivus/chat.py @@ -283,7 +283,7 @@ class OccupantsWidget(urwid.WidgetWrap): 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 @@ class Chat(PrimitivusWidget, quick_chat.QuickChat): 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 diff --git a/sat_frontends/quick_frontend/quick_app.py b/sat_frontends/quick_frontend/quick_app.py index 3c6df620..8ef95f48 100644 --- a/sat_frontends/quick_frontend/quick_app.py +++ b/sat_frontends/quick_frontend/quick_app.py @@ -859,7 +859,8 @@ class QuickApp(object): 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 @@ class QuickApp(object): nick=user_nick, occupants=occupants, subject=subject, + statuses=statuses, profile=profile, ) diff --git a/sat_frontends/quick_frontend/quick_chat.py b/sat_frontends/quick_frontend/quick_chat.py index e3904daf..26dc9676 100644 --- a/sat_frontends/quick_frontend/quick_chat.py +++ b/sat_frontends/quick_frontend/quick_chat.py @@ -264,7 +264,7 @@ class QuickChat(quick_widgets.QuickWidget): 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 @@ class QuickChat(quick_widgets.QuickWidget): 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,