implement XEP-0280: Message Carbons
This commit is contained in:
parent
4a0b02ac3a
commit
188950f470
|
@ -2924,12 +2924,12 @@ class ChatControl(ChatControlBase):
|
|||
kind = 'info'
|
||||
else:
|
||||
kind = 'print_queue'
|
||||
dm = None
|
||||
if len(data) > 10:
|
||||
dm = data[10]
|
||||
if data[11]:
|
||||
kind = 'out'
|
||||
dm = data[10]
|
||||
self.print_conversation(data[0], kind, tim=data[3],
|
||||
encrypted=data[4], subject=data[1], xhtml=data[7],
|
||||
displaymarking=dm)
|
||||
encrypted=data[4], subject=data[1], xhtml=data[7],
|
||||
displaymarking=dm)
|
||||
if len(data) > 6 and isinstance(data[6], int):
|
||||
message_ids.append(data[6])
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ class Config:
|
|||
'roster_version': [opt_str, ''],
|
||||
'subscription_request_msg': [opt_str, '', _('Message that is sent to contacts you want to add')],
|
||||
'last_archiving_time': [opt_str, '1970-01-01T00:00:00Z', _('Last time we syncronized with logs from server.')],
|
||||
'enable_message_carbons': [ opt_bool, False, _('If enabled and if server supports this feature, Gajim will receive messages sent and received by other resources.')],
|
||||
}, {}),
|
||||
'statusmsg': ({
|
||||
'message': [ opt_str, '' ],
|
||||
|
|
|
@ -1709,6 +1709,13 @@ class Connection(CommonConnection, ConnectionHandlers):
|
|||
self.archive_manual_supported = True
|
||||
if common.xmpp.NS_ARCHIVE_PREF in obj.features:
|
||||
self.archive_pref_supported = True
|
||||
if common.xmpp.NS_CARBONS in obj.features and \
|
||||
gajim.config.get_per('accounts', self.name,
|
||||
'enable_message_carbons'):
|
||||
# Server supports carbons, activate it
|
||||
iq = common.xmpp.Iq('set')
|
||||
iq.setTag('enable', namespace=common.xmpp.NS_CARBONS)
|
||||
self.connection.send(iq)
|
||||
if common.xmpp.NS_BYTESTREAM in obj.features and \
|
||||
gajim.config.get_per('accounts', self.name, 'use_ft_proxies'):
|
||||
our_fjid = helpers.parse_jid(our_jid + '/' + \
|
||||
|
|
|
@ -977,6 +977,8 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
self.conn = self.base_event.conn
|
||||
self.stanza = self.base_event.stanza
|
||||
self.get_id()
|
||||
self.forwarded = False
|
||||
self.sent = False
|
||||
|
||||
account = self.conn.name
|
||||
|
||||
|
@ -1013,6 +1015,39 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
return
|
||||
self.jid = gajim.get_jid_without_resource(self.fjid)
|
||||
|
||||
forward_tag = self.stanza.getTag('forwarded', namespace=xmpp.NS_FORWARD)
|
||||
# Be sure it comes from one of our resource, else ignore forward element
|
||||
if forward_tag and self.jid == gajim.get_jid_from_account(account):
|
||||
received_tag = forward_tag.getTag('received',
|
||||
namespace=xmpp.NS_CARBONS)
|
||||
sent_tag = forward_tag.getTag('sent', namespace=xmpp.NS_CARBONS)
|
||||
if received_tag:
|
||||
msg = forward_tag.getTag('message')
|
||||
self.stanza = xmpp.Message(node=msg)
|
||||
try:
|
||||
self.get_jid_resource()
|
||||
except helpers.InvalidFormat:
|
||||
self.conn.dispatch('ERROR', (_('Invalid Jabber ID'),
|
||||
_('A message from a non-valid JID arrived, it has been '
|
||||
'ignored.')))
|
||||
return
|
||||
self.forwarded = True
|
||||
elif sent_tag:
|
||||
msg = forward_tag.getTag('message')
|
||||
self.stanza = xmpp.Message(node=msg)
|
||||
to = self.stanza.getTo()
|
||||
self.stanza.setTo(self.stanza.getFrom())
|
||||
self.stanza.setFrom(to)
|
||||
try:
|
||||
self.get_jid_resource()
|
||||
except helpers.InvalidFormat:
|
||||
self.conn.dispatch('ERROR', (_('Invalid Jabber ID'),
|
||||
_('A message from a non-valid JID arrived, it has been '
|
||||
'ignored.')))
|
||||
return
|
||||
self.forwarded = True
|
||||
self.sent = True
|
||||
|
||||
self.enc_tag = self.stanza.getTag('x', namespace=xmpp.NS_ENCRYPTED)
|
||||
|
||||
self.invite_tag = None
|
||||
|
@ -1052,7 +1087,8 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
self.session.last_receive = time_time()
|
||||
|
||||
# check if the message is a XEP-0020 feature negotiation request
|
||||
if self.stanza.getTag('feature', namespace=xmpp.NS_FEATURE):
|
||||
if not self.forwarded and self.stanza.getTag('feature',
|
||||
namespace=xmpp.NS_FEATURE):
|
||||
if gajim.HAVE_PYCRYPTO:
|
||||
feature = self.stanza.getTag(name='feature',
|
||||
namespace=xmpp.NS_FEATURE)
|
||||
|
@ -1069,7 +1105,8 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
self.conn.connection.send(reply)
|
||||
return
|
||||
|
||||
if self.stanza.getTag('init', namespace=xmpp.NS_ESESSION_INIT):
|
||||
if not self.forwarded and self.stanza.getTag('init',
|
||||
namespace=xmpp.NS_ESESSION_INIT):
|
||||
init = self.stanza.getTag(name='init',
|
||||
namespace=xmpp.NS_ESESSION_INIT)
|
||||
form = xmpp.DataForm(node=init.getTag('x'))
|
||||
|
@ -1084,6 +1121,9 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
xep_200_encrypted = self.stanza.getTag('c',
|
||||
namespace=xmpp.NS_STANZA_CRYPTO)
|
||||
if xep_200_encrypted:
|
||||
if self.forwarded:
|
||||
# Ignore E2E forwarded encrypted messages
|
||||
return False
|
||||
self.encrypted = 'xep200'
|
||||
|
||||
return True
|
||||
|
@ -1155,6 +1195,8 @@ class DecryptedMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
self.session = self.msg_obj.session
|
||||
self.timestamp = self.msg_obj.timestamp
|
||||
self.encrypted = self.msg_obj.encrypted
|
||||
self.forwarded = self.msg_obj.forwarded
|
||||
self.sent = self.msg_obj.sent
|
||||
self.popup = False
|
||||
|
||||
self.receipt_request_tag = self.stanza.getTag('request',
|
||||
|
|
|
@ -47,10 +47,11 @@ NS_BOB = 'urn:xmpp:bob' # XEP-0231
|
|||
NS_BOOKMARKS = 'storage:bookmarks' # XEP-0048
|
||||
NS_BROWSE = 'jabber:iq:browse'
|
||||
NS_BROWSING = 'http://jabber.org/protocol/browsing' # XEP-0195
|
||||
NS_BYTESTREAM = 'http://jabber.org/protocol/bytestreams' # JEP-0065
|
||||
NS_CAPS = 'http://jabber.org/protocol/caps' # JEP-0115
|
||||
NS_BYTESTREAM = 'http://jabber.org/protocol/bytestreams' # XEP-0065
|
||||
NS_CAPS = 'http://jabber.org/protocol/caps' # XEP-0115
|
||||
NS_CAPTCHA = 'urn:xmpp:captcha' # XEP-0158
|
||||
NS_CHATSTATES = 'http://jabber.org/protocol/chatstates' # JEP-0085
|
||||
NS_CARBONS = 'urn:xmpp:carbons:1' # XEP-0280
|
||||
NS_CHATSTATES = 'http://jabber.org/protocol/chatstates' # XEP-0085
|
||||
NS_CHATTING = 'http://jabber.org/protocol/chatting' # XEP-0194
|
||||
NS_CLIENT = 'jabber:client'
|
||||
NS_CONDITIONS = 'urn:xmpp:muc:conditions:0' # XEP-0306
|
||||
|
@ -70,9 +71,10 @@ NS_DISCO_ITEMS = NS_DISCO + '#items'
|
|||
NS_ENCRYPTED = 'jabber:x:encrypted' # XEP-0027
|
||||
NS_ESESSION = 'http://www.xmpp.org/extensions/xep-0116.html#ns'
|
||||
NS_ESESSION_INIT = 'http://www.xmpp.org/extensions/xep-0116.html#ns-init' # XEP-0116
|
||||
NS_EVENT = 'jabber:x:event' # XEP-0022
|
||||
NS_EVENT = 'jabber:x:event' # XEP-0022
|
||||
NS_FEATURE = 'http://jabber.org/protocol/feature-neg'
|
||||
NS_FILE = 'http://jabber.org/protocol/si/profile/file-transfer' # JEP-0096
|
||||
NS_FILE = 'http://jabber.org/protocol/si/profile/file-transfer' # XEP-0096
|
||||
NS_FORWARD = 'urn:xmpp:forward:0' # XEP-0297
|
||||
NS_GAMING = 'http://jabber.org/protocol/gaming' # XEP-0196
|
||||
NS_GATEWAY = 'jabber:iq:gateway' # XEP-0100
|
||||
NS_GEOLOC = 'http://jabber.org/protocol/geoloc' # XEP-0080
|
||||
|
@ -102,7 +104,7 @@ NS_MUC_CONFIG = NS_MUC + '#roomconfig'
|
|||
NS_NICK = 'http://jabber.org/protocol/nick' # XEP-0172
|
||||
NS_OFFLINE = 'http://www.jabber.org/jeps/jep-0030.html' # XEP-0013
|
||||
NS_PHYSLOC = 'http://jabber.org/protocol/physloc' # XEP-0112
|
||||
NS_PING = 'urn:xmpp:ping' # SEP-0199
|
||||
NS_PING = 'urn:xmpp:ping' # XEP-0199
|
||||
NS_PRESENCE = 'presence' # Jabberd2
|
||||
NS_PRIVACY = 'jabber:iq:privacy'
|
||||
NS_PRIVATE = 'jabber:iq:private'
|
||||
|
@ -110,7 +112,7 @@ NS_PROFILE = 'http://jabber.org/protocol/profile' # XEP-0154
|
|||
NS_PUBSUB = 'http://jabber.org/protocol/pubsub' # XEP-0060
|
||||
NS_PUBSUB_EVENT = 'http://jabber.org/protocol/pubsub#event'
|
||||
NS_PUBSUB_PUBLISH_OPTIONS = NS_PUBSUB + '#publish-options' # XEP-0060
|
||||
NS_PUBSUB_OWNER = 'http://jabber.org/protocol/pubsub#owner' # JEP-0060
|
||||
NS_PUBSUB_OWNER = 'http://jabber.org/protocol/pubsub#owner' # XEP-0060
|
||||
NS_REGISTER = 'jabber:iq:register'
|
||||
NS_ROSTER = 'jabber:iq:roster'
|
||||
NS_ROSTERNOTES = 'storage:rosternotes'
|
||||
|
|
|
@ -2584,10 +2584,12 @@ class RosterWindow:
|
|||
typ = ''
|
||||
if obj.mtype == 'error':
|
||||
typ = 'error'
|
||||
if obj.forwarded and obj.sent:
|
||||
typ = 'out'
|
||||
|
||||
obj.session.control.print_conversation(obj.msgtxt, typ,
|
||||
tim=obj.timestamp, encrypted=obj.encrypted, subject=obj.subject,
|
||||
xhtml=obj.xhtml, displaymarking=obj.displaymarking)
|
||||
tim=obj.timestamp, encrypted=obj.encrypted, subject=obj.subject,
|
||||
xhtml=obj.xhtml, displaymarking=obj.displaymarking)
|
||||
if obj.msg_id:
|
||||
gajim.logger.set_read_messages([obj.msg_id])
|
||||
elif obj.popup:
|
||||
|
|
|
@ -79,9 +79,13 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
|||
if not obj.stanza.getTag('body') and obj.chatstate is None:
|
||||
return
|
||||
|
||||
log_type = 'chat_msg_recv'
|
||||
log_type = 'chat_msg'
|
||||
else:
|
||||
log_type = 'single_msg_recv'
|
||||
log_type = 'single_msg'
|
||||
end = '_recv'
|
||||
if obj.forwarded and obj.sent:
|
||||
end = '_sent'
|
||||
log_type += end
|
||||
|
||||
if self.is_loggable() and obj.msgtxt:
|
||||
try:
|
||||
|
@ -113,7 +117,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
|||
# Handle chat states
|
||||
contact = gajim.contacts.get_contact(self.conn.name, obj.jid,
|
||||
obj.resource)
|
||||
if contact:
|
||||
if contact and (not obj.forwarded or not obj.sent):
|
||||
if self.control and self.control.type_id == \
|
||||
message_control.TYPE_CHAT:
|
||||
if obj.chatstate is not None:
|
||||
|
@ -237,7 +241,8 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
|
|||
if not self.control:
|
||||
event = gajim.events.create_event(type_, (obj.msgtxt, obj.subject,
|
||||
obj.mtype, obj.timestamp, obj.encrypted, obj.resource,
|
||||
obj.msg_id, obj.xhtml, self, obj.form_node, obj.displaymarking),
|
||||
obj.msg_id, obj.xhtml, self, obj.form_node, obj.displaymarking,
|
||||
obj.forwarded and obj.sent),
|
||||
show_in_roster=obj.show_in_roster,
|
||||
show_in_systray=obj.show_in_systray)
|
||||
|
||||
|
|
Loading…
Reference in New Issue