Added detection of missed calls. As part of this I moved some of the connections...
[theonering] / src / aliasing.py
1 import logging
2
3 import telepathy
4
5 import tp
6 import gtk_toolbox
7 import util.misc as util_misc
8 import handle
9
10
11 _moduleLogger = logging.getLogger('aliasing')
12
13
14 def _make_pretty_with_areacodde(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         if phonenumber.startswith("0"):
32                 prettynumber = "+%s " % (phonenumber[0:3], )
33                 if 3 < len(phonenumber):
34                         prettynumber += _make_pretty_with_areacodde(phonenumber[3:])
35         if phonenumber.startswith("1"):
36                 prettynumber = "1 "
37                 prettynumber += _make_pretty_with_areacodde(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 = util_misc.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_areacodde(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         @gtk_toolbox.log_exception(_moduleLogger)
118         def GetAliasFlags(self):
119                 return 0
120
121         @gtk_toolbox.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         @gtk_toolbox.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         @gtk_toolbox.log_exception(_moduleLogger)
137         def SetAliases(self, aliases):
138                 _moduleLogger.debug("Called SetAliases")
139                 # first validate that no other handle types are included
140                 for handleId, alias in aliases.iteritems():
141                         h = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId)
142                         if isinstance(h, handle.ConnectionHandle):
143                                 break
144                 else:
145                         raise telepathy.errors.PermissionDenied("No user customizable aliases")
146
147                 uglyNumber = util_misc.normalize_number(alias)
148                 if len(uglyNumber) == 0:
149                         # Reset to the original from login if one was provided
150                         uglyNumber = self.callbackNumberParameter
151                 if not util_misc.is_valid_number(uglyNumber):
152                         raise telepathy.errors.InvalidArgument("Invalid phone number %r" % (uglyNumber, ))
153
154                 # Update callback
155                 self.session.backend.set_callback_number(uglyNumber)
156
157                 # Inform of change
158                 userAlias = make_pretty(uglyNumber)
159                 changedAliases = ((handleId, userAlias), )
160                 self.AliasesChanged(changedAliases)
161
162         def _get_alias(self, handleId):
163                 h = self.get_handle_by_id(telepathy.HANDLE_TYPE_CONTACT, handleId)
164                 if isinstance(h, handle.ConnectionHandle):
165                         aliasNumber = self.session.backend.get_callback_number()
166                         userAlias = make_pretty(aliasNumber)
167                         return userAlias
168                 else:
169                         number = h.phoneNumber
170                         try:
171                                 contactAlias = self.session.addressbook.get_contact_name(number)
172                         except KeyError:
173                                 contactAlias = make_pretty(number)
174                         return contactAlias