X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fsession.py;h=ae98cdd55ad1c48918027b2fbbc9dcae46f17bd6;hb=7d31dbf7bceb96bf0da4846b4c9b7f137d4011ec;hp=1bbe04c6a77a1297ea7fc62ef1c1dc3f8776cf7b;hpb=6a62f28edba4f7b6dd8305e8626fe03a559835c9;p=gc-dialer diff --git a/src/session.py b/src/session.py index 1bbe04c..ae98cdd 100644 --- a/src/session.py +++ b/src/session.py @@ -2,17 +2,34 @@ import os import time import logging +try: + import cPickle + pickle = cPickle +except ImportError: + import pickle + from PyQt4 import QtCore from util import qore_utils from util import concurrent +from util import misc as misc_utils +import constants from backends import gv_backend _moduleLogger = logging.getLogger(__name__) +class _DraftContact(object): + + def __init__(self, title, description, numbersWithDescriptions): + self.title = title + self.description = description + self.numbers = numbersWithDescriptions + self.selectedNumber = numbersWithDescriptions[0][0] + + class Draft(QtCore.QObject): sendingMessage = QtCore.pyqtSignal() @@ -32,13 +49,15 @@ class Draft(QtCore.QObject): def send(self, text): assert 0 < len(self._contacts) + numbers = [contact.selectedNumber for contact in self._contacts.itervalues()] le = concurrent.AsyncLinearExecution(self._pool, self._send) - le.start(text) + le.start(numbers, text) def call(self): assert len(self._contacts) == 1 + (contact, ) = self._contacts.itervalues() le = concurrent.AsyncLinearExecution(self._pool, self._call) - le.start() + le.start(contact.selectedNumber) def cancel(self): le = concurrent.AsyncLinearExecution(self._pool, self._cancel) @@ -46,7 +65,7 @@ class Draft(QtCore.QObject): def add_contact(self, contactId, title, description, numbersWithDescriptions): assert contactId not in self._contacts - contactDetails = title, description, numbersWithDescriptions + contactDetails = _DraftContact(title, description, numbersWithDescriptions) self._contacts[contactId] = contactDetails self.recipientsChanged.emit() @@ -56,7 +75,27 @@ class Draft(QtCore.QObject): self.recipientsChanged.emit() def get_contacts(self): - return self._contacts + return self._contacts.iterkeys() + + def get_num_contacts(self): + return len(self._contacts) + + def get_title(self, cid): + return self._contacts[cid].title + + def get_description(self, cid): + return self._contacts[cid].description + + def get_numbers(self, cid): + return self._contacts[cid].numbers + + def get_selected_number(self, cid): + return self._contacts[cid].selectedNumber + + def set_selected_number(self, cid, number): + # @note I'm lazy, this isn't firing any kind of signal since only one + # controller right now and that is the viewer + return self._contacts[cid].numbers def clear(self): oldContacts = self._contacts @@ -64,7 +103,7 @@ class Draft(QtCore.QObject): if oldContacts: self.recipientsChanged.emit() - def _send(self, text): + def _send(self, numbers, text): self.sendingMessage.emit() try: self.error.emit("Not Implemented") @@ -73,7 +112,7 @@ class Draft(QtCore.QObject): except Exception, e: self.error.emit(str(e)) - def _call(self): + def _call(self, number): self.calling.emit() try: self.error.emit("Not Implemented") @@ -113,6 +152,8 @@ class Session(QtCore.QObject): LOGGINGIN_STATE = "logging in" LOGGEDIN_STATE = "logged in" + _OLDEST_COMPATIBLE_FORMAT_VERSION = misc_utils.parse_version("1.2.0") + _LOGGEDOUT_TIME = -1 _LOGGINGIN_TIME = 0 @@ -178,21 +219,27 @@ class Session(QtCore.QObject): self._loggedInTime = self._LOGGEDOUT_TIME self.clear() - def update_contacts(self): + def update_contacts(self, force = True): + if not force and self._contacts: + return le = concurrent.AsyncLinearExecution(self._pool, self._update_contacts) self._perform_op_while_loggedin(le) def get_contacts(self): return self._contacts - def update_messages(self): + def update_messages(self, force = True): + if not force and self._messages: + return le = concurrent.AsyncLinearExecution(self._pool, self._update_messages) self._perform_op_while_loggedin(le) def get_messages(self): return self._messages - def update_history(self): + def update_history(self, force = True): + if not force and self._history: + return le = concurrent.AsyncLinearExecution(self._pool, self._update_history) self._perform_op_while_loggedin(le) @@ -288,8 +335,13 @@ class Session(QtCore.QObject): finalState = self.LOGGEDIN_STATE self.loggedIn.emit() if oldUsername != self._username: - self._load_from_cache() - loginOps = self._loginOps[:] + needOps = not self._load() + else: + needOps = True + if needOps: + loginOps = self._loginOps[:] + else: + loginOps = [] del self._loginOps[:] for asyncOp in loginOps: asyncOp.start() @@ -298,7 +350,7 @@ class Session(QtCore.QObject): finally: self.stateChange.emit(finalState) - def _load_from_cache(self): + def _load(self): updateContacts = len(self._contacts) != 0 updateMessages = len(self._messages) != 0 updateHistory = len(self._history) != 0 @@ -311,6 +363,12 @@ class Session(QtCore.QObject): self._dnd = False self._callback = "" + loadedFromCache = self._load_from_cache() + if loadedFromCache: + updateContacts = True + updateMessages = True + updateHistory = True + if updateContacts: self.contactsUpdated.emit() if updateMessages: @@ -322,9 +380,63 @@ class Session(QtCore.QObject): if oldCallback != self._callback: self.callbackNumberChanged.emit(self._callback) + return loadedFromCache + + def _load_from_cache(self): + if self._cachePath is None: + return False + cachePath = os.path.join(self._cachePath, "%s.cache" % self._username) + + try: + with open(cachePath, "rb") as f: + dumpedData = pickle.load(f) + except (pickle.PickleError, IOError, EOFError, ValueError): + _moduleLogger.exception("Pickle fun loading") + return False + except: + _moduleLogger.exception("Weirdness loading") + return False + + ( + version, build, + contacts, messages, history, dnd, callback + ) = dumpedData + + if misc_utils.compare_versions( + self._OLDEST_COMPATIBLE_FORMAT_VERSION, + misc_utils.parse_version(version), + ) <= 0: + _moduleLogger.info("Loaded cache") + self._contacts = contacts + self._messages = messages + self._history = history + self._dnd = dnd + self._callback = callback + return True + else: + _moduleLogger.debug( + "Skipping cache due to version mismatch (%s-%s)" % ( + version, build + ) + ) + return False + def _save_to_cache(self): - # @todo - pass + _moduleLogger.info("Saving cache") + if self._cachePath is None: + return + cachePath = os.path.join(self._cachePath, "%s.cache" % self._username) + + try: + dataToDump = ( + constants.__version__, constants.__build__, + self._contacts, self._messages, self._history, self._dnd, self._callback + ) + with open(cachePath, "wb") as f: + pickle.dump(dataToDump, f, pickle.HIGHEST_PROTOCOL) + _moduleLogger.info("Cache saved") + except (pickle.PickleError, IOError): + _moduleLogger.exception("While saving") def _clear_cache(self): updateContacts = len(self._contacts) != 0