# HG changeset patch # User Goffi # Date 1448478099 -3600 # Node ID 61391d8637097fafba3bd2201ed7955778724ae8 # Parent c6c8350466813a9c838bfb39d447fd95a9e643f1 plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start diff -r c6c835046681 -r 61391d863709 src/memory/memory.py --- 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) diff -r c6c835046681 -r 61391d863709 src/plugins/plugin_xep_0054.py --- 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) +