6 import util.coroutines as coroutines
7 import util.misc as util_misc
10 _moduleLogger = logging.getLogger("gvoice.addressbook")
13 class Addressbook(object):
15 def __init__(self, backend):
16 self._backend = backend
19 self.updateSignalHandler = coroutines.CoTee()
21 def update(self, force=False):
22 if not force and self._contacts:
24 oldContacts = self._contacts
25 oldContactIds = set(self.get_contact_ids())
28 self._populate_contacts()
29 newContactIds = set(self.get_contact_ids())
31 addedContacts = newContactIds - oldContactIds
32 removedContacts = oldContactIds - newContactIds
33 changedContacts = set(
35 for contactId in newContactIds.intersection(oldContactIds)
36 if self._has_contact_changed(contactId, oldContacts)
39 if addedContacts or removedContacts or changedContacts:
40 message = self, addedContacts, removedContacts, changedContacts
41 self.updateSignalHandler.stage.send(message)
43 def get_contact_ids(self):
44 return self._contacts.iterkeys()
46 def get_contact_name(self, contactId):
47 return self._contacts[contactId][0]
49 def get_contact_details(self, contactId):
50 return iter(self._contacts[contactId][1])
52 def find_contacts_with_number(self, queryNumber):
53 strippedQueryNumber = util_misc.normalize_number(queryNumber)
54 for contactId, (contactName, contactDetails) in self._contacts.iteritems():
55 for phoneType, number in contactDetails:
56 if number == strippedQueryNumber:
59 def _populate_contacts(self):
62 contacts = self._backend.get_contacts()
63 for contactId, contactDetails in contacts:
64 contactName = contactDetails["name"]
67 numberDetails.get("phoneType", "Mobile"),
68 util_misc.normalize_number(numberDetails["phoneNumber"]),
70 for numberDetails in contactDetails["numbers"]
72 self._contacts[contactId] = (contactName, contactNumbers)
74 def _has_contact_changed(self, contactId, oldContacts):
75 oldContact = oldContacts[contactId]
76 oldContactName = oldContact[0]
77 oldContactDetails = oldContact[1]
78 if oldContactName != self.get_contact_name(contactId):
80 if not oldContactDetails:
82 # if its already in the old cache, purposefully add it into the new cache
83 return oldContactDetails != self.get_contact_details(contactId)