Slowly transforming things into the shape needed to be ready to get things working
authorEd Page <eopage@byu.net>
Thu, 1 Oct 2009 02:37:39 +0000 (21:37 -0500)
committerEd Page <eopage@byu.net>
Thu, 1 Oct 2009 02:37:39 +0000 (21:37 -0500)
src/connection.py
src/gvoice/__init__.py [new file with mode: 0644]
src/gvoice/addressbook.py
src/gvoice/backend.py
src/gvoice/session.py [new file with mode: 0644]
src/location.py
src/simple_presence.py

index 2fd3632..32b47c2 100644 (file)
@@ -46,8 +46,7 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                        self._channelManager = channel_manager.ChannelManager(self)
 
                        cookieFilePath = "%s/cookies.txt" % constants._data_path_
-                       self._backend = gvoice.dialer.GVDialer(cookieFilePath)
-                       self._addressbook = gvoice.addressbook.Addressbook(self._backend)
+                       self._session = gvoice.session.Session(cookieFilePath)
 
                        self.set_self_handle(handle.create_handle(self, 'connection'))
 
@@ -61,12 +60,8 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                return self._manager
 
        @property
-       def gvoice_backend(self):
-               return self._backend
-
-       @property
-       def addressbook(self):
-               return self._addressbook
+       def session(self):
+               return self._session
 
        @property
        def username(self):
@@ -85,9 +80,9 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                        telepathy.CONNECTION_STATUS_REASON_REQUESTED
                )
                try:
-                       self._backend.login(*self._credentials)
-                       self._backend.set_callback_number(self._callbackNumber)
-               except gvoice.dialer.NetworkError:
+                       self.session.login(*self._credentials)
+                       self.session.backend.set_callback_number(self._callbackNumber)
+               except gvoice.backend.NetworkError:
                        self.StatusChanged(
                                telepathy.CONNECTION_STATUS_DISCONNECTED,
                                telepathy.CONNECTION_STATUS_REASON_NETWORK_ERROR
@@ -108,7 +103,7 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
                For org.freedesktop.telepathy.Connection
                """
                try:
-                       self._backend.logout()
+                       self.session.logout()
                        _moduleLogger.info("Disconnected")
                except Exception:
                        _moduleLogger.exception("Disconnecting Failed")
@@ -171,7 +166,7 @@ class TheOneRingConnection(telepathy.server.Connection, simple_presence.SimplePr
        def _create_contact_handle(self, name):
                requestedContactId = name
 
-               contacts = self._addressbook.get_contacts()
+               contacts = self.session.addressbook.get_contacts()
                contactsFound = [
                        contactId for contactId in contacts
                        if contactId == requestedContactId
diff --git a/src/gvoice/__init__.py b/src/gvoice/__init__.py
new file mode 100644 (file)
index 0000000..afabc11
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/python
+
+import backend
+import addressbook
+import session
index aeb8de5..bdbd9d8 100644 (file)
@@ -20,7 +20,9 @@ class Addressbook(object):
 
                self.updateSignalHandler = coroutines.CoTee()
 
-       def update(self):
+       def update(self, force=False):
+               if not force and self._contacts:
+                       return
                oldContacts = self._contacts
                oldContactIds = set(self.get_contacts())
 
index 9029606..b578445 100755 (executable)
@@ -46,7 +46,7 @@ except ImportError:
        simplejson = None
 
 
-_moduleLogger = logging.getLogger("gvoice.dialer")
+_moduleLogger = logging.getLogger("gvoice.backend")
 _TRUE_REGEX = re.compile("true")
 _FALSE_REGEX = re.compile("false")
 
@@ -98,7 +98,11 @@ def itergroup(iterator, count, padValue = None):
        return itertools.izip(*nIterators)
 
 
-class GVDialer(object):
+class NetworkError(RuntimeError):
+       pass
+
+
+class GVoiceBackend(object):
        """
        This class encapsulates all of the knowledge necessary to interact with the GoogleVoice servers
        the functions include login, setting up a callback number, and initalting a callback
@@ -159,8 +163,8 @@ class GVDialer(object):
                try:
                        loginSuccessOrFailurePage = self._browser.download(self._loginURL, loginPostData)
                except urllib2.URLError, e:
-                       _moduleLogger.exception(str(e))
-                       raise RuntimeError("%s is not accesible" % self._loginURL)
+                       _moduleLogger.exception("Translating error: %s" % str(e))
+                       raise NetworkError("%s is not accesible" % self._loginURL)
 
                try:
                        self._grab_account_info(loginSuccessOrFailurePage)
@@ -196,8 +200,8 @@ class GVDialer(object):
                        }
                        callSuccessPage = self._browser.download(self._clicktocallURL, clickToCallData, None, otherData)
                except urllib2.URLError, e:
-                       _moduleLogger.exception(str(e))
-                       raise RuntimeError("%s is not accesible" % self._clicktocallURL)
+                       _moduleLogger.exception("Translating error: %s" % str(e))
+                       raise NetworkError("%s is not accesible" % self._clicktocallURL)
 
                if self._gvDialingStrRe.search(callSuccessPage) is None:
                        raise RuntimeError("Google Voice returned an error")
@@ -221,8 +225,8 @@ class GVDialer(object):
                        }
                        smsSuccessPage = self._browser.download(self._sendSmsURL, smsData, None, otherData)
                except urllib2.URLError, e:
-                       _moduleLogger.exception(str(e))
-                       raise RuntimeError("%s is not accesible" % self._sendSmsURL)
+                       _moduleLogger.exception("Translating error: %s" % str(e))
+                       raise NetworkError("%s is not accesible" % self._sendSmsURL)
 
                return True
 
@@ -282,8 +286,8 @@ class GVDialer(object):
                        try:
                                flatXml = self._browser.download(url)
                        except urllib2.URLError, e:
-                               _moduleLogger.exception(str(e))
-                               raise RuntimeError("%s is not accesible" % url)
+                               _moduleLogger.exception("Translating error: %s" % str(e))
+                               raise NetworkError("%s is not accesible" % url)
 
                        allRecentHtml = self._grab_html(flatXml)
                        allRecentData = self._parse_voicemail(allRecentHtml)
@@ -304,8 +308,8 @@ class GVDialer(object):
                        try:
                                contactsPage = self._browser.download(contactsPageUrl)
                        except urllib2.URLError, e:
-                               _moduleLogger.exception(str(e))
-                               raise RuntimeError("%s is not accesible" % contactsPageUrl)
+                               _moduleLogger.exception("Translating error: %s" % str(e))
+                               raise NetworkError("%s is not accesible" % contactsPageUrl)
                        for contact_match in self._contactsRe.finditer(contactsPage):
                                contactId = contact_match.group(1)
                                contactName = saxutils.unescape(contact_match.group(2))
@@ -327,8 +331,8 @@ class GVDialer(object):
                try:
                        detailPage = self._browser.download(self._contactDetailURL + '/' + contactId)
                except urllib2.URLError, e:
-                       _moduleLogger.exception(str(e))
-                       raise RuntimeError("%s is not accesible" % self._contactDetailURL)
+                       _moduleLogger.exception("Translating error: %s" % str(e))
+                       raise NetworkError("%s is not accesible" % self._contactDetailURL)
 
                for detail_match in self._contactDetailPhoneRe.finditer(detailPage):
                        phoneNumber = detail_match.group(1)
@@ -342,8 +346,8 @@ class GVDialer(object):
                try:
                        voicemailPage = self._browser.download(self._voicemailURL)
                except urllib2.URLError, e:
-                       _moduleLogger.exception(str(e))
-                       raise RuntimeError("%s is not accesible" % self._voicemailURL)
+                       _moduleLogger.exception("Translating error: %s" % str(e))
+                       raise NetworkError("%s is not accesible" % self._voicemailURL)
                voicemailHtml = self._grab_html(voicemailPage)
                parsedVoicemail = self._parse_voicemail(voicemailHtml)
                decoratedVoicemails = self._decorate_voicemail(parsedVoicemail)
@@ -351,8 +355,8 @@ class GVDialer(object):
                try:
                        smsPage = self._browser.download(self._smsURL)
                except urllib2.URLError, e:
-                       _moduleLogger.exception(str(e))
-                       raise RuntimeError("%s is not accesible" % self._smsURL)
+                       _moduleLogger.exception("Translating error: %s" % str(e))
+                       raise NetworkError("%s is not accesible" % self._smsURL)
                smsHtml = self._grab_html(smsPage)
                parsedSms = self._parse_sms(smsHtml)
                decoratedSms = self._decorate_sms(parsedSms)
@@ -616,7 +620,7 @@ def decorate_message(messageData):
 
 
 def test_backend(username, password):
-       backend = GVDialer()
+       backend = GVoiceBackend()
        print "Authenticated: ", backend.is_authed()
        if not backend.is_authed():
                print "Login?: ", backend.login(username, password)
diff --git a/src/gvoice/session.py b/src/gvoice/session.py
new file mode 100644 (file)
index 0000000..674baf7
--- /dev/null
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+
+import logging
+
+import backend
+import addressbook
+
+
+_moduleLogger = logging.getLogger("gvoice.session")
+
+
+class Session(object):
+
+       def __init__(self, cookiePath):
+               self._cookiePath = cookiePath
+               self._username = None
+               self._password = None
+               self._backend = None
+               self._addressbook = None
+
+       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)
+
+       def logout(self):
+               self._username = None
+               self._password = None
+               self._backend = None
+               self._addressbook = None
+
+       def is_logged_in(self):
+               if self._backend is None:
+                       return False
+               elif self._backend.is_authed():
+                       return True
+               else:
+                       try:
+                               loggedIn = self._backend.login(self._username, self._password)
+                       except RuntimeError:
+                               loggedIn = False
+                       if loggedIn:
+                               return True
+                       else:
+                               self.logout()
+                               return False
+
+       @property
+       def backend(self):
+               """
+               Login enforcing backend
+               """
+               assert self.is_logged_in(), "User not logged in"
+               return self._backend
+
+       @property
+       def addressbook(self):
+               """
+               Delay initialized addressbook
+               """
+               if self._addressbook is None:
+                       _moduleLogger.info("Initializing addressbook")
+                       self._addressbook = addressbook.Addressbook(self.backend)
+                       self._addressbook.update()
+               return self._addressbook
index 1965255..24e73a0 100644 (file)
@@ -7,7 +7,7 @@ class LocationMixin(telepathy.server.ConnectionInterfaceLocation):
                telepathy.server.ConnectionInterfaceLocation.__init__(self)
 
        @property
-       def gvoice_backend(self):
+       def session(self):
                """
                @abstract
                """
index b309e14..b95c2ea 100644 (file)
@@ -26,7 +26,7 @@ class SimplePresenceMixin(telepathy.server.ConnectionInterfaceSimplePresence):
                self._implement_property_get(dbus_interface, {'Statuses' : self._get_statuses})
 
        @property
-       def gvoice_backend(self):
+       def session(self):
                """
                @abstract
                """