From 2c32f0f706b57475a70eae47e5750c52d2dfbda8 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 18 Feb 2010 21:51:15 -0600 Subject: [PATCH] Adding basic avatar support --- src/avatars.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/connection.py | 27 ++++++------ 2 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 src/avatars.py diff --git a/src/avatars.py b/src/avatars.py new file mode 100644 index 0000000..f4ce3f4 --- /dev/null +++ b/src/avatars.py @@ -0,0 +1,124 @@ +from __future__ import with_statement + +import os +import logging + +import telepathy + +import tp +import util.misc as misc_utils + + +_moduleLogger = logging.getLogger('avatars') + + +class AvatarsMixin(tp.server.ConnectionInterfaceAvatars): + + __SELF_AVATAR = "tor_self" + __MOBILE_AVATAR = "tor_handset" + __LANDLINE_AVATAR = "tor_phone" + __OTHER_AVATAR = "tor_question" + + __LOOKUP_PATHS = ( + "/usr/share/theonering", + os.path.join(os.path.dirname(__file__), "../support/icons"), + ) + + def __init__(self): + tp.server.ConnectionInterfaceAvatars.__init__(self) + + self._implement_property_get( + telepathy.interfaces.CONNECTION_INTERFACE_AVATARS, + { + 'SupportedAvatarMimeTypes': lambda: ("image/png", ), + 'MinimumAvatarHeight': lambda: 32, + 'MinimumAvatarWidth': lambda: 32, + 'RecommendedAvatarHeight': lambda: 32, + 'RecommendedAvatarWidth': lambda: 32, + 'MaximumAvatarHeight': lambda: 32, + 'MaximumAvatarWidth': lambda: 32, + 'MaximumAvatarBytes': lambda: 500 * 1024, + }, + ) + + @property + def session(self): + """ + @abstract + """ + raise NotImplementedError("Abstract property called") + + def get_handle_by_id(self, handleType, handleId): + """ + @abstract + """ + raise NotImplementedError("Abstract function called") + + @misc_utils.log_exception(_moduleLogger) + def GetAvatarRequirements(self): + mime_types = ("image/png", ) + return (mime_types, 32, 32, 64, 64, 500 * 1024) + + @misc_utils.log_exception(_moduleLogger) + def GetAvatarTokens(self, contacts): + result = {} + for handleid in contacts: + imageName = self._select_avatar(handleid) + result[handleid] = imageName + return result + + @misc_utils.log_exception(_moduleLogger) + def GetKnownAvatarTokens(self, contacts): + result = {} + for handleid in contacts: + imageName = self._select_avatar(handleid) + result[handleid] = imageName + return result + + @misc_utils.log_exception(_moduleLogger) + def RequestAvatar(self, contact): + imageName = self._select_avatar(contact) + image = self._load_avatar(imageName) + return image, "image/png" + + @misc_utils.log_exception(_moduleLogger) + def RequestAvatars(self, contacts): + for handleid in contacts: + imageName = self._select_avatar(handleid) + image = self._load_avatar(imageName) + self.AvatarRetrieved(handleid, imageName, image, "image/png") + + @misc_utils.log_exception(_moduleLogger) + def SetAvatar(self, avatar, mime_type): + raise telepathy.errors.PermissionDenied + + @misc_utils.log_exception(_moduleLogger) + def ClearAvatar(self): + pass + + def _select_avatar(self, handleId): + handle = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId) + + if handle == self.GetSelfHandle(): + imageName = self.__SELF_AVATAR + else: + accountNumber = misc_utils.normalize_number(self.session.backend.get_account_number()) + phoneType = self.session.addressbook.get_phone_type(handle.phoneNumber) + if handle.phoneNumber == accountNumber: + imageName = self.__SELF_AVATAR + elif phoneType in ("mobile", ): + imageName = self.__MOBILE_AVATAR + elif phoneType in ("home", "work"): + imageName = self.__LANDLINE_AVATAR + else: + imageName = self.__OTHER_AVATAR + + return imageName + + def _load_avatar(self, imageName): + try: + with open(os.sep.join([self.__LOOKUP_PATHS[0], imageName+".png"]), "rb") as f: + return f.read() + except IOError: + with open(os.sep.join([self.__LOOKUP_PATHS[1], "32-"+imageName+".png"]), "rb") as f: + return f.read() diff --git a/src/connection.py b/src/connection.py index b097993..30350ed 100644 --- a/src/connection.py +++ b/src/connection.py @@ -12,12 +12,13 @@ import util.misc as misc_utils import gvoice import handle -import requests -import contacts import aliasing -import simple_presence -import presence +import avatars import capabilities +import contacts +import presence +import requests +import simple_presence import autogv import channel_manager @@ -50,12 +51,13 @@ class TheOneRingOptions(object): class TheOneRingConnection( tp.Connection, - requests.RequestsMixin, - contacts.ContactsMixin, aliasing.AliasingMixin, - simple_presence.SimplePresenceMixin, - presence.PresenceMixin, + avatars.AvatarsMixin, capabilities.CapabilitiesMixin, + contacts.ContactsMixin, + presence.PresenceMixin, + requests.RequestsMixin, + simple_presence.SimplePresenceMixin, ): # overiding base class variable @@ -108,12 +110,13 @@ class TheOneRingConnection( account, constants._telepathy_implementation_name_ ) - requests.RequestsMixin.__init__(self) - contacts.ContactsMixin.__init__(self) aliasing.AliasingMixin.__init__(self) - simple_presence.SimplePresenceMixin.__init__(self) - presence.PresenceMixin.__init__(self) + avatars.AvatarsMixin.__init__(self) capabilities.CapabilitiesMixin.__init__(self) + contacts.ContactsMixin.__init__(self) + presence.PresenceMixin.__init__(self) + requests.RequestsMixin.__init__(self) + simple_presence.SimplePresenceMixin.__init__(self) self.__manager = weakref.proxy(manager) self.__credentials = ( -- 1.7.9.5