plugin XEP-0054: naive approach to have a persistent cache of avatars

This commit is contained in:
Goffi 2012-11-22 00:46:49 +01:00
commit 17a7c62123

View file

@ -33,6 +33,7 @@ from wokkel import disco, iwokkel
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 @@ class XEP_0054():
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 @@ class XEP_0054():
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 @@ class XEP_0054_handler(XMPPHandler):
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)