5 from PyQt4 import QtCore
7 from util import qore_utils
8 from util import concurrent
10 from backends import gv_backend
13 _moduleLogger = logging.getLogger(__name__)
16 class Draft(QtCore.QObject):
18 sendingMessage = QtCore.pyqtSignal()
19 sentMessage = QtCore.pyqtSignal()
20 calling = QtCore.pyqtSignal()
21 called = QtCore.pyqtSignal()
22 cancelling = QtCore.pyqtSignal()
23 cancelled = QtCore.pyqtSignal()
24 error = QtCore.pyqtSignal(str)
26 recipientsChanged = QtCore.pyqtSignal()
28 def __init__(self, pool):
29 QtCore.QObject.__init__(self)
34 assert 0 < len(self._contacts)
35 self.sendingMessage.emit()
36 self.error.emit("Not Implemented")
40 assert len(self._contacts) == 1
42 self.error.emit("Not Implemented")
46 self.cancelling.emit()
47 self.error.emit("Not Implemented")
49 def add_contact(self, contact, details):
50 assert contact not in self._contacts
51 self._contacts[contact] = details
52 self.recipientsChanged.emit()
54 def remove_contact(self, contact):
55 assert contact not in self._contacts
56 del self._contacts[contact]
57 self.recipientsChanged.emit()
59 def get_contacts(self, contact):
64 self.recipientsChanged.emit()
67 class Session(QtCore.QObject):
69 stateChange = QtCore.pyqtSignal(str)
70 loggedOut = QtCore.pyqtSignal()
71 loggedIn = QtCore.pyqtSignal()
72 callbackNumberChanged = QtCore.pyqtSignal(str)
74 contactsUpdated = QtCore.pyqtSignal()
75 messagesUpdated = QtCore.pyqtSignal()
76 historyUpdated = QtCore.pyqtSignal()
77 dndStateChange = QtCore.pyqtSignal(bool)
79 error = QtCore.pyqtSignal(str)
81 LOGGEDOUT_STATE = "logged out"
82 LOGGINGIN_STATE = "logging in"
83 LOGGEDIN_STATE = "logged in"
88 def __init__(self, cachePath = None):
89 QtCore.QObject.__init__(self)
90 self._pool = qore_utils.AsyncPool()
92 self._loggedInTime = self._LOGGEDOUT_TIME
94 self._cachePath = cachePath
96 self._draft = Draft(self._pool)
106 self._LOGGEDOUT_TIME: self.LOGGEDOUT_STATE,
107 self._LOGGINGIN_TIME: self.LOGGINGIN_STATE,
108 }.get(self._loggedInTime, self.LOGGEDIN_STATE)
114 def login(self, username, password):
115 assert self.state == self.LOGGEDOUT_STATE
116 if self._cachePath is not None:
117 cookiePath = os.path.join(self._cachePath, "%s.cookies" % username)
121 if self._username != username or self._backend is None:
122 self._backend = gv_backend.GVDialer(cookiePath)
125 le = concurrent.AsyncLinearExecution(self._pool, self._login)
126 le.start(username, password)
129 assert self.state != self.LOGGEDOUT_STATE
131 self.error.emit("Not Implemented")
134 assert self.state == self.LOGGEDOUT_STATE
138 self.contactsUpdated.emit()
140 self.messagesUpdated.emit()
142 self.historyUpdated.emit()
144 self.dndStateChange.emit(self._dnd)
146 def update_contacts(self):
147 le = concurrent.AsyncLinearExecution(self._pool, self._update_contacts)
148 self._perform_op_while_loggedin(le)
150 def get_contacts(self):
151 return self._contacts
153 def update_messages(self):
154 le = concurrent.AsyncLinearExecution(self._pool, self._update_messages)
155 self._perform_op_while_loggedin(le)
157 def get_messages(self):
158 return self._messages
160 def update_history(self):
161 le = concurrent.AsyncLinearExecution(self._pool, self._update_history)
162 self._perform_op_while_loggedin(le)
164 def get_history(self):
167 def update_dnd(self):
168 le = concurrent.AsyncLinearExecution(self._pool, self._update_dnd)
169 self._perform_op_while_loggedin(le)
171 def set_dnd(self, dnd):
172 assert self.state == self.LOGGEDIN_STATE
173 self.error.emit("Not Implemented")
178 def get_callback_numbers(self):
181 def get_callback_number(self):
184 def set_callback_number(self):
185 assert self.state == self.LOGGEDIN_STATE
186 self.error.emit("Not Implemented")
188 def _login(self, username, password):
189 self._loggedInTime = self._LOGGINGIN_TIME
190 self.stateChange.emit(self.LOGGINGIN_STATE)
191 finalState = self.LOGGEDOUT_STATE
195 if not isLoggedIn and self._backend.is_quick_login_possible():
198 self._backend.is_authed,
203 self.error.emit(str(e))
206 _moduleLogger.info("Logged in through cookies")
212 (username, password),
216 self.error.emit(str(e))
219 _moduleLogger.info("Logged in through credentials")
222 self._loggedInTime = time.time()
223 self._username = username
224 finalState = self.LOGGEDIN_STATE
226 # if the username is the same, do nothing
227 # else clear the in-memory caches and attempt to load from file-caches
228 # If caches went from empty to something, fire signals
229 # Fire off queued async ops
231 self.error.emit(str(e))
233 self.stateChange.emit(finalState)
235 def _update_contacts(self):
236 self.error.emit("Not Implemented")
239 self._backend.is_authed,
244 self.error.emit(str(e))
247 def _update_messages(self):
248 self.error.emit("Not Implemented")
251 self._backend.is_authed,
256 self.error.emit(str(e))
259 def _update_history(self):
260 self.error.emit("Not Implemented")
263 self._backend.is_authed,
268 self.error.emit(str(e))
271 def _update_dnd(self):
272 self.error.emit("Not Implemented")
275 self._backend.is_authed,
280 self.error.emit(str(e))
283 def _perform_op_while_loggedin(self, op):
284 if self.state == self.LOGGEDIN_STATE:
287 self._push_login_op(op)
289 def _push_login_op(self, asyncOp):
290 assert self.state != self.LOGGEDIN_STATE
291 if asyncOp in self._loginOps:
292 _moduleLogger.info("Skipping queueing duplicate op: %r" % asyncOp)
294 self._loginOps.append(asyncOp)