Pulling in latest skeleton code
[theonering] / src / aliasing.py
1 import logging
2
3 import dbus
4 import telepathy
5
6 import tp
7 import util.misc as misc_utils
8 import handle
9
10
11 _moduleLogger = logging.getLogger(__name__)
12
13
14 def _make_pretty_with_areacode(phonenumber):
15         prettynumber = "(%s)" % (phonenumber[0:3], )
16         if 3 < len(phonenumber):
17                 prettynumber += " %s" % (phonenumber[3:6], )
18                 if 6 < len(phonenumber):
19                         prettynumber += "-%s" % (phonenumber[6:], )
20         return prettynumber
21
22
23 def _make_pretty_local(phonenumber):
24         prettynumber = "%s" % (phonenumber[0:3], )
25         if 3 < len(phonenumber):
26                 prettynumber += "-%s" % (phonenumber[3:], )
27         return prettynumber
28
29
30 def _make_pretty_international(phonenumber):
31         prettynumber = phonenumber
32         if phonenumber.startswith("0"):
33                 prettynumber = "+%s " % (phonenumber[0:3], )
34                 if 3 < len(phonenumber):
35                         prettynumber += _make_pretty_with_areacode(phonenumber[3:])
36         elif phonenumber.startswith("1"):
37                 prettynumber = "1 "
38                 prettynumber += _make_pretty_with_areacode(phonenumber[1:])
39         return prettynumber
40
41
42 def make_pretty(phonenumber):
43         """
44         Function to take a phone number and return the pretty version
45         pretty numbers:
46                 if phonenumber begins with 0:
47                         ...-(...)-...-....
48                 if phonenumber begins with 1: ( for gizmo callback numbers )
49                         1 (...)-...-....
50                 if phonenumber is 13 digits:
51                         (...)-...-....
52                 if phonenumber is 10 digits:
53                         ...-....
54         >>> make_pretty("12")
55         '12'
56         >>> make_pretty("1234567")
57         '123-4567'
58         >>> make_pretty("2345678901")
59         '+1 (234) 567-8901'
60         >>> make_pretty("12345678901")
61         '+1 (234) 567-8901'
62         >>> make_pretty("01234567890")
63         '+012 (345) 678-90'
64         >>> make_pretty("+01234567890")
65         '+012 (345) 678-90'
66         >>> make_pretty("+12")
67         '+1 (2)'
68         >>> make_pretty("+123")
69         '+1 (23)'
70         >>> make_pretty("+1234")
71         '+1 (234)'
72         """
73         if phonenumber is None or phonenumber == "":
74                 return ""
75
76         phonenumber = misc_utils.normalize_number(phonenumber)
77
78         if phonenumber == "":
79                 return ""
80         elif phonenumber[0] == "+":
81                 prettynumber = _make_pretty_international(phonenumber[1:])
82                 if not prettynumber.startswith("+"):
83                         prettynumber = "+"+prettynumber
84         elif 8 < len(phonenumber) and phonenumber[0] in ("0", "1"):
85                 prettynumber = _make_pretty_international(phonenumber)
86         elif 7 < len(phonenumber):
87                 prettynumber = _make_pretty_with_areacode(phonenumber)
88         elif 3 < len(phonenumber):
89                 prettynumber = _make_pretty_local(phonenumber)
90         else:
91                 prettynumber = phonenumber
92         return prettynumber.strip()
93
94
95 class AliasingMixin(tp.ConnectionInterfaceAliasing):
96
97         def __init__(self):
98                 tp.ConnectionInterfaceAliasing.__init__(self)
99
100         @property
101         def session(self):
102                 """
103                 @abstract
104                 """
105                 raise NotImplementedError("Abstract property called")
106
107         @property
108         def callbackNumberParameter(self):
109                 """
110                 @abstract
111                 """
112                 raise NotImplementedError("Abstract property called")
113
114         def get_handle_by_id(self, handleType, handleId):
115                 """
116                 @abstract
117                 """
118                 raise NotImplementedError("Abstract function called")
119
120         @misc_utils.log_exception(_moduleLogger)
121         def GetAliasFlags(self):
122                 return 0
123
124         @misc_utils.log_exception(_moduleLogger)
125         def RequestAliases(self, contactHandleIds):
126                 _moduleLogger.debug("Called RequestAliases")
127                 return [self._get_alias(handleId) for handleId in contactHandleIds]
128
129         @misc_utils.log_exception(_moduleLogger)
130         def GetAliases(self, contactHandleIds):
131                 _moduleLogger.debug("Called GetAliases")
132
133                 idToAlias = dbus.Dictionary(
134                         (
135                                 (handleId, self._get_alias(handleId))
136                                 for handleId in contactHandleIds
137                         ),
138                         signature="us",
139                 )
140                 return idToAlias
141
142         @misc_utils.log_exception(_moduleLogger)
143         def SetAliases(self, aliases):
144                 _moduleLogger.debug("Called SetAliases")
145                 # first validate that no other handle types are included
146                 handleId, alias = None, None
147                 for handleId, alias in aliases.iteritems():
148                         h = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId)
149                         if isinstance(h, handle.ConnectionHandle):
150                                 break
151                 else:
152                         raise telepathy.errors.PermissionDenied("No user customizable aliases")
153
154                 uglyNumber = misc_utils.normalize_number(alias)
155                 if len(uglyNumber) == 0:
156                         # Reset to the original from login if one was provided
157                         uglyNumber = self.callbackNumberParameter
158                 if not misc_utils.is_valid_number(uglyNumber):
159                         raise telepathy.errors.InvalidArgument("Invalid phone number %r" % (uglyNumber, ))
160
161                 # Update callback
162                 self.session.backend.set_callback_number(uglyNumber)
163
164                 # Inform of change
165                 userAlias = make_pretty(uglyNumber)
166                 changedAliases = ((handleId, userAlias), )
167                 self.AliasesChanged(changedAliases)
168
169         def _get_alias(self, handleId):
170                 h = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId)
171                 if isinstance(h, handle.ConnectionHandle):
172                         aliasNumber = self.session.backend.get_callback_number()
173                         userAlias = make_pretty(aliasNumber)
174                         return userAlias
175                 else:
176                         number = h.phoneNumber
177                         try:
178                                 contactAlias = self.session.addressbook.get_contact_name(number)
179                         except KeyError:
180                                 contactAlias = make_pretty(number)
181                         return contactAlias