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:
parent
1492f2a3d7
commit
60bc78db4c
1 changed files with 27 additions and 11 deletions
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in a new issue