core, quick frontend, plugin xep-0054, bridge: use of memory's entities data for vcard:

- bridge: new bridge method getEntityData and signal entityDataUpdated
	- core: entityDataUpdated signal sent on new string data
	- quick frontend: fixed avatars/vcard infos, fixed _replace in quick_contact_list
	- plugin xep-0054: dropped updatedValue signal, use entities data instead
This commit is contained in:
Goffi 2012-09-26 01:23:56 +02:00
commit 0f6de78a3b

View file

@ -20,11 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from logging import debug, info, error
from twisted.words.xish import domish
from twisted.internet import protocol, defer, threads, reactor
from twisted.internet import threads
from twisted.internet.defer import inlineCallbacks, returnValue
from twisted.words.protocols.jabber import client, jid, xmlstream
from twisted.words.protocols.jabber import error as jab_error
from twisted.words.protocols.jabber import jid
from twisted.words.protocols.jabber.xmlstream import IQ
import os.path
@ -34,8 +32,7 @@ from wokkel import disco, iwokkel
from base64 import b64decode
from hashlib import sha1
from time import sleep
from sat.memory.persistent import PersistentBinaryDict
from sat.core import exceptions
try:
from twisted.words.protocols.xmlstream import XMPPHandler
@ -64,6 +61,9 @@ PLUGIN_INFO = {
}
class XEP_0054():
#TODO: - check that nickname is ok
# - refactor the code/better use of Wokkel
# - get missing values
def __init__(self, host):
info(_("Plugin XEP_0054 initialization"))
@ -73,7 +73,6 @@ class XEP_0054():
os.makedirs(self.avatar_path)
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("getCardCache", ".plugin", in_sign='ss', out_sign='a{ss}', method=self.getCardCache)
def getHandler(self, profile):
return XEP_0054_handler(self)
@ -81,35 +80,29 @@ class XEP_0054():
def update_cache(self, jid, name, value, profile):
"""update cache value
- save value in memory in case of change
- send updatedValue signal if the value is new or updated
@param jid: jid of the owner of the vcard
@param name: name of the item which changed
@param value: new value of the item
@param profile: profile which received the update
"""
client = self.host.getClient(profile)
if not jid.userhost() in client._vcard_cache:
client._vcard_cache[jid.userhost()] = {}
cache = client._vcard_cache[jid.userhost()]
old_value = cache[name] if name in cache else None
if not old_value or value != old_value:
cache[name] = value
client._vcard_cache.force(jid.userhost()) #we force saving of data to storage
self.host.bridge.updatedValue('card_'+name, {'jid':jid.userhost(), name:value}, profile)
try:
cached = self.host.memory.getEntityData(jid, [name], profile)
except exceptions.UnknownEntityError:
cached = {}
if not name in cached or cached[name] != value:
self.host.memory.updateEntityData(jid, name, value, profile)
def get_cache(self, jid, name, profile):
"""return cached value for jid
@param jid: target contact
@param name: name of the value ('nick' or 'avatar')
@param profile: %(doc_profile)s
@return: wanted value or None"""
client = self.host.getClient(profile)
try:
return client._vcard_cache[jid.userhost()][name]
except KeyError:
data = self.host.memory.getEntityData(jid, [name], profile)
except exceptions.UnknownEntityError:
return None
return data.get(name)
def save_photo(self, photo_xml):
"""Parse a <PHOTO> elem and save the picture"""
@ -134,7 +127,6 @@ class XEP_0054():
"""Convert a VCard to a dict, and save binaries"""
debug (_("parsing vcard"))
dictionary = {}
d = defer.Deferred()
for elem in vcard.elements():
if elem.name == 'FN':
@ -189,7 +181,7 @@ class XEP_0054():
reg_request=IQ(xmlstream,'get')
reg_request["from"]=current_jid.full()
reg_request["to"] = to_jid.userhost()
query=reg_request.addElement('vCard', NS_VCARD)
reg_request.addElement('vCard', NS_VCARD)
reg_request.send(to_jid.userhost()).addCallbacks(self.vcard_ok, self.vcard_err, [profile])
return reg_request["id"]
@ -204,27 +196,6 @@ class XEP_0054():
return ""
return filename
def getCardCache(self, target, profile_key):
"""Request for cached values of profile
return the cached nickname and avatar if exists, else get VCard
@param target: target's jid
@param profile_key: %(doc_profile_key)s
"""
profile = self.host.memory.getProfileName(profile_key)
if not profile:
error(_("Profile not found"))
return {}
to_jid = jid.JID(target)
result = {}
nick = self.get_cache(to_jid, 'nick', profile)
if nick:
result['nick'] = nick
avatar = self.get_cache(to_jid, 'avatar', profile)
if avatar:
result['avatar'] = avatar
return result
class XEP_0054_handler(XMPPHandler):
implements(iwokkel.IDisco)
@ -234,8 +205,6 @@ class XEP_0054_handler(XMPPHandler):
self.host = plugin_parent.host
def connectionInitialized(self):
self.parent._vcard_cache = PersistentBinaryDict(NS_VCARD, self.parent.profile)
self.parent._vcard_cache.load()
self.xmlstream.addObserver(VCARD_UPDATE, self.update)
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):