Trying to improve debug output due to an exception from some of this code
[theonering] / src / gvoice / addressbook.py
1 #!/usr/bin/python
2
3
4 import logging
5
6 import util.coroutines as coroutines
7 import util.misc as misc_utils
8 import util.go_utils as gobject_utils
9
10
11 _moduleLogger = logging.getLogger(__name__)
12
13
14 class Addressbook(object):
15
16         _RESPONSE_GOOD = 0
17         _RESPONSE_BLOCKED = 3
18
19         def __init__(self, backend, asyncPool):
20                 self._backend = backend
21                 self._numbers = {}
22                 self._asyncPool = asyncPool
23
24                 self.updateSignalHandler = coroutines.CoTee()
25
26         def update(self, force=False):
27                 if not force and self._numbers:
28                         return
29
30                 le = gobject_utils.AsyncLinearExecution(self._asyncPool, self._update)
31                 le.start()
32
33         @misc_utils.log_exception(_moduleLogger)
34         def _update(self):
35                 contacts = yield (
36                         self._backend.get_contacts,
37                         (),
38                         {},
39                 )
40
41                 oldContacts = self._numbers
42                 oldContactNumbers = set(self.get_numbers())
43
44                 self._numbers = self._populate_contacts(contacts)
45                 newContactNumbers = set(self.get_numbers())
46
47                 addedContacts = newContactNumbers - oldContactNumbers
48                 removedContacts = oldContactNumbers - newContactNumbers
49                 changedContacts = set(
50                         contactNumber
51                         for contactNumber in newContactNumbers.intersection(oldContactNumbers)
52                         if self._numbers[contactNumber] != oldContacts[contactNumber]
53                 )
54
55                 if addedContacts or removedContacts or changedContacts:
56                         message = self, addedContacts, removedContacts, changedContacts
57                         self.updateSignalHandler.stage.send(message)
58
59         def get_numbers(self):
60                 return self._numbers.iterkeys()
61
62         def get_contact_name(self, strippedNumber):
63                 """
64                 @throws KeyError if contact not in list (so client can choose what to display)
65                 """
66                 return self._numbers[strippedNumber][0]
67
68         def get_phone_type(self, strippedNumber):
69                 try:
70                         return self._numbers[strippedNumber][1]
71                 except KeyError:
72                         return "unknown"
73
74         def is_blocked(self, strippedNumber):
75                 try:
76                         return self._numbers[strippedNumber][2]["response"] == self._RESPONSE_BLOCKED
77                 except KeyError:
78                         return False
79
80         def _populate_contacts(self, contacts):
81                 numbers = {}
82                 for contactId, contactDetails in contacts:
83                         contactName = contactDetails["name"]
84                         contactNumbers = (
85                                 (
86                                         misc_utils.normalize_number(numberDetails["phoneNumber"]),
87                                         numberDetails.get("phoneType", "Mobile"),
88                                 )
89                                 for numberDetails in contactDetails["numbers"]
90                         )
91                         numbers.update(
92                                 (number, (contactName, phoneType, contactDetails))
93                                 for (number, phoneType) in contactNumbers
94                         )
95                 return numbers