diff src/plugins/plugin_xep_0085.py @ 908:2ef523f0b5c3

plugin XEP-0085: bug fixes, especially for groupchat messages
author souliane <souliane@mailoo.org>
date Tue, 18 Mar 2014 13:52:12 +0100
parents 967b94ef821e
children 1a759096ccbd
line wrap: on
line diff
--- 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()