implement XEP-0280: Message Carbons

This commit is contained in:
Yann Leboulanger 2011-11-06 17:20:58 +01:00
parent 4a0b02ac3a
commit 188950f470
7 changed files with 79 additions and 20 deletions

View File

@ -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])

View File

@ -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, '' ],

View File

@ -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 + '/' + \

View File

@ -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',

View File

@ -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'

View File

@ -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:

View File

@ -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)