plugin XEP-0045: cache presences if they are received before the room is fully joined:

presences are then replayed (only the last one) once the room is fully joined.
This commit is contained in:
Goffi 2019-03-01 12:16:57 +01:00
commit fe2e5dd8ce

View file

@ -116,6 +116,7 @@ class XEP_0045(object):
self._si = self.host.plugins[u"XEP-0359"]
host.trigger.add("presence_available", self.presenceTrigger)
host.trigger.add("presence_received", self.presenceReceivedTrigger)
host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=1000000)
host.trigger.add("message_parse", self._message_parseTrigger)
@ -765,6 +766,32 @@ class XEP_0045(object):
client.presence.send(elt)
return True
def presenceReceivedTrigger(self, client, entity, show, priority, statuses):
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
return True
class SatMUCClient(muc.MUCClient):
implements(iwokkel.IDisco)
@ -827,6 +854,8 @@ class SatMUCClient(muc.MUCClient):
# cache data until room is ready
# list of elements which will be re-injected in stream
room._cache = []
# we only need to keep last presence status for each jid, so a dict is suitable
room._cache_presence = {}
@defer.inlineCallbacks
def _joinLegacy(self, client, room_jid, nick, password):
@ -1195,8 +1224,12 @@ class SatMUCClient(muc.MUCClient):
del room._history_type
cache = room._cache
del room._cache
cache_presence = room._cache_presence
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)
def _historyEb(self, failure_, room):
log.error(u"Error while managing history: {}".format(failure_))