diff --git a/gajim/common/config.py b/gajim/common/config.py index ed629bc73..5081eaf6b 100644 --- a/gajim/common/config.py +++ b/gajim/common/config.py @@ -268,7 +268,6 @@ class Config: 'check_idle_every_foo_seconds': [opt_int, 2, _('Choose interval between 2 checks of idleness.')], 'uri_schemes': [opt_str, 'aaa:// aaas:// acap:// cap:// cid: crid:// data: dav: dict:// dns: fax: file:/ ftp:// geo: go: gopher:// h323: http:// https:// iax: icap:// im: imap:// info: ipp:// iris: iris.beep: iris.xpc: iris.xpcs: iris.lwz: ldap:// mid: modem: msrp:// msrps:// mtqp:// mupdate:// news: nfs:// nntp:// opaquelocktoken: pop:// pres: prospero:// rtsp:// service: shttp:// sip: sips: sms: snmp:// soap.beep:// soap.beeps:// tag: tel: telnet:// tftp:// thismessage:/ tip:// tv: urn:// vemmi:// xmlrpc.beep:// xmlrpc.beeps:// z39.50r:// z39.50s:// about: apt: cvs:// daap:// ed2k:// feed: fish:// git:// iax2: irc:// ircs:// ldaps:// magnet: mms:// rsync:// ssh:// svn:// sftp:// smb:// webcal:// aesgcm://', _('Valid uri schemes. Only schemes in this list will be accepted as "real" uri. (mailto and xmpp are handled separately)'), True], 'shell_like_completion': [opt_bool, False, _('If true, completion in groupchats will be like a shell auto-completion')], - 'show_self_contact': [opt_str, 'when_other_resource', _('When is self contact row displayed. Can be "always", "when_other_resource" or "never"'), True], 'audio_input_device': [opt_str, 'autoaudiosrc ! volume name=gajim_vol'], 'audio_output_device': [opt_str, 'autoaudiosink'], 'video_input_device': [opt_str, 'autovideosrc'], diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py index 6ad109d76..e61879549 100644 --- a/gajim/common/connection_handlers.py +++ b/gajim/common/connection_handlers.py @@ -67,136 +67,13 @@ class ConnectionHandlersBase: # We decrypt GPG messages one after the other. Keep queue in mem self.gpg_messages_to_decrypt = [] - app.ged.register_event_handler('presence-received', ged.CORE, - self._nec_presence_received) app.ged.register_event_handler('gc-message-received', ged.CORE, self._nec_gc_message_received) def cleanup(self): - app.ged.remove_event_handler('presence-received', ged.CORE, - self._nec_presence_received) app.ged.remove_event_handler('gc-message-received', ged.CORE, self._nec_gc_message_received) - def _nec_presence_received(self, obj): - account = obj.conn.name - if account != self.name: - return - jid = obj.jid - resource = obj.resource or '' - - statuss = ['offline', 'error', 'online', 'chat', 'away', 'xa', 'dnd', - 'invisible'] - obj.old_show = 0 - obj.new_show = statuss.index(obj.show) - - obj.contact_list = [] - - highest = app.contacts.get_contact_with_highest_priority(account, jid) - obj.was_highest = (highest and highest.resource == resource) - - # Update contact - obj.contact_list = app.contacts.get_contacts(account, jid) - obj.contact = None - resources = [] - for c in obj.contact_list: - resources.append(c.resource) - if c.resource == resource: - obj.contact = c - break - - if obj.contact: - if obj.contact.show in statuss: - obj.old_show = statuss.index(obj.contact.show) - # nick changed - if obj.contact_nickname is not None and \ - obj.contact.contact_name != obj.contact_nickname: - obj.contact.contact_name = obj.contact_nickname - obj.need_redraw = True - - elif obj.old_show != obj.new_show or obj.contact.status != \ - obj.status: - obj.need_redraw = True - else: - obj.contact = app.contacts.get_first_contact_from_jid(account, - jid) - if not obj.contact: - # Presence of another resource of our jid - # Create self contact and add to roster - if resource == obj.conn.server_resource: - return - # Ignore offline presence of unknown self resource - if obj.new_show < 2: - return - obj.contact = app.contacts.create_self_contact(jid=jid, - account=account, show=obj.show, status=obj.status, - priority=obj.prio, keyID=obj.keyID, - resource=obj.resource) - app.contacts.add_contact(account, obj.contact) - obj.contact_list.append(obj.contact) - elif obj.contact.show in statuss: - obj.old_show = statuss.index(obj.contact.show) - if (resources != [''] and (len(obj.contact_list) != 1 or \ - obj.contact_list[0].show not in ('not in roster', 'offline'))) and \ - not app.jid_is_transport(jid): - # Another resource of an existing contact connected - obj.old_show = 0 - obj.contact = app.contacts.copy_contact(obj.contact) - obj.contact_list.append(obj.contact) - obj.contact.resource = resource - - obj.need_redraw = True - obj.need_add_in_roster = True - - if not app.jid_is_transport(jid) and len(obj.contact_list) == 1: - # It's not an agent - if obj.old_show == 0 and obj.new_show > 1: - if not jid in app.newly_added[account]: - app.newly_added[account].append(jid) - if jid in app.to_be_removed[account]: - app.to_be_removed[account].remove(jid) - elif obj.old_show > 1 and obj.new_show == 0 and \ - obj.conn.connected > 1: - if not jid in app.to_be_removed[account]: - app.to_be_removed[account].append(jid) - if jid in app.newly_added[account]: - app.newly_added[account].remove(jid) - obj.need_redraw = True - - obj.contact.show = obj.show - obj.contact.status = obj.status - obj.contact.priority = obj.prio - attached_keys = app.config.get_per('accounts', account, - 'attached_gpg_keys').split() - if jid in attached_keys: - obj.contact.keyID = attached_keys[attached_keys.index(jid) + 1] - else: - # Do not override assigned key - obj.contact.keyID = obj.keyID - obj.contact.contact_nickname = obj.contact_nickname - obj.contact.idle_time = obj.idle_time - - if app.jid_is_transport(jid): - return - - # It isn't an agent - # (when contact signs out or has errors) - if obj.show in ('offline', 'error'): - # TODO: This causes problems when another - # resource signs off! - self.stop_all_active_file_transfers(obj.contact) - - if app.config.get('log_contact_status_changes') and \ - app.config.should_log(self.name, obj.jid): - show = app.logger.convert_show_values_to_db_api_values(obj.show) - if show is not None: - app.logger.insert_into_logs(self.name, - nbxmpp.JID(obj.jid).getStripped(), - time.time(), - KindConstant.STATUS, - message=obj.status, - show=show) - 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: diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py index 64f7ebf51..d8098b7e2 100644 --- a/gajim/common/connection_handlers_events.py +++ b/gajim/common/connection_handlers_events.py @@ -144,105 +144,8 @@ class StreamConflictReceivedEvent(nec.NetworkIncomingEvent): self.conn = self.base_event.conn return True -class PresenceHelperEvent: - def _generate_show(self): - self.show = self.stanza.getShow() - if self.show not in ('chat', 'away', 'xa', 'dnd'): - self.show = '' # We ignore unknown show - if not self.ptype and not self.show: - self.show = 'online' - elif self.ptype == 'unavailable': - self.show = 'offline' - - def _generate_ptype(self): - self.ptype = self.stanza.getType() - if self.ptype == 'available': - self.ptype = None - rfc_types = ('unavailable', 'error', 'subscribe', 'subscribed', - 'unsubscribe', 'unsubscribed') - if self.ptype and not self.ptype in rfc_types: - self.ptype = None - -class PresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent, -PresenceHelperEvent): +class PresenceReceivedEvent(nec.NetworkIncomingEvent): name = 'presence-received' - base_network_events = ['raw-pres-received'] - - def _generate_keyID(self, sig_tag): - self.keyID = '' - if sig_tag and self.conn.USE_GPG and self.ptype != 'error': - # error presences contain our own signature - # verify - sig_msg = sig_tag.getData() - self.keyID = self.conn.gpg.verify(self.status, sig_msg) - self.keyID = helpers.prepare_and_validate_gpg_keyID(self.conn.name, - self.jid, - self.keyID) - - def _generate_prio(self): - self.prio = self.stanza.getPriority() - try: - self.prio = int(self.prio) - except Exception: - self.prio = 0 - - def generate(self): - self.conn = self.base_event.conn - self.stanza = self.base_event.stanza - - self.need_add_in_roster = False - self.need_redraw = False - - self.popup = False # Do we want to open chat window ? - - if not self.conn or self.conn.connected < 2: - log.debug('account is no more connected') - return - - self._generate_ptype() - try: - self.get_jid_resource() - except Exception: - log.warning('Invalid JID: %s, ignoring it', self.stanza.getFrom()) - return - jid_list = app.contacts.get_jid_list(self.conn.name) - self.timestamp = None - self.get_id() - self.avatar_sha = None - # XEP-0172 User Nickname - self.user_nick = self.stanza.getTagData('nick') or '' - self.contact_nickname = None - self.transport_auto_auth = False - - # XEP-0203 - self.timestamp = parse_delay(self.stanza) - if self.timestamp is None: - self.timestamp = time_time() - - # XEP-0319 - self.idle_time = parse_idle(self.stanza) - - sig_tag = self.stanza.getTag('x', namespace=nbxmpp.NS_SIGNED) - - self.status = self.stanza.getStatus() or '' - self._generate_show() - self._generate_prio() - self._generate_keyID(sig_tag) - - self.errcode = self.stanza.getErrorCode() - self.errmsg = self.stanza.getErrorMsg() - - if self.ptype == 'error': - return - - if not self.ptype or self.ptype == 'unavailable': - our_jid = app.get_jid_from_account(self.conn.name) - if self.jid == our_jid and self.resource == self.conn.server_resource: - # We got our own presence - app.nec.push_incoming_event(OurShowEvent(None, conn=self.conn, - show=self.show)) - elif self.jid in jid_list or self.jid == our_jid: - return True class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent): name = 'presence-received' @@ -254,16 +157,13 @@ class ZeroconfPresenceReceivedEvent(nec.NetworkIncomingEvent): self.keyID = None self.idle_time = None self.timestamp = 0 - self.contact_nickname = None self.avatar_sha = None self.need_add_in_roster = False - self.need_redraw = False if self.show == 'offline': self.ptype = 'unavailable' else: self.ptype = None self.user_nick = '' - self.transport_auto_auth = False self.errcode = None self.errmsg = '' self.popup = False # Do we want to open chat window ? diff --git a/gajim/common/contacts.py b/gajim/common/contacts.py index 34fdaef3f..b8f711151 100644 --- a/gajim/common/contacts.py +++ b/gajim/common/contacts.py @@ -368,6 +368,9 @@ class LegacyContactsAPI: def get_contact(self, account, jid, resource=None): return self._accounts[account].contacts.get_contact(jid, resource=resource) + def get_contact_strict(self, account, jid, resource): + return self._accounts[account].contacts.get_contact_strict(jid, resource) + def get_avatar(self, account, *args, **kwargs): return self._accounts[account].contacts.get_avatar(*args, **kwargs) @@ -553,7 +556,7 @@ class Contacts(): """ Return the list of contact instances for this jid """ - return self._contacts.get(jid, []) + return list(self._contacts.get(jid, [])) def get_contact(self, jid, resource=None): ### WARNING ### diff --git a/gajim/common/modules/presence.py b/gajim/common/modules/presence.py index dee33b3cb..99b0c261e 100644 --- a/gajim/common/modules/presence.py +++ b/gajim/common/modules/presence.py @@ -15,13 +15,17 @@ # Presence handler import logging +import time import nbxmpp +from nbxmpp.structs import StanzaHandler +from nbxmpp.const import PresenceType from gajim.common import app from gajim.common.i18n import _ from gajim.common.nec import NetworkEvent -from gajim.common.modules.user_nickname import parse_nickname +from gajim.common.const import KindConstant +from gajim.common.helpers import prepare_and_validate_gpg_keyID log = logging.getLogger('gajim.c.m.presence') @@ -32,11 +36,25 @@ class Presence: self._account = con.name self.handlers = [ - ('presence', self._presence_received), - ('presence', self._subscribe_received, 'subscribe'), - ('presence', self._subscribed_received, 'subscribed'), - ('presence', self._unsubscribe_received, 'unsubscribe'), - ('presence', self._unsubscribed_received, 'unsubscribed'), + StanzaHandler(name='presence', + callback=self._presence_received, + priority=50), + StanzaHandler(name='presence', + callback=self._subscribe_received, + typ='subscribe', + priority=49), + StanzaHandler(name='presence', + callback=self._subscribed_received, + typ='subscribed', + priority=49), + StanzaHandler(name='presence', + callback=self._unsubscribe_received, + typ='unsubscribe', + priority=49), + StanzaHandler(name='presence', + callback=self._unsubscribed_received, + typ='unsubscribed', + priority=49), ] # keep the jids we auto added (transports contacts) to not send the @@ -46,32 +64,198 @@ class Presence: # list of jid to auto-authorize self.jids_for_auto_auth = [] - def _presence_received(self, _con, stanza): - if stanza.getType() in ('subscribe', 'subscribed', - 'unsubscribe', 'unsubscribed'): - # Dont handle that here + def _presence_received(self, _con, stanza, properties): + log.info('Received from %s', properties.jid) + + if properties.type == PresenceType.ERROR: + log.info('Error: %s %s', properties.jid, properties.error) + raise nbxmpp.NodeProcessed + + if self._account == 'Local': + app.nec.push_incoming_event( + NetworkEvent('raw-pres-received', + conn=self._con, + stanza=stanza)) + raise nbxmpp.NodeProcessed + + if properties.is_self_presence: + app.nec.push_incoming_event( + NetworkEvent('our-show', + conn=self._con, + show=properties.show.value)) + raise nbxmpp.NodeProcessed + + contacts = app.contacts.get_jid_list(self._account) + if properties.jid.getBare() not in contacts and not properties.is_self_bare: + # Handle only presence from roster contacts + log.warning('Unkown presence received') + log.warning(stanza) return - log.info('Received from %s', stanza.getFrom()) - if nbxmpp.isErrorNode(stanza): - log.info('Error:\n%s', stanza) + key_id = '' + if properties.signed is not None and self._con.USE_GPG: + key_id = self._con.gpg.verify(properties.status, properties.signed) + key_id = prepare_and_validate_gpg_keyID( + self._account, properties.jid.getBare(), key_id) - app.nec.push_incoming_event( - NetworkEvent('raw-pres-received', - conn=self._con, - stanza=stanza)) + show = properties.show.value + if properties.type.is_unavailable: + show = 'offline' + + event_attrs = { + 'conn': self._con, + 'stanza': stanza, + 'keyID': key_id, + 'prio': properties.priority, + 'need_add_in_roster': False, + 'popup': False, + 'ptype': properties.type.value, + 'jid': properties.jid.getBare(), + 'resource': properties.jid.getResource(), + 'id_': properties.id, + 'fjid': str(properties.jid), + 'timestamp': properties.timestamp, + 'avatar_sha': properties.avatar_sha, + 'user_nick': properties.nickname, + 'idle_time': properties.idle_timestamp, + 'show': show, + 'new_show': show, + 'old_show': 0, + 'status': properties.status, + 'contact_list': [], + 'contact': None, + 'need_add_in_roster': False, + } + + event_ = NetworkEvent('presence-received', **event_attrs) + + # TODO: Refactor + self._update_contact(event_, properties) + + app.nec.push_incoming_event(event_) + + raise nbxmpp.NodeProcessed + + def _update_contact(self, event, properties): + jid = properties.jid.getBare() + resource = properties.jid.getResource() + + status_strings = ['offline', 'error', 'online', 'chat', 'away', + 'xa', 'dnd', 'invisible'] + + event.new_show = status_strings.index(event.show) + + # Update contact + contact_list = app.contacts.get_contacts(self._account, jid) + if not contact_list: + log.warning('No contact found') + return + + event.contact_list = contact_list + + contact = app.contacts.get_contact_strict(self._account, + properties.jid.getBare(), + properties.jid.getResource()) + if contact is None: + contact = app.contacts.get_first_contact_from_jid(self._account, jid) + if contact is None: + log.warning('First contact not found') + return + + if self._is_resource_known(contact_list) and not app.jid_is_transport(jid): + # Another resource of an existing contact connected + # Add new contact + event.old_show = 0 + contact = app.contacts.copy_contact(contact) + contact.resource = resource + app.contacts.add_contact(self._account, contact) + else: + # Convert the inital roster contact to a contact with resource + contact.resource = resource + event.old_show = status_strings.index(contact.show) + + event.need_add_in_roster = True + + elif contact.show in status_strings: + event.old_show = status_strings.index(contact.show) + + # Update contact with presence data + contact.show = event.show + contact.status = properties.status + contact.priority = properties.priority + attached_keys = app.config.get_per('accounts', self._account, + 'attached_gpg_keys').split() + if jid in attached_keys: + contact.keyID = attached_keys[attached_keys.index(jid) + 1] + else: + # Do not override assigned key + contact.keyID = event.keyID + contact.idle_time = properties.idle_timestamp + + event.contact = contact + + if not app.jid_is_transport(jid) and len(contact_list) == 1: + # It's not an agent + if event.old_show == 0 and event.new_show > 1: + if not jid in app.newly_added[self._account]: + app.newly_added[self._account].append(jid) + if jid in app.to_be_removed[self._account]: + app.to_be_removed[self._account].remove(jid) + elif event.old_show > 1 and event.new_show == 0 and \ + self._con.connected > 1: + if not jid in app.to_be_removed[self._account]: + app.to_be_removed[self._account].append(jid) + if jid in app.newly_added[self._account]: + app.newly_added[self._account].remove(jid) + + if app.jid_is_transport(jid): + return + + if properties.type.is_unavailable: + # TODO: This causes problems when another + # resource signs off! + self._con.stop_all_active_file_transfers(contact) + self._log_presence(properties) + + @staticmethod + def _is_resource_known(contact_list): + if len(contact_list) > 1: + return True + + if contact_list[0].resource == '': + return False + return contact_list[0].show not in ('not in roster', 'offline') + + def _log_presence(self, properties): + if not app.config.get('log_contact_status_changes'): + return + if not app.config.should_log(self._account, properties.jid.getBare()): + return + + # TODO: Refactor + if properties.type.is_unavailable: + show = 'offline' + else: + show = properties.show.value + + app.logger.insert_into_logs(self._account, + properties.jid.getBare(), + time.time(), + KindConstant.STATUS, + message=properties.status, + show=show) + + def _subscribe_received(self, _con, _stanza, properties): + jid = properties.jid.getBare() + fjid = str(properties.jid) - def _subscribe_received(self, _con, stanza): - from_ = stanza.getFrom() - jid = from_.getStripped() - fjid = str(from_) - status = stanza.getStatus() is_transport = app.jid_is_transport(fjid) auto_auth = app.config.get_per('accounts', self._account, 'autoauth') - user_nick = parse_nickname(stanza) - log.info('Received Subscribe: %s, transport: %s, auto_auth: %s, ' - 'user_nick: %s', from_, is_transport, auto_auth, user_nick) + log.info('Received Subscribe: %s, transport: %s, ' + 'auto_auth: %s, user_nick: %s', + properties.jid, is_transport, auto_auth, properties.nickname) + if is_transport and fjid in self._con.agent_registrations: self._con.agent_registrations[fjid]['sub_received'] = True if not self._con.agent_registrations[fjid]['roster_push']: @@ -81,8 +265,8 @@ class Presence: if auto_auth or is_transport or jid in self.jids_for_auto_auth: self.send_presence(fjid, 'subscribed') - if not status: - status = _('I would like to add you to my roster.') + status = (properties.status or + _('I would like to add you to my roster.')) app.nec.push_incoming_event(NetworkEvent( 'subscribe-presence-received', @@ -90,16 +274,15 @@ class Presence: jid=jid, fjid=fjid, status=status, - user_nick=user_nick, + user_nick=properties.nickname, is_transport=is_transport)) raise nbxmpp.NodeProcessed - def _subscribed_received(self, _con, stanza): - from_ = stanza.getFrom() - jid = from_.getStripped() - resource = from_.getResource() - log.info('Received Subscribed: %s', from_) + def _subscribed_received(self, _con, _stanza, properties): + jid = properties.jid.getBare() + resource = properties.jid.getResource() + log.info('Received Subscribed: %s', properties.jid) if jid in self.automatically_added: self.automatically_added.remove(jid) raise nbxmpp.NodeProcessed @@ -110,17 +293,15 @@ class Presence: raise nbxmpp.NodeProcessed @staticmethod - def _unsubscribe_received(_con, stanza): - log.info('Received Unsubscribe: %s', stanza.getFrom()) + def _unsubscribe_received(_con, _stanza, properties): + log.info('Received Unsubscribe: %s', properties.jid) raise nbxmpp.NodeProcessed - def _unsubscribed_received(self, _con, stanza): - from_ = stanza.getFrom() - jid = from_.getStripped() - log.info('Received Unsubscribed: %s', from_) + def _unsubscribed_received(self, _con, _stanza, properties): + log.info('Received Unsubscribed: %s', properties.jid) app.nec.push_incoming_event(NetworkEvent( 'unsubscribed-presence-received', - conn=self._con, jid=jid)) + conn=self._con, jid=properties.jid.getBare())) raise nbxmpp.NodeProcessed def subscribed(self, jid): diff --git a/gajim/common/zeroconf/connection_zeroconf.py b/gajim/common/zeroconf/connection_zeroconf.py index 081edef8c..761d3bd8d 100644 --- a/gajim/common/zeroconf/connection_zeroconf.py +++ b/gajim/common/zeroconf/connection_zeroconf.py @@ -152,7 +152,7 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): def _on_remove_service(self, jid): self.roster.delItem(jid) # 'NOTIFY' (account, (jid, status, status message, resource, priority, - # keyID, timestamp, contact_nickname)) + # keyID, timestamp)) app.nec.push_incoming_event(ZeroconfPresenceReceivedEvent( None, conn=self, fjid=jid, show='offline', status='')) diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py index b359ae0ce..360432ea2 100644 --- a/gajim/gui_interface.py +++ b/gajim/gui_interface.py @@ -331,7 +331,7 @@ class Interface: def handle_event_presence(self, obj): # 'NOTIFY' (account, (jid, status, status message, resource, - # priority, # keyID, timestamp, contact_nickname)) + # priority, # keyID, timestamp)) # # Contact changed show account = obj.conn.name diff --git a/gajim/remote_control.py b/gajim/remote_control.py index 6e682dbad..3cddf6094 100644 --- a/gajim/remote_control.py +++ b/gajim/remote_control.py @@ -366,8 +366,7 @@ class GajimRemote(Server): else: return self.raise_signal(event, (obj.conn.name, [obj.jid, obj.show, - obj.status, obj.resource, obj.prio, obj.keyID, obj.timestamp, - obj.contact_nickname])) + obj.status, obj.resource, obj.prio, obj.keyID, obj.timestamp])) def on_subscribe_presence_received(self, obj): self.raise_signal('Subscribe', (obj.conn.name, [obj.jid, obj.status, diff --git a/gajim/roster_window.py b/gajim/roster_window.py index 645443914..c4b02d43d 100644 --- a/gajim/roster_window.py +++ b/gajim/roster_window.py @@ -720,14 +720,7 @@ class RosterWindow: return if jid == app.get_jid_from_account(account): - show_self_contact = app.config.get('show_self_contact') - if show_self_contact == 'never': - return - if (contact.resource != app.connections[account].server_resource \ - and show_self_contact == 'when_other_resource') or \ - show_self_contact == 'always': - return self._add_self_contact(account) - return + return self._add_self_contact(account) is_observer = contact.is_observer() if is_observer: @@ -1871,13 +1864,13 @@ class RosterWindow: 'contacts': {}} if account not in app.groups: app.groups[account] = {} - if app.config.get('show_self_contact') == 'always': - self_jid = app.get_jid_from_account(account) - if app.connections[account].server_resource: - self_jid += '/' + app.connections[account].server_resource - array[self_jid] = {'name': app.nicks[account], - 'groups': ['self_contact'], 'subscription': 'both', - 'ask': 'none'} + + self_jid = app.get_jid_from_account(account) + if app.connections[account].server_resource: + self_jid += '/' + app.connections[account].server_resource + array[self_jid] = {'name': app.nicks[account], + 'groups': ['self_contact'], 'subscription': 'both', + 'ask': 'none'} # .keys() is needed for jid in list(array.keys()): @@ -2212,10 +2205,7 @@ class RosterWindow: elif contact.jid == app.get_jid_from_account(account) and \ show in ('offline', 'error'): - if app.config.get('show_self_contact') != 'never': - # SelfContact went offline. Remove him when last pending - # message was read - self.remove_contact(contact.jid, account, backend=True) + self.remove_contact(contact.jid, account, backend=True) uf_show = helpers.get_uf_show(show) @@ -2249,13 +2239,12 @@ class RosterWindow: if account not in app.contacts.get_accounts(): return child_iterA = self._get_account_iter(account, self.model) - if app.config.get('show_self_contact') == 'always': - self_resource = app.connections[account].server_resource - self_contact = app.contacts.get_contact(account, - app.get_jid_from_account(account), resource=self_resource) - if self_contact: - status = app.connections[account].status - self.chg_contact_status(self_contact, show, status, account) + self_resource = app.connections[account].server_resource + self_contact = app.contacts.get_contact(account, + app.get_jid_from_account(account), resource=self_resource) + if self_contact: + status = app.connections[account].status + self.chg_contact_status(self_contact, show, status, account) self.set_account_status_icon(account) if show == 'offline': if self.quit_on_next_offline > -1: @@ -2570,8 +2559,7 @@ class RosterWindow: GLib.timeout_add_seconds(5, self.remove_to_be_removed, jid, account) - if obj.need_redraw: - self.draw_contact(jid, account) + self.draw_contact(jid, account) if app.jid_is_transport(jid) and jid in jid_list: # It must be an agent @@ -2579,7 +2567,7 @@ class RosterWindow: self.draw_contact(jid, account) self.draw_group(_('Transports'), account) - if obj.contact and obj.need_redraw: + if obj.contact: self.chg_contact_status(obj.contact, obj.show, obj.status, account) if obj.popup: @@ -2598,20 +2586,20 @@ class RosterWindow: self.fire_up_unread_messages_events(obj.conn.name) else: # add self contact - if app.config.get('show_self_contact') == 'always': - account = obj.conn.name - self_jid = app.get_jid_from_account(account) - if self_jid not in app.contacts.get_jid_list(account): - resource = '' - if app.connections[account].server_resource: - resource = app.connections[account].server_resource - sha = app.config.get_per('accounts', account, 'avatar_sha') - contact = app.contacts.create_contact( - jid=self_jid, account=account, name=app.nicks[account], - groups=['self_contact'], show='offline', sub='both', - ask='none', resource=resource, avatar_sha=sha) - app.contacts.add_contact(account, contact) - self.add_contact(self_jid, account) + account = obj.conn.name + self_jid = app.get_jid_from_account(account) + if self_jid not in app.contacts.get_jid_list(account): + resource = '' + if app.connections[account].server_resource: + resource = app.connections[account].server_resource + sha = app.config.get_per('accounts', account, 'avatar_sha') + contact = app.contacts.create_contact( + jid=self_jid, account=account, name=app.nicks[account], + groups=['self_contact'], show='offline', sub='both', + ask='none', resource=resource, avatar_sha=sha) + app.contacts.add_contact(account, contact) + self.add_contact(self_jid, account) + if app.config.get('remember_opened_chat_controls'): account = obj.conn.name controls = app.config.get_per(