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)
This commit is contained in:
Goffi 2015-02-24 17:01:33 +01:00
commit 60bc78db4c

View file

@ -36,7 +36,7 @@ from wokkel import disco, iwokkel
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 @@ PRESENCE = '/presence'
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 @@ class XEP_0054(object):
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 @@ class XEP_0054(object):
# 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 @@ class XEP_0054(object):
"""
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 @@ class XEP_0054(object):
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):