changeset 83e8b2dc4e93 in /home/hg/repos/gajim
author: Yann Leboulanger <[email protected]>
branches: gajim_0.16
details:http://hg.gajim.org/gajim?cmd=changeset;node=83e8b2dc4e93
description: add XEP-313 (MAM) support
diffstat:
src/chat_control.py | 2 +-
src/common/config.py | 1 +
src/common/connection.py | 10 +
src/common/connection_handlers.py | 93 +++-------------
src/common/connection_handlers_events.py | 54 ++++++++++
src/common/logger.py | 12 +-
src/common/message_archiving.py | 166 +++++++++++++++++++++++++++++++
src/gui_interface.py | 8 +-
8 files changed, 266 insertions(+), 80 deletions(-)
diffs (truncated from 543 to 300 lines):
diff -r b5b34a9bcf6e -r 83e8b2dc4e93 src/chat_control.py
--- a/src/chat_control.py Sun Nov 09 15:39:26 2014 +0100
+++ b/src/chat_control.py Tue Nov 11 15:28:24 2014 +0100
@@ -2972,7 +2972,7 @@
and gajim.HAVE_PYCRYPTO and self.contact.supports(NS_ESESSION):
self.begin_e2e_negotiation()
elif (not self.session or not self.session.status) and \
- gajim.connections[self.account].archiving_supported:
+ gajim.connections[self.account].archiving_136_supported:
self.begin_archiving_negotiation()
else:
self.send_chatstate('active', self.contact)
diff -r b5b34a9bcf6e -r 83e8b2dc4e93 src/common/config.py
--- a/src/common/config.py Sun Nov 09 15:39:26 2014 +0100
+++ b/src/common/config.py Tue Nov 11 15:28:24 2014 +0100
@@ -316,6 +316,7 @@
'ignore_incoming_attention': [opt_bool, False, _('If True, Gajim
will ignore incoming attention requestd ("wizz").')],
'remember_opened_chat_controls': [ opt_bool, True, _('If enabled,
Gajim will reopen chat windows that were opened last time Gajim was closed.')],
'positive_184_ack': [ opt_bool, False, _('If enabled, Gajim will
show an icon to show that sent message has been received by your contact')],
+ 'last_mam_id': [opt_str, '', _('Last MAM id we are syncronized
with')],
}, {})
__options_per_key = {
diff -r b5b34a9bcf6e -r 83e8b2dc4e93 src/common/connection.py
--- a/src/common/connection.py Sun Nov 09 15:39:26 2014 +0100
+++ b/src/common/connection.py Tue Nov 11 15:28:24 2014 +0100
@@ -424,6 +424,8 @@
msg_iq.setTag(nbxmpp.NS_ENCRYPTED + ' x').setData(msgenc)
if self.carbons_enabled:
msg_iq.addChild(name='private', namespace=nbxmpp.NS_CARBONS)
+ msg_iq.addChild(name='no-permanent-storage',
+ namespace=nbxmpp.NS_MSG_HINTS)
if form_node:
msg_iq.addChild(node=form_node)
@@ -502,6 +504,10 @@
if self.carbons_enabled:
msg_iq.addChild(name='private',
namespace=nbxmpp.NS_CARBONS)
+ msg_iq.addChild(name='no-permanent-storage',
+ namespace=nbxmpp.NS_MSG_HINTS)
+ msg_iq.addChild(name='no-copy',
+ namespace=nbxmpp.NS_MSG_HINTS)
if callback:
callback(jid, msg, keyID, forward_from, session, original_message,
@@ -1959,8 +1965,12 @@
# Remove stored bookmarks accessible to everyone.
self.send_pb_purge(our_jid, 'storage:bookmarks')
self.send_pb_delete(our_jid, 'storage:bookmarks')
+ if nbxmpp.NS_MAM in obj.features:
+ self.archiving_supported = True
+ self.archiving_313_supported = True
if nbxmpp.NS_ARCHIVE in obj.features:
self.archiving_supported = True
+ self.archiving_136_supported = True
if nbxmpp.NS_ARCHIVE_AUTO in obj.features:
self.archive_auto_supported = True
if nbxmpp.NS_ARCHIVE_MANAGE in obj.features:
diff -r b5b34a9bcf6e -r 83e8b2dc4e93 src/common/connection_handlers.py
--- a/src/common/connection_handlers.py Sun Nov 09 15:39:26 2014 +0100
+++ b/src/common/connection_handlers.py Tue Nov 11 15:28:24 2014 +0100
@@ -54,10 +54,8 @@
from common.protocol.caps import ConnectionCaps
from common.protocol.bytestream import ConnectionSocks5Bytestream
from common.protocol.bytestream import ConnectionIBBytestream
-from common.message_archiving import ConnectionArchive
-from common.message_archiving import ARCHIVING_COLLECTIONS_ARRIVED
-from common.message_archiving import ARCHIVING_COLLECTION_ARRIVED
-from common.message_archiving import ARCHIVING_MODIFICATIONS_ARRIVED
+from common.message_archiving import ConnectionArchive136
+from common.message_archiving import ConnectionArchive313
from common.connection_handlers_events import *
from common import ged
@@ -464,6 +462,7 @@
if id_ not in self.awaiting_answers:
return
+
if self.awaiting_answers[id_][0] == VCARD_PUBLISHED:
if iq_obj.getType() == 'result':
vcard_iq = self.awaiting_answers[id_][1]
@@ -482,6 +481,7 @@
if self.vcard_sha != new_sha and gajim.SHOW_LIST[
self.connected] != 'invisible':
if not self.connection or self.connected < 2:
+ del self.awaiting_answers[id_]
return
self.vcard_sha = new_sha
sshow = helpers.get_xmpp_show(gajim.SHOW_LIST[
@@ -495,6 +495,7 @@
elif iq_obj.getType() == 'error':
gajim.nec.push_incoming_event(VcardNotPublishedEvent(None,
conn=self))
+ del self.awaiting_answers[id_]
elif self.awaiting_answers[id_][0] == VCARD_ARRIVED:
# If vcard is empty, we send to the interface an empty vcard so
that
# it knows it arrived
@@ -517,10 +518,12 @@
vcard = {'jid': jid, 'resource': resource}
gajim.nec.push_incoming_event(VcardReceivedEvent(None,
conn=self, vcard_dict=vcard))
+ del self.awaiting_answers[id_]
elif self.awaiting_answers[id_][0] == AGENT_REMOVED:
jid = self.awaiting_answers[id_][1]
gajim.nec.push_incoming_event(AgentRemovedEvent(None, conn=self,
agent=jid))
+ del self.awaiting_answers[id_]
elif self.awaiting_answers[id_][0] == METACONTACTS_ARRIVED:
if not self.connection:
return
@@ -531,7 +534,9 @@
if iq_obj.getErrorCode() not in ('403', '406', '404'):
self.private_storage_supported = False
self.get_roster_delimiter()
+ del self.awaiting_answers[id_]
elif self.awaiting_answers[id_][0] == DELIMITER_ARRIVED:
+ del self.awaiting_answers[id_]
if not self.connection:
return
if iq_obj.getType() == 'result':
@@ -566,7 +571,9 @@
gajim.nec.push_incoming_event(RosterReceivedEvent(None,
conn=self))
gobject.timeout_add_seconds(10, self.discover_servers)
+ del self.awaiting_answers[id_]
elif self.awaiting_answers[id_][0] == PRIVACY_ARRIVED:
+ del self.awaiting_answers[id_]
if iq_obj.getType() != 'error':
self.privacy_rules_supported = True
self.get_privacy_list('block')
@@ -595,6 +602,7 @@
# Ask metacontacts before roster
self.get_metacontacts()
elif self.awaiting_answers[id_][0] == BLOCKING_ARRIVED:
+ del self.awaiting_answers[id_]
if iq_obj.getType() == 'result':
list_node = iq_obj.getTag('blocklist')
if not list_node:
@@ -603,6 +611,7 @@
for i in list_node.iterTags('item'):
self.blocked_contacts.append(i.getAttr('jid'))
elif self.awaiting_answers[id_][0] == PEP_CONFIG:
+ del self.awaiting_answers[id_]
if iq_obj.getType() == 'error':
return
if not iq_obj.getTag('pubsub'):
@@ -617,71 +626,6 @@
gajim.nec.push_incoming_event(PEPConfigReceivedEvent(None,
conn=self, node=node, form=form))
- elif self.awaiting_answers[id_][0] == ARCHIVING_COLLECTIONS_ARRIVED:
- # TODO
- print 'ARCHIVING_COLLECTIONS_ARRIVED'
-
- elif self.awaiting_answers[id_][0] == ARCHIVING_COLLECTION_ARRIVED:
- def save_if_not_exists(with_, nick, direction, tim, payload):
- assert len(payload) == 1, 'got several archiving messages in'
+\
- ' the same time %s' % ''.join(payload)
- if payload[0].getName() == 'body':
- gajim.logger.save_if_not_exists(with_, direction, tim,
- msg=payload[0].getData(), nick=nick)
- elif payload[0].getName() == 'message':
- print 'Not implemented'
- chat = iq_obj.getTag('chat')
- if chat:
- with_ = chat.getAttr('with')
- start_ = chat.getAttr('start')
- tim = helpers.datetime_tuple(start_)
- tim = timegm(tim)
- nb = 0
- for element in chat.getChildren():
- try:
- secs = int(element.getAttr('secs'))
- except TypeError:
- secs = 0
- if secs:
- tim += secs
- nick = element.getAttr('name')
- if element.getName() == 'from':
- save_if_not_exists(with_, nick, 'from', localtime(tim),
- element.getPayload())
- nb += 1
- if element.getName() == 'to':
- save_if_not_exists(with_, nick, 'to', localtime(tim),
- element.getPayload())
- nb += 1
- set_ = chat.getTag('set')
- first = set_.getTag('first')
- if first:
- try:
- index = int(first.getAttr('index'))
- except TypeError:
- index = 0
- try:
- count = int(set_.getTagData('count'))
- except TypeError:
- count = 0
- if count > index + nb:
- # Request the next page
- after = element.getTagData('last')
- self.request_collection_page(with_, start_, after=after)
-
- elif self.awaiting_answers[id_][0] == ARCHIVING_MODIFICATIONS_ARRIVED:
- modified = iq_obj.getTag('modified')
- if modified:
- for element in modified.getChildren():
- if element.getName() == 'changed':
- with_ = element.getAttr('with')
- start_ = element.getAttr('start')
- self.request_collection_page(with_, start_)
- #elif element.getName() == 'removed':
- # do nothing
-
- del self.awaiting_answers[id_]
-
def _vCardCB(self, con, vc):
"""
Called when we receive a vCard Parse the vCard and send it to plugins
@@ -1423,13 +1367,14 @@
return sess
-class ConnectionHandlers(ConnectionArchive, ConnectionVcard,
-ConnectionSocks5Bytestream, ConnectionDisco, ConnectionCommands,
-ConnectionPubSub, ConnectionPEP, ConnectionCaps, ConnectionHandlersBase,
-ConnectionJingle, ConnectionIBBytestream):
+class ConnectionHandlers(ConnectionArchive136, ConnectionArchive313,
+ConnectionVcard, ConnectionSocks5Bytestream, ConnectionDisco,
+ConnectionCommands, ConnectionPubSub, ConnectionPEP, ConnectionCaps,
+ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
def __init__(self):
global HAS_IDLE
- ConnectionArchive.__init__(self)
+ ConnectionArchive136.__init__(self)
+ ConnectionArchive313.__init__(self)
ConnectionVcard.__init__(self)
ConnectionSocks5Bytestream.__init__(self)
ConnectionIBBytestream.__init__(self)
diff -r b5b34a9bcf6e -r 83e8b2dc4e93 src/common/connection_handlers_events.py
--- a/src/common/connection_handlers_events.py Sun Nov 09 15:39:26 2014 +0100
+++ b/src/common/connection_handlers_events.py Tue Nov 11 15:28:24 2014 +0100
@@ -1089,6 +1089,60 @@
return
self.forwarded = True
+ result = self.stanza.getTag('result', namespace=nbxmpp.NS_MAM)
+ if result:
+ forwarded = result.getTag('forwarded', namespace=nbxmpp.NS_FORWARD)
+ if not forwarded:
+ return
+ delay = forwarded.getTag('delay', namespace=nbxmpp.NS_DELAY2)
+ if not delay:
+ return
+ tim = delay.getAttr('stamp')
+ tim = helpers.datetime_tuple(tim)
+ tim = localtime(timegm(tim))
+ msg_ = forwarded.getTag('message')
+ to_ = msg_.getAttr('to')
+ if to_:
+ gajim.get_jid_without_resource(to_)
+ else:
+ to_ = gajim.get_jid_from_account(account)
+ frm_ = gajim.get_jid_without_resource(msg_.getAttr('from'))
+ nick = None
+ msg_txt = msg_.getTagData('body')
+ if to_ == gajim.get_jid_from_account(account):
+ with_ = frm_
+ direction = 'from'
+ res = gajim.get_resource_from_jid(msg_.getAttr('from'))
+ else:
+ with_ = to_
+ direction = 'to'
+ res = gajim.get_resource_from_jid(msg_.getAttr('to'))
+ is_pm = gajim.logger.jid_is_room_jid(with_)
+ if msg_.getAttr('type') == 'groupchat':
+ if is_pm == False:
+ log.warn('JID %s is marked as normal contact in database '
+ 'but we got a groupchat message from it.')
+ return
+ if is_pm == None:
+ gajim.logger.get_jid_id(with_, 'ROOM')
+ nick = res
+ else:
+ if is_pm == None:
+ # we don't know this JID, we need to disco it.
+ server = gajim.get_server_from_jid(with_)
+ if server not in self.conn.mam_awaiting_disco_result:
+ self.conn.mam_awaiting_disco_result[server] = [
+ [with_, direction, tim, msg_txt, res]]
+ self.conn.discoverInfo(server)
+ else:
+ self.conn.mam_awaiting_disco_result[server].append(
+ [with_, direction, tim, msg_txt, res])
+ return
+
+ gajim.logger.save_if_not_exists(with_, direction, tim,
+ msg=msg_txt, nick=nick)
+ return
_______________________________________________
Commits mailing list
[email protected]
https://lists.gajim.org/cgi-bin/listinfo/commits