diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py index ff72de957e366d6db3fff08a2b9945d56cc7c5ea..ee21ccb131b1be83e089e4084036002f04fb8993 100644 --- a/gajim/common/connection_handlers_events.py +++ b/gajim/common/connection_handlers_events.py @@ -163,6 +163,23 @@ class HelperEvent: if forwarded is not None: return forwarded.getTag('message', protocol=True) + def _is_self_message(self, message): + if self.self_message is not None: + return self.self_message + own_jid = self.conn.get_own_jid() + frm = message.getFrom() + to = message.getTo() + # If 'to' is not set we assume own jid + self.self_message = frm.bareMatch(to or own_jid) + return self.self_message + + def _is_muc_pm(self, message): + if self.muc_pm is not None: + return self.muc_pm + self.muc_pm = message.getTag( + 'x', namespace=nbxmpp.NS_MUC_USER) is not None + return self.muc_pm + class HttpAuthReceivedEvent(nec.NetworkIncomingEvent): name = 'http-auth-received' base_network_events = [] @@ -1015,6 +1032,8 @@ class MamMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): self.encrypted = False self.groupchat = False self.nick = None + self.self_message = None + self.muc_pm = None def generate(self): account = self.conn.name @@ -1081,6 +1100,11 @@ class MamMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): def get_unique_id(self): stanza_id = self.get_stanza_id(self.result, query=True) + + if self._is_self_message(self.msg_) or self._is_muc_pm(self.msg_): + origin_id = self.msg_.getOriginID() + return stanza_id, origin_id + if self.conn.get_own_jid().bareMatch(self.msg_.getFrom()): # message we sent origin_id = self.msg_.getOriginID() @@ -1217,6 +1241,8 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): self.forwarded = False self.sent = False self.encrypted = False + self.self_message = None + self.muc_pm = None account = self.conn.name if self.stanza.getFrom() == self.conn.get_own_jid(warn=True): @@ -1250,11 +1276,12 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): self.unique_id = self.get_unique_id() # Check groupchat messages for duplicates, # We do this because of MUC History messages - if self.stanza.getType() == 'groupchat': + type_ = self.stanza.getType() + if type_ == 'groupchat' or self.self_message or self.muc_pm: if app.logger.find_stanza_id(account, self.stanza.getFrom().getStripped(), self.unique_id, - groupchat=True): + groupchat=type_ == 'groupchat'): return address_tag = self.stanza.getTag('addresses', @@ -1406,6 +1433,21 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): return True def get_unique_id(self): + ''' + Messages to self: + + Messages to self are stored multiple times in MAM so we cant use + stanza-id to deduplicate. We use origin-id instead. Its not perfect + but there is no better way for now. + We drop "received"-Carbons of Message to self, so we dont have to + parse origin-id in that case. + + MUC PMs: + + MUC PMs are also stored multiple times, we also depend on origin-id + for now. + ''' + if self.stanza.getType() == 'groupchat': # TODO: Disco the MUC check if 'urn:xmpp:mam:2' is announced return self.get_stanza_id(self.stanza) @@ -1424,6 +1466,8 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): protocol=True) if sent_carbon is not None: message = self.get_forwarded_message(sent_carbon) + if self._is_self_message(message) or self._is_muc_pm(message): + return message.getOriginID() return self.get_stanza_id(message) # Received Carbon @@ -1432,9 +1476,13 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): protocol=True) if received_carbon is not None: message = self.get_forwarded_message(received_carbon) + if self._is_muc_pm(message): + return message.getOriginID() return self.get_stanza_id(message) # Normal Message + if self._is_self_message(self.stanza) or self._is_muc_pm(self.stanza): + return self.stanza.getOriginID() return self.get_stanza_id(self.stanza) class ZeroconfMessageReceivedEvent(MessageReceivedEvent):