# HG changeset patch # User souliane # Date 1395147132 -3600 # Node ID 2ef523f0b5c3ea5c696bd9b558d8f0644f74663c # Parent cd02f5ef30df586f245e0bcdd8b84c5ccff36940 plugin XEP-0085: bug fixes, especially for groupchat messages diff -r cd02f5ef30df -r 2ef523f0b5c3 src/plugins/plugin_xep_0085.py --- a/src/plugins/plugin_xep_0085.py Mon Mar 17 13:24:55 2014 +0100 +++ b/src/plugins/plugin_xep_0085.py Tue Mar 18 13:52:12 2014 +0100 @@ -137,38 +137,40 @@ return False return True - def messageReceivedTrigger(self, message, post_treat, profile): """ Update the entity cache when we receive a message with body. - Check for a check state in the incoming message and broadcast signal. + Check for a chat state in the message and signal frontends. """ if not self.host.memory.getParamA(PARAM_NAME, PARAM_KEY, profile_key=profile): return True + from_jid = JID(message.getAttribute("from")) try: domish.generateElementsNamed(message.elements(), name="body").next() - from_jid = JID(message.getAttribute("from")) try: domish.generateElementsNamed(message.elements(), name="active").next() # contact enabled Chat State Notifications self.updateEntityData(from_jid, True, profile) - # init to send following "composing" state - self.__chatStateInit(from_jid, message.getAttribute("type"), profile) except StopIteration: - # contact didn't enable Chat State Notifications - self.updateEntityData(from_jid, False, profile) - return True + if message.getAttribute('type') == 'chat': + # contact didn't enable Chat State Notifications + self.updateEntityData(from_jid, False, profile) + return True except StopIteration: pass + # send our next "composing" states to any MUC and to the contacts who enabled the feature + self.__chatStateInit(from_jid, message.getAttribute("type"), profile) + state_list = [child.name for child in message.elements() if message.getAttribute("type") in MESSAGE_TYPES and child.name in CHAT_STATES and child.defaultUri == NS_CHAT_STATES] for state in state_list: # there must be only one state according to the XEP - self.host.bridge.chatStateReceived(message.getAttribute("from"), state, profile) + if state != 'gone' or message.getAttribute('type') != 'groupchat': + self.host.bridge.chatStateReceived(message.getAttribute("from"), state, profile) break return True @@ -211,6 +213,12 @@ return False # check if notifications should be sent to this contact try: + type_ = self.host.memory.getEntityData(to_jid, ['type'], profile)['type'] + if type_ == 'groupchat': # always send to groupchat + return True + except (exceptions.UnknownEntityError, KeyError): + pass # private chat + try: return self.host.memory.getEntityData(to_jid, [ENTITY_KEY], profile)[ENTITY_KEY] except (exceptions.UnknownEntityError, KeyError): if forceEntityData: @@ -224,7 +232,7 @@ """ Data initialization for the chat state machine. """ - # TODO: use also the resource in map key + # TODO: use also the resource in map key (not for groupchat) to_jid = to_jid.userhostJID() if mess_type is None: return @@ -240,7 +248,7 @@ """ Launch the chat state machine on "active" state. """ - # TODO: use also the JID resource in the map key + # TODO: use also the JID resource in the map key (not for groupchat) to_jid = to_jid.userhostJID() profile = self.host.memory.getProfileName(profile_key) if profile is None: @@ -257,7 +265,7 @@ data associated to the target JID. TODO: try to optimize this method which is called often """ - # TODO: use also the JID resource in the map key + # TODO: use also the JID resource in the map key (not for groupchat) to_jid = JID(to_jid_s).userhostJID() profile = self.host.memory.getProfileName(profile_key) if profile is None: @@ -267,7 +275,7 @@ return try: self.map[profile][to_jid]._onEvent("composing") - except AttributeError: + except (KeyError, AttributeError): # no message has been sent/received since the notifications # have been enabled, it's better to wait for a first one pass @@ -302,13 +310,11 @@ automatically sent with each message) and set the timer. """ if state != self.state and state != "active": - # send a new message without body - self.host.sendMessage(self.to_jid, - '', - '', - self.mess_type, - extra={"chat_state": state}, - profile_key=self.profile) + if state != 'gone' or self.mess_type != 'groupchat': + # send a new message without body + self.host.sendMessage(self.to_jid, '', '', self.mess_type, + extra={"chat_state": state}, + profile_key=self.profile) self.state = state if not self.timer is None: self.timer.cancel()