comparison sat/plugins/plugin_xep_0045.py @ 2822:5284be4c601b

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.
author Goffi <goffi@goffi.org>
date Fri, 01 Mar 2019 12:16:57 +0100
parents 27d9d25ec3cd
children 177f11163ed0
comparison
equal deleted inserted replaced
2821:3d735e0ab2fa 2822:5284be4c601b
114 114
115 self._mam = self.host.plugins.get(u"XEP-0313") 115 self._mam = self.host.plugins.get(u"XEP-0313")
116 self._si = self.host.plugins[u"XEP-0359"] 116 self._si = self.host.plugins[u"XEP-0359"]
117 117
118 host.trigger.add("presence_available", self.presenceTrigger) 118 host.trigger.add("presence_available", self.presenceTrigger)
119 host.trigger.add("presence_received", self.presenceReceivedTrigger)
119 host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=1000000) 120 host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=1000000)
120 host.trigger.add("message_parse", self._message_parseTrigger) 121 host.trigger.add("message_parse", self._message_parseTrigger)
121 122
122 def profileConnected(self, client): 123 def profileConnected(self, client):
123 def assign_service(service): 124 def assign_service(service):
763 elt = xml_tools.elementCopy(presence_elt) 764 elt = xml_tools.elementCopy(presence_elt)
764 elt['to'] = room_jid.userhost() + '/' + room.nick 765 elt['to'] = room_jid.userhost() + '/' + room.nick
765 client.presence.send(elt) 766 client.presence.send(elt)
766 return True 767 return True
767 768
769 def presenceReceivedTrigger(self, client, entity, show, priority, statuses):
770 entity_bare = entity.userhostJID()
771 muc_client = client._muc_client
772 if entity_bare in muc_client.joined_rooms:
773 room = muc_client.joined_rooms[entity_bare]
774 if hasattr(room, "_cache_presence"):
775 # room has a cache for presence, meaning it has not been fully
776 # joined yet. So we put presence in cache, and stop workflow.
777 # Or delete current presence and continue workflow if it's an
778 # "unavailable" presence
779 cache = room._cache_presence
780 if show == C.PRESENCE_UNAVAILABLE:
781 try:
782 del cache[entity]
783 except KeyError:
784 pass
785 return True
786 else:
787 cache[entity] = {
788 "entity": entity,
789 "show": show,
790 "statuses": statuses,
791 "priority": priority}
792 return False
793 return True
794
768 795
769 class SatMUCClient(muc.MUCClient): 796 class SatMUCClient(muc.MUCClient):
770 implements(iwokkel.IDisco) 797 implements(iwokkel.IDisco)
771 798
772 def __init__(self, plugin_parent): 799 def __init__(self, plugin_parent):
825 # FIXME: check if history_d is not redundant with fully_joined 852 # FIXME: check if history_d is not redundant with fully_joined
826 room.fully_joined = defer.Deferred() # called when everything is OK 853 room.fully_joined = defer.Deferred() # called when everything is OK
827 # cache data until room is ready 854 # cache data until room is ready
828 # list of elements which will be re-injected in stream 855 # list of elements which will be re-injected in stream
829 room._cache = [] 856 room._cache = []
857 # we only need to keep last presence status for each jid, so a dict is suitable
858 room._cache_presence = {}
830 859
831 @defer.inlineCallbacks 860 @defer.inlineCallbacks
832 def _joinLegacy(self, client, room_jid, nick, password): 861 def _joinLegacy(self, client, room_jid, nick, password):
833 """Join room an retrieve history with legacy method""" 862 """Join room an retrieve history with legacy method"""
834 mess_data_list = yield self.host.memory.historyGet(room_jid, 863 mess_data_list = yield self.host.memory.historyGet(room_jid,
1193 room.fully_joined.callback(room) 1222 room.fully_joined.callback(room)
1194 del room._history_d 1223 del room._history_d
1195 del room._history_type 1224 del room._history_type
1196 cache = room._cache 1225 cache = room._cache
1197 del room._cache 1226 del room._cache
1227 cache_presence = room._cache_presence
1228 del room._cache_presence
1198 for elem in cache: 1229 for elem in cache:
1199 self.client.xmlstream.dispatch(elem) 1230 self.client.xmlstream.dispatch(elem)
1231 for __, presence_data in cache_presence.iteritems():
1232 self.client.presence.availableReceived(**presence_data)
1200 1233
1201 def _historyEb(self, failure_, room): 1234 def _historyEb(self, failure_, room):
1202 log.error(u"Error while managing history: {}".format(failure_)) 1235 log.error(u"Error while managing history: {}".format(failure_))
1203 self._historyCb(None, room) 1236 self._historyCb(None, room)
1204 1237