X-Git-Url: http://git.maemo.org/git/?p=theonering;a=blobdiff_plain;f=src%2Fgvoice%2Faddressbook.py;h=4b3793ba555c7e2d988e744d57ff5f4a85006d0c;hp=f5fa02e45f6a011f74aa127a68b8cbfac9f9830c;hb=b1c44f59a82702e7e673dccbdd8262db5bc967b6;hpb=1c892d1b9bf14b28eb54ce3590ed2ee29d5e3d25 diff --git a/src/gvoice/addressbook.py b/src/gvoice/addressbook.py index f5fa02e..4b3793b 100644 --- a/src/gvoice/addressbook.py +++ b/src/gvoice/addressbook.py @@ -1,13 +1,23 @@ #!/usr/bin/python +from __future__ import with_statement + import logging +try: + import cPickle + pickle = cPickle +except ImportError: + import pickle + +import constants import util.coroutines as coroutines import util.misc as misc_utils +import util.go_utils as gobject_utils -_moduleLogger = logging.getLogger("gvoice.addressbook") +_moduleLogger = logging.getLogger(__name__) class Addressbook(object): @@ -15,20 +25,76 @@ class Addressbook(object): _RESPONSE_GOOD = 0 _RESPONSE_BLOCKED = 3 - def __init__(self, backend): + OLDEST_COMPATIBLE_FORMAT_VERSION = misc_utils.parse_version("0.8.0") + + def __init__(self, backend, asyncPool): self._backend = backend self._numbers = {} + self._asyncPool = asyncPool self.updateSignalHandler = coroutines.CoTee() + def load(self, path): + _moduleLogger.debug("Loading cache") + assert not self._numbers + try: + with open(path, "rb") as f: + fileVersion, fileBuild, contacts = pickle.load(f) + except (pickle.PickleError, IOError, EOFError, ValueError, Exception): + _moduleLogger.exception("While loading") + return + + if contacts and misc_utils.compare_versions( + self.OLDEST_COMPATIBLE_FORMAT_VERSION, + misc_utils.parse_version(fileVersion), + ) <= 0: + _moduleLogger.info("Loaded cache") + self._numbers = contacts + self._loadedFromCache = True + else: + _moduleLogger.debug( + "Skipping cache due to version mismatch (%s-%s)" % ( + fileVersion, fileBuild + ) + ) + + def save(self, path): + _moduleLogger.info("Saving cache") + if not self._numbers: + _moduleLogger.info("Odd, no conversations to cache. Did we never load the cache?") + return + + try: + dataToDump = (constants.__version__, constants.__build__, self._numbers) + with open(path, "wb") as f: + pickle.dump(dataToDump, f, pickle.HIGHEST_PROTOCOL) + except (pickle.PickleError, IOError): + _moduleLogger.exception("While saving for %s" % self._name) + _moduleLogger.info("Cache saved") + def update(self, force=False): if not force and self._numbers: return + + le = gobject_utils.AsyncLinearExecution(self._asyncPool, self._update) + le.start() + + @misc_utils.log_exception(_moduleLogger) + def _update(self): + try: + contacts = yield ( + self._backend.get_contacts, + (), + {}, + ) + except Exception: + _moduleLogger.exception("While updating the addressbook") + return + oldContacts = self._numbers oldContactNumbers = set(self.get_numbers()) - self._numbers = {} - self._populate_contacts() + self._numbers = self._populate_contacts(contacts) newContactNumbers = set(self.get_numbers()) addedContacts = newContactNumbers - oldContactNumbers @@ -64,10 +130,8 @@ class Addressbook(object): except KeyError: return False - def _populate_contacts(self): - if self._numbers: - return - contacts = self._backend.get_contacts() + def _populate_contacts(self, contacts): + numbers = {} for contactId, contactDetails in contacts: contactName = contactDetails["name"] contactNumbers = ( @@ -77,7 +141,21 @@ class Addressbook(object): ) for numberDetails in contactDetails["numbers"] ) - self._numbers.update( + numbers.update( (number, (contactName, phoneType, contactDetails)) for (number, phoneType) in contactNumbers ) + return numbers + + +def print_addressbook(path): + import pprint + + try: + with open(path, "rb") as f: + fileVersion, fileBuild, contacts = pickle.load(f) + except (pickle.PickleError, IOError, EOFError, ValueError): + _moduleLogger.exception("") + else: + pprint.pprint((fileVersion, fileBuild)) + pprint.pprint(contacts)