comparison src/plugins/plugin_xep_0033.py @ 749:192b804ee446

plugin XEP-0033: bug fix for sending messages with the addressing feature to several servers
author souliane <souliane@mailoo.org>
date Mon, 16 Dec 2013 14:48:28 +0100
parents 03744d9ebc13
children c8b9f675ac17
comparison
equal deleted inserted replaced
748:a0f4a80a6536 749:192b804ee446
27 from twisted.words.protocols.xmlstream import XMPPHandler 27 from twisted.words.protocols.xmlstream import XMPPHandler
28 except ImportError: 28 except ImportError:
29 from wokkel.subprotocols import XMPPHandler 29 from wokkel.subprotocols import XMPPHandler
30 from threading import Timer 30 from threading import Timer
31 from twisted.words.xish import domish 31 from twisted.words.xish import domish
32 from twisted.internet import defer 32 from twisted.internet import defer, threads
33 33
34 from sat.core.sat_main import MessageSentAndStored, AbortSendMessage 34 from sat.core.sat_main import MessageSentAndStored, AbortSendMessage
35 from sat.tools.misc import TriggerManager 35 from sat.tools.misc import TriggerManager
36 from time import time
36 37
37 # TODO: fix Prosody "addressing" plugin to leave the concerned bcc according to the spec: 38 # TODO: fix Prosody "addressing" plugin to leave the concerned bcc according to the spec:
38 # 39 #
39 # http://xmpp.org/extensions/xep-0033.html#addr-type-bcc 40 # http://xmpp.org/extensions/xep-0033.html#addr-type-bcc
40 # "This means that the server MUST remove these addresses before the stanza is delivered to anyone other than the given bcc addressee or the multicast service of the bcc addressee." 41 # "This means that the server MUST remove these addresses before the stanza is delivered to anyone other than the given bcc addressee or the multicast service of the bcc addressee."
67 Implementation for XEP 0033 68 Implementation for XEP 0033
68 """ 69 """
69 def __init__(self, host): 70 def __init__(self, host):
70 logging.info(_("Extended Stanza Addressing plugin initialization")) 71 logging.info(_("Extended Stanza Addressing plugin initialization"))
71 self.host = host 72 self.host = host
73 self.internal_data = {}
72 host.trigger.add("sendMessage", self.sendMessageTrigger, TriggerManager.MIN_PRIORITY) 74 host.trigger.add("sendMessage", self.sendMessageTrigger, TriggerManager.MIN_PRIORITY)
73 host.trigger.add("MessageReceived", self.messageReceivedTrigger) 75 host.trigger.add("MessageReceived", self.messageReceivedTrigger)
74 76
75 def sendMessageTrigger(self, mess_data, treatments, profile): 77 def sendMessageTrigger(self, mess_data, treatments, profile):
76 """Process the XEP-0033 related data to be sent""" 78 """Process the XEP-0033 related data to be sent"""
117 def discoCallback(entity, to_jid): 119 def discoCallback(entity, to_jid):
118 new_data = copy.deepcopy(mess_data) 120 new_data = copy.deepcopy(mess_data)
119 new_data['to'] = JID(to_jid) 121 new_data['to'] = JID(to_jid)
120 new_data['xml']['to'] = to_jid 122 new_data['xml']['to'] = to_jid
121 if entity: 123 if entity:
122 if 'address' in mess_data['extra']: 124 if entity not in self.internal_data[timestamp]:
123 self.host.sendAndStoreMessage(mess_data, False, profile) 125 self.host.sendAndStoreMessage(mess_data, False, profile)
124 # just to remember that the message has been sent 126 self.internal_data[timestamp].append(entity)
125 del mess_data['extra']['address']
126 # we still need to fill the history and signal the echo... 127 # we still need to fill the history and signal the echo...
127 self.host.sendAndStoreMessage(new_data, True, profile) 128 self.host.sendAndStoreMessage(new_data, True, profile)
128 else: 129 else:
129 # target server misses the addressing feature 130 # target server misses the addressing feature
130 self.host.sendAndStoreMessage(new_data, False, profile) 131 self.host.sendAndStoreMessage(new_data, False, profile)
131 132
132 def errback(failure, to_jid): 133 def errback(failure, to_jid):
133 discoCallback(None, to_jid) 134 discoCallback(None, to_jid)
134 135
136 timestamp = time()
137 self.internal_data[timestamp] = []
138 defer_list = []
135 for type_, jid_ in entries: 139 for type_, jid_ in entries:
136 d = defer.Deferred() 140 d = defer.Deferred()
137 d.addCallback(self.host.requestServerDisco, JID(JID(jid_).host), profile_key=profile) 141 d.addCallback(self.host.requestServerDisco, JID(JID(jid_).host), profile_key=profile)
138 d.addCallbacks(discoCallback, errback, callbackArgs=[jid_], errbackArgs=[jid_]) 142 d.addCallbacks(discoCallback, errback, callbackArgs=[jid_], errbackArgs=[jid_])
139 d.callback(NS_ADDRESS) 143 d.callback(NS_ADDRESS)
144 defer_list.append(d)
145 d = defer.Deferred().addCallback(lambda dummy: self.internal_data.pop(timestamp))
146 defer.DeferredList(defer_list).chainDeferred(d)
140 147
141 raise MessageSentAndStored("XEP-0033 took over") 148 raise MessageSentAndStored("XEP-0033 took over")
142 149
143 def messageReceivedTrigger(self, message, post_treat, profile): 150 def messageReceivedTrigger(self, message, post_treat, profile):
144 """In order to save the addressing information in the history""" 151 """In order to save the addressing information in the history"""