Adding basic avatar support
authorEd Page <eopage@byu.net>
Fri, 19 Feb 2010 03:51:15 +0000 (21:51 -0600)
committerEd Page <eopage@byu.net>
Fri, 19 Feb 2010 03:51:15 +0000 (21:51 -0600)
src/avatars.py [new file with mode: 0644]
src/connection.py

diff --git a/src/avatars.py b/src/avatars.py
new file mode 100644 (file)
index 0000000..f4ce3f4
--- /dev/null
@@ -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()
index b097993..30350ed 100644 (file)
@@ -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 = (