def init(self): self.additional_data = AdditionalDataDict() self.message = None self.type_ = 'chat' self.kind = None self.timestamp = None self.subject = '' self.chatstate = None self.stanza_id = None self.resource = None self.user_nick = None self.xhtml = None self.label = None self.session = None self.form_node = None self.delayed = None self.callback = None self.callback_args = [] self.now = False self.is_loggable = True self.control = None self.attention = False self.correct_id = None self.automatic_message = True self.encryption = '' self.encrypted = False
def __init__(self, message, subject, kind, time_, resource, msg_log_id, correct_id=None, message_id=None, session=None, displaymarking=None, sent_forwarded=False, show_in_roster=False, show_in_systray=True, additional_data=None): Event.__init__(self, time_, show_in_roster=show_in_roster, show_in_systray=show_in_systray) self.message = message self.subject = subject self.kind = kind self.time = time_ self.resource = resource self.msg_log_id = msg_log_id self.message_id = message_id self.correct_id = correct_id self.session = session self.displaymarking = displaymarking self.sent_forwarded = sent_forwarded if additional_data is None: from gajim.common.helpers import AdditionalDataDict additional_data = AdditionalDataDict() self.additional_data = additional_data
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')
def init(self): self.additional_data = AdditionalDataDict() self.message = '' self.chatstate = None self.stanza_id = None self.label = None self.callback = None self.callback_args = [] self.is_loggable = True self.control = None self.correct_id = None self.automatic_message = True
def _namedtuple_factory(self, cursor, row): fields = [col[0] for col in cursor.description] Row = namedtuple("Row", fields) named_row = Row(*row) if 'additional_data' in fields: _dict = json.loads(named_row.additional_data or '{}') named_row = named_row._replace( additional_data=AdditionalDataDict(_dict)) # if an alias `account` for the field `account_id` is used for the # query, the account_id is converted to the account jid if 'account' in fields: if named_row.account: jid = self._jid_ids_reversed[named_row.account].jid named_row = named_row._replace(account=jid) return named_row
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 _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 roster_message(self, jid, msg, tim, encrypted=False, msg_type='', subject=None, resource='', msg_log_id=None, user_nick='', xhtml=None, form_node=None, displaymarking=None, additional_data=None): """ Display the message or show notification in the roster """ contact = None fjid = jid if additional_data is None: additional_data = AdditionalDataDict() # Try to catch the contact with correct resource if resource: fjid = jid + '/' + resource contact = app.contacts.get_contact(self.conn.name, jid, resource) highest_contact = app.contacts.get_contact_with_highest_priority( self.conn.name, jid) if not contact: # If there is another resource, it may be a message from an invisible # resource lcontact = app.contacts.get_contacts(self.conn.name, jid) if (len(lcontact) > 1 or (lcontact and lcontact[0].resource and \ lcontact[0].show != 'offline')) and jid.find('@') > 0: contact = app.contacts.copy_contact(highest_contact) contact.resource = resource if resource: fjid = jid + '/' + resource contact.priority = 0 contact.show = 'offline' contact.status = '' app.contacts.add_contact(self.conn.name, contact) else: # Default to highest prio fjid = jid contact = highest_contact if not contact: # contact is not in roster contact = app.interface.roster.add_to_not_in_the_roster( self.conn.name, jid, user_nick) if not self.control: ctrl = app.interface.msg_win_mgr.get_control(fjid, self.conn.name) if ctrl: self.control = ctrl self.control.set_session(self) else: fjid = jid # Do we have a queue? no_queue = len(app.events.get_events(self.conn.name, fjid)) == 0 popup = helpers.allow_popup_window(self.conn.name) if msg_type == 'normal' and popup: # it's single message to be autopopuped SingleMessageWindow(self.conn.name, contact.jid, action='receive', from_whom=jid, subject=subject, message=msg, resource=resource, session=self, form_node=form_node) return # We print if window is opened and it's not a single message if self.control and msg_type != 'normal': typ = '' if msg_type == 'error': typ = 'error' self.control.print_conversation(msg, typ, tim=tim, encrypted=encrypted, subject=subject, xhtml=xhtml, displaymarking=displaymarking, additional_data=additional_data) if msg_log_id: app.logger.set_read_messages([msg_log_id]) return # We save it in a queue event_t = events.ChatEvent event_type = 'message_received' if msg_type == 'normal': event_t = events.NormalEvent event_type = 'single_message_received' show_in_roster = get_show_in_roster(event_type, self) show_in_systray = get_show_in_systray(event_type, contact.jid) event = event_t(msg, subject, msg_type, tim, encrypted, resource, msg_log_id, xhtml=xhtml, session=self, form_node=form_node, displaymarking=displaymarking, sent_forwarded=False, show_in_roster=show_in_roster, show_in_systray=show_in_systray, additional_data=additional_data) app.events.add_event(self.conn.name, fjid, event) if popup: if not self.control: self.control = app.interface.new_chat(contact, self.conn.name, session=self) if app.events.get_events(self.conn.name, fjid): self.control.read_queue() else: if no_queue: # We didn't have a queue: we change icons app.interface.roster.draw_contact(jid, self.conn.name) app.interface.roster.show_title() # we show the * or [n] # Select the big brother contact in roster, it's visible because it has # events. family = app.contacts.get_metacontacts_family(self.conn.name, jid) if family: _nearby_family, bb_jid, bb_account = \ app.contacts.get_nearby_family_and_big_brother(family, self.conn.name) else: bb_jid, bb_account = jid, self.conn.name app.interface.roster.select_contact(bb_jid, bb_account)
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))
def _messageCB(self, con, stanza, properties): """ Called when we receive a message """ log.info('Zeroconf MessageCB') # Dont trust from attr set by sender stanza.setFrom(con._owner.to) 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()) 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': AdditionalDataDict(), 'forwarded': False, 'sent': False, 'timestamp': time.time(), 'fjid': fjid, 'jid': jid, 'resource': resource, 'unique_id': id_, 'message_id': properties.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: if properties.eme is not None: event.msgtxt = get_eme_message(properties.eme) self._on_message_decrypted(event)
def _messageCB(self, con, stanza, properties): """ Called when we receive a message """ if properties.type.is_error: return log.info('Zeroconf MessageCB') # Don’t trust from attr set by sender stanza.setFrom(con._owner.to) 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()) jid, resource = app.get_room_and_nick_from_fjid(fjid) msgtxt = stanza.getBody() session = self.get_or_create_session(fjid, properties.thread) if properties.thread and not session.received_thread_id: session.received_thread_id = True timestamp = time.time() session.last_receive = timestamp additional_data = AdditionalDataDict() parse_oob(properties, additional_data) parse_xhtml(properties, additional_data) if properties.is_encrypted: additional_data['encrypted'] = properties.encrypted.additional_data else: if properties.eme is not None: msgtxt = get_eme_message(properties.eme) event_attr = { 'conn': self, 'stanza': stanza, 'account': self.name, 'additional_data': additional_data, 'timestamp': time.time(), 'fjid': fjid, 'jid': jid, 'resource': resource, 'unique_id': id_, 'correct_id': parse_correction(properties), 'msgtxt': msgtxt, 'session': session, 'gc_control': None, 'popup': False, 'msg_log_id': None, 'displaymarking': None, 'stanza_id': id_, 'properties': properties, } app.nec.push_incoming_event( NetworkEvent('decrypted-message-received', **event_attr))