changeset 697:0c84fb112d70

core: sendMessage triggers now use a treatments deferred; - treaments deferred can be used by plugins to change XML elements before sending them, in a similar way as for newMessage - sendMessageXml trigger became useless, so it as been removed in favor of the new deferred
author Goffi <goffi@goffi.org>
date Wed, 13 Nov 2013 13:57:36 +0100
parents f1a2831d549d
children d731ae066158
files src/core/sat_main.py src/core/xmpp.py src/plugins/plugin_exp_parrot.py src/plugins/plugin_misc_text_commands.py src/plugins/plugin_xep_0085.py
diffstat 5 files changed, 52 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/sat_main.py	Tue Nov 12 16:56:34 2013 +0100
+++ b/src/core/sat_main.py	Wed Nov 13 13:57:36 2013 +0100
@@ -490,6 +490,7 @@
             "type": mess_type,
             "options": options,
         }
+        treatments = defer.Deferred() # XXX: plugin can add their treatments to this deferred
 
         if mess_data["type"] == "auto":
             # we try to guess the type
@@ -512,38 +513,39 @@
             mess_data["type"] == "chat" if mess_data["subject"] else "normal"
 
         if not no_trigger:
-            if not self.trigger.point("sendMessage", mess_data, profile):
+            if not self.trigger.point("sendMessage", mess_data, treatments, profile):
                 return
 
         debug(_("Sending jabber message of type [%(type)s] to %(to)s...") % {"type": mess_data["type"], "to": to_jid.full()})
-        message = domish.Element((None, 'message'))
-        message["to"] = mess_data["to"].full()
-        message["from"] = current_jid.full()
-        message["type"] = mess_data["type"]
+        mess_data['xml'] = domish.Element((None, 'message'))
+        mess_data['xml']["to"] = mess_data["to"].full()
+        mess_data['xml']["from"] = current_jid.full()
+        mess_data['xml']["type"] = mess_data["type"]
         if mess_data["subject"]:
-            message.addElement("subject", None, subject)
+            mess_data['xml'].addElement("subject", None, subject)
         # message without body are used to send chat states
         if mess_data["message"]:
-            message.addElement("body", None, mess_data["message"])
-        if not no_trigger:
-            if not self.trigger.point("sendMessageXml", message,
-                                      mess_data, profile):
-                return
-        client.xmlstream.send(message)
-        if mess_data["type"] != "groupchat":
-            # we don't add groupchat message to history, as we get them back
-            # and they will be added then
-            self.memory.addToHistory(current_jid, mess_data['to'],
-                                     unicode(mess_data["message"]),
-                                     unicode(mess_data["type"]),
-                                     profile=profile)
-            # We send back the message, so all clients are aware of it
-            if mess_data["message"]:
-                self.bridge.newMessage(message['from'],
-                                       unicode(mess_data["message"]),
-                                       mess_type=mess_data["type"],
-                                       to_jid=message['to'], extra={},
-                                       profile=profile)
+            mess_data['xml'].addElement("body", None, mess_data["message"])
+
+        def sendAndStore(mess_data):
+            client.xmlstream.send(mess_data['xml'])
+            if mess_data["type"] != "groupchat":
+                # we don't add groupchat message to history, as we get them back
+                # and they will be added then
+                self.memory.addToHistory(current_jid, mess_data['to'],
+                                         unicode(mess_data["message"]),
+                                         unicode(mess_data["type"]),
+                                         profile=profile)
+                # We send back the message, so all clients are aware of it
+                if mess_data["message"]:
+                    self.bridge.newMessage(mess_data['xml']['from'],
+                                           unicode(mess_data["message"]),
+                                           mess_type=mess_data["type"],
+                                           to_jid=mess_data['xml']['to'], extra={},
+                                           profile=profile)
+
+        treatments.addCallback(sendAndStore)
+        treatments.callback(mess_data)
 
     def setPresence(self, to="", show="", priority=0, statuses={}, profile_key='@DEFAULT@'):
         """Send our presence information"""
--- a/src/core/xmpp.py	Tue Nov 12 16:56:34 2013 +0100
+++ b/src/core/xmpp.py	Wed Nov 13 13:57:36 2013 +0100
@@ -112,7 +112,7 @@
 
     def onMessage(self, message):
         debug(_(u"got message from: %s"), message["from"])
