changeset 1341:6dbeb2ef966c frontends_multi_profiles

plugin XEP-0054: "nick" is now keeped in cache: - cache now manage different kind of data (instead of only avatar) - PeristentBinaryDict is used to keep cache (because we now store a dict, not just strings) - CACHED_DATA is a set of data kept in cache (only nick and avatar so far) - a signal update flag is put on "nick" - data in cache are reset if they are not present in cache (this avoid to keep the old value)
author Goffi <goffi@goffi.org>
date Tue, 24 Feb 2015 17:01:33 +0100
parents 91e72da1d093
children e31a07a5614d
files src/plugins/plugin_xep_0054.py
diffstat 1 files changed, 27 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0054.py	Tue Feb 24 16:54:28 2015 +0100
+++ b/src/plugins/plugin_xep_0054.py	Tue Feb 24 17:01:33 2015 +0100
@@ -36,7 +36,7 @@
 from base64 import b64decode, b64encode
 from hashlib import sha1
 from sat.core import exceptions
-from sat.memory.persistent import PersistentDict
+from sat.memory import persistent
 from PIL import Image
 from cStringIO import StringIO
 
@@ -56,6 +56,8 @@
 NS_VCARD_UPDATE = 'vcard-temp:x:update'
 VCARD_UPDATE = PRESENCE + '/x[@xmlns="' + NS_VCARD_UPDATE + '"]'
 
+CACHED_DATA = {'avatar', 'nick'}
+
 PLUGIN_INFO = {
     "name": "XEP 0054 Plugin",
     "import_name": "XEP-0054",
@@ -79,20 +81,21 @@
         self.avatar_path = os.path.join(self.host.memory.getConfig('', 'local_dir'), AVATAR_PATH)
         if not os.path.exists(self.avatar_path):
             os.makedirs(self.avatar_path)
-        self.avatars_cache = {}
+        self.cache = {}
         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.memory.setSignalOnUpdate("avatar")
+        host.memory.setSignalOnUpdate("nick")
 
     def getHandler(self, profile):
         return XEP_0054_handler(self)
 
     def presenceTrigger(self, presence_elt, client):
-        if client.jid.userhost() in self.avatars_cache[client.profile]:
+        if client.jid.userhost() in self.cache[client.profile]:
             x_elt = domish.Element((NS_VCARD_UPDATE, 'x'))
-            x_elt.addElement('photo', content=self.avatars_cache[client.profile][client.jid.userhost()])
+            x_elt.addElement('photo', content=self.cache[client.profile][client.jid.userhost()]['avatar'])
             presence_elt.addChild(x_elt)
 
         return True
@@ -102,19 +105,23 @@
         #       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
-        for jid_s, avatar_hash in self.avatars_cache[profile].iteritems():
+        for jid_s, data in self.cache[profile].iteritems():
             jid_ = jid.JID(jid_s)
-            self.host.memory.updateEntityData(jid_, "avatar", avatar_hash, silent=True, profile_key=profile)
+            for name in CACHED_DATA:
+                try:
+                    self.host.memory.updateEntityData(jid_, name, data[name], silent=True, profile_key=profile)
+                except KeyError:
+                    pass
 
     @defer.inlineCallbacks
     def profileConnecting(self, profile):
-        self.avatars_cache[profile] = PersistentDict(NS_VCARD, profile)
-        yield self.avatars_cache[profile].load()
+        self.cache[profile] = persistent.PersistentBinaryDict(NS_VCARD, profile)
+        yield self.cache[profile].load()
         self._fillCachedValues(profile)
 
     def profileDisconnected(self, profile):
         log.debug(u"Deleting profile cache for avatars")
-        del self.avatars_cache[profile]
+        del self.cache[profile]
 
     def updateCache(self, jid_, name, value, profile):
         """update cache value
@@ -127,8 +134,10 @@
         """
         assert not jid_.resource # VCard are retrieved with bare jid
         self.host.memory.updateEntityData(jid_, name, value, profile_key=profile)
-        if name == "avatar":
-            self.avatars_cache[profile][jid_.userhost()] = value
+        if name in CACHED_DATA:
+            jid_s = jid_.userhost()
+            self.cache[profile].setdefault(jid_s, {})[name] = value
+            self.cache[profile].force(jid_s)
 
     def getCache(self, entity_jid, name, profile):
         """return cached value for jid
@@ -205,6 +214,13 @@
             else:
                 log.info(_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
 
+        # if a data in cache doesn't exist anymore, we need to reset it
+        # so we check CACHED_DATA no gotten (i.e. not in dictionary keys)
+        # and we reset them
+        for datum in CACHED_DATA.difference(dictionary.keys()):
+            log.debug(u"reseting vcard datum [{datum}] for {entity}".format(datum=datum, entity=target.full()))
+            self.updateCache(target, datum, '', profile)
+
         defer.returnValue(dictionary)
 
     def _VCardCb(self, answer, profile):