restore messages with Zeroconf
This commit is contained in:
parent
70f7ceb2a2
commit
b5b04f2a3d
|
@ -761,6 +761,10 @@ class ConnectionHandlersBase:
|
|||
self._nec_iq_error_received)
|
||||
gajim.ged.register_event_handler('presence-received', ged.CORE,
|
||||
self._nec_presence_received)
|
||||
gajim.ged.register_event_handler('message-received', ged.CORE,
|
||||
self._nec_message_received)
|
||||
gajim.ged.register_event_handler('decrypted-message-received', ged.CORE,
|
||||
self._nec_decrypted_message_received)
|
||||
|
||||
def _nec_iq_error_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
|
@ -935,6 +939,104 @@ class ConnectionHandlersBase:
|
|||
self.dispatch('DB_ERROR', (pritext, sectext))
|
||||
our_jid = gajim.get_jid_from_account(self.name)
|
||||
|
||||
def _nec_message_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
return
|
||||
if obj.encrypted == 'xep200':
|
||||
try:
|
||||
obj.stanza = obj.session.decrypt_stanza(obj.stanza)
|
||||
obj.msgtxt = obj.stanza.getBody()
|
||||
except Exception:
|
||||
gajim.nec.push_incoming_event(FailedDecryptEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
return
|
||||
|
||||
if obj.enc_tag and self.USE_GPG:
|
||||
encmsg = obj.enc_tag.getData()
|
||||
|
||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||
if keyID:
|
||||
def decrypt_thread(encmsg, keyID, obj):
|
||||
decmsg = self.gpg.decrypt(encmsg, keyID)
|
||||
# \x00 chars are not allowed in C (so in GTK)
|
||||
obj.msgtxt = helpers.decode_string(decmsg.replace('\x00',
|
||||
''))
|
||||
obj.encrypted = 'xep27'
|
||||
gajim.thread_interface(decrypt_thread, [encmsg, keyID, obj],
|
||||
self._on_message_decrypted, [obj])
|
||||
return
|
||||
self._on_message_decrypted(None, obj)
|
||||
|
||||
def _on_message_decrypted(self, output, obj):
|
||||
gajim.nec.push_incoming_event(DecryptedMessageReceivedEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
|
||||
def _nec_decrypted_message_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
return
|
||||
|
||||
# Receipt requested
|
||||
# TODO: We shouldn't answer if we're invisible!
|
||||
contact = gajim.contacts.get_contact(self.name, obj.jid)
|
||||
nick = obj.resource
|
||||
gc_contact = gajim.contacts.get_gc_contact(self.name, obj.jid, nick)
|
||||
if obj.receipt_request_tag and gajim.config.get_per('accounts',
|
||||
self.name, 'answer_receipts') and ((contact and contact.sub \
|
||||
not in (u'to', u'none')) or gc_contact) and obj.mtype != 'error':
|
||||
receipt = common.xmpp.Message(to=obj.fjid, typ='chat')
|
||||
receipt.setID(obj.id_)
|
||||
receipt.setTag('received', namespace='urn:xmpp:receipts',
|
||||
attrs={'id': obj.id_})
|
||||
|
||||
if obj.thread_id:
|
||||
receipt.setThread(obj.thread_id)
|
||||
self.connection.send(receipt)
|
||||
|
||||
# We got our message's receipt
|
||||
if obj.receipt_received_tag and obj.session.control and \
|
||||
gajim.config.get_per('accounts', self.name, 'request_receipt'):
|
||||
obj.session.control.conv_textview.hide_xep0184_warning(obj.id_)
|
||||
|
||||
if obj.mtype == 'error':
|
||||
self.dispatch_error_message(obj.stanza, obj.msgtxt,
|
||||
obj.session, obj.fjid, obj.timestamp)
|
||||
return True
|
||||
elif obj.mtype == 'groupchat':
|
||||
gajim.nec.push_incoming_event(GcMessageReceivedEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
return True
|
||||
elif obj.invite_tag is not None:
|
||||
gajim.nec.push_incoming_event(GcInvitationReceivedEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
return True
|
||||
|
||||
# process and dispatch an error message
|
||||
def dispatch_error_message(self, msg, msgtxt, session, frm, tim):
|
||||
error_msg = msg.getErrorMsg()
|
||||
|
||||
if not error_msg:
|
||||
error_msg = msgtxt
|
||||
msgtxt = None
|
||||
|
||||
subject = msg.getSubject()
|
||||
|
||||
if session.is_loggable():
|
||||
try:
|
||||
gajim.logger.write('error', frm, error_msg, tim=tim,
|
||||
subject=subject)
|
||||
except exceptions.PysqliteOperationalError, e:
|
||||
self.dispatch('DB_ERROR', (_('Disk Write Error'), str(e)))
|
||||
except exceptions.DatabaseMalformed:
|
||||
pritext = _('Database Error')
|
||||
sectext = _('The database file (%s) cannot be read. Try to '
|
||||
'repair it (see http://trac.gajim.org/wiki/DatabaseBackup) '
|
||||
'or remove it (all history will be lost).') % \
|
||||
common.logger.LOG_DB_PATH
|
||||
self.dispatch('DB_ERROR', (pritext, sectext))
|
||||
gajim.nec.push_incoming_event(MessageErrorEvent(None, conn=self,
|
||||
fjid=frm, error_code=msg.getErrorCode(), error_msg=error_msg,
|
||||
msg=msgtxt, time_=tim, session=session))
|
||||
|
||||
def _LastResultCB(self, con, iq_obj):
|
||||
log.debug('LastResultCB')
|
||||
gajim.nec.push_incoming_event(LastResultReceivedEvent(None, conn=self,
|
||||
|
@ -1160,10 +1262,6 @@ ConnectionJingle, ConnectionIBBytestream):
|
|||
ged.CORE, self._nec_unsubscribed_presence_received)
|
||||
gajim.ged.register_event_handler('unsubscribed-presence-received',
|
||||
ged.POSTGUI, self._nec_unsubscribed_presence_received_end)
|
||||
gajim.ged.register_event_handler('message-received', ged.CORE,
|
||||
self._nec_message_received)
|
||||
gajim.ged.register_event_handler('decrypted-message-received', ged.CORE,
|
||||
self._nec_decrypted_message_received)
|
||||
gajim.ged.register_event_handler('agent-removed', ged.CORE,
|
||||
self._nec_agent_removed)
|
||||
|
||||
|
@ -1435,104 +1533,6 @@ ConnectionJingle, ConnectionIBBytestream):
|
|||
gajim.nec.push_incoming_event(NetworkEvent('raw-message-received',
|
||||
conn=self, stanza=msg, account=self.name))
|
||||
|
||||
def _nec_message_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
return
|
||||
if obj.encrypted == 'xep200':
|
||||
try:
|
||||
obj.stanza = obj.session.decrypt_stanza(obj.stanza)
|
||||
obj.msgtxt = obj.stanza.getBody()
|
||||
except Exception:
|
||||
gajim.nec.push_incoming_event(FailedDecryptEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
return
|
||||
|
||||
if obj.enc_tag and self.USE_GPG:
|
||||
encmsg = obj.enc_tag.getData()
|
||||
|
||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||
if keyID:
|
||||
def decrypt_thread(encmsg, keyID, obj):
|
||||
decmsg = self.gpg.decrypt(encmsg, keyID)
|
||||
# \x00 chars are not allowed in C (so in GTK)
|
||||
obj.msgtxt = helpers.decode_string(decmsg.replace('\x00',
|
||||
''))
|
||||
obj.encrypted = 'xep27'
|
||||
gajim.thread_interface(decrypt_thread, [encmsg, keyID, obj],
|
||||
self._on_message_decrypted, [obj])
|
||||
return
|
||||
self._on_message_decrypted(None, obj)
|
||||
|
||||
def _on_message_decrypted(self, output, obj):
|
||||
gajim.nec.push_incoming_event(DecryptedMessageReceivedEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
|
||||
def _nec_decrypted_message_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
return
|
||||
|
||||
# Receipt requested
|
||||
# TODO: We shouldn't answer if we're invisible!
|
||||
contact = gajim.contacts.get_contact(self.name, obj.jid)
|
||||
nick = obj.resource
|
||||
gc_contact = gajim.contacts.get_gc_contact(self.name, obj.jid, nick)
|
||||
if obj.receipt_request_tag and gajim.config.get_per('accounts',
|
||||
self.name, 'answer_receipts') and ((contact and contact.sub \
|
||||
not in (u'to', u'none')) or gc_contact) and obj.mtype != 'error':
|
||||
receipt = common.xmpp.Message(to=obj.fjid, typ='chat')
|
||||
receipt.setID(obj.id_)
|
||||
receipt.setTag('received', namespace='urn:xmpp:receipts',
|
||||
attrs={'id': obj.id_})
|
||||
|
||||
if obj.thread_id:
|
||||
receipt.setThread(obj.thread_id)
|
||||
self.connection.send(receipt)
|
||||
|
||||
# We got our message's receipt
|
||||
if obj.receipt_received_tag and obj.session.control and \
|
||||
gajim.config.get_per('accounts', self.name, 'request_receipt'):
|
||||
obj.session.control.conv_textview.hide_xep0184_warning(obj.id_)
|
||||
|
||||
if obj.mtype == 'error':
|
||||
self.dispatch_error_message(obj.stanza, obj.msgtxt,
|
||||
obj.session, obj.fjid, obj.timestamp)
|
||||
return True
|
||||
elif obj.mtype == 'groupchat':
|
||||
gajim.nec.push_incoming_event(GcMessageReceivedEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
return True
|
||||
elif obj.invite_tag is not None:
|
||||
gajim.nec.push_incoming_event(GcInvitationReceivedEvent(None,
|
||||
conn=self, msg_obj=obj))
|
||||
return True
|
||||
|
||||
# process and dispatch an error message
|
||||
def dispatch_error_message(self, msg, msgtxt, session, frm, tim):
|
||||
error_msg = msg.getErrorMsg()
|
||||
|
||||
if not error_msg:
|
||||
error_msg = msgtxt
|
||||
msgtxt = None
|
||||
|
||||
subject = msg.getSubject()
|
||||
|
||||
if session.is_loggable():
|
||||
try:
|
||||
gajim.logger.write('error', frm, error_msg, tim=tim,
|
||||
subject=subject)
|
||||
except exceptions.PysqliteOperationalError, e:
|
||||
self.dispatch('DB_ERROR', (_('Disk Write Error'), str(e)))
|
||||
except exceptions.DatabaseMalformed:
|
||||
pritext = _('Database Error')
|
||||
sectext = _('The database file (%s) cannot be read. Try to '
|
||||
'repair it (see http://trac.gajim.org/wiki/DatabaseBackup) '
|
||||
'or remove it (all history will be lost).') % \
|
||||
common.logger.LOG_DB_PATH
|
||||
self.dispatch('DB_ERROR', (pritext, sectext))
|
||||
gajim.nec.push_incoming_event(MessageErrorEvent(None, conn=self,
|
||||
fjid=frm, error_code=msg.getErrorCode(), error_msg=error_msg,
|
||||
msg=msgtxt, time_=tim, session=session))
|
||||
|
||||
def _dispatch_gc_msg_with_captcha(self, stanza, msg_obj):
|
||||
msg_obj.stanza = stanza
|
||||
gajim.nec.push_incoming_event(GcMessageReceivedEvent(None,
|
||||
|
|
|
@ -799,6 +799,7 @@ class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent):
|
|||
base_network_events = []
|
||||
|
||||
def generate(self):
|
||||
self.jid, self.resource = gajim.get_room_and_nick_from_fjid(self.fjid)
|
||||
self.resource = 'local'
|
||||
self.prio = 0
|
||||
self.keyID = None
|
||||
|
@ -1064,6 +1065,11 @@ class ZeroconfMessageReceivedEvent(MessageReceivedEvent):
|
|||
self.fjid = unicode(self.fjid)
|
||||
self.jid, self.resource = gajim.get_room_and_nick_from_fjid(self.fjid)
|
||||
|
||||
def generate(self):
|
||||
self.base_event = nec.NetworkIncomingEvent(None, conn=self.conn,
|
||||
stanza=self.stanza)
|
||||
return super(ZeroconfMessageReceivedEvent, self).generate()
|
||||
|
||||
class GcInvitationReceivedEvent(nec.NetworkIncomingEvent):
|
||||
name = 'gc-invitation-received'
|
||||
base_network_events = []
|
||||
|
|
|
@ -36,6 +36,7 @@ from common.zeroconf import zeroconf
|
|||
from common.commands import ConnectionCommands
|
||||
from common.pep import ConnectionPEP
|
||||
from common.protocol.bytestream import ConnectionSocks5BytestreamZeroconf
|
||||
from common.connection_handlers_events import ZeroconfMessageReceivedEvent
|
||||
|
||||
import logging
|
||||
log = logging.getLogger('gajim.c.z.connection_handlers_zeroconf')
|
||||
|
@ -91,82 +92,9 @@ connection_handlers.ConnectionHandlersBase, connection_handlers.ConnectionJingle
|
|||
Called when we receive a message
|
||||
"""
|
||||
log.debug('Zeroconf MessageCB')
|
||||
|
||||
frm = msg.getFrom()
|
||||
mtype = msg.getType()
|
||||
thread_id = msg.getThread()
|
||||
|
||||
if not mtype:
|
||||
mtype = 'normal'
|
||||
|
||||
if frm is None:
|
||||
for key in self.connection.zeroconf.contacts:
|
||||
if ip == self.connection.zeroconf.contacts[key][zeroconf.C_ADDRESS]:
|
||||
frm = key
|
||||
|
||||
frm = unicode(frm)
|
||||
|
||||
session = self.get_or_create_session(frm, thread_id)
|
||||
|
||||
if thread_id and not session.received_thread_id:
|
||||
session.received_thread_id = True
|
||||
|
||||
if msg.getTag('feature') and msg.getTag('feature').namespace == \
|
||||
common.xmpp.NS_FEATURE:
|
||||
if gajim.HAVE_PYCRYPTO:
|
||||
self._FeatureNegCB(con, msg, session)
|
||||
return
|
||||
|
||||
if msg.getTag('init') and msg.getTag('init').namespace == \
|
||||
common.xmpp.NS_ESESSION_INIT:
|
||||
self._InitE2ECB(con, msg, session)
|
||||
|
||||
encrypted = False
|
||||
tim = msg.getTimestamp()
|
||||
tim = helpers.datetime_tuple(tim)
|
||||
tim = time.localtime(timegm(tim))
|
||||
|
||||
if msg.getTag('c', namespace = common.xmpp.NS_STANZA_CRYPTO):
|
||||
encrypted = True
|
||||
|
||||
try:
|
||||
msg = session.decrypt_stanza(msg)
|
||||
except Exception:
|
||||
self.dispatch('FAILED_DECRYPT', (frm, tim, session))
|
||||
|
||||
|
||||
msgtxt = msg.getBody()
|
||||
subject = msg.getSubject() # if not there, it's None
|
||||
|
||||
# invitations
|
||||
invite = None
|
||||
encTag = msg.getTag('x', namespace = common.xmpp.NS_ENCRYPTED)
|
||||
|
||||
if not encTag:
|
||||
invite = msg.getTag('x', namespace = common.xmpp.NS_MUC_USER)
|
||||
if invite and not invite.getTag('invite'):
|
||||
invite = None
|
||||
|
||||
if encTag and self.USE_GPG:
|
||||
#decrypt
|
||||
encmsg = encTag.getData()
|
||||
|
||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||
if keyID:
|
||||
decmsg = self.gpg.decrypt(encmsg, keyID)
|
||||
# \x00 chars are not allowed in C (so in GTK)
|
||||
msgtxt = decmsg.replace('\x00', '')
|
||||
encrypted = True
|
||||
|
||||
if mtype == 'error':
|
||||
self.dispatch_error_msg(msg, msgtxt, session, frm, tim, subject)
|
||||
else:
|
||||
# XXX this shouldn't be hardcoded
|
||||
if isinstance(session, ChatControlSession):
|
||||
session.received(frm, msgtxt, tim, encrypted, msg)
|
||||
else:
|
||||
session.received(msg)
|
||||
# END messageCB
|
||||
gajim.nec.push_incoming_event(ZeroconfMessageReceivedEvent(None,
|
||||
conn=self, stanza=msg, ip=ip))
|
||||
return
|
||||
|
||||
def store_metacontacts(self, tags):
|
||||
"""
|
||||
|
|
|
@ -140,7 +140,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
|
|||
jid=key, nickname=self.roster.getName(key), sub='both',
|
||||
ask='no', groups=self.roster.getGroups(key)))
|
||||
gajim.nec.push_incoming_event(ZeroconfPresenceReceivedEvent(
|
||||
None, conn=self, jid=key, show=self.roster.getStatus(key),
|
||||
None, conn=self, fjid=key, show=self.roster.getStatus(key),
|
||||
status=self.roster.getMessage(key)))
|
||||
#XXX open chat windows don't get refreshed (full name), add that
|
||||
return self.call_resolve_timeout
|
||||
|
@ -152,7 +152,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
|
|||
jid=jid, nickname=self.roster.getName(jid), sub='both',
|
||||
ask='no', groups=self.roster.getGroups(jid)))
|
||||
gajim.nec.push_incoming_event(ZeroconfPresenceReceivedEvent(
|
||||
None, conn=self, jid=jid, show=self.roster.getStatus(jid),
|
||||
None, conn=self, fjid=jid, show=self.roster.getStatus(jid),
|
||||
status=self.roster.getMessage(jid)))
|
||||
|
||||
def _on_remove_service(self, jid):
|
||||
|
@ -160,7 +160,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
|
|||
# 'NOTIFY' (account, (jid, status, status message, resource, priority,
|
||||
# keyID, timestamp, contact_nickname))
|
||||
gajim.nec.push_incoming_event(ZeroconfPresenceReceivedEvent(
|
||||
None, conn=self, jid=jid, show='offline', status=''))
|
||||
None, conn=self, fjid=jid, show='offline', status=''))
|
||||
|
||||
def _disconnectedReconnCB(self):
|
||||
"""
|
||||
|
@ -229,7 +229,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf):
|
|||
jid=jid, nickname=self.roster.getName(jid), sub='both',
|
||||
ask='no', groups=self.roster.getGroups(jid)))
|
||||
gajim.nec.push_incoming_event(ZeroconfPresenceReceivedEvent(
|
||||
None, conn=self, jid=jid, show=self.roster.getStatus(jid),
|
||||
None, conn=self, fjid=jid, show=self.roster.getStatus(jid),
|
||||
status=self.roster.getMessage(jid)))
|
||||
|
||||
self.connected = STATUS_LIST.index(show)
|
||||
|
|
Loading…
Reference in New Issue