Determine delay timestamp correctly
- Check the from attr on the delay node to determine if its a user timestamp or from the server - Dont use user timestamp for sorting - Record the user timestamp in additional data so its saved to the database Fixes #9444
This commit is contained in:
parent
b2ecc14cae
commit
6c2df54132
|
@ -130,12 +130,13 @@ class MAM:
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
# Timestamp parsing
|
# Timestamp parsing
|
||||||
timestamp = parse_delay(forwarded)
|
# Most servers dont set the 'from' attr, so we cant check for it
|
||||||
if timestamp is None:
|
delay_timestamp = parse_delay(forwarded)
|
||||||
|
if delay_timestamp is None:
|
||||||
|
log.warning('No timestamp on MAM message')
|
||||||
|
log.warning(stanza)
|
||||||
raise nbxmpp.NodeProcessed
|
raise nbxmpp.NodeProcessed
|
||||||
|
|
||||||
user_timestamp = parse_delay(message)
|
|
||||||
|
|
||||||
# Fix for self messaging
|
# Fix for self messaging
|
||||||
if not groupchat:
|
if not groupchat:
|
||||||
to = message.getTo()
|
to = message.getTo()
|
||||||
|
@ -180,8 +181,7 @@ class MAM:
|
||||||
{'conn': self._con,
|
{'conn': self._con,
|
||||||
'additional_data': {},
|
'additional_data': {},
|
||||||
'encrypted': False,
|
'encrypted': False,
|
||||||
'timestamp': timestamp,
|
'timestamp': delay_timestamp,
|
||||||
'user_timestamp': user_timestamp,
|
|
||||||
'self_message': self_message,
|
'self_message': self_message,
|
||||||
'groupchat': groupchat,
|
'groupchat': groupchat,
|
||||||
'muc_pm': muc_pm,
|
'muc_pm': muc_pm,
|
||||||
|
@ -248,7 +248,12 @@ class MAM:
|
||||||
# For example Chatstates, Receipts, Chatmarkers
|
# For example Chatstates, Receipts, Chatmarkers
|
||||||
log.debug(event.message.getProperties())
|
log.debug(event.message.getProperties())
|
||||||
return
|
return
|
||||||
log.debug(event.msgtxt)
|
|
||||||
|
user_timestamp = parse_delay(event.stanza)
|
||||||
|
if user_timestamp is not None:
|
||||||
|
# Record it as a user timestamp
|
||||||
|
event.additional_data.set_value(
|
||||||
|
'gajim', 'user_timestamp', user_timestamp)
|
||||||
|
|
||||||
event.correct_id = parse_correction(event.message)
|
event.correct_id = parse_correction(event.message)
|
||||||
parse_oob(event.message, event.additional_data)
|
parse_oob(event.message, event.additional_data)
|
||||||
|
|
|
@ -223,15 +223,40 @@ class Message:
|
||||||
except nbxmpp.NodeProcessed:
|
except nbxmpp.NodeProcessed:
|
||||||
return
|
return
|
||||||
|
|
||||||
timestamp, delayed = parse_delay(event.stanza), True
|
subject = event.stanza.getSubject()
|
||||||
|
groupchat = event.mtype == 'groupchat'
|
||||||
|
muc_subject = subject and groupchat
|
||||||
|
|
||||||
|
# Determine timestamps
|
||||||
|
if groupchat:
|
||||||
|
delay_entity_jid = event.jid
|
||||||
|
else:
|
||||||
|
delay_entity_jid = self._con.get_own_jid().getDomain()
|
||||||
|
|
||||||
|
if muc_subject:
|
||||||
|
# MUC Subjects can have a delay timestamp
|
||||||
|
# to indicate when the user has set the subject,
|
||||||
|
# the 'from' attr on these delays is the MUC server
|
||||||
|
# but we treat it as user timestamp
|
||||||
|
timestamp = time.time()
|
||||||
|
user_timestamp = parse_delay(event.stanza, from_=delay_entity_jid)
|
||||||
|
|
||||||
|
else:
|
||||||
|
timestamp = parse_delay(event.stanza, from_=delay_entity_jid)
|
||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
timestamp = time.time()
|
timestamp = time.time()
|
||||||
delayed = False
|
|
||||||
|
user_timestamp = parse_delay(event.stanza,
|
||||||
|
not_from=[delay_entity_jid])
|
||||||
|
|
||||||
|
if user_timestamp is not None:
|
||||||
|
event.additional_data.set_value(
|
||||||
|
'gajim', 'user_timestamp', user_timestamp)
|
||||||
|
|
||||||
event_attr = {
|
event_attr = {
|
||||||
'popup': False,
|
'popup': False,
|
||||||
'msg_log_id': None,
|
'msg_log_id': None,
|
||||||
'subject': event.stanza.getSubject(),
|
'subject': subject,
|
||||||
'displaymarking': parse_securitylabel(event.stanza),
|
'displaymarking': parse_securitylabel(event.stanza),
|
||||||
'attention': parse_attention(event.stanza),
|
'attention': parse_attention(event.stanza),
|
||||||
'correct_id': parse_correction(event.stanza),
|
'correct_id': parse_correction(event.stanza),
|
||||||
|
@ -239,7 +264,7 @@ class Message:
|
||||||
'form_node': parse_form(event.stanza),
|
'form_node': parse_form(event.stanza),
|
||||||
'xhtml': parse_xhtml(event.stanza),
|
'xhtml': parse_xhtml(event.stanza),
|
||||||
'timestamp': timestamp,
|
'timestamp': timestamp,
|
||||||
'delayed': delayed,
|
'delayed': user_timestamp is not None,
|
||||||
}
|
}
|
||||||
parse_oob(event.stanza, event.additional_data)
|
parse_oob(event.stanza, event.additional_data)
|
||||||
|
|
||||||
|
@ -257,7 +282,7 @@ class Message:
|
||||||
event.session, event.fjid, timestamp)
|
event.session, event.fjid, timestamp)
|
||||||
return
|
return
|
||||||
|
|
||||||
if event.mtype == 'groupchat':
|
if groupchat:
|
||||||
app.nec.push_incoming_event(GcMessageReceivedEvent(
|
app.nec.push_incoming_event(GcMessageReceivedEvent(
|
||||||
None,
|
None,
|
||||||
conn=self._con,
|
conn=self._con,
|
||||||
|
|
|
@ -65,16 +65,43 @@ def parse_eme(stanza):
|
||||||
|
|
||||||
# XEP-0203: Delayed Delivery
|
# XEP-0203: Delayed Delivery
|
||||||
|
|
||||||
def parse_delay(stanza, epoch=True, convert='utc'):
|
def parse_delay(stanza, epoch=True, convert='utc', from_=None, not_from=None):
|
||||||
timestamp = None
|
'''
|
||||||
delay = stanza.getTagAttr(
|
Returns the first valid delay timestamp that matches
|
||||||
'delay', 'stamp', namespace=nbxmpp.NS_DELAY2)
|
|
||||||
if delay is not None:
|
:param epoch: Returns the timestamp as epoch
|
||||||
timestamp = parse_datetime(delay, check_utc=True,
|
|
||||||
|
:param convert: Converts the timestamp to either utc or local
|
||||||
|
|
||||||
|
:param from_: Matches only delays that have the according
|
||||||
|
from attr set
|
||||||
|
|
||||||
|
:param not_from: Matches only delays that have the according
|
||||||
|
from attr not set
|
||||||
|
'''
|
||||||
|
delays = stanza.getTags('delay', namespace=nbxmpp.NS_DELAY2)
|
||||||
|
|
||||||
|
for delay in delays:
|
||||||
|
stamp = delay.getAttr('stamp')
|
||||||
|
if stamp is None:
|
||||||
|
log.warning('Invalid timestamp received: %s', stamp)
|
||||||
|
log.warning(stanza)
|
||||||
|
continue
|
||||||
|
|
||||||
|
delay_from = delay.getAttr('from')
|
||||||
|
if from_ is not None:
|
||||||
|
if delay_from != from_:
|
||||||
|
continue
|
||||||
|
if not_from is not None:
|
||||||
|
if delay_from in not_from:
|
||||||
|
continue
|
||||||
|
|
||||||
|
timestamp = parse_datetime(stamp, check_utc=True,
|
||||||
epoch=epoch, convert=convert)
|
epoch=epoch, convert=convert)
|
||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
log.warning('Invalid timestamp received: %s', delay)
|
log.warning('Invalid timestamp received: %s', stamp)
|
||||||
log.warning(stanza)
|
log.warning(stanza)
|
||||||
|
continue
|
||||||
|
|
||||||
return timestamp
|
return timestamp
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import nbxmpp
|
||||||
|
|
||||||
|
from gajim.common.modules.misc import parse_delay
|
||||||
|
|
||||||
|
class TestHelpers(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_parse_delay(self):
|
||||||
|
|
||||||
|
node = """
|
||||||
|
<message>
|
||||||
|
<delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25Z' />
|
||||||
|
<delay xmlns='urn:xmpp:delay' from='romeo.com' stamp='2010-09-10T23:08:25Z' />
|
||||||
|
<delay xmlns='urn:xmpp:delay' stamp='2015-09-10T23:08:25Z' />
|
||||||
|
</message>
|
||||||
|
"""
|
||||||
|
message = nbxmpp.Node(node=node)
|
||||||
|
|
||||||
|
timestamp = parse_delay(message)
|
||||||
|
self.assertEqual(timestamp, 1031699305.0)
|
||||||
|
|
||||||
|
timestamp = parse_delay(message, from_='capulet.com')
|
||||||
|
self.assertEqual(timestamp, 1031699305.0)
|
||||||
|
|
||||||
|
timestamp = parse_delay(message, from_='romeo.com')
|
||||||
|
self.assertEqual(timestamp, 1284160105.0)
|
||||||
|
|
||||||
|
timestamp = parse_delay(message, not_from=['romeo.com'])
|
||||||
|
self.assertEqual(timestamp, 1031699305.0)
|
Loading…
Reference in New Issue