-        post_treat = defer.Deferred() # XXX: plugin can add there treatments to this deferred
+        post_treat = defer.Deferred() # XXX: plugin can add their treatments to this deferred
 
         if not self.host.trigger.point("MessageReceived", message, post_treat, profile=self.parent.profile):
             return
--- a/src/plugins/plugin_exp_parrot.py	Tue Nov 12 16:56:34 2013 +0100
+++ b/src/plugins/plugin_exp_parrot.py	Wed Nov 13 13:57:36 2013 +0100
@@ -48,7 +48,7 @@
         host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=100)
         #host.trigger.add("sendMessage", self.sendMessageTrigger, priority=100)
 
-    #def sendMessageTrigger(self, mess_data, profile):
+    #def sendMessageTrigger(self, mess_data, treatments, profile):
     #    """ Deactivate other triggers if recipient is in parrot links """
     #    client = self.host.getClient(profile)
     #    try:
--- a/src/plugins/plugin_misc_text_commands.py	Tue Nov 12 16:56:34 2013 +0100
+++ b/src/plugins/plugin_misc_text_commands.py	Wed Nov 13 13:57:36 2013 +0100
@@ -42,7 +42,7 @@
         self.host = host
         host.trigger.add("sendMessage", self.sendMessageTrigger)
 
-    def sendMessageTrigger(self, mess_data, profile):
+    def sendMessageTrigger(self, mess_data, treatments, profile):
         """ Check text commands in message, and react consequently """
         msg = mess_data["message"]
         if msg:
--- a/src/plugins/plugin_xep_0085.py	Tue Nov 12 16:56:34 2013 +0100
+++ b/src/plugins/plugin_xep_0085.py	Wed Nov 13 13:57:36 2013 +0100
@@ -97,7 +97,7 @@
 
         # triggers from core
         host.trigger.add("MessageReceived", self.messageReceivedTrigger)
-        host.trigger.add("sendMessageXml", self.sendMessageXmlTrigger)
+        host.trigger.add("sendMessage", self.sendMessageTrigger)
         host.trigger.add("paramUpdateTrigger", self.paramUpdateTrigger)
         # TODO: handle profile disconnection (free memory in entity data)
 
@@ -168,25 +168,30 @@
             break
         return True
 
-    def sendMessageXmlTrigger(self, message, mess_data, profile):
+    def sendMessageTrigger(self, mess_data, treatments, profile):
         """
         Eventually add the chat state to the message and initiate
         the state machine when sending an "active" state.
         """
-        to_jid = JID(message.getAttribute("to"))
-        if not self.__checkActivation(to_jid, forceEntityData=True, profile=profile):
-            return True
-        try:
-            # message with a body always mean active state
-            domish.generateElementsNamed(message.elements(), name="body").next()
-            message.addElement('active', NS_CHAT_STATES)
-            # launch the chat state machine (init the timer)
-            self.__chatStateActive(to_jid, mess_data["type"], profile)
-        except StopIteration:
-            if "chat_state" in mess_data["options"]:
-                state = mess_data["options"]["chat_state"]
-                assert(state in CHAT_STATES)
-                message.addElement(state, NS_CHAT_STATES)
+        def treatment(mess_data):
+            message = mess_data['xml']
+            to_jid = JID(message.getAttribute("to"))
+            if not self.__checkActivation(to_jid, forceEntityData=True, profile=profile):
+                return True
+            try:
+                # message with a body always mean active state
+                domish.generateElementsNamed(message.elements(), name="body").next()
+                message.addElement('active', NS_CHAT_STATES)
+                # launch the chat state machine (init the timer)
+                self.__chatStateActive(to_jid, mess_data["type"], profile)
+            except StopIteration:
+                if "chat_state" in mess_data["options"]:
+                    state = mess_data["options"]["chat_state"]
+                    assert(state in CHAT_STATES)
+                    message.addElement(state, NS_CHAT_STATES)
+            return mess_data
+
+        treatments.addCallback(treatment)
         return True
 
     def __checkActivation(self, to_jid, forceEntityData, profile):