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