Improving state machine timing, logged material, comments, etc
[theonering] / src / gvoice / session.py
1 #!/usr/bin/env python
2
3 import logging
4
5 import backend
6 import addressbook
7 import conversations
8 import state_machine
9
10
11 _moduleLogger = logging.getLogger("gvoice.session")
12
13
14 class Session(object):
15
16         def __init__(self, cookiePath = None):
17                 self._username = None
18                 self._password = None
19
20                 self._backend = backend.GVoiceBackend(cookiePath)
21
22                 self._addressbook = addressbook.Addressbook(self._backend)
23                 self._addressbookStateMachine = state_machine.UpdateStateMachine([self.addressbook], "Addressbook")
24                 self._addressbookStateMachine.set_state_strategy(
25                         state_machine.StateMachine.STATE_DND,
26                         state_machine.NopStateStrategy()
27                 )
28                 self._addressbookStateMachine.set_state_strategy(
29                         state_machine.StateMachine.STATE_IDLE,
30                         state_machine.ConstantStateStrategy(state_machine.to_milliseconds(hours=6))
31                 )
32                 self._addressbookStateMachine.set_state_strategy(
33                         state_machine.StateMachine.STATE_ACTIVE,
34                         state_machine.ConstantStateStrategy(state_machine.to_milliseconds(hours=2))
35                 )
36
37                 self._voicemails = conversations.Conversations(self._backend.get_voicemails)
38                 self._voicemailsStateMachine = state_machine.UpdateStateMachine([self.voicemails], "Voicemail")
39                 self._voicemailsStateMachine.set_state_strategy(
40                         state_machine.StateMachine.STATE_DND,
41                         state_machine.NopStateStrategy()
42                 )
43                 self._voicemailsStateMachine.set_state_strategy(
44                         state_machine.StateMachine.STATE_IDLE,
45                         state_machine.ConstantStateStrategy(state_machine.to_milliseconds(minutes=60))
46                 )
47                 self._voicemailsStateMachine.set_state_strategy(
48                         state_machine.StateMachine.STATE_ACTIVE,
49                         state_machine.ConstantStateStrategy(state_machine.to_milliseconds(minutes=10))
50                 )
51                 self._voicemails.updateSignalHandler.register_sink(
52                         self._voicemailsStateMachine.request_reset_timers
53                 )
54
55                 self._texts = conversations.Conversations(self._backend.get_texts)
56                 self._textsStateMachine = state_machine.UpdateStateMachine([self.texts], "Texting")
57                 self._textsStateMachine.set_state_strategy(
58                         state_machine.StateMachine.STATE_DND,
59                         state_machine.NopStateStrategy()
60                 )
61                 self._textsStateMachine.set_state_strategy(
62                         state_machine.StateMachine.STATE_IDLE,
63                         state_machine.ConstantStateStrategy(state_machine.to_milliseconds(minutes=30))
64                 )
65                 self._textsStateMachine.set_state_strategy(
66                         state_machine.StateMachine.STATE_ACTIVE,
67                         state_machine.GeometricStateStrategy(
68                                 state_machine.to_milliseconds(seconds=20),
69                                 state_machine.to_milliseconds(milliseconds=500),
70                                 state_machine.to_milliseconds(minutes=10),
71                         )
72                 )
73                 self._texts.updateSignalHandler.register_sink(
74                         self._textsStateMachine.request_reset_timers
75                 )
76
77                 self._masterStateMachine = state_machine.MasterStateMachine()
78                 self._masterStateMachine.append_machine(self._addressbookStateMachine)
79                 self._masterStateMachine.append_machine(self._voicemailsStateMachine)
80                 self._masterStateMachine.append_machine(self._textsStateMachine)
81
82         def close(self):
83                 self._voicemails.updateSignalHandler.unregister_sink(
84                         self._voicemailsStateMachine.request_reset_timers
85                 )
86                 self._texts.updateSignalHandler.unregister_sink(
87                         self._textsStateMachine.request_reset_timers
88                 )
89                 self._masterStateMachine.close()
90
91         def login(self, username, password):
92                 self._username = username
93                 self._password = password
94                 self._backend.login(self._username, self._password)
95
96                 self._masterStateMachine.start()
97
98         def logout(self):
99                 self._masterStateMachine.stop()
100                 self._backend.logout()
101
102                 self._username = None
103                 self._password = None
104
105         def is_logged_in(self):
106                 if self._username is None and self._password is None:
107                         _moduleLogger.info("Hasn't even attempted to login yet")
108                         return False
109                 elif self._backend.is_authed():
110                         return True
111                 else:
112                         try:
113                                 loggedIn = self._backend.login(self._username, self._password)
114                         except RuntimeError, e:
115                                 _moduleLogger.exception("Re-authenticating and erroring")
116                                 loggedIn = False
117                         if loggedIn:
118                                 return True
119                         else:
120                                 _moduleLogger.info("Login failed")
121                                 self.logout()
122                                 return False
123
124         @property
125         def backend(self):
126                 """
127                 Login enforcing backend
128                 """
129                 assert self.is_logged_in(), "User not logged in"
130                 return self._backend
131
132         @property
133         def addressbook(self):
134                 return self._addressbook
135
136         @property
137         def texts(self):
138                 return self._texts
139
140         @property
141         def voicemails(self):
142                 return self._voicemails
143
144         @property
145         def stateMachine(self):
146                 return self._masterStateMachine
147
148         @property
149         def addressbookStateMachine(self):
150                 return self._addressbookStateMachine
151
152         @property
153         def voicemailsStateMachine(self):
154                 return self._voicemailsStateMachine
155
156         @property
157         def textsStateMachine(self):
158                 return self._textsStateMachine