changeset 551:dcec4ba8e72c

plugin XEP-0054: naive approach to have a persistent cache of avatars
author Goffi <goffi@goffi.org>
date Thu, 22 Nov 2012 00:46:49 +0100
parents f25eef861b43
children 6970ab58b020
files src/plugins/plugin_xep_0054.py
diffstat 1 files changed, 21 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/plugin_xep_0054.py	Thu Nov 22 00:46:00 2012 +0100
+++ b/src/plugins/plugin_xep_0054.py	Thu Nov 22 00:46:49 2012 +0100
@@ -33,6 +33,7 @@
 from base64 import b64decode
 from hashlib import sha1
 from sat.core import exceptions
+from sat.memory.persistent import PersistentDict
 
 try:
     from twisted.words.protocols.xmlstream import XMPPHandler
@@ -71,12 +72,27 @@
         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 = PersistentDict(NS_VCARD)
+        self.avatars_cache.load() #FIXME: resulting deferred must be correctly managed
         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)
 
     def getHandler(self, profile):
         return XEP_0054_handler(self)  
-   
+  
+    def _fillCachedValues(self, result, client):
+        #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, and check if cached jid are in roster, then put avatar
+        #       hashs in memory.
+        for _jid in client.roster.getBareJids():
+            if _jid in self.avatars_cache:
+                self.host.memory.updateEntityData(jid.JID(_jid), "avatar", self.avatars_cache[_jid], client.profile)
+        
+    def profileConnected(self, profile):
+        client = self.host.getClient(profile)
+        client.roster.got_roster.addCallback(self._fillCachedValues, client)
+    
     def update_cache(self, jid, name, value, profile):
         """update cache value
         - save value in memory in case of change
@@ -91,6 +107,8 @@
             cached = {}
         if not name in cached or cached[name] != value:
             self.host.memory.updateEntityData(jid, name, value, profile)
+            if name == "avatar":
+                self.avatars_cache[jid.userhost()] = value
             
     def get_cache(self, jid, name, profile):
         """return cached value for jid
@@ -222,8 +240,8 @@
         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)
+                _hash = str(elem)
                 old_avatar = self.plugin_parent.get_cache(from_jid, 'avatar', self.parent.profile)
-                if not old_avatar or old_avatar != hash:
+                if not old_avatar or old_avatar != _hash:
                     debug(_('New avatar found, requesting vcard'))
                     self.plugin_parent.getCard(from_jid.userhost(), self.parent.profile)