comparison src/plugins/plugin_xep_0054.py @ 1682:61391d863709

plugin XEP-0054: fixed vcard-update callback which was updating avatar when hash was empty, resulting in a really slow start
author Goffi <goffi@goffi.org>
date Wed, 25 Nov 2015 20:01:39 +0100
parents 94901070478e
children 9bf1262297f2
comparison
equal deleted inserted replaced
1681:c6c835046681 1682:61391d863709
86 os.makedirs(self.avatar_path) 86 os.makedirs(self.avatar_path)
87 self.cache = {} 87 self.cache = {}
88 host.bridge.addMethod("getCard", ".plugin", in_sign='ss', out_sign='s', method=self._getCard) 88 host.bridge.addMethod("getCard", ".plugin", in_sign='ss', out_sign='s', method=self._getCard)
89 host.bridge.addMethod("getAvatarFile", ".plugin", in_sign='s', out_sign='s', method=self.getAvatarFile) 89 host.bridge.addMethod("getAvatarFile", ".plugin", in_sign='s', out_sign='s', method=self.getAvatarFile)
90 host.bridge.addMethod("setAvatar", ".plugin", in_sign='ss', out_sign='', method=self.setAvatar, async=True) 90 host.bridge.addMethod("setAvatar", ".plugin", in_sign='ss', out_sign='', method=self.setAvatar, async=True)
91 host.trigger.add("presence_available", self.presenceTrigger) 91 host.trigger.add("presence_available", self.presenceAvailableTrigger)
92 host.memory.setSignalOnUpdate("avatar") 92 host.memory.setSignalOnUpdate("avatar")
93 host.memory.setSignalOnUpdate("nick") 93 host.memory.setSignalOnUpdate("nick")
94 94
95 def getHandler(self, profile): 95 def getHandler(self, profile):
96 return XEP_0054_handler(self) 96 return XEP_0054_handler(self)
97 97
98 def presenceTrigger(self, presence_elt, client): 98 def presenceAvailableTrigger(self, presence_elt, client):
99 if client.jid.userhost() in self.cache[client.profile]: 99 if client.jid.userhost() in self.cache[client.profile]:
100 x_elt = domish.Element((NS_VCARD_UPDATE, 'x')) 100 x_elt = domish.Element((NS_VCARD_UPDATE, 'x'))
101 x_elt.addElement('photo', content=self.cache[client.profile][client.jid.userhost()]['avatar']) 101 x_elt.addElement('photo', content=self.cache[client.profile][client.jid.userhost()]['avatar'])
102 presence_elt.addChild(x_elt) 102 presence_elt.addChild(x_elt)
103 103
104 return True 104 return True
105 105
106 def _fillCachedValues(self, profile): 106 def _fillCachedValues(self, profile):
107 #FIXME: this is really suboptimal, need to be reworked 107 #FIXME: this is really suboptimal, need to be reworked
108 # the current naive approach keeps a map between all jids of all profiles 108 # the current naive approach keeps a map between all jids of all profiles
109 # in persistent cache, then put avatar 109 # in persistent cache, then put avatar hashs in memory.
110 # hashs in memory. Hashed should be shared between profiles 110 # Hashes should be shared between profiles
111 for jid_s, data in self.cache[profile].iteritems(): 111 for jid_s, data in self.cache[profile].iteritems():
112 jid_ = jid.JID(jid_s) 112 jid_ = jid.JID(jid_s)
113 for name in CACHED_DATA: 113 for name in CACHED_DATA:
114 try: 114 try:
115 self.host.memory.updateEntityData(jid_, name, data[name], silent=True, profile_key=profile) 115 self.host.memory.updateEntityData(jid_, name, data[name], silent=True, profile_key=profile)
359 @param presend(domish.Element): <presence/> stanza 359 @param presend(domish.Element): <presence/> stanza
360 """ 360 """
361 # FIXME: doesn't manage MUC correctly 361 # FIXME: doesn't manage MUC correctly
362 from_jid = jid.JID(presence['from']).userhostJID() 362 from_jid = jid.JID(presence['from']).userhostJID()
363 #FIXME: wokkel's data_form should be used here 363 #FIXME: wokkel's data_form should be used here
364 x_elem = filter(lambda x: x.name == "x", presence.elements())[0] # We only want the "x" element 364 try:
365 for elem in x_elem.elements(): 365 x_elt = presence.elements(NS_VCARD_UPDATE, 'x').next()
366 if elem.name == 'photo': 366 except StopIteration:
367 hash_ = str(elem) 367 return
368 old_avatar = self.plugin_parent.getCache(from_jid, 'avatar', self.parent.profile) 368
369 filename = self.plugin_parent._getFilename(hash_) 369 try:
370 if not old_avatar or old_avatar != hash_: 370 photo_elt = x_elt.elements(NS_VCARD_UPDATE, 'photo').next()
371 if os.path.exists(filename): 371 except StopIteration:
372 log.debug(u"New avatar found for [{}], it's already in cache, we use it".format(from_jid.full())) 372 return
373 self.plugin_parent.updateCache(from_jid, 'avatar', hash_, self.parent.profile) 373
374 else: 374 hash_ = str(photo_elt)
375 log.debug(u'New avatar found for [{}], requesting vcard'.format(from_jid.full())) 375 if not hash_:
376 self.plugin_parent.getCard(from_jid, self.parent.profile) 376 return
377 else: 377 old_avatar = self.plugin_parent.getCache(from_jid, 'avatar', self.parent.profile)
378 if os.path.exists(filename): 378 filename = self.plugin_parent._getFilename(hash_)
379 log.debug(u"avatar for {} already in cache".format(from_jid.full())) 379 if not old_avatar or old_avatar != hash_:
380 else: 380 if os.path.exists(filename):
381 log.error(u"Avatar for [{}] should be in cache but it is not ! We get it".format(from_jid.full())) 381 log.debug(u"New avatar found for [{}], it's already in cache, we use it".format(from_jid.full()))
382 self.plugin_parent.getCard(from_jid, self.parent.profile) 382 self.plugin_parent.updateCache(from_jid, 'avatar', hash_, self.parent.profile)
383 383 else:
384 log.debug(u'New avatar found for [{}], requesting vcard'.format(from_jid.full()))
385 self.plugin_parent.getCard(from_jid, self.parent.profile)
386 else:
387 if os.path.exists(filename):
388 log.debug(u"avatar for {} already in cache".format(from_jid.full()))
389 else:
390 log.error(u"Avatar for [{}] should be in cache but it is not ! We get it".format(from_jid.full()))
391 self.plugin_parent.getCard(from_jid, self.parent.profile)
392