[Git][gajim/gajim][master] 3 commits: Remove old PEP code

Philipp Hörist gitlab at dev.gajim.org
Wed Jan 2 02:11:01 CET 2019


Philipp Hörist pushed to branch master at gajim / gajim


Commits:
608607b7 by Philipp Hörist at 2018-12-31T09:54:51Z
Remove old PEP code

- - - - -
a289ad5f by Philipp Hörist at 2019-01-02T01:04:42Z
Refactor Presence

- Remove option to hide self contacts for now. This makes the code less
complicated.
- Move as much code as possible into the presence module
- Use nbxmpp properties

- - - - -
f2beea0d by Philipp Hörist at 2019-01-02T01:04:54Z
Refactor Caps module

- - - - -


12 changed files:

- gajim/common/config.py
- gajim/common/connection_handlers.py
- gajim/common/connection_handlers_events.py
- gajim/common/contacts.py
- gajim/common/modules/caps.py
- gajim/common/modules/pep.py
- gajim/common/modules/presence.py
- − gajim/common/pep.py
- gajim/common/zeroconf/connection_zeroconf.py
- gajim/gui_interface.py
- gajim/remote_control.py
- gajim/roster_window.py


Changes:

=====================================
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'],


=====================================
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:


=====================================
gajim/common/connection_handlers_events.py
=====================================
@@ -33,7 +33,6 @@ from gajim.common.modules import dataforms
 from gajim.common.modules.misc import parse_idle
 from gajim.common.modules.misc import parse_delay
 from gajim.common.const import KindConstant, SSLError
-from gajim.common.pep import SUPPORTED_PERSONAL_USER_EVENTS
 from gajim.common.jingle_transport import JingleTransportSocks5
 from gajim.common.file_props import FilesProp
 
@@ -145,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'
@@ -255,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 ?
@@ -429,30 +328,6 @@ class GPGPasswordRequiredEvent(nec.NetworkIncomingEvent):
         self.keyid = app.config.get_per('accounts', self.conn.name, 'keyid')
         return True
 
-class PEPReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
-    name = 'pep-received'
-
-    def generate(self):
-        if not self.stanza.getTag('event'):
-            return
-        if self.stanza.getTag('error'):
-            log.debug('PEPReceivedEvent received error stanza. Ignoring')
-            return
-
-        try:
-            self.get_jid_resource()
-        except Exception:
-            return
-
-        self.event_tag = self.stanza.getTag('event')
-
-        for pep_class in SUPPORTED_PERSONAL_USER_EVENTS:
-            pep = pep_class.get_tag_as_PEP(self.fjid, self.conn.name,
-                self.event_tag)
-            if pep:
-                self.pep_type = pep.type_
-                return True
-
 class PlainConnectionEvent(nec.NetworkIncomingEvent):
     name = 'plain-connection'
 


=====================================
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 ###


=====================================
gajim/common/modules/caps.py
=====================================
@@ -1,4 +1,5 @@
 # Copyright (C) 2009 Stephan Erb <steve-e AT h3c.de>
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
 #
 # This file is part of Gajim.
 #
@@ -19,12 +20,11 @@
 import logging
 
 import nbxmpp
+from nbxmpp.structs import StanzaHandler
 
 from gajim.common import caps_cache
 from gajim.common import app
 from gajim.common.nec import NetworkEvent
-from gajim.common.modules.presence import parse_show
-from gajim.common.modules.presence import parse_type
 
 log = logging.getLogger('gajim.c.m.caps')
 
@@ -35,69 +35,50 @@ class Caps:
         self._account = con.name
 
         self.handlers = [
-            ('presence', self._presence_received, '', nbxmpp.NS_CAPS)
+            StanzaHandler(name='presence',
+                          callback=self._entity_caps,
+                          ns=nbxmpp.NS_CAPS,
+                          priority=45),
         ]
 
         self._capscache = caps_cache.capscache
         self._create_suitable_client_caps = caps_cache.create_suitable_client_caps
 
-    def _presence_received(self, _con, stanza):
-        if stanza.getType() in ('unavailable', 'error'):
+    def _entity_caps(self, _con, _stanza, properties):
+        if properties.type.is_error or properties.type.is_unavailable:
             return
 
-        from_ = stanza.getFrom()
-        if from_ is None:
-            # Presence from ourself
+        if properties.is_self_presence:
             return
-        full_jid = str(from_)
 
-        hash_method = node = caps_hash = None
+        jid = str(properties.jid)
 
-        caps = stanza.getTag('c', namespace=nbxmpp.NS_CAPS)
-        if caps is not None:
-            hash_method = caps['hash']
-            node = caps['node']
-            caps_hash = caps['ver']
-
-        show = parse_show(stanza)
-        type_ = parse_type(stanza)
+        hash_method = properties.entity_caps.hash
+        node = properties.entity_caps.node
+        caps_hash = properties.entity_caps.ver
 
         log.info('Received from %s, type: %s, method: %s, node: %s, hash: %s',
-                 from_, stanza.getType(), hash_method, node, caps_hash)
+                 jid, properties.type, hash_method, node, caps_hash)
 
         client_caps = self._create_suitable_client_caps(
-            node, caps_hash, hash_method, full_jid)
+            node, caps_hash, hash_method, jid)
 
         # Type is None means 'available'
-        if stanza.getType() is None and client_caps._hash_method == 'no':
+        if properties.type.is_available and client_caps._hash_method == 'no':
             self._capscache.forget_caps(client_caps)
             client_caps = self._create_suitable_client_caps(
                 node, caps_hash, hash_method)
         else:
             self._capscache.query_client_of_jid_if_unknown(
-                self._con, full_jid, client_caps)
+                self._con, jid, client_caps)
 
-        self._update_client_caps_of_contact(from_, client_caps)
+        self._update_client_caps_of_contact(properties.jid, client_caps)
 
-        # Event is only used by ClientIcons Plugin
         app.nec.push_incoming_event(
-            NetworkEvent('caps-presence-received',
+            NetworkEvent('caps-update',
                          conn=self._con,
-                         fjid=full_jid,
-                         jid=from_.getStripped(),
-                         resource=from_.getResource(),
-                         hash_method=hash_method,
-                         node=node,
-                         caps_hash=caps_hash,
-                         client_caps=client_caps,
-                         show=show,
-                         ptype=type_,
-                         stanza=stanza))
-
-        app.nec.push_incoming_event(NetworkEvent('caps-update',
-                                                 conn=self._con,
-                                                 fjid=full_jid,
-                                                 jid=from_.getStripped()))
+                         fjid=jid,
+                         jid=properties.jid.getBare()))
 
     def _update_client_caps_of_contact(self, from_, client_caps):
         contact = self._get_contact_or_gc_contact_for_jid(from_)


=====================================
gajim/common/modules/pep.py
=====================================
@@ -93,27 +93,23 @@ class PEP:
 
         handlers = self._pep_handlers.get(namespace, None)
         if handlers is None:
-            # Old Fallback
-            from gajim.common.connection_handlers_events import PEPReceivedEvent as OldPEPReceivedEvent
-            app.nec.push_incoming_event(
-                OldPEPReceivedEvent(None, conn=self._con, stanza=stanza))
             raise nbxmpp.NodeProcessed
-        else:
-            # Check if this is a retraction
-            retract = items.getTag('retract')
-            if retract is not None:
-                id_ = retract.getAttr('id')
-                log.info('Received retract of id: %s', id_)
-                raise nbxmpp.NodeProcessed
-
-            # Check if we have items
-            items_ = items.getTags('item')
-            if items_ is None:
-                log.warning('Malformed PEP event received: %s', stanza)
-                raise nbxmpp.NodeProcessed
-            for handler in handlers:
-                handler(jid, items_[0])
-                raise nbxmpp.NodeProcessed
+
+        # Check if this is a retraction
+        retract = items.getTag('retract')
+        if retract is not None:
+            id_ = retract.getAttr('id')
+            log.info('Received retract of id: %s', id_)
+            raise nbxmpp.NodeProcessed
+
+        # Check if we have items
+        items_ = items.getTags('item')
+        if items_ is None:
+            log.warning('Malformed PEP event received: %s', stanza)
+            raise nbxmpp.NodeProcessed
+        for handler in handlers:
+            handler(jid, items_[0])
+            raise nbxmpp.NodeProcessed
 
     def send_stored_publish(self) -> None:
         for module in self._store_publish_modules:


=====================================
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
+
+        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)
+
+        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
 
-        log.info('Received from %s', stanza.getFrom())
-        if nbxmpp.isErrorNode(stanza):
-            log.info('Error:\n%s', stanza)
+        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
 
-        app.nec.push_incoming_event(
-            NetworkEvent('raw-pres-received',
-                         conn=self._con,
-                         stanza=stanza))
+        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):
@@ -208,34 +389,5 @@ class Presence:
         self._con.connection.send(presence)
 
 
-def parse_show(stanza):
-    show = stanza.getShow()
-    type_ = parse_type(stanza)
-    if show is None and type_ is None:
-        return 'online'
-
-    if type_ == 'unavailable':
-        return 'offline'
-
-    if show not in (None, 'chat', 'away', 'xa', 'dnd'):
-        log.warning('Invalid show element: %s', stanza)
-        if type_ is None:
-            return 'online'
-        return 'offline'
-
-    if show is None:
-        return 'online'
-    return show
-
-
-def parse_type(stanza):
-    type_ = stanza.getType()
-    if type_ not in (None, 'unavailable', 'error', 'subscribe',
-                     'subscribed', 'unsubscribe', 'unsubscribed'):
-        log.warning('Invalid type: %s', stanza)
-        return None
-    return type_
-
-
 def get_instance(*args, **kwargs):
     return Presence(*args, **kwargs), 'Presence'


=====================================
gajim/common/pep.py deleted
=====================================
@@ -1,81 +0,0 @@
-# Copyright (C) 2007 Piotr Gaczkowski <doomhammerng AT gmail.com>
-# Copyright (C) 2007-2014 Yann Leboulanger <asterix AT lagaule.org>
-# Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com>
-#                    Jean-Marie Traissard <jim AT lapin.org>
-#                    Jonathan Schleifer <js-common.gajim AT webkeks.org>
-#                    Stephan Erb <steve-e AT h3c.de>
-#
-# 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/>.
-
-from typing import Any  # pylint: disable=unused-import
-from typing import List  # pylint: disable=unused-import
-
-import logging
-
-from gajim.common import app
-
-log = logging.getLogger('gajim.c.pep')
-
-class AbstractPEP:
-
-    type_ = ''
-    namespace = ''
-
-    @classmethod
-    def get_tag_as_PEP(cls, jid, account, event_tag):
-        items = event_tag.getTag('items', {'node': cls.namespace})
-        if items:
-            log.debug('Received PEP "user %s" from %s', cls.type_, jid)
-            return cls(jid, account, items)
-        return None
-
-    def __init__(self, jid, account, items):
-        self.data, self._retracted = self._extract_info(items)
-
-        self._update_contacts(jid, account)
-        if jid == app.get_jid_from_account(account):
-            self._update_account(account)
-        self._on_receive(jid, account)
-
-    def _extract_info(self, items):
-        '''To be implemented by subclasses'''
-        raise NotImplementedError
-
-    def _update_contacts(self, jid, account):
-        for contact in app.contacts.get_contacts(account, jid):
-            if self._retracted:
-                if self.type_ in contact.pep:
-                    del contact.pep[self.type_]
-            else:
-                contact.pep[self.type_] = self
-
-    def _update_account(self, account):
-        acc = app.connections[account]
-        if self._retracted:
-            if self.type_ in acc.pep:
-                del acc.pep[self.type_]
-        else:
-            acc.pep[self.type_] = self
-
-    def as_markup_text(self):
-        '''SHOULD be implemented by subclasses'''
-        return ''
-
-    def _on_receive(self, jid, account):
-        '''SHOULD be implemented by subclasses'''
-        pass
-
-
-SUPPORTED_PERSONAL_USER_EVENTS = []  # type: List[Any]


=====================================
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=''))
 


=====================================
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


=====================================
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,


=====================================
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(



View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/a7aea4cac1fc0439ad5b1d56751d8d0dfaf4666d...f2beea0df398be1b598b024ad657af65d005f7c4

-- 
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/a7aea4cac1fc0439ad5b1d56751d8d0dfaf4666d...f2beea0df398be1b598b024ad657af65d005f7c4
You're receiving this email because of your account on dev.gajim.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.gajim.org/pipermail/commits/attachments/20190102/64f99543/attachment-0001.html>


More information about the Commits mailing list