Mercurial > libervia-backend
diff sat/core/xmpp.py @ 2701:2ea2369ae7de
plugin XEP-0313: implementation of MAM for messages:
- (core/xmpp): new messageGetBridgeArgs to easily retrieve arguments used in bridge from message data
- : parseMessage is not static anymore
- : new "message_parse" trigger point
- (xep-0313) : new "MAMGet" bridge method to retrieve history from MAM instead of local one
- : on profileConnected, if previous MAM message is found (i.e. message with a stanza_id), message received while offline are retrieved and injected in message workflow.
In other words, one2one history is synchronised on connection.
- : new "parseExtra" method which parse MAM (and optionally RSM) option from extra dictionary used in bridge.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 01 Dec 2018 10:33:43 +0100 |
parents | a8ec00731ce7 |
children | 57eac4fd0ec0 |
line wrap: on
line diff
--- a/sat/core/xmpp.py Sat Dec 01 10:10:25 2018 +0100 +++ b/sat/core/xmpp.py Sat Dec 01 10:33:43 2018 +0100 @@ -60,8 +60,8 @@ self.profile = profile self.host_app = host_app self.cache = cache.Cache(host_app, profile) - self._mess_id_uid = {} # map from message id to uid used in history. - # Key: (full_jid,message_id) Value: uid + self.mess_id2uid = {} # map from message id to uid used in history. + # Key: (full_jid, message_id) Value: uid # this Deferred fire when entity is connected self.conn_deferred = defer.Deferred() self._progress_cb = {} # callback called when a progress is requested @@ -540,6 +540,13 @@ ) # empty body should be managed by plugins before this point return data + def messageGetBridgeArgs(self, data): + """Generate args to use with bridge from data dict""" + return (data[u"uid"], data[u"timestamp"], data[u"from"].full(), + data[u"to"].full(), data[u"message"], data[u"subject"], + data[u"type"], data[u"extra"]) + + def messageSendToBridge(self, data): """Send message to bridge, so frontends can display it @@ -549,20 +556,13 @@ if data[u"type"] != C.MESS_TYPE_GROUPCHAT: # we don't send groupchat message to bridge, as we get them back # and they will be added the - if ( - data[u"message"] or data[u"subject"] - ): # we need a message to send something + if (data[u"message"] or data[u"subject"]): # we need a message to send + # something + # We send back the message, so all frontends are aware of it self.host_app.bridge.messageNew( - data[u"uid"], - data[u"timestamp"], - data[u"from"].full(), - data[u"to"].full(), - data[u"message"], - data[u"subject"], - data[u"type"], - data[u"extra"], - profile=self.profile, + *self.messageGetBridgeArgs(data), + profile=self.profile ) else: log.warning(_(u"No message found")) @@ -843,8 +843,7 @@ xmppim.MessageProtocol.__init__(self) self.host = host - @staticmethod - def parseMessage(message_elt, client=None): + def parseMessage(self, message_elt): """parse a message XML and return message_data @param message_elt(domish.Element): raw <message> xml @@ -852,28 +851,33 @@ if None, mapping will not be done @return(dict): message data """ + if message_elt.name != u"message": + log.warning(_( + u"parseMessage used with a non <message/> stanza, ignoring: {xml}" + .format(xml=message_elt.toXml()))) + return {} + client = self.parent message = {} subject = {} extra = {} data = { - "from": jid.JID(message_elt["from"]), - "to": jid.JID(message_elt["to"]), - "uid": message_elt.getAttribute( - "uid", unicode(uuid.uuid4()) + u"from": jid.JID(message_elt["from"]), + u"to": jid.JID(message_elt["to"]), + u"uid": message_elt.getAttribute( + u"uid", unicode(uuid.uuid4()) ), # XXX: uid is not a standard attribute but may be added by plugins - "message": message, - "subject": subject, - "type": message_elt.getAttribute("type", "normal"), - "extra": extra, + u"message": message, + u"subject": subject, + u"type": message_elt.getAttribute(u"type", u"normal"), + u"extra": extra, } - if client is not None: - try: - data["stanza_id"] = message_elt["id"] - except KeyError: - pass - else: - client._mess_id_uid[(data["from"], data["stanza_id"])] = data["uid"] + try: + message_id = data[u"extra"][u"message_id"] = message_elt[u"id"] + except KeyError: + pass + else: + client.mess_id2uid[(data["from"], message_id)] = data["uid"] # message for e in message_elt.elements(C.NS_CLIENT, "body"): @@ -894,6 +898,8 @@ data["received_timestamp"] = unicode(time.time()) if parsed_delay.sender: data["delay_sender"] = parsed_delay.sender.full() + + self.host.trigger.point("message_parse", client, message_elt, data) return data def _onMessageStartWorkflow(self, cont, client, message_elt, post_treat): @@ -907,7 +913,7 @@ """ if not cont: return - data = self.parseMessage(message_elt, client=client) + data = self.parseMessage(message_elt) post_treat.addCallback(self.skipEmptyMessage) post_treat.addCallback(self.addToHistory, client) post_treat.addCallback(self.bridgeSignal, client, data)