Imitiating buttfly in being explicitly typed
[theonering] / src / aliasing.py
index 9d76629..8476e9c 100644 (file)
@@ -1,12 +1,42 @@
 import logging
 
+import dbus
 import telepathy
 
-import gtk_toolbox
+import tp
+import util.misc as misc_utils
 import handle
 
 
-_moduleLogger = logging.getLogger('aliasing')
+_moduleLogger = logging.getLogger(__name__)
+
+
+def _make_pretty_with_areacode(phonenumber):
+       prettynumber = "(%s)" % (phonenumber[0:3], )
+       if 3 < len(phonenumber):
+               prettynumber += " %s" % (phonenumber[3:6], )
+               if 6 < len(phonenumber):
+                       prettynumber += "-%s" % (phonenumber[6:], )
+       return prettynumber
+
+
+def _make_pretty_local(phonenumber):
+       prettynumber = "%s" % (phonenumber[0:3], )
+       if 3 < len(phonenumber):
+               prettynumber += "-%s" % (phonenumber[3:], )
+       return prettynumber
+
+
+def _make_pretty_international(phonenumber):
+       prettynumber = phonenumber
+       if phonenumber.startswith("0"):
+               prettynumber = "+%s " % (phonenumber[0:3], )
+               if 3 < len(phonenumber):
+                       prettynumber += _make_pretty_with_areacode(phonenumber[3:])
+       elif phonenumber.startswith("1"):
+               prettynumber = "1 "
+               prettynumber += _make_pretty_with_areacode(phonenumber[1:])
+       return prettynumber
 
 
 def make_pretty(phonenumber):
@@ -26,43 +56,44 @@ def make_pretty(phonenumber):
        >>> make_pretty("1234567")
        '123-4567'
        >>> make_pretty("2345678901")
-       '(234)-567-8901'
+       '+1 (234) 567-8901'
        >>> make_pretty("12345678901")
-       '1 (234)-567-8901'
+       '+1 (234) 567-8901'
        >>> make_pretty("01234567890")
-       '+012-(345)-678-90'
+       '+012 (345) 678-90'
+       >>> make_pretty("+01234567890")
+       '+012 (345) 678-90'
+       >>> make_pretty("+12")
+       '+1 (2)'
+       >>> make_pretty("+123")
+       '+1 (23)'
+       >>> make_pretty("+1234")
+       '+1 (234)'
        """
        if phonenumber is None or phonenumber is "":
                return ""
 
-       phonenumber = handle.strip_number(phonenumber)
+       phonenumber = misc_utils.normalize_number(phonenumber)
 
-       if len(phonenumber) < 3:
-               return phonenumber
-
-       if phonenumber[0] == "0":
-               prettynumber = ""
-               prettynumber += "+%s" % phonenumber[0:3]
-               if 3 < len(phonenumber):
-                       prettynumber += "-(%s)" % phonenumber[3:6]
-                       if 6 < len(phonenumber):
-                               prettynumber += "-%s" % phonenumber[6:9]
-                               if 9 < len(phonenumber):
-                                       prettynumber += "-%s" % phonenumber[9:]
-               return prettynumber
-       elif len(phonenumber) <= 7:
-               prettynumber = "%s-%s" % (phonenumber[0:3], phonenumber[3:])
-       elif len(phonenumber) > 8 and phonenumber[0] == "1":
-               prettynumber = "1 (%s)-%s-%s" % (phonenumber[1:4], phonenumber[4:7], phonenumber[7:])
-       elif len(phonenumber) > 7:
-               prettynumber = "(%s)-%s-%s" % (phonenumber[0:3], phonenumber[3:6], phonenumber[6:])
-       return prettynumber
+       if phonenumber[0] == "+":
+               prettynumber = _make_pretty_international(phonenumber[1:])
+               if not prettynumber.startswith("+"):
+                       prettynumber = "+"+prettynumber
+       elif 8 < len(phonenumber) and phonenumber[0] in ("0", "1"):
+               prettynumber = _make_pretty_international(phonenumber)
+       elif 7 < len(phonenumber):
+               prettynumber = _make_pretty_with_areacode(phonenumber)
+       elif 3 < len(phonenumber):
+               prettynumber = _make_pretty_local(phonenumber)
+       else:
+               prettynumber = phonenumber
+       return prettynumber.strip()
 
 
-class AliasingMixin(telepathy.server.ConnectionInterfaceAliasing):
+class AliasingMixin(tp.ConnectionInterfaceAliasing):
 
        def __init__(self):
-               telepathy.server.ConnectionInterfaceAliasing.__init__(self)
+               tp.ConnectionInterfaceAliasing.__init__(self)
 
        @property
        def session(self):
@@ -72,64 +103,77 @@ class AliasingMixin(telepathy.server.ConnectionInterfaceAliasing):
                raise NotImplementedError("Abstract property called")
 
        @property
-       def handle(self):
+       def callbackNumberParameter(self):
                """
                @abstract
                """
                raise NotImplementedError("Abstract property called")
 
-       @gtk_toolbox.log_exception(_moduleLogger)
+       def get_handle_by_id(self, handleType, handleId):
+               """
+               @abstract
+               """
+               raise NotImplementedError("Abstract function called")
+
+       @misc_utils.log_exception(_moduleLogger)
        def GetAliasFlags(self):
                return 0
 
-       @gtk_toolbox.log_exception(_moduleLogger)
+       @misc_utils.log_exception(_moduleLogger)
        def RequestAliases(self, contactHandleIds):
                _moduleLogger.debug("Called RequestAliases")
                return [self._get_alias(handleId) for handleId in contactHandleIds]
 
-       @gtk_toolbox.log_exception(_moduleLogger)
+       @misc_utils.log_exception(_moduleLogger)
        def GetAliases(self, contactHandleIds):
                _moduleLogger.debug("Called GetAliases")
 
-               idToAlias = dict(
-                       (handleId, self._get_alias(handleId))
-                       for handleId in contactHandleIds
+               idToAlias = dbus.Dictionary(
+                       (
+                               (handleId, self._get_alias(handleId))
+                               for handleId in contactHandleIds
+                       ),
+                       signature="us",
                )
                return idToAlias
 
-       @gtk_toolbox.log_exception(_moduleLogger)
+       @misc_utils.log_exception(_moduleLogger)
        def SetAliases(self, aliases):
                _moduleLogger.debug("Called SetAliases")
-
                # first validate that no other handle types are included
-               userHandleAndAlias = None
+               handleId, alias = None, None
                for handleId, alias in aliases.iteritems():
-                       h = self.handle(telepathy.HANDLE_TYPE_CONTACT, handleId)
-                       if not isinstance(h, handle.ConnectionHandle):
-                               raise telepathy.errors.PermissionDenied("No user customizable aliases")
-                       userHandleAndAlias = h, alias
-               if userHandleAndAlias is None:
-                       _moduleLogger.debug("No user handle")
-                       return
+                       h = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId)
+                       if isinstance(h, handle.ConnectionHandle):
+                               break
+               else:
+                       raise telepathy.errors.PermissionDenied("No user customizable aliases")
+
+               uglyNumber = misc_utils.normalize_number(alias)
+               if len(uglyNumber) == 0:
+                       # Reset to the original from login if one was provided
+                       uglyNumber = self.callbackNumberParameter
+               if not misc_utils.is_valid_number(uglyNumber):
+                       raise telepathy.errors.InvalidArgument("Invalid phone number %r" % (uglyNumber, ))
 
                # Update callback
-               uglyNumber = handle.strip_number(userHandleAndAlias[1])
                self.session.backend.set_callback_number(uglyNumber)
 
                # Inform of change
-               changedAliases = (userHandleAndAlias, )
+               userAlias = make_pretty(uglyNumber)
+               changedAliases = ((handleId, userAlias), )
                self.AliasesChanged(changedAliases)
 
        def _get_alias(self, handleId):
-               h = self.handle(telepathy.HANDLE_TYPE_CONTACT, handleId)
+               h = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId)
                if isinstance(h, handle.ConnectionHandle):
-                       callbackNumber = self.session.backend.get_callback_number()
-                       userAlias = make_pretty(callbackNumber)
+                       aliasNumber = self.session.backend.get_callback_number()
+                       userAlias = make_pretty(aliasNumber)
                        return userAlias
                else:
-                       contactId = h.contactID
-                       if contactId:
-                               contactAlias = self.session.addressbook.get_contact_name(contactId)
-                       else:
-                               contactAlias = make_pretty(h.phoneNumber)
+                       number = h.phoneNumber
+                       try:
+                               contactAlias = self.session.addressbook.get_contact_name(number)
+                       except KeyError:
+                               contactAlias = make_pretty(number)
                        return contactAlias