def _log_muc_event(self, event_name, properties): if event_name not in [ 'muc-user-joined', 'muc-user-left', 'muc-user-status-show-changed' ]: return if (not app.config.get('log_contact_status_changes') or not app.config.should_log(self._account, properties.jid)): return additional_data = AdditionalDataDict() if properties.muc_user is not None: if properties.muc_user.jid is not None: additional_data.set_value('gajim', 'real_jid', str(properties.muc_user.jid)) # TODO: Refactor if properties.type == PresenceType.UNAVAILABLE: show = 'offline' else: show = properties.show.value show = app.logger.convert_show_values_to_db_api_values(show) app.logger.insert_into_logs(self._account, properties.jid.getBare(), properties.timestamp, KindConstant.GCSTATUS, contact_name=properties.muc_nickname, message=properties.status or None, show=show, additional_data=additional_data)
def _print_xhtml(self): for xhtml in XHTML: additional_data = AdditionalDataDict() additional_data.set_value('gajim', 'xhtml', xhtml) self._textview.print_real_text(None, additional_data=additional_data) self._textview.print_real_text('\n')
class OutgoingMessage: def __init__(self, account, contact, message, type_, subject=None, chatstate=None, marker=None, resource=None, user_nick=None, label=None, control=None, attention=None, correct_id=None, oob_url=None, xhtml=None, nodes=None, play_sound=True): if type_ not in ('chat', 'groupchat', 'normal', 'headline'): raise ValueError('Unknown message type: %s' % type_) if not message and chatstate is None and marker is None: raise ValueError('Trying to send message without content') self.account = account self.contact = contact self.message = message self.type_ = type_ if type_ == 'chat': self.kind = KindConstant.CHAT_MSG_SENT elif type_ == 'groupchat': self.kind = KindConstant.GC_MSG elif type_ == 'normal': self.kind = KindConstant.SINGLE_MSG_SENT else: raise ValueError('Unknown message type') from gajim.common.helpers import AdditionalDataDict self.additional_data = AdditionalDataDict() self.subject = subject self.chatstate = chatstate self.marker = marker self.resource = resource self.user_nick = user_nick self.label = label self.control = control self.attention = attention self.correct_id = correct_id self.oob_url = oob_url if oob_url is not None: self.additional_data.set_value('gajim', 'oob_url', oob_url) self.xhtml = xhtml if xhtml is not None: self.additional_data.set_value('gajim', 'xhtml', xhtml) self.nodes = nodes self.play_sound = play_sound self.timestamp = None self.message_id = None self.stanza = None self.session = None self.delayed = None # TODO never set self.is_loggable = True def copy(self): message = OutgoingMessage(self.account, self.contact, self.message, self.type_) for name, value in vars(self).items(): setattr(message, name, value) message.additional_data = self.additional_data.copy() return message @property def jid(self): return self.contact.jid @property def is_groupchat(self): return self.type_ == 'groupchat' @property def is_chat(self): return self.type_ == 'chat' @property def is_normal(self): return self.type_ == 'normal' def set_sent_timestamp(self): if self.is_groupchat: return self.timestamp = time.time() @property def is_encrypted(self): return bool(self.additional_data.get_value('encrypted', 'name', False)) @property def msg_iq(self): # Backwards compatibility for plugins return self.stanza @msg_iq.setter def msg_iq(self, value): # Backwards compatibility for plugins self.stanza = value
def _mam_message_received(self, _con, stanza, properties): if not properties.is_mam_message: return app.nec.push_incoming_event( NetworkIncomingEvent('mam-message-received', account=self._account, stanza=stanza, properties=properties)) if not self._from_valid_archive(stanza, properties): self._log.warning('Message from invalid archive %s', properties.mam.archive) raise nbxmpp.NodeProcessed self._log.info('Received message from archive: %s', properties.mam.archive) if not self._is_valid_request(properties): self._log.warning('Invalid MAM Message: unknown query id %s', properties.mam.query_id) self._log.debug(stanza) raise nbxmpp.NodeProcessed is_groupchat = properties.type.is_groupchat if is_groupchat: kind = KindConstant.GC_MSG else: if properties.from_.bareMatch(self._con.get_own_jid()): kind = KindConstant.CHAT_MSG_SENT else: kind = KindConstant.CHAT_MSG_RECV stanza_id, message_id = self._get_unique_id(properties) if properties.mam.is_ver_2: # Search only with stanza-id for duplicates on mam:2 if app.logger.find_stanza_id(self._account, str(properties.mam.archive), stanza_id, message_id, groupchat=is_groupchat): self._log.info( 'Found duplicate with stanza-id: %s, ' 'message-id: %s', stanza_id, message_id) raise nbxmpp.NodeProcessed additional_data = AdditionalDataDict() if properties.has_user_delay: # Record it as a user timestamp additional_data.set_value('gajim', 'user_timestamp', properties.user_timestamp) parse_oob(properties, additional_data) msgtxt = properties.body if properties.is_encrypted: additional_data['encrypted'] = properties.encrypted.additional_data else: if properties.eme is not None: msgtxt = get_eme_message(properties.eme) if not msgtxt: # For example Chatstates, Receipts, Chatmarkers self._log.debug(stanza.getProperties()) return with_ = properties.jid.getStripped() if properties.is_muc_pm: # we store the message with the full JID with_ = str(with_) if properties.is_self_message: # Self messages can only be deduped with origin-id if message_id is None: self._log.warning('Self message without origin-id found') return stanza_id = message_id if properties.mam.namespace == nbxmpp.NS_MAM_1: if app.logger.search_for_duplicate(self._account, with_, properties.mam.timestamp, msgtxt): self._log.info('Found duplicate with fallback for mam:1') return app.logger.insert_into_logs(self._account, with_, properties.mam.timestamp, kind, unread=False, message=msgtxt, contact_name=properties.muc_nickname, additional_data=additional_data, stanza_id=stanza_id, message_id=properties.id) app.nec.push_incoming_event( NetworkEvent( 'mam-decrypted-message-received', account=self._account, additional_data=additional_data, correct_id=parse_correction(properties), archive_jid=properties.mam.archive, msgtxt=properties.body, properties=properties, kind=kind, ))
def _mam_message_received(self, _con, stanza, properties): if not properties.is_mam_message: return app.nec.push_incoming_event( NetworkIncomingEvent('raw-mam-message-received', conn=self._con, stanza=stanza)) if not self._from_valid_archive(stanza, properties): self._log.warning('Message from invalid archive %s', properties.mam.archive) raise nbxmpp.NodeProcessed self._log.info('Received message from archive: %s', properties.mam.archive) if not self._is_valid_request(properties): self._log.warning('Invalid MAM Message: unknown query id %s', properties.mam.query_id) self._log.debug(stanza) raise nbxmpp.NodeProcessed event_attrs = {} groupchat = properties.type.is_groupchat if groupchat: event_attrs.update(self._parse_gc_attrs(properties)) else: event_attrs.update(self._parse_chat_attrs(stanza, properties)) stanza_id, message_id = self._get_unique_id(properties) if properties.mam.is_ver_2: # Search only with stanza-id for duplicates on mam:2 if app.logger.find_stanza_id(self._account, str(properties.mam.archive), stanza_id, message_id, groupchat=groupchat): self._log.info( 'Found duplicate with stanza-id: %s, ' 'message-id: %s', stanza_id, message_id) raise nbxmpp.NodeProcessed additional_data = AdditionalDataDict() if properties.has_user_delay: # Record it as a user timestamp additional_data.set_value('gajim', 'user_timestamp', properties.user_timestamp) event_attrs.update({ 'conn': self._con, 'account': self._account, 'additional_data': additional_data, 'encrypted': False, 'timestamp': properties.mam.timestamp, 'self_message': properties.is_self_message, 'groupchat': groupchat, 'muc_pm': properties.is_muc_pm, 'stanza_id': stanza_id, 'origin_id': message_id, 'message_id': properties.id, 'correct_id': None, 'archive_jid': properties.mam.archive, 'msgtxt': properties.body, 'message': stanza, 'stanza': stanza, 'namespace': properties.mam.namespace, }) if groupchat: event = MamGcMessageReceivedEvent(None, **event_attrs) else: event = MamMessageReceivedEvent(None, **event_attrs) if properties.is_encrypted: event.additional_data[ 'encrypted'] = properties.encrypted.additional_data self._decryption_finished(event) else: app.plugin_manager.extension_point('decrypt', self._con, event, self._decryption_finished) if not event.encrypted: if properties.eme is not None: event.msgtxt = get_eme_message(properties.eme) self._decryption_finished(event) raise nbxmpp.NodeProcessed
def _message_received(self, _con, stanza, properties): if properties.is_mam_message or properties.is_pubsub: return # 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 self._log.info('Received from %s', stanza.getFrom()) app.nec.push_incoming_event( NetworkEvent('raw-message-received', conn=self._con, stanza=stanza, account=self._account)) forwarded = properties.carbon_type is not None sent = properties.carbon_type == 'sent' if sent: # Ugly, we treat the from attr as the remote jid, # to make that work with sent carbons we have to do this. # TODO: Check where in Gajim and plugins we depend on that behavior stanza.setFrom(stanza.getTo()) from_ = stanza.getFrom() fjid = str(from_) jid = from_.getBare() resource = from_.getResource() type_ = properties.type stanza_id, message_id = self._get_unique_id(properties) if properties.type.is_groupchat and properties.has_server_delay: # Only for XEP-0045 MUC History # Dont check for message text because the message could be encrypted if app.logger.deduplicate_muc_message(self._account, properties.jid.getBare(), properties.jid.getResource(), properties.timestamp, properties.id): raise nbxmpp.NodeProcessed if (properties.is_self_message or properties.is_muc_pm): archive_jid = self._con.get_own_jid().getStripped() if app.logger.find_stanza_id(self._account, archive_jid, stanza_id, message_id, properties.type.is_groupchat): return thread_id = properties.thread msgtxt = properties.body # 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 properties.type.is_error: if msgtxt: msgtxt = _( 'error while sending %(message)s ( %(error)s )') % { 'message': msgtxt, 'error': stanza.getErrorMsg() } else: msgtxt = _('error: %s') % stanza.getErrorMsg() # TODO: why is this here? if stanza.getTag('html'): stanza.delChild('html') type_ = MessageType.GROUPCHAT session = None if not properties.type.is_groupchat: if properties.is_muc_pm and properties.type.is_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() additional_data = AdditionalDataDict() if properties.has_user_delay: additional_data.set_value('gajim', 'user_timestamp', properties.user_timestamp) event_attr = { 'conn': self._con, 'stanza': stanza, 'account': self._account, 'id_': properties.id, 'encrypted': False, 'additional_data': additional_data, 'forwarded': forwarded, 'sent': sent, 'fjid': fjid, 'jid': jid, 'resource': resource, 'stanza_id': stanza_id, 'unique_id': stanza_id or message_id, 'message_id': properties.id, 'mtype': type_.value, 'msgtxt': msgtxt, 'thread_id': thread_id, 'session': session, 'self_message': properties.is_self_message, 'timestamp': properties.timestamp, 'delayed': properties.user_timestamp is not None, 'muc_pm': properties.is_muc_pm, 'gc_control': gc_control } app.nec.push_incoming_event( NetworkEvent('update-client-info', account=self._account, jid=jid, resource=resource)) event = MessageReceivedEvent(None, **event_attr) app.nec.push_incoming_event(event) if properties.is_encrypted: event.additional_data[ 'encrypted'] = properties.encrypted.additional_data self._on_message_decrypted(event) else: app.plugin_manager.extension_point('decrypt', self._con, event, self._on_message_decrypted) if not event.encrypted: if properties.eme is not None: event.msgtxt = get_eme_message(properties.eme) self._on_message_decrypted(event)
def _message_received(self, _con, stanza, properties): if (properties.is_mam_message or properties.is_pubsub or properties.type.is_error): return # 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 self._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 properties.is_carbon_message and properties.carbon.is_sent: # Ugly, we treat the from attr as the remote jid, # to make that work with sent carbons we have to do this. # TODO: Check where in Gajim and plugins we depend on that behavior stanza.setFrom(stanza.getTo()) from_ = stanza.getFrom() fjid = str(from_) jid = from_.bare resource = from_.resource type_ = properties.type stanza_id, message_id = self._get_unique_id(properties) if properties.type.is_groupchat and properties.has_server_delay: # Only for XEP-0045 MUC History # Don’t check for message text because the message could be # encrypted. if app.storage.archive.deduplicate_muc_message( self._account, properties.jid.bare, properties.jid.resource, properties.timestamp, properties.id): raise nbxmpp.NodeProcessed if (properties.is_self_message or properties.is_muc_pm): archive_jid = self._con.get_own_jid().bare if app.storage.archive.find_stanza_id( self._account, archive_jid, stanza_id, message_id, properties.type.is_groupchat): return msgtxt = properties.body # 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) session = None if not properties.type.is_groupchat: if properties.is_muc_pm and properties.type.is_error: session = self._con.find_session(fjid, properties.thread) if not session: session = self._con.get_latest_session(fjid) if not session: session = self._con.make_new_session(fjid, properties.thread, type_='pm') else: session = self._con.get_or_create_session( fjid, properties.thread) if properties.thread and not session.received_thread_id: session.received_thread_id = True session.last_receive = time.time() additional_data = AdditionalDataDict() if properties.has_user_delay: additional_data.set_value('gajim', 'user_timestamp', properties.user_timestamp) parse_oob(properties, additional_data) parse_xhtml(properties, additional_data) app.nec.push_incoming_event( NetworkEvent('update-client-info', account=self._account, jid=jid, resource=resource)) if properties.is_encrypted: additional_data['encrypted'] = properties.encrypted.additional_data else: if properties.eme is not None: msgtxt = get_eme_message(properties.eme) displaymarking = None if properties.has_security_label: displaymarking = properties.security_label.displaymarking event_attr = { 'conn': self._con, 'stanza': stanza, 'account': self._account, 'additional_data': additional_data, 'fjid': fjid, 'jid': jid, 'resource': resource, 'stanza_id': stanza_id, 'unique_id': stanza_id or message_id, 'correct_id': parse_correction(properties), 'msgtxt': msgtxt, 'session': session, 'delayed': properties.user_timestamp is not None, 'gc_control': gc_control, 'popup': False, 'msg_log_id': None, 'displaymarking': displaymarking, 'properties': properties, } if type_.is_groupchat: if not msgtxt: return event_attr.update({ 'room_jid': jid, }) event = NetworkEvent('gc-message-received', **event_attr) app.nec.push_incoming_event(event) # TODO: Some plugins modify msgtxt in the GUI event self._log_muc_message(event) return app.nec.push_incoming_event( NetworkEvent('decrypted-message-received', **event_attr))