Separating voicemail / texts into their own state machines
[theonering] / src / gvoice / session.py
index bf5e328..0235daa 100644 (file)
@@ -5,6 +5,7 @@ import logging
 import backend
 import addressbook
 import conversations
+import state_machine
 
 
 _moduleLogger = logging.getLogger("gvoice.session")
@@ -12,31 +13,99 @@ _moduleLogger = logging.getLogger("gvoice.session")
 
 class Session(object):
 
-       def __init__(self, cookiePath):
-               self._cookiePath = cookiePath
+       def __init__(self, cookiePath = None):
                self._username = None
                self._password = None
-               self._backend = None
-               self._addressbook = None
-               self._conversations = None
+
+               self._backend = backend.GVoiceBackend(cookiePath)
+
+               self._addressbook = addressbook.Addressbook(self._backend)
+               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.ConstantStateStrategy(state_machine.to_milliseconds(hours=6))
+               )
+               self._addressbookStateMachine.set_state_strategy(
+                       state_machine.StateMachine.STATE_ACTIVE,
+                       state_machine.ConstantStateStrategy(state_machine.to_milliseconds(hours=1))
+               )
+
+               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(state_machine.to_milliseconds(minutes=30))
+               )
+               self._voicemailsStateMachine.set_state_strategy(
+                       state_machine.StateMachine.STATE_ACTIVE,
+                       state_machine.ConstantStateStrategy(state_machine.to_milliseconds(minutes=5))
+               )
+               self._voicemails.updateSignalHandler.register_sink(
+                       self._voicemailsStateMachine.request_reset_timers
+               )
+
+               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(state_machine.to_milliseconds(minutes=30))
+               )
+               self._textsStateMachine.set_state_strategy(
+                       state_machine.StateMachine.STATE_ACTIVE,
+                       state_machine.GeometricStateStrategy(
+                               state_machine.to_milliseconds(seconds=10),
+                               state_machine.to_milliseconds(seconds=1),
+                               state_machine.to_milliseconds(minutes=10),
+                       )
+               )
+               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)
+
+       def close(self):
+               self._voicemails.updateSignalHandler.unregister_sink(
+                       self._voicemailsStateMachine.request_reset_timers
+               )
+               self._texts.updateSignalHandler.unregister_sink(
+                       self._textsStateMachine.request_reset_timers
+               )
+               self._masterStateMachine.close()
 
        def login(self, username, password):
                self._username = username
                self._password = password
-               self._backend = backend.GVoiceBackend(self._cookiePath)
                if not self._backend.is_authed():
                        self._backend.login(self._username, self._password)
 
+               self._masterStateMachine.start()
+
        def logout(self):
+               self._masterStateMachine.stop()
+               self._backend.logout()
+
                self._username = None
                self._password = None
-               self._backend = None
-               self._addressbook = None
-               self._conversations = None
 
        def is_logged_in(self):
-               if self._backend is None:
-                       _moduleLogger.info("No Backend")
+               if self._username is None and self._password is None:
+                       _moduleLogger.info("Hasn't even attempted to login yet")
                        return False
                elif self._backend.is_authed():
                        return True
@@ -63,20 +132,28 @@ class Session(object):
 
        @property
        def addressbook(self):
-               """
-               Delay initialized addressbook
-               """
-               if self._addressbook is None:
-                       _moduleLogger.info("Initializing addressbook")
-                       self._addressbook = addressbook.Addressbook(self.backend)
                return self._addressbook
 
        @property
-       def conversations(self):
-               """
-               Delay initialized addressbook
-               """
-               if self._conversations is None:
-                       _moduleLogger.info("Initializing conversations")
-                       self._conversations = conversations.Conversations(self.backend)
-               return self._conversations
+       def texts(self):
+               return self._texts
+
+       @property
+       def voicemails(self):
+               return self._voicemails
+
+       @property
+       def stateMachine(self):
+               return self._masterStateMachine
+
+       @property
+       def addressbookStateMachine(self):
+               return self._addressbookStateMachine
+
+       @property
+       def voicemailsStateMachine(self):
+               return self._voicemailsStateMachine
+
+       @property
+       def textsStateMachine(self):
+               return self._textsStateMachine