changeset 1682:61391d863709

plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
author Goffi <goffi@goffi.org>
date Wed, 25 Nov 2015 20:01:39 +0100
parents c6c835046681
children 9bf1262297f2
files src/memory/memory.py src/plugins/plugin_xep_0054.py
diffstat 2 files changed, 35 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/memory/memory.py	Wed Nov 25 18:24:34 2015 +0100
+++ b/src/memory/memory.py	Wed Nov 25 20:01:39 2015 +0100
@@ -453,9 +453,9 @@
             raise ValueError("Empty profile name")
         if name[0] == '@':
             raise ValueError("A profile name can't start with a '@'")
-        
+
         d = self.params.asyncCreateProfile(name)
-        
+
         def initPersonalKey(dummy):
             # be sure to call this after checking that the profile doesn't exist yet
             personal_key = BlockCipher.getRandomKey(base64=True)  # generated once for all and saved in a PersistentDict
@@ -691,7 +691,7 @@
                            C.ENTITY_ALL for all entities (all resources + bare jids)
         @param key: key to set (eg: "type")
         @param value: value for this key (eg: "chatroom")
-        @param silent(bool): if True, doesn't send signal to frontend, even there is a signal flag (see setSignalOnUpdate)
+        @param silent(bool): if True, doesn't send signal to frontend, even if there is a signal flag (see setSignalOnUpdate)
         @param profile_key: %(doc_profile_key)s
         """
         profile_cache = self._getProfileCache(profile_key)
--- a/src/plugins/plugin_xep_0054.py	Wed Nov 25 18:24:34 2015 +0100
+++ b/src/plugins/plugin_xep_0054.py	Wed Nov 25 20:01:39 2015 +0100
@@ -88,14 +88,14 @@
         host.bridge.addMethod("getCard", ".plugin", in_sign='ss', out_sign='s', method=self._getCard)
         host.bridge.addMethod("getAvatarFile", ".plugin", in_sign='s', out_sign='s', method=self.getAvatarFile)
         host.bridge.addMethod("setAvatar", ".plugin", in_sign='ss', out_sign='', method=self.setAvatar, async=True)
-        host.trigger.add("presence_available", self.presenceTrigger)
+        host.trigger.add("presence_available", self.presenceAvailableTrigger)
         host.memory.setSignalOnUpdate("avatar")
         host.memory.setSignalOnUpdate("nick")
 
     def getHandler(self, profile):
         return XEP_0054_handler(self)
 
-    def presenceTrigger(self, presence_elt, client):
+    def presenceAvailableTrigger(self, presence_elt, client):
         if client.jid.userhost() in self.cache[client.profile]:
             x_elt = domish.Element((NS_VCARD_UPDATE, 'x'))
             x_elt.addElement('photo', content=self.cache[client.profile][client.jid.userhost()]['avatar'])
@@ -106,8 +106,8 @@
     def _fillCachedValues(self, profile):
         #FIXME: this is really suboptimal, need to be reworked
         #       the current naive approach keeps a map between all jids of all profiles
-        #       in persistent cache, then put avatar
-        #       hashs in memory. Hashed should be shared between profiles
+        #       in persistent cache, then put avatar hashs in memory.
+        #       Hashes should be shared between profiles
         for jid_s, data in self.cache[profile].iteritems():
             jid_ = jid.JID(jid_s)
             for name in CACHED_DATA:
@@ -361,23 +361,32 @@
         # FIXME: doesn't manage MUC correctly
         from_jid = jid.JID(presence['from']).userhostJID()
         #FIXME: wokkel's data_form should be used here
-        x_elem = filter(lambda x: x.name == "x", presence.elements())[0]  # We only want the "x" element
-        for elem in x_elem.elements():
-            if elem.name == 'photo':
-                hash_ = str(elem)
-                old_avatar = self.plugin_parent.getCache(from_jid, 'avatar', self.parent.profile)
-                filename = self.plugin_parent._getFilename(hash_)
-                if not old_avatar or old_avatar != hash_:
-                    if os.path.exists(filename):
-                        log.debug(u"New avatar found for [{}], it's already in cache, we use it".format(from_jid.full()))
-                        self.plugin_parent.updateCache(from_jid, 'avatar', hash_, self.parent.profile)
-                    else:
-                        log.debug(u'New avatar found for [{}], requesting vcard'.format(from_jid.full()))
-                        self.plugin_parent.getCard(from_jid, self.parent.profile)
-                else:
-                    if os.path.exists(filename):
-                        log.debug(u"avatar for {} already in cache".format(from_jid.full()))
-                    else:
-                        log.error(u"Avatar for [{}] should be in cache but it is not ! We get it".format(from_jid.full()))
-                        self.plugin_parent.getCard(from_jid, self.parent.profile)
+        try:
+            x_elt = presence.elements(NS_VCARD_UPDATE, 'x').next()
+        except StopIteration:
+            return
+
+        try:
+            photo_elt = x_elt.elements(NS_VCARD_UPDATE, 'photo').next()
+        except StopIteration:
+            return
 
+        hash_ = str(photo_elt)
+        if not hash_:
+            return
+        old_avatar = self.plugin_parent.getCache(from_jid, 'avatar', self.parent.profile)
+        filename = self.plugin_parent._getFilename(hash_)
+        if not old_avatar or old_avatar != hash_:
+            if os.path.exists(filename):
+                log.debug(u"New avatar found for [{}], it's already in cache, we use it".format(from_jid.full()))
+                self.plugin_parent.updateCache(from_jid, 'avatar', hash_, self.parent.profile)
+            else:
+                log.debug(u'New avatar found for [{}], requesting vcard'.format(from_jid.full()))
+                self.plugin_parent.getCard(from_jid, self.parent.profile)
+        else:
+            if os.path.exists(filename):
+                log.debug(u"avatar for {} already in cache".format(from_jid.full()))
+            else:
+                log.error(u"Avatar for [{}] should be in cache but it is not ! We get it".format(from_jid.full()))
+                self.plugin_parent.getCard(from_jid, self.parent.profile)
+