diff --git a/services/presence2/buddy.py b/services/presence2/buddy.py index f9946b5d..458d1247 100644 --- a/services/presence2/buddy.py +++ b/services/presence2/buddy.py @@ -71,6 +71,7 @@ class Buddy(DBusGObject): self._valid = False self._owner = False self._key = None + self._icon = '' gobject.GObject.__init__(self, **kwargs) if not self._key: diff --git a/services/presence2/buddyiconcache.py b/services/presence2/buddyiconcache.py index b11ddd5b..80c6813e 100644 --- a/services/presence2/buddyiconcache.py +++ b/services/presence2/buddyiconcache.py @@ -29,19 +29,21 @@ class BuddyIconCache(object): if not os.path.exists(self._cachepath): self._cache = {} + # md5 and server token of the last avatar uploaded + self._md5 = '' + self._token = '' else: self._load_cache() def _load_cache(self): try: - self._cache = cPickle.load(open(self._cachepath, "r")) + self._cache, self._md5, self._token = cPickle.load(open(self._cachepath, "r")) except: - self._cache = {} - + self._cache, self._md5, self._token = {}, '', '' def _save_cache(self): out = open(self._cachepath, "w") - cPickle.dump(self._cache, out, protocol=2) + cPickle.dump((self._cache, self._md5, self._token), out, protocol=2) def get_icon(self, jid, token): hit = self._cache.get(jid) @@ -57,6 +59,14 @@ class BuddyIconCache(object): self._cache[jid] = (token, data) self._save_cache() + def check_avatar(self, md5, token): + return self._md5 == md5 and self._token == token + + def set_avatar(self, md5, token): + self._md5 = md5 + self._token = token + self._save_cache() + if __name__ == "__main__": my_cache = BuddyIconCache() @@ -76,3 +86,17 @@ if __name__ == "__main__": # the icon in the cache is not valid now icon = my_cache.get_icon("test@olpc.collabora.co.uk", "aaaa") print icon + + + my_avatar_md5 = "111" + my_avatar_token = "222" + + if not my_cache.check_avatar(my_avatar_md5, my_avatar_token): + # upload of the new avatar + print "upload of the new avatar" + my_cache.set_avatar(my_avatar_md5, my_avatar_token) + else: + print "No need to upload the new avatar" + + if my_cache.check_avatar(my_avatar_md5, my_avatar_token): + print "No need to upload the new avatar" diff --git a/services/presence2/server_plugin.py b/services/presence2/server_plugin.py index a0c03b85..056ede97 100644 --- a/services/presence2/server_plugin.py +++ b/services/presence2/server_plugin.py @@ -24,6 +24,7 @@ import gtk from buddyiconcache import BuddyIconCache import logging import os +import hashlib from telepathy.client import ConnectionManager, ManagerRegistry, Connection, Channel from telepathy.interfaces import ( @@ -222,6 +223,31 @@ class ServerPlugin(gobject.GObject): # Request presence for everyone on the channel self._conn[CONN_INTERFACE_PRESENCE].GetPresence(subscribe_handles) + def _upload_avatar(self): + icon = os.path.join(env.get_profile_path(), "buddy-icon.jpg") + md5 = hashlib.md5() + md5.update(open(icon).read()) + hash = md5.hexdigest() + + self_handle = self._conn[CONN_INTERFACE].GetSelfHandle() + token = self._conn[CONN_INTERFACE_AVATARS].GetAvatarTokens([self_handle])[0] + + if self._icon_cache.check_avatar(hash, token): + # avatar is up to date + return + + types, minw, minh, maxw, maxh, maxsize = self._conn[CONN_INTERFACE_AVATARS].GetAvatarRequirements() + if not "image/jpeg" in types: + print "server does not accept JPEG format avatars." + return + + try: + img_data = _get_buddy_icon_at_size(min(maxw, 96), min(maxh, 96), maxsize) + token = self._conn[CONN_INTERFACE_AVATARS].SetAvatar(img_data, "image/jpeg") + self._icon_cache.set_avatar(hash, token) + except RuntimeError, e: + pass + def _set_self_buddy_info(self): # Set our OLPC buddy properties props = {} @@ -237,18 +263,7 @@ class ServerPlugin(gobject.GObject): self_handle = self._conn[CONN_INTERFACE].GetSelfHandle() self._conn[CONN_INTERFACE_ALIASING].SetAliases( {self_handle : name} ) - types, minw, minh, maxw, maxh, maxsize = self._conn[CONN_INTERFACE_AVATARS].GetAvatarRequirements() - if not "image/jpeg" in types: - print "server does not accept JPEG format avatars." - return - - # FIXME: check server avatar token and only upload if we know our - # buddy icon has changed - try: - img_data = _get_buddy_icon_at_size(min(maxw, 96), min(maxh, 96), maxsize) - self._conn[CONN_INTERFACE_AVATARS].SetAvatar(img_data, "image/jpeg") - except RuntimeError, e: - pass + self._upload_avatar() def _status_changed_cb(self, state, reason): if state == CONNECTION_STATUS_CONNECTING: