changeset 2991:f4590ca2acff

plugin XEP-0045: avoid sending useless presence signals: - presence signals were sent twice (from XEP-0045 itself + core), this is now avoided by cancelling presence workflow in core when presence if from a joined room. - filter out cached presences if no status or show information is set (occupants are already specified in mucRoomJoined signal)
author Goffi <goffi@goffi.org>
date Sun, 07 Jul 2019 15:39:53 +0200 (2019-07-07)
parents 6959c71ab8bf
children 4d5b9d4c7448
files sat/plugins/plugin_xep_0045.py
diffstat 1 files changed, 26 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0045.py	Sat Jul 06 15:51:48 2019 +0200
+++ b/sat/plugins/plugin_xep_0045.py	Sun Jul 07 15:39:53 2019 +0200
@@ -792,26 +792,8 @@
         entity_bare = entity.userhostJID()
         muc_client = client._muc_client
         if entity_bare in muc_client.joined_rooms:
-            room = muc_client.joined_rooms[entity_bare]
-            if hasattr(room, "_cache_presence"):
-                # room has a cache for presence, meaning it has not been fully
-                # joined yet. So we put presence in cache, and stop workflow.
-                # Or delete current presence and continue workflow if it's an
-                # "unavailable" presence
-                cache = room._cache_presence
-                if show == C.PRESENCE_UNAVAILABLE:
-                    try:
-                        del cache[entity]
-                    except KeyError:
-                        pass
-                    return True
-                else:
-                    cache[entity] = {
-                        "entity": entity,
-                        "show": show,
-                        "statuses": statuses,
-                        "priority": priority}
-                    return False
+            # presence is already handled in (un)availableReceived
+            return False
         return True
 
 
@@ -1150,7 +1132,23 @@
         self.host.bridge.mucRoomUserChangedNick(room.roomJID.userhost(), user.nick, new_nick, self.client.profile)
 
     def userUpdatedStatus(self, room, user, show, status):
-        self.host.bridge.presenceUpdate(room.roomJID.userhost() + '/' + user.nick, show or '', 0, {C.PRESENCE_STATUSES_DEFAULT: status or ''}, self.client.profile)
+        entity = jid.JID(tuple=(room.roomJID.user, room.roomJID.host, user.nick))
+        if hasattr(room, "_cache_presence"):
+            # room has a cache for presence, meaning it has not been fully
+            # joined yet. So we put presence in cache, and stop workflow.
+            # Or delete current presence and continue workflow if it's an
+            # "unavailable" presence
+            cache = room._cache_presence
+            cache[entity] = {
+                "room": room,
+                "user": user,
+                "show": show,
+                "status": status,
+                }
+            return
+        statuses = {C.PRESENCE_STATUSES_DEFAULT: status or ''}
+        self.host.bridge.presenceUpdate(
+            entity.full(), show or '', 0, statuses, self.client.profile)
 
     ## messages ##
 
@@ -1256,8 +1254,13 @@
         del room._cache_presence
         for elem in cache:
             self.client.xmlstream.dispatch(elem)
-        for __, presence_data in cache_presence.iteritems():
-            self.client.presence.availableReceived(**presence_data)
+        for presence_data in cache_presence.itervalues():
+            if not presence_data[u'show'] and not presence_data[u'status']:
+                # occupants are already sent in mucRoomJoined, so if we don't have
+                # extra information like show or statuses, we can discard the signal
+                continue
+            else:
+                self.userUpdatedStatus(**presence_data)
 
     def _historyEb(self, failure_, room):
         log.error(u"Error while managing history: {}".format(failure_))