13 _moduleLogger = logging.getLogger("gvoice.session")
16 class Session(object):
19 "contacts": (3, "hours"),
20 "voicemail": (30, "minutes"),
21 "texts": (5, "minutes"),
24 _MINIMUM_MESSAGE_PERIOD = state_machine.to_seconds(minutes=30)
26 def __init__(self, cookiePath = None, defaults = None):
28 defaults = self._DEFAULTS
30 for key, (quant, unit) in defaults.iteritems():
32 defaults[key] = self._DEFAULTS[key]
34 defaults[key] = state_machine.INFINITE_PERIOD
38 self._backend = backend.GVoiceBackend(cookiePath)
40 contactsPeriodInSeconds = state_machine.to_seconds(
41 **{defaults["contacts"][1]: defaults["contacts"][0],}
43 self._addressbook = addressbook.Addressbook(self._backend)
44 self._addressbookStateMachine = state_machine.UpdateStateMachine([self.addressbook], "Addressbook")
45 self._addressbookStateMachine.set_state_strategy(
46 state_machine.StateMachine.STATE_DND,
47 state_machine.NopStateStrategy()
49 self._addressbookStateMachine.set_state_strategy(
50 state_machine.StateMachine.STATE_IDLE,
51 state_machine.NopStateStrategy()
53 self._addressbookStateMachine.set_state_strategy(
54 state_machine.StateMachine.STATE_ACTIVE,
55 state_machine.ConstantStateStrategy(contactsPeriodInSeconds)
58 voicemailPeriodInSeconds = state_machine.to_seconds(
59 **{defaults["voicemail"][1]: defaults["voicemail"][0],}
61 self._voicemails = conversations.Conversations(self._backend.get_voicemails)
62 self._voicemailsStateMachine = state_machine.UpdateStateMachine([self.voicemails], "Voicemail")
63 self._voicemailsStateMachine.set_state_strategy(
64 state_machine.StateMachine.STATE_DND,
65 state_machine.NopStateStrategy()
67 self._voicemailsStateMachine.set_state_strategy(
68 state_machine.StateMachine.STATE_IDLE,
69 state_machine.ConstantStateStrategy(
70 min(voicemailPeriodInSeconds * 4, self._MINIMUM_MESSAGE_PERIOD)
73 self._voicemailsStateMachine.set_state_strategy(
74 state_machine.StateMachine.STATE_ACTIVE,
75 state_machine.ConstantStateStrategy(voicemailPeriodInSeconds)
77 self._voicemails.updateSignalHandler.register_sink(
78 self._voicemailsStateMachine.request_reset_timers
81 textsPeriodInSeconds = state_machine.to_seconds(
82 **{defaults["texts"][1]: defaults["texts"][0],}
84 self._texts = conversations.Conversations(self._backend.get_texts)
85 self._textsStateMachine = state_machine.UpdateStateMachine([self.texts], "Texting")
86 self._textsStateMachine.set_state_strategy(
87 state_machine.StateMachine.STATE_DND,
88 state_machine.NopStateStrategy()
90 self._textsStateMachine.set_state_strategy(
91 state_machine.StateMachine.STATE_IDLE,
92 state_machine.ConstantStateStrategy(
93 min(textsPeriodInSeconds * 4, self._MINIMUM_MESSAGE_PERIOD)
96 self._textsStateMachine.set_state_strategy(
97 state_machine.StateMachine.STATE_ACTIVE,
98 state_machine.GeometricStateStrategy(
99 state_machine.to_seconds(seconds=20),
100 state_machine.to_seconds(seconds=1),
101 textsPeriodInSeconds,
104 self._texts.updateSignalHandler.register_sink(
105 self._textsStateMachine.request_reset_timers
108 self._masterStateMachine = state_machine.MasterStateMachine()
109 self._masterStateMachine.append_machine(self._addressbookStateMachine)
110 self._masterStateMachine.append_machine(self._voicemailsStateMachine)
111 self._masterStateMachine.append_machine(self._textsStateMachine)
113 self._lastDndCheck = 0
114 self._cachedIsDnd = False
116 def load(self, path):
117 self._texts.load(os.sep.join((path, "texts.cache")))
118 self._voicemails.load(os.sep.join((path, "voicemails.cache")))
120 def save(self, path):
121 self._texts.save(os.sep.join((path, "texts.cache")))
122 self._voicemails.save(os.sep.join((path, "voicemails.cache")))
125 self._voicemails.updateSignalHandler.unregister_sink(
126 self._voicemailsStateMachine.request_reset_timers
128 self._texts.updateSignalHandler.unregister_sink(
129 self._textsStateMachine.request_reset_timers
131 self._masterStateMachine.close()
133 def login(self, username, password):
134 self._username = username
135 self._password = password
136 self._backend.login(self._username, self._password)
138 self._masterStateMachine.start()
141 self._masterStateMachine.stop()
142 self._backend.logout()
144 self._username = None
145 self._password = None
147 def is_logged_in(self):
148 if self._username is None and self._password is None:
149 _moduleLogger.info("Hasn't even attempted to login yet")
151 elif self._backend.is_authed():
155 loggedIn = self._backend.login(self._username, self._password)
156 except RuntimeError, e:
157 _moduleLogger.exception("Re-authenticating and erroring")
162 _moduleLogger.info("Login failed")
166 def set_dnd(self, doNotDisturb):
167 self._backend.set_dnd(doNotDisturb)
168 self._cachedIsDnd = doNotDisturb
171 # To throttle checking with the server, use a 30s cache
172 newTime = time.time()
173 if self._lastDndCheck + 30 < newTime:
174 self._lasDndCheck = newTime
175 self._cachedIsDnd = self._backend.is_dnd()
176 return self._cachedIsDnd
181 Login enforcing backend
183 assert self.is_logged_in(), "User not logged in"
187 def addressbook(self):
188 return self._addressbook
195 def voicemails(self):
196 return self._voicemails
199 def stateMachine(self):
200 return self._masterStateMachine
203 def addressbookStateMachine(self):
204 return self._addressbookStateMachine
207 def voicemailsStateMachine(self):
208 return self._voicemailsStateMachine
211 def textsStateMachine(self):
212 return self._textsStateMachine