Move message handler into own module
This commit is contained in:
parent
d4fd621d11
commit
37f7a80396
|
@ -241,6 +241,9 @@ class ChatControl(ChatControlBase):
|
|||
app.ged.register_event_handler(
|
||||
'decrypted-message-received',
|
||||
ged.GUI1, self._nec_decrypted_message_received)
|
||||
app.ged.register_event_handler(
|
||||
'receipt-received',
|
||||
ged.GUI1, self._receipt_received)
|
||||
|
||||
# PluginSystem: adding GUI extension point for this ChatControl
|
||||
# instance object
|
||||
|
@ -984,6 +987,14 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
self.old_msg_kind = kind
|
||||
|
||||
def _receipt_received(self, event):
|
||||
if event.conn.name != self.account:
|
||||
return
|
||||
if event.jid != self.contact.jid:
|
||||
return
|
||||
|
||||
self.conv_textview.show_xep0184_ack(event.receipt_id)
|
||||
|
||||
def get_tab_label(self):
|
||||
unread = ''
|
||||
if self.resource:
|
||||
|
@ -1153,6 +1164,9 @@ class ChatControl(ChatControlBase):
|
|||
app.ged.remove_event_handler(
|
||||
'decrypted-message-received',
|
||||
ged.GUI1, self._nec_decrypted_message_received)
|
||||
app.ged.remove_event_handler(
|
||||
'receipt-received',
|
||||
ged.GUI1, self._receipt_received)
|
||||
|
||||
self.unsubscribe_events()
|
||||
|
||||
|
|
|
@ -292,22 +292,10 @@ class ConnectionHandlersBase:
|
|||
# We decrypt GPG messages one after the other. Keep queue in mem
|
||||
self.gpg_messages_to_decrypt = []
|
||||
|
||||
# XEPs that are based on Message
|
||||
self._message_namespaces = set([nbxmpp.NS_HTTP_AUTH,
|
||||
nbxmpp.NS_PUBSUB_EVENT,
|
||||
nbxmpp.NS_ROSTERX,
|
||||
nbxmpp.NS_MAM_1,
|
||||
nbxmpp.NS_MAM_2,
|
||||
nbxmpp.NS_CONFERENCE])
|
||||
|
||||
app.ged.register_event_handler('iq-error-received', ged.CORE,
|
||||
self._nec_iq_error_received)
|
||||
app.ged.register_event_handler('presence-received', ged.CORE,
|
||||
self._nec_presence_received)
|
||||
app.ged.register_event_handler('message-received', ged.CORE,
|
||||
self._nec_message_received)
|
||||
app.ged.register_event_handler('decrypted-message-received', ged.CORE,
|
||||
self._nec_decrypted_message_received)
|
||||
app.ged.register_event_handler('gc-message-received', ged.CORE,
|
||||
self._nec_gc_message_received)
|
||||
|
||||
|
@ -316,10 +304,6 @@ class ConnectionHandlersBase:
|
|||
self._nec_iq_error_received)
|
||||
app.ged.remove_event_handler('presence-received', ged.CORE,
|
||||
self._nec_presence_received)
|
||||
app.ged.remove_event_handler('message-received', ged.CORE,
|
||||
self._nec_message_received)
|
||||
app.ged.remove_event_handler('decrypted-message-received', ged.CORE,
|
||||
self._nec_decrypted_message_received)
|
||||
app.ged.remove_event_handler('gc-message-received', ged.CORE,
|
||||
self._nec_gc_message_received)
|
||||
|
||||
|
@ -448,96 +432,10 @@ class ConnectionHandlersBase:
|
|||
message=obj.status,
|
||||
show=show)
|
||||
|
||||
def _nec_message_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
return
|
||||
|
||||
app.plugin_manager.extension_point(
|
||||
'decrypt', self, obj, self._on_message_received)
|
||||
if not obj.encrypted:
|
||||
eme = parse_eme(obj.stanza)
|
||||
if eme is not None:
|
||||
obj.msgtxt = eme
|
||||
self._on_message_received(obj)
|
||||
|
||||
def _on_message_received(self, obj):
|
||||
app.nec.push_incoming_event(
|
||||
DecryptedMessageReceivedEvent(
|
||||
None, conn=self, msg_obj=obj, stanza_id=obj.unique_id))
|
||||
|
||||
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 = app.contacts.get_contact(self.name, obj.jid)
|
||||
nick = obj.resource
|
||||
gc_contact = app.contacts.get_gc_contact(self.name, obj.jid, nick)
|
||||
if obj.sent:
|
||||
jid_to = obj.stanza.getFrom()
|
||||
else:
|
||||
jid_to = obj.stanza.getTo()
|
||||
reply = False
|
||||
if not jid_to:
|
||||
reply = True
|
||||
else:
|
||||
fjid_to = str(jid_to)
|
||||
if self.name != 'Local':
|
||||
# Dont check precis for zeroconf
|
||||
fjid_to = helpers.parse_jid(str(jid_to))
|
||||
jid_to = app.get_jid_without_resource(fjid_to)
|
||||
if jid_to == app.get_jid_from_account(self.name):
|
||||
reply = True
|
||||
|
||||
if obj.jid != app.get_jid_from_account(self.name):
|
||||
if obj.receipt_request_tag and app.config.get_per('accounts',
|
||||
self.name, 'answer_receipts') and ((contact and contact.sub \
|
||||
not in ('to', 'none')) or gc_contact) and obj.mtype != 'error' and \
|
||||
reply:
|
||||
receipt = nbxmpp.Message(to=obj.fjid, typ='chat')
|
||||
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 app.config.get_per('accounts',
|
||||
self.name, 'request_receipt'):
|
||||
ctrl = None
|
||||
if obj.session is not None:
|
||||
ctrl = obj.session.control
|
||||
if not ctrl:
|
||||
# Received <message> doesn't have the <thread> element
|
||||
# or control is not bound to session?
|
||||
# --> search for it
|
||||
ctrl = app.interface.msg_win_mgr.search_control(obj.jid,
|
||||
obj.conn.name, obj.resource)
|
||||
|
||||
if ctrl:
|
||||
id_ = obj.receipt_received_tag.getAttr('id')
|
||||
if not id_:
|
||||
# old XEP implementation
|
||||
id_ = obj.id_
|
||||
ctrl.conv_textview.show_xep0184_ack(id_)
|
||||
|
||||
if obj.mtype == 'error':
|
||||
if not obj.msgtxt:
|
||||
obj.msgtxt = _('message')
|
||||
self.dispatch_error_message(obj.stanza, obj.msgtxt,
|
||||
obj.session, obj.fjid, obj.timestamp)
|
||||
return True
|
||||
elif obj.mtype == 'groupchat':
|
||||
app.nec.push_incoming_event(GcMessageReceivedEvent(None,
|
||||
conn=self, msg_obj=obj, stanza_id=obj.unique_id))
|
||||
return True
|
||||
|
||||
def _check_for_mam_compliance(self, room_jid, stanza_id):
|
||||
namespace = muc_caps_cache.get_mam_namespace(room_jid)
|
||||
if stanza_id is None and namespace == nbxmpp.NS_MAM_2:
|
||||
log.warning('%s announces mam:2 without stanza-id')
|
||||
log.warning('%s announces mam:2 without stanza-id', room_jid)
|
||||
|
||||
def _nec_gc_message_received(self, obj):
|
||||
if obj.conn.name != self.name:
|
||||
|
@ -743,7 +641,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream, ConnectionDisco,
|
|||
self.continue_connect_info = None
|
||||
|
||||
app.nec.register_incoming_event(StreamConflictReceivedEvent)
|
||||
app.nec.register_incoming_event(MessageReceivedEvent)
|
||||
app.nec.register_incoming_event(NotificationEvent)
|
||||
|
||||
app.ged.register_event_handler('roster-set-received',
|
||||
|
@ -939,29 +836,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream, ConnectionDisco,
|
|||
app.config.set_per('accounts', self.name, 'roster_version',
|
||||
obj.version)
|
||||
|
||||
def _messageCB(self, con, stanza):
|
||||
"""
|
||||
Called when we receive a message
|
||||
"""
|
||||
|
||||
# Check if a child of the message contains any
|
||||
# of these namespaces, so we dont execute the
|
||||
# message handler for them.
|
||||
# They have defined their own message handlers
|
||||
# but nbxmpp executes less common handlers last
|
||||
if self._message_namespaces & set(stanza.getProperties()):
|
||||
return
|
||||
|
||||
muc_user = stanza.getTag('x', namespace=nbxmpp.NS_MUC_USER)
|
||||
if muc_user is not None:
|
||||
if muc_user.getChildren():
|
||||
# Not a PM, handled by MUC module
|
||||
return
|
||||
log.debug('MessageCB')
|
||||
|
||||
app.nec.push_incoming_event(NetworkEvent('raw-message-received',
|
||||
conn=self, stanza=stanza, account=self.name))
|
||||
|
||||
def _dispatch_gc_msg_with_captcha(self, stanza, msg_obj):
|
||||
msg_obj.stanza = stanza
|
||||
app.nec.push_incoming_event(GcMessageReceivedEvent(None,
|
||||
|
@ -1282,7 +1156,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream, ConnectionDisco,
|
|||
def _register_handlers(self, con, con_type):
|
||||
# try to find another way to register handlers in each class
|
||||
# that defines handlers
|
||||
con.RegisterHandler('message', self._messageCB)
|
||||
con.RegisterHandler('presence', self._presenceCB)
|
||||
con.RegisterHandler('iq', self._rosterSetCB, 'set', nbxmpp.NS_ROSTER)
|
||||
con.RegisterHandler('iq', self._siSetCB, 'set', nbxmpp.NS_SI)
|
||||
|
|
|
@ -632,242 +632,6 @@ class BeforeChangeShowEvent(nec.NetworkIncomingEvent):
|
|||
name = 'before-change-show'
|
||||
base_network_events = []
|
||||
|
||||
class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
||||
name = 'message-received'
|
||||
base_network_events = ['raw-message-received']
|
||||
|
||||
def init(self):
|
||||
self.additional_data = {}
|
||||
|
||||
def generate(self):
|
||||
self.conn = self.base_event.conn
|
||||
self.stanza = self.base_event.stanza
|
||||
self.encrypted = False
|
||||
self.self_message = None
|
||||
self.muc_pm = None
|
||||
account = self.conn.name
|
||||
|
||||
if self.stanza.getFrom() == self.conn.get_own_jid(warn=True):
|
||||
# Drop messages sent from our own full jid
|
||||
# It can happen that when we sent message to our own bare jid
|
||||
# that the server routes that message back to us
|
||||
log.info('Received message from self: %s, message is dropped',
|
||||
self.stanza.getFrom())
|
||||
return
|
||||
|
||||
from gajim.common.modules.carbons import parse_carbon
|
||||
self.stanza, self.sent, self.forwarded = parse_carbon(self.conn,
|
||||
self.stanza)
|
||||
|
||||
self.get_id()
|
||||
try:
|
||||
self.get_jid_resource()
|
||||
except helpers.InvalidFormat:
|
||||
log.warning('Invalid JID: %s, ignoring it',
|
||||
self.stanza.getFrom())
|
||||
return
|
||||
|
||||
# Check for duplicates
|
||||
self.unique_id = self.get_unique_id()
|
||||
# Check groupchat messages for duplicates,
|
||||
# We do this because of MUC History messages
|
||||
type_ = self.stanza.getType()
|
||||
if type_ == 'groupchat' or self.self_message or self.muc_pm:
|
||||
if type_ == 'groupchat':
|
||||
archive_jid = self.stanza.getFrom().getStripped()
|
||||
else:
|
||||
archive_jid = self.conn.get_own_jid().getStripped()
|
||||
if app.logger.find_stanza_id(account,
|
||||
archive_jid,
|
||||
self.unique_id,
|
||||
groupchat=type_ == 'groupchat'):
|
||||
return
|
||||
|
||||
self.thread_id = self.stanza.getThread()
|
||||
self.mtype = self.stanza.getType()
|
||||
if not self.mtype or self.mtype not in ('chat', 'groupchat', 'error'):
|
||||
self.mtype = 'normal'
|
||||
|
||||
self.msgtxt = self.stanza.getBody()
|
||||
|
||||
self.get_gc_control()
|
||||
|
||||
if self.gc_control and self.jid == self.fjid:
|
||||
if self.mtype == 'error':
|
||||
self.msgtxt = _('error while sending %(message)s ( %(error)s )'\
|
||||
) % {'message': self.msgtxt,
|
||||
'error': self.stanza.getErrorMsg()}
|
||||
if self.stanza.getTag('html'):
|
||||
self.stanza.delChild('html')
|
||||
# message from a gc without a resource
|
||||
self.mtype = 'groupchat'
|
||||
|
||||
self.session = None
|
||||
if self.mtype != 'groupchat':
|
||||
if app.interface.is_pm_contact(self.fjid, account) and \
|
||||
self.mtype == 'error':
|
||||
self.session = self.conn.find_session(self.fjid, self.thread_id)
|
||||
if not self.session:
|
||||
self.session = self.conn.get_latest_session(self.fjid)
|
||||
if not self.session:
|
||||
self.session = self.conn.make_new_session(self.fjid,
|
||||
self.thread_id,
|
||||
type_='pm')
|
||||
else:
|
||||
self.session = self.conn.get_or_create_session(self.fjid,
|
||||
self.thread_id)
|
||||
|
||||
if self.thread_id and not self.session.received_thread_id:
|
||||
self.session.received_thread_id = True
|
||||
|
||||
self.session.last_receive = time_time()
|
||||
|
||||
self._generate_timestamp(self.stanza.timestamp)
|
||||
|
||||
return True
|
||||
|
||||
def get_unique_id(self):
|
||||
'''
|
||||
Messages to self:
|
||||
|
||||
Messages to self are stored multiple times in MAM so we cant use
|
||||
stanza-id to deduplicate. We use origin-id instead. Its not perfect
|
||||
but there is no better way for now.
|
||||
We drop "received"-Carbons of Message to self, so we dont have to
|
||||
parse origin-id in that case.
|
||||
|
||||
MUC PMs:
|
||||
|
||||
MUC PMs are also stored multiple times, we also depend on origin-id
|
||||
for now.
|
||||
'''
|
||||
|
||||
if self.stanza.getType() == 'groupchat':
|
||||
# TODO: Disco the MUC check if 'urn:xmpp:mam:2' is announced
|
||||
return self.get_stanza_id(self.stanza)
|
||||
|
||||
elif self.stanza.getType() != 'chat':
|
||||
return
|
||||
|
||||
# Messages we receive live
|
||||
if self.conn.get_module('MAM').archiving_namespace != nbxmpp.NS_MAM_2:
|
||||
# Only mam:2 ensures valid stanza-id
|
||||
return
|
||||
|
||||
# Sent Carbon
|
||||
sent_carbon = self.stanza.getTag('sent',
|
||||
namespace=nbxmpp.NS_CARBONS,
|
||||
protocol=True)
|
||||
if sent_carbon is not None:
|
||||
message = self.get_forwarded_message(sent_carbon)
|
||||
if self._is_self_message(message) or self._is_muc_pm(message):
|
||||
return message.getOriginID()
|
||||
return self.get_stanza_id(message)
|
||||
|
||||
# Received Carbon
|
||||
received_carbon = self.stanza.getTag('received',
|
||||
namespace=nbxmpp.NS_CARBONS,
|
||||
protocol=True)
|
||||
if received_carbon is not None:
|
||||
message = self.get_forwarded_message(received_carbon)
|
||||
if self._is_muc_pm(message):
|
||||
return message.getOriginID()
|
||||
return self.get_stanza_id(message)
|
||||
|
||||
# Normal Message
|
||||
if self._is_self_message(self.stanza) or self._is_muc_pm(self.stanza):
|
||||
return self.stanza.getOriginID()
|
||||
return self.get_stanza_id(self.stanza)
|
||||
|
||||
class ZeroconfMessageReceivedEvent(MessageReceivedEvent):
|
||||
name = 'message-received'
|
||||
base_network_events = []
|
||||
|
||||
def get_jid_resource(self):
|
||||
self.fjid = str(self.stanza.getFrom())
|
||||
|
||||
if self.fjid is None:
|
||||
for key in self.conn.connection.zeroconf.contacts:
|
||||
if self.ip == self.conn.connection.zeroconf.contacts[key][
|
||||
Constant.ADDRESS]:
|
||||
self.fjid = key
|
||||
break
|
||||
|
||||
self.jid, self.resource = app.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 DecryptedMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
||||
name = 'decrypted-message-received'
|
||||
base_network_events = []
|
||||
|
||||
def generate(self):
|
||||
self.stanza = self.msg_obj.stanza
|
||||
self.additional_data = self.msg_obj.additional_data
|
||||
self.id_ = self.msg_obj.id_
|
||||
self.unique_id = self.msg_obj.unique_id
|
||||
self.jid = self.msg_obj.jid
|
||||
self.fjid = self.msg_obj.fjid
|
||||
self.resource = self.msg_obj.resource
|
||||
self.mtype = self.msg_obj.mtype
|
||||
self.thread_id = self.msg_obj.thread_id
|
||||
self.msgtxt = self.msg_obj.msgtxt
|
||||
self.gc_control = self.msg_obj.gc_control
|
||||
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.conn = self.msg_obj.conn
|
||||
self.muc_pm = self.msg_obj.muc_pm
|
||||
self.popup = False
|
||||
self.msg_log_id = None # id in log database
|
||||
self.attention = False # XEP-0224
|
||||
self.correct_id = None # XEP-0308
|
||||
self.msghash = None
|
||||
|
||||
self.receipt_request_tag = self.stanza.getTag('request',
|
||||
namespace=nbxmpp.NS_RECEIPTS)
|
||||
self.receipt_received_tag = self.stanza.getTag('received',
|
||||
namespace=nbxmpp.NS_RECEIPTS)
|
||||
|
||||
self.subject = self.stanza.getSubject()
|
||||
|
||||
self.displaymarking = None
|
||||
self.seclabel = self.stanza.getTag('securitylabel',
|
||||
namespace=nbxmpp.NS_SECLABEL)
|
||||
if self.seclabel:
|
||||
self.displaymarking = self.seclabel.getTag('displaymarking')
|
||||
|
||||
if self.stanza.getTag('attention', namespace=nbxmpp.NS_ATTENTION):
|
||||
delayed = self.stanza.getTag('x', namespace=nbxmpp.NS_DELAY) is not\
|
||||
None
|
||||
if not delayed:
|
||||
self.attention = True
|
||||
|
||||
self.form_node = self.stanza.getTag('x', namespace=nbxmpp.NS_DATA)
|
||||
|
||||
if app.config.get('ignore_incoming_xhtml'):
|
||||
self.xhtml = None
|
||||
else:
|
||||
self.xhtml = self.stanza.getXHTML()
|
||||
|
||||
# XEP-0172 User Nickname
|
||||
self.user_nick = self.stanza.getTagData('nick') or ''
|
||||
|
||||
self.get_chatstate()
|
||||
|
||||
self.get_oob_data(self.stanza)
|
||||
|
||||
from gajim.common.modules.misc import parse_correction
|
||||
self.correct_id = parse_correction(self.stanza)
|
||||
|
||||
return True
|
||||
|
||||
class ChatstateReceivedEvent(nec.NetworkIncomingEvent):
|
||||
name = 'chatstate-received'
|
||||
base_network_events = []
|
||||
|
|
|
@ -18,7 +18,7 @@ from pathlib import Path
|
|||
|
||||
log = logging.getLogger('gajim.c.m')
|
||||
|
||||
ZEROCONF_MODULES = ['adhoc_commands']
|
||||
ZEROCONF_MODULES = ['adhoc_commands', 'receipts']
|
||||
|
||||
imported_modules = []
|
||||
_modules = {}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# This file is part of Gajim.
|
||||
#
|
||||
# Gajim is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation; version 3 only.
|
||||
#
|
||||
# Gajim is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# XEP-0085: Chat State Notifications
|
||||
|
||||
import logging
|
||||
|
||||
import nbxmpp
|
||||
|
||||
from gajim.common.modules.misc import parse_delay
|
||||
|
||||
log = logging.getLogger('gajim.c.m.chatstates')
|
||||
|
||||
|
||||
def parse_chatstate(stanza):
|
||||
if parse_delay(stanza) is not None:
|
||||
return
|
||||
|
||||
children = stanza.getChildren()
|
||||
for child in children:
|
||||
if child.getNamespace() == nbxmpp.NS_CHATSTATES:
|
||||
return child.getName()
|
|
@ -27,6 +27,8 @@ from gajim.common.modules.misc import parse_delay
|
|||
from gajim.common.modules.misc import parse_oob
|
||||
from gajim.common.modules.misc import parse_correction
|
||||
from gajim.common.modules.misc import parse_eme
|
||||
from gajim.common.modules.util import is_self_message
|
||||
from gajim.common.modules.util import is_muc_pm
|
||||
|
||||
log = logging.getLogger('gajim.c.m.archiving')
|
||||
|
||||
|
@ -61,28 +63,6 @@ class MAM:
|
|||
if archive_jid.bareMatch(expected_archive):
|
||||
return archive_jid
|
||||
|
||||
@staticmethod
|
||||
def _is_self_message(message, groupchat):
|
||||
if groupchat:
|
||||
return False
|
||||
frm = message.getFrom()
|
||||
to = message.getTo()
|
||||
return frm.bareMatch(to)
|
||||
|
||||
@staticmethod
|
||||
def _is_muc_pm(message, groupchat, with_):
|
||||
if groupchat:
|
||||
return False
|
||||
muc_user = message.getTag('x', namespace=nbxmpp.NS_MUC_USER)
|
||||
if muc_user is not None:
|
||||
return muc_user.getChildren() == []
|
||||
else:
|
||||
# muc#user namespace was added in MUC 1.28 so we need a fallback
|
||||
# Check if we know the jid, otherwise disco it
|
||||
if app.logger.jid_is_room_jid(with_.getStripped()):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_unique_id(self, result, message, groupchat, self_message, muc_pm):
|
||||
stanza_id = result.getAttr('id')
|
||||
if groupchat:
|
||||
|
@ -150,8 +130,8 @@ class MAM:
|
|||
else:
|
||||
event_attrs.update(self._parse_chat_attrs(message))
|
||||
|
||||
self_message = self._is_self_message(message, groupchat)
|
||||
muc_pm = self._is_muc_pm(message, groupchat, event_attrs['with_'])
|
||||
self_message = is_self_message(message, groupchat)
|
||||
muc_pm = is_muc_pm(message, event_attrs['with_'], groupchat)
|
||||
|
||||
stanza_id, origin_id = self._get_unique_id(
|
||||
result, message, groupchat, self_message, muc_pm)
|
||||
|
|
|
@ -0,0 +1,297 @@
|
|||
# This file is part of Gajim.
|
||||
#
|
||||
# Gajim is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation; version 3 only.
|
||||
#
|
||||
# Gajim is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Message handler
|
||||
|
||||
import time
|
||||
import logging
|
||||
|
||||
import nbxmpp
|
||||
|
||||
from gajim.common import app
|
||||
from gajim.common import helpers
|
||||
from gajim.common.nec import NetworkIncomingEvent, NetworkEvent
|
||||
from gajim.common.modules.user_nickname import parse_nickname
|
||||
from gajim.common.modules.chatstates import parse_chatstate
|
||||
from gajim.common.modules.carbons import parse_carbon
|
||||
from gajim.common.modules.misc import parse_delay
|
||||
from gajim.common.modules.misc import parse_eme
|
||||
from gajim.common.modules.misc import parse_correction
|
||||
from gajim.common.modules.misc import parse_attention
|
||||
from gajim.common.modules.misc import parse_securitylabel
|
||||
from gajim.common.modules.misc import parse_form
|
||||
from gajim.common.modules.misc import parse_oob
|
||||
from gajim.common.modules.misc import parse_xhtml
|
||||
from gajim.common.modules.util import is_self_message
|
||||
from gajim.common.modules.util import is_muc_pm
|
||||
from gajim.common.connection_handlers_events import GcMessageReceivedEvent
|
||||
|
||||
|
||||
log = logging.getLogger('gajim.c.m.message')
|
||||
|
||||
|
||||
class Message:
|
||||
def __init__(self, con):
|
||||
self._con = con
|
||||
self._account = con.name
|
||||
|
||||
self.handlers = [('message', self._message_received)]
|
||||
|
||||
# XEPs for which this message module should not be executed
|
||||
self._message_namespaces = set([nbxmpp.NS_HTTP_AUTH,
|
||||
nbxmpp.NS_PUBSUB_EVENT,
|
||||
nbxmpp.NS_ROSTERX,
|
||||
nbxmpp.NS_MAM_1,
|
||||
nbxmpp.NS_MAM_2,
|
||||
nbxmpp.NS_CONFERENCE,
|
||||
nbxmpp.NS_IBB])
|
||||
|
||||
def _message_received(self, con, stanza):
|
||||
# Check if a child of the message contains any
|
||||
# namespaces that we handle in other modules.
|
||||
# nbxmpp executes less common handlers last
|
||||
if self._message_namespaces & set(stanza.getProperties()):
|
||||
return
|
||||
|
||||
muc_user = stanza.getTag('x', namespace=nbxmpp.NS_MUC_USER)
|
||||
if muc_user is not None:
|
||||
if muc_user.getChildren():
|
||||
# Not a PM, handled by MUC module
|
||||
return
|
||||
|
||||
log.info('Received from %s', stanza.getFrom())
|
||||
|
||||
app.nec.push_incoming_event(NetworkEvent(
|
||||
'raw-message-received',
|
||||
conn=self._con,
|
||||
stanza=stanza,
|
||||
account=self._account))
|
||||
|
||||
if stanza.getFrom() == self._con.get_own_jid(warn=True):
|
||||
# Drop messages sent from our own full jid
|
||||
# It can happen that when we sent message to our own bare jid
|
||||
# that the server routes that message back to us
|
||||
log.info('Received message from self: %s, message is dropped',
|
||||
stanza.getFrom())
|
||||
return
|
||||
|
||||
stanza, sent, forwarded = parse_carbon(self._con, stanza)
|
||||
|
||||
from_ = stanza.getFrom()
|
||||
type_ = stanza.getType()
|
||||
if type_ is None:
|
||||
type_ = 'normal'
|
||||
self_message = is_self_message(stanza, type_ == 'groupchat')
|
||||
muc_pm = is_muc_pm(stanza, from_, type_ == 'groupchat')
|
||||
|
||||
id_ = stanza.getID()
|
||||
|
||||
fjid = None
|
||||
if from_ is not None:
|
||||
try:
|
||||
fjid = helpers.parse_jid(str(from_))
|
||||
except helpers.InvalidFormat:
|
||||
log.warning('Invalid JID: %s, ignoring it',
|
||||
stanza.getFrom())
|
||||
return
|
||||
|
||||
jid, resource = app.get_room_and_nick_from_fjid(fjid)
|
||||
|
||||
# Check for duplicates
|
||||
unique_id = self._get_unique_id(stanza, forwarded, sent,
|
||||
self_message, muc_pm)
|
||||
|
||||
# Check groupchat messages for duplicates,
|
||||
# We do this because of MUC History messages
|
||||
if type_ == 'groupchat' or self_message or muc_pm:
|
||||
if type_ == 'groupchat':
|
||||
archive_jid = stanza.getFrom().getStripped()
|
||||
else:
|
||||
archive_jid = self._con.get_own_jid().getStripped()
|
||||
if app.logger.find_stanza_id(self._account,
|
||||
archive_jid,
|
||||
unique_id,
|
||||
groupchat=type_ == 'groupchat'):
|
||||
return
|
||||
|
||||
thread_id = stanza.getThread()
|
||||
msgtxt = stanza.getBody()
|
||||
|
||||
# TODO: remove all control UI stuff
|
||||
gc_control = app.interface.msg_win_mgr.get_gc_control(
|
||||
jid, self._account)
|
||||
if not gc_control:
|
||||
minimized = app.interface.minimized_controls[self._account]
|
||||
gc_control = minimized.get(jid)
|
||||
|
||||
if gc_control and jid == fjid:
|
||||
if type_ == 'error':
|
||||
msgtxt = _('error while sending %(message)s ( %(error)s )') % {
|
||||
'message': msgtxt, 'error': stanza.getErrorMsg()}
|
||||
# TODO: why is this here?
|
||||
if stanza.getTag('html'):
|
||||
stanza.delChild('html')
|
||||
|
||||
session = None
|
||||
if type_ != 'groupchat':
|
||||
if muc_pm and type_ == 'error':
|
||||
session = self._con.find_session(fjid, thread_id)
|
||||
if not session:
|
||||
session = self._con.get_latest_session(fjid)
|
||||
if not session:
|
||||
session = self._con.make_new_session(
|
||||
fjid, thread_id, type_='pm')
|
||||
else:
|
||||
session = self._con.get_or_create_session(fjid, thread_id)
|
||||
|
||||
if thread_id and not session.received_thread_id:
|
||||
session.received_thread_id = True
|
||||
|
||||
session.last_receive = time.time()
|
||||
|
||||
timestamp = parse_delay(stanza)
|
||||
if timestamp is None:
|
||||
timestamp = time.time()
|
||||
|
||||
event_attr = {
|
||||
'conn': self._con,
|
||||
'stanza': stanza,
|
||||
'account': self._account,
|
||||
'id_': id_,
|
||||
'encrypted': False,
|
||||
'additional_data': {},
|
||||
'forwarded': forwarded,
|
||||
'sent': sent,
|
||||
'timestamp': timestamp,
|
||||
'fjid': fjid,
|
||||
'jid': jid,
|
||||
'resource': resource,
|
||||
'unique_id': unique_id,
|
||||
'mtype': type_,
|
||||
'msgtxt': msgtxt,
|
||||
'thread_id': thread_id,
|
||||
'session': session,
|
||||
'self_message': self_message,
|
||||
'muc_pm': muc_pm,
|
||||
'gc_control': gc_control
|
||||
}
|
||||
|
||||
event = MessageReceivedEvent(None, **event_attr)
|
||||
app.nec.push_incoming_event(event)
|
||||
|
||||
app.plugin_manager.extension_point(
|
||||
'decrypt', self._con, event, self._on_message_decrypted)
|
||||
if not event.encrypted:
|
||||
eme = parse_eme(event.stanza)
|
||||
if eme is not None:
|
||||
event.msgtxt = eme
|
||||
self._on_message_decrypted(event)
|
||||
|
||||
def _on_message_decrypted(self, event):
|
||||
try:
|
||||
self._con.get_module('Receipts').delegate(event)
|
||||
except nbxmpp.NodeProcessed:
|
||||
return
|
||||
|
||||
event_attr = {
|
||||
'popup': False,
|
||||
'msg_log_id': None,
|
||||
'subject': event.stanza.getSubject(),
|
||||
'displaymarking': parse_securitylabel(event.stanza),
|
||||
'attention': parse_attention(event.stanza),
|
||||
'correct_id': parse_correction(event.stanza),
|
||||
'user_nick': parse_nickname(event.stanza),
|
||||
'form_node': parse_form(event.stanza),
|
||||
'xhtml': parse_xhtml(event.stanza),
|
||||
'chatstate': parse_chatstate(event.stanza),
|
||||
'stanza_id': event.unique_id
|
||||
}
|
||||
parse_oob(event.stanza, event.additional_data)
|
||||
|
||||
for name, value in event_attr.items():
|
||||
setattr(event, name, value)
|
||||
|
||||
if event.mtype == 'error':
|
||||
if not event.msgtxt:
|
||||
event.msgtxt = _('message')
|
||||
self._con.dispatch_error_message(
|
||||
event.stanza, event.msgtxt,
|
||||
event.session, event.fjid, event.timestamp)
|
||||
return
|
||||
|
||||
if event.mtype == 'groupchat':
|
||||
app.nec.push_incoming_event(GcMessageReceivedEvent(
|
||||
None,
|
||||
conn=self._con,
|
||||
msg_obj=event,
|
||||
stanza_id=event.unique_id))
|
||||
return
|
||||
|
||||
app.nec.push_incoming_event(
|
||||
DecryptedMessageReceivedEvent(
|
||||
None, **vars(event)))
|
||||
|
||||
def _get_unique_id(self, stanza, forwarded, sent, self_message, muc_pm):
|
||||
if stanza.getType() == 'groupchat':
|
||||
# TODO: Disco the MUC check if 'urn:xmpp:mam:2' is announced
|
||||
return self._get_stanza_id(stanza)
|
||||
|
||||
if stanza.getType() != 'chat':
|
||||
return
|
||||
|
||||
# Messages we receive live
|
||||
if self._con.get_module('MAM').archiving_namespace != nbxmpp.NS_MAM_2:
|
||||
# Only mam:2 ensures valid stanza-id
|
||||
return
|
||||
|
||||
if forwarded:
|
||||
if sent:
|
||||
if self_message or muc_pm:
|
||||
return stanza.getOriginID()
|
||||
return self._get_stanza_id(stanza)
|
||||
else:
|
||||
if muc_pm:
|
||||
return stanza.getOriginID()
|
||||
return self._get_stanza_id(stanza)
|
||||
|
||||
# Normal Message
|
||||
if self_message or muc_pm:
|
||||
return stanza.getOriginID()
|
||||
return self._get_stanza_id(stanza)
|
||||
|
||||
def _get_stanza_id(self, stanza):
|
||||
stanza_id, by = stanza.getStanzaIDAttrs()
|
||||
if by is None:
|
||||
# We can not verify who set this stanza-id, ignore it.
|
||||
return
|
||||
if stanza.getType() == 'groupchat':
|
||||
if stanza.getFrom().bareMatch(by):
|
||||
# by attribute must match the server
|
||||
return stanza_id
|
||||
elif self._con.get_own_jid().bareMatch(by):
|
||||
# by attribute must match the server
|
||||
return stanza_id
|
||||
return
|
||||
|
||||
|
||||
class MessageReceivedEvent(NetworkIncomingEvent):
|
||||
name = 'message-received'
|
||||
|
||||
|
||||
class DecryptedMessageReceivedEvent(NetworkIncomingEvent):
|
||||
name = 'decrypted-message-received'
|
||||
|
||||
|
||||
def get_instance(*args, **kwargs):
|
||||
return Message(*args, **kwargs), 'Message'
|
|
@ -18,6 +18,7 @@ import logging
|
|||
|
||||
import nbxmpp
|
||||
|
||||
from gajim.common import app
|
||||
from gajim.common.modules.date_and_time import parse_datetime
|
||||
|
||||
log = logging.getLogger('gajim.c.m.misc')
|
||||
|
@ -111,3 +112,38 @@ def parse_correction(stanza):
|
|||
if id_ is not None:
|
||||
return id_
|
||||
log.warning('No id attr found: %s' % stanza)
|
||||
|
||||
|
||||
# XEP-0224: Attention
|
||||
|
||||
def parse_attention(stanza):
|
||||
attention = stanza.getTag('attention', namespace=nbxmpp.NS_ATTENTION)
|
||||
if attention is None:
|
||||
return False
|
||||
delayed = stanza.getTag('x', namespace=nbxmpp.NS_DELAY2)
|
||||
if delayed is not None:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
# XEP-0258: Security Labels in XMPP
|
||||
|
||||
def parse_securitylabel(stanza):
|
||||
seclabel = stanza.getTag('securitylabel', namespace=nbxmpp.NS_SECLABEL)
|
||||
if seclabel is None:
|
||||
return None
|
||||
return seclabel.getTag('displaymarking')
|
||||
|
||||
|
||||
# XEP-0004: Data Forms
|
||||
|
||||
def parse_form(stanza):
|
||||
return stanza.getTag('x', namespace=nbxmpp.NS_DATA)
|
||||
|
||||
|
||||
# XEP-0071: XHTML-IM
|
||||
|
||||
def parse_xhtml(stanza):
|
||||
if app.config.get('ignore_incoming_xhtml'):
|
||||
return None
|
||||
return stanza.getXHTML()
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
# This file is part of Gajim.
|
||||
#
|
||||
# Gajim is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation; version 3 only.
|
||||
#
|
||||
# Gajim is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# XEP-0184: Message Delivery Receipts
|
||||
|
||||
import logging
|
||||
|
||||
import nbxmpp
|
||||
|
||||
from gajim.common import app
|
||||
from gajim.common.nec import NetworkIncomingEvent
|
||||
|
||||
log = logging.getLogger('gajim.c.m.receipts')
|
||||
|
||||
|
||||
class Receipts:
|
||||
def __init__(self, con):
|
||||
self._con = con
|
||||
self._account = con.name
|
||||
|
||||
self.handlers = []
|
||||
|
||||
def delegate(self, event):
|
||||
request = event.stanza.getTag('request',
|
||||
namespace=nbxmpp.NS_RECEIPTS)
|
||||
if request is not None:
|
||||
self._answer_request(event)
|
||||
return
|
||||
|
||||
received = event.stanza.getTag('received',
|
||||
namespace=nbxmpp.NS_RECEIPTS)
|
||||
if received is not None:
|
||||
self._receipt_received(event, received)
|
||||
raise nbxmpp.NodeProcessed
|
||||
|
||||
def _answer_request(self, event):
|
||||
if not app.config.get_per('accounts', self._account,
|
||||
'answer_receipts'):
|
||||
return
|
||||
|
||||
if event.mtype not in ('chat', 'groupchat'):
|
||||
return
|
||||
|
||||
if event.sent:
|
||||
# Never answer messages that we sent from another device
|
||||
return
|
||||
|
||||
from_ = event.stanza.getFrom()
|
||||
if self._con.get_own_jid().bareMatch(from_):
|
||||
# Dont answer receipts from our other resources
|
||||
return
|
||||
|
||||
receipt_id = event.stanza.getID()
|
||||
|
||||
contact = self._get_contact(event)
|
||||
if contact is None:
|
||||
return
|
||||
|
||||
receipt = self._build_answer_receipt(from_, receipt_id)
|
||||
log.info('Answer %s', receipt_id)
|
||||
self._con.connection.send(receipt)
|
||||
|
||||
def _get_contact(self, event):
|
||||
if event.mtype == 'chat':
|
||||
contact = app.contacts.get_contact(self._account, event.jid)
|
||||
if contact and contact.sub not in ('to', 'none'):
|
||||
return contact
|
||||
else:
|
||||
return app.contacts.get_gc_contact(self._account,
|
||||
event.jid,
|
||||
event.resource)
|
||||
|
||||
def _build_answer_receipt(self, to, receipt_id):
|
||||
receipt = nbxmpp.Message(to=to, typ='chat')
|
||||
receipt.setTag('received',
|
||||
namespace='urn:xmpp:receipts',
|
||||
attrs={'id': receipt_id})
|
||||
return receipt
|
||||
|
||||
def _receipt_received(self, event, received):
|
||||
receipt_id = received.getAttr('id')
|
||||
if receipt_id is None:
|
||||
log.warning('Receipt without ID: %s', event.stanza)
|
||||
return
|
||||
log.info('Received %s', receipt_id)
|
||||
app.nec.push_incoming_event(
|
||||
NetworkIncomingEvent('receipt-received',
|
||||
conn=self._con,
|
||||
receipt_id=receipt_id,
|
||||
jid=event.jid))
|
||||
|
||||
|
||||
def get_instance(*args, **kwargs):
|
||||
return Receipts(*args, **kwargs), 'Receipts'
|
|
@ -78,5 +78,12 @@ class UserNickname(AbstractPEPModule):
|
|||
'accounts', self._account, 'name')
|
||||
|
||||
|
||||
def parse_nickname(stanza):
|
||||
nick = stanza.getTag('nick', namespace=nbxmpp.NS_NICK)
|
||||
if nick is None:
|
||||
return ''
|
||||
return nick.getData()
|
||||
|
||||
|
||||
def get_instance(*args, **kwargs):
|
||||
return UserNickname(*args, **kwargs), 'UserNickname'
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# This file is part of Gajim.
|
||||
#
|
||||
# Gajim is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation; version 3 only.
|
||||
#
|
||||
# Gajim is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Util module
|
||||
|
||||
import nbxmpp
|
||||
|
||||
from gajim.common import app
|
||||
|
||||
|
||||
def is_self_message(message, groupchat=False):
|
||||
if groupchat:
|
||||
return False
|
||||
frm = message.getFrom()
|
||||
to = message.getTo()
|
||||
return frm.bareMatch(to)
|
||||
|
||||
|
||||
def is_muc_pm(message, jid, groupchat=False):
|
||||
if groupchat:
|
||||
return False
|
||||
muc_user = message.getTag('x', namespace=nbxmpp.NS_MUC_USER)
|
||||
if muc_user is not None:
|
||||
return muc_user.getChildren() == []
|
||||
else:
|
||||
# muc#user namespace was added in MUC 1.28 so we need a fallback
|
||||
# Check if we know the jid
|
||||
if app.logger.jid_is_room_jid(jid.getStripped()):
|
||||
return True
|
||||
return False
|
|
@ -23,21 +23,40 @@
|
|||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
import time
|
||||
|
||||
import nbxmpp
|
||||
|
||||
from gajim.common import app
|
||||
|
||||
from gajim.common.protocol.bytestream import ConnectionSocks5BytestreamZeroconf
|
||||
from gajim.common.connection_handlers_events import ZeroconfMessageReceivedEvent
|
||||
from gajim.common.zeroconf.zeroconf import Constant
|
||||
from gajim.common import connection_handlers
|
||||
from gajim.common.nec import NetworkIncomingEvent, NetworkEvent
|
||||
from gajim.common.modules.user_nickname import parse_nickname
|
||||
from gajim.common.modules.chatstates import parse_chatstate
|
||||
from gajim.common.modules.misc import parse_eme
|
||||
from gajim.common.modules.misc import parse_correction
|
||||
from gajim.common.modules.misc import parse_attention
|
||||
from gajim.common.modules.misc import parse_oob
|
||||
from gajim.common.modules.misc import parse_xhtml
|
||||
|
||||
import logging
|
||||
log = logging.getLogger('gajim.c.z.connection_handlers_zeroconf')
|
||||
|
||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||
'invisible']
|
||||
'invisible']
|
||||
# kind of events we can wait for an answer
|
||||
AGENT_REMOVED = 'agent_removed'
|
||||
|
||||
from gajim.common import connection_handlers
|
||||
|
||||
class ZeroconfMessageReceivedEvent(NetworkIncomingEvent):
|
||||
name = 'message-received'
|
||||
|
||||
|
||||
class DecryptedMessageReceivedEvent(NetworkIncomingEvent):
|
||||
name = 'decrypted-message-received'
|
||||
|
||||
|
||||
class ConnectionVcard:
|
||||
def add_sha(self, p, *args):
|
||||
|
@ -57,14 +76,113 @@ connection_handlers.ConnectionJingle):
|
|||
connection_handlers.ConnectionJingle.__init__(self)
|
||||
connection_handlers.ConnectionHandlersBase.__init__(self)
|
||||
|
||||
def _messageCB(self, ip, con, msg):
|
||||
def _messageCB(self, ip, con, stanza):
|
||||
"""
|
||||
Called when we receive a message
|
||||
"""
|
||||
log.debug('Zeroconf MessageCB')
|
||||
app.nec.push_incoming_event(ZeroconfMessageReceivedEvent(None,
|
||||
conn=self, stanza=msg, ip=ip))
|
||||
return
|
||||
|
||||
app.nec.push_incoming_event(NetworkEvent(
|
||||
'raw-message-received',
|
||||
conn=self,
|
||||
stanza=stanza,
|
||||
account=self.name))
|
||||
|
||||
type_ = stanza.getType()
|
||||
if type_ is None:
|
||||
type_ = 'normal'
|
||||
|
||||
id_ = stanza.getID()
|
||||
|
||||
fjid = str(stanza.getFrom())
|
||||
|
||||
if fjid is None:
|
||||
for key in self.connection.zeroconf.contacts:
|
||||
if ip == self.connection.zeroconf.contacts[key][
|
||||
Constant.ADDRESS]:
|
||||
fjid = key
|
||||
break
|
||||
|
||||
jid, resource = app.get_room_and_nick_from_fjid(fjid)
|
||||
|
||||
thread_id = stanza.getThread()
|
||||
msgtxt = stanza.getBody()
|
||||
|
||||
session = self.get_or_create_session(fjid, thread_id)
|
||||
|
||||
if thread_id and not session.received_thread_id:
|
||||
session.received_thread_id = True
|
||||
|
||||
session.last_receive = time.time()
|
||||
|
||||
event_attr = {
|
||||
'conn': self,
|
||||
'stanza': stanza,
|
||||
'account': self.name,
|
||||
'id_': id_,
|
||||
'encrypted': False,
|
||||
'additional_data': {},
|
||||
'forwarded': False,
|
||||
'sent': False,
|
||||
'timestamp': time.time(),
|
||||
'fjid': fjid,
|
||||
'jid': jid,
|
||||
'resource': resource,
|
||||
'unique_id': id_,
|
||||
'mtype': type_,
|
||||
'msgtxt': msgtxt,
|
||||
'thread_id': thread_id,
|
||||
'session': session,
|
||||
'self_message': False,
|
||||
'muc_pm': False,
|
||||
'gc_control': None}
|
||||
|
||||
event = ZeroconfMessageReceivedEvent(None, **event_attr)
|
||||
app.nec.push_incoming_event(event)
|
||||
|
||||
app.plugin_manager.extension_point(
|
||||
'decrypt', self, event, self._on_message_decrypted)
|
||||
if not event.encrypted:
|
||||
eme = parse_eme(event.stanza)
|
||||
if eme is not None:
|
||||
event.msgtxt = eme
|
||||
self._on_message_decrypted(event)
|
||||
|
||||
def _on_message_decrypted(self, event):
|
||||
try:
|
||||
self.get_module('Receipts').delegate(event)
|
||||
except nbxmpp.NodeProcessed:
|
||||
return
|
||||
|
||||
event_attr = {
|
||||
'popup': False,
|
||||
'msg_log_id': None,
|
||||
'subject': None,
|
||||
'displaymarking': None,
|
||||
'form_node': None,
|
||||
'attention': parse_attention(event.stanza),
|
||||
'correct_id': parse_correction(event.stanza),
|
||||
'user_nick': parse_nickname(event.stanza),
|
||||
'xhtml': parse_xhtml(event.stanza),
|
||||
'chatstate': parse_chatstate(event.stanza),
|
||||
'stanza_id': event.unique_id
|
||||
}
|
||||
|
||||
parse_oob(event.stanza, event.additional_data)
|
||||
|
||||
for name, value in event_attr.items():
|
||||
setattr(event, name, value)
|
||||
|
||||
if event.mtype == 'error':
|
||||
if not event.msgtxt:
|
||||
event.msgtxt = _('message')
|
||||
self.dispatch_error_message(
|
||||
event.stanza, event.msgtxt,
|
||||
event.session, event.fjid, event.timestamp)
|
||||
return
|
||||
|
||||
app.nec.push_incoming_event(
|
||||
DecryptedMessageReceivedEvent(None, **vars(event)))
|
||||
|
||||
def store_metacontacts(self, tags):
|
||||
"""
|
||||
|
|
|
@ -12,7 +12,7 @@ from gajim.common import app
|
|||
from gajim.common import nec
|
||||
from gajim.common import ged
|
||||
from gajim.common.nec import NetworkEvent
|
||||
from gajim.common.connection_handlers_events import MessageReceivedEvent
|
||||
from gajim.common.modules.message import MessageReceivedEvent
|
||||
from gajim.common.connection_handlers_events import DecryptedMessageReceivedEvent
|
||||
import nbxmpp
|
||||
|
||||
|
|
Loading…
Reference in New Issue