X-Git-Url: http://git.maemo.org/git/?p=theonering;a=blobdiff_plain;f=src%2Fgvoice%2Fsession.py;h=3a7de001e01708c4d7263f39e49e1192aa53d090;hp=a890ac9c22bc0d963efd7520008954bc88ea6505;hb=074b7adedaeba92d5993f8015be26c684f8bbfd8;hpb=68d1653679bdce47f008d9167a263dbb2259e91d diff --git a/src/gvoice/session.py b/src/gvoice/session.py index a890ac9..3a7de00 100644 --- a/src/gvoice/session.py +++ b/src/gvoice/session.py @@ -1,5 +1,7 @@ #!/usr/bin/env python +import os +import time import logging import backend @@ -8,40 +10,150 @@ import conversations import state_machine -_moduleLogger = logging.getLogger("gvoice.session") +_moduleLogger = logging.getLogger(__name__) class Session(object): - def __init__(self, cookiePath = None): + _DEFAULTS = { + "contacts": (12, "hours"), + "voicemail": (120, "minutes"), + "texts": (10, "minutes"), + } + + _MINIMUM_MESSAGE_PERIOD = state_machine.to_seconds(minutes=30) + + def __init__(self, cookiePath = None, defaults = None): + if defaults is None: + defaults = self._DEFAULTS + else: + for key, (quant, unit) in defaults.iteritems(): + if quant == 0: + defaults[key] = (self._DEFAULTS[key], unit) + elif quant < 0: + defaults[key] = (state_machine.UpdateStateMachine.INFINITE_PERIOD, unit) self._username = None self._password = None self._backend = backend.GVoiceBackend(cookiePath) + + if defaults["contacts"][0] == state_machine.UpdateStateMachine.INFINITE_PERIOD: + contactsPeriodInSeconds = state_machine.UpdateStateMachine.INFINITE_PERIOD + else: + contactsPeriodInSeconds = state_machine.to_seconds( + **{defaults["contacts"][1]: defaults["contacts"][0],} + ) self._addressbook = addressbook.Addressbook(self._backend) - self._conversations = conversations.Conversations(self._backend) - self._stateMachine = state_machine.StateMachine([self.addressbook], [self.conversations]) + self._addressbookStateMachine = state_machine.UpdateStateMachine([self.addressbook], "Addressbook") + self._addressbookStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_DND, + state_machine.NopStateStrategy() + ) + self._addressbookStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_IDLE, + state_machine.NopStateStrategy() + ) + self._addressbookStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_ACTIVE, + state_machine.ConstantStateStrategy(contactsPeriodInSeconds) + ) - self._conversations.updateSignalHandler.register_sink( - self._stateMachine.request_reset_timers + if defaults["voicemail"][0] == state_machine.UpdateStateMachine.INFINITE_PERIOD: + voicemailPeriodInSeconds = state_machine.UpdateStateMachine.INFINITE_PERIOD + idleVoicemailPeriodInSeconds = state_machine.UpdateStateMachine.INFINITE_PERIOD + else: + voicemailPeriodInSeconds = state_machine.to_seconds( + **{defaults["voicemail"][1]: defaults["voicemail"][0],} + ) + idleVoicemailPeriodInSeconds = max(voicemailPeriodInSeconds * 4, self._MINIMUM_MESSAGE_PERIOD) + self._voicemails = conversations.Conversations(self._backend.get_voicemails) + self._voicemailsStateMachine = state_machine.UpdateStateMachine([self.voicemails], "Voicemail") + self._voicemailsStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_DND, + state_machine.NopStateStrategy() + ) + self._voicemailsStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_IDLE, + state_machine.ConstantStateStrategy(idleVoicemailPeriodInSeconds) ) + self._voicemailsStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_ACTIVE, + state_machine.NTimesStateStrategy( + 3 * [state_machine.to_seconds(minutes=1)], voicemailPeriodInSeconds + ) + ) + self._voicemails.updateSignalHandler.register_sink( + self._voicemailsStateMachine.request_reset_timers + ) + + if defaults["texts"][0] == state_machine.UpdateStateMachine.INFINITE_PERIOD: + initTextsPeriodInSeconds = state_machine.UpdateStateMachine.INFINITE_PERIOD + minTextsPeriodInSeconds = state_machine.UpdateStateMachine.INFINITE_PERIOD + textsPeriodInSeconds = state_machine.UpdateStateMachine.INFINITE_PERIOD + idleTextsPeriodInSeconds = state_machine.UpdateStateMachine.INFINITE_PERIOD + else: + initTextsPeriodInSeconds = state_machine.to_seconds(seconds=20) + minTextsPeriodInSeconds = state_machine.to_seconds(seconds=1) + textsPeriodInSeconds = state_machine.to_seconds( + **{defaults["texts"][1]: defaults["texts"][0],} + ) + idleTextsPeriodInSeconds = max(textsPeriodInSeconds * 4, self._MINIMUM_MESSAGE_PERIOD) + self._texts = conversations.Conversations(self._backend.get_texts) + self._textsStateMachine = state_machine.UpdateStateMachine([self.texts], "Texting") + self._textsStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_DND, + state_machine.NopStateStrategy() + ) + self._textsStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_IDLE, + state_machine.ConstantStateStrategy(idleTextsPeriodInSeconds) + ) + self._textsStateMachine.set_state_strategy( + state_machine.StateMachine.STATE_ACTIVE, + state_machine.GeometricStateStrategy( + initTextsPeriodInSeconds, + minTextsPeriodInSeconds, + textsPeriodInSeconds, + ) + ) + self._texts.updateSignalHandler.register_sink( + self._textsStateMachine.request_reset_timers + ) + + self._masterStateMachine = state_machine.MasterStateMachine() + self._masterStateMachine.append_machine(self._addressbookStateMachine) + self._masterStateMachine.append_machine(self._voicemailsStateMachine) + self._masterStateMachine.append_machine(self._textsStateMachine) + + self._lastDndCheck = 0 + self._cachedIsDnd = False + + def load(self, path): + self._texts.load(os.sep.join((path, "texts.cache"))) + self._voicemails.load(os.sep.join((path, "voicemails.cache"))) + + def save(self, path): + self._texts.save(os.sep.join((path, "texts.cache"))) + self._voicemails.save(os.sep.join((path, "voicemails.cache"))) def close(self): - self._conversations.updateSignalHandler.unregister_sink( - self._stateMachine.request_reset_timers + self._voicemails.updateSignalHandler.unregister_sink( + self._voicemailsStateMachine.request_reset_timers ) - self._stateMachine.close() + self._texts.updateSignalHandler.unregister_sink( + self._textsStateMachine.request_reset_timers + ) + self._masterStateMachine.close() def login(self, username, password): self._username = username self._password = password - if not self._backend.is_authed(): - self._backend.login(self._username, self._password) + self._backend.login(self._username, self._password) - self._stateMachine.start() + self._masterStateMachine.start() def logout(self): - self._stateMachine.stop() + self._masterStateMachine.stop() self._backend.logout() self._username = None @@ -66,6 +178,18 @@ class Session(object): self.logout() return False + def set_dnd(self, doNotDisturb): + self._backend.set_dnd(doNotDisturb) + self._cachedIsDnd = doNotDisturb + + def is_dnd(self): + # To throttle checking with the server, use a 30s cache + newTime = time.time() + if self._lastDndCheck + 30 < newTime: + self._lastDndCheck = newTime + self._cachedIsDnd = self._backend.is_dnd() + return self._cachedIsDnd + @property def backend(self): """ @@ -76,18 +200,28 @@ class Session(object): @property def addressbook(self): - """ - Delay initialized addressbook - """ return self._addressbook @property - def conversations(self): - """ - Delay initialized addressbook - """ - return self._conversations + def texts(self): + return self._texts + + @property + def voicemails(self): + return self._voicemails @property def stateMachine(self): - return self._stateMachine + return self._masterStateMachine + + @property + def addressbookStateMachine(self): + return self._addressbookStateMachine + + @property + def voicemailsStateMachine(self): + return self._voicemailsStateMachine + + @property + def textsStateMachine(self): + return self._textsStateMachine