* Trying to make some areas clearer to myself through comments
[gc-dialer] / gc_dialer / gcbackend.py
index 85b8fe4..888e8e4 100644 (file)
@@ -38,60 +38,34 @@ class GCDialer(object):
        def __init__(self, cookieFile = None):
                # Important items in this function are the setup of the browser emulation and cookie file
                self._msg = ""
+
+               self._browser = MozillaEmulator(None, 0)
                if cookieFile is None:
                        cookieFile = os.path.join(os.path.expanduser("~"), ".gc_dialer_cookies.txt")
-               self._browser = MozillaEmulator(None, 0)
                self._browser.cookies.filename = cookieFile
                if os.path.isfile(cookieFile):
                        self._browser.cookies.load()
-               #else:
-               #       self._browser.cookies.save()
-               self._lastData = ""
+
                self._accessToken = None
                self._accountNum = None
                self._callbackNumbers = {}
                self._lastAuthed = 0.0
 
-       def grabToken(self, data):
-               "Pull the magic cookie from the datastream"
-               atGroup = GCDialer._accessTokenRe.search(data)
-               try:
-                       self._accessToken = atGroup.group(1)
-               except:
-                       pass
-
-               anGroup = GCDialer._accountNumRe.search(data)
-               try:
-                       self._accountNum = anGroup.group(1)
-               except:
-                       pass
-
-               self._callbackNumbers = {}
-               try:
-                       for match in GCDialer._callbackRe.finditer(data):
-                               self._callbackNumbers[match.group(1)] = match.group(2)
-               except:
-                       pass
-
-       def getAccountNumber(self):
-               return self._accountNum
-
        def isAuthed(self, force = False):
                """
-               Attempts to detect a current session and pull the
-               auth token ( a_t ) from the page.  Once logged in
-               try not to reauth more than once a minute.
+               Attempts to detect a current session and pull the auth token ( a_t ) from the page.
+               @note Once logged in try not to reauth more than once a minute.
+               @returns If authenticated
                """
-       
 
                if time.time() - self._lastAuthed < 60 and not force:
                        return True
 
                try:    
-                       self._lastData = self._browser.download(GCDialer._forwardselectURL)
+                       forwardSelectionPage = self._browser.download(GCDialer._forwardselectURL)
                        self._browser.cookies.save()
-                       if GCDialer._isLoginPageRe.search(self._lastData) is None:
-                               self.grabToken(self._lastData)
+                       if GCDialer._isLoginPageRe.search(forwardSelectionPage) is None:
+                               self._grabToken(forwardSelectionPage)
                                self._lastAuthed = time.time()
                                return True
                except:
@@ -101,17 +75,76 @@ class GCDialer(object):
        def login(self, username, password):
                """
                Attempt to login to grandcentral
+               @returns Whether login was successful or not
                """
                try:
                        if self.isAuthed():
-                               return
+                               return True
                        loginPostData = urllib.urlencode( {'username' : username , 'password' : password } )
-                       self._lastData = self._browser.download(GCDialer._loginURL, loginPostData)
+                       loginSuccessOrFailurePage = self._browser.download(GCDialer._loginURL, loginPostData)
                        return self.isAuthed()
                except:
                        pass
                return False
 
+       def dial(self, number):
+               """
+               This is the main function responsible for initating the callback
+               """
+               self._msg = ""
+
+               # If the number is not valid throw exception
+               if self.validate(number) is False:
+                       raise ValueError('number is not valid')
+
+               # No point if we don't have the magic cookie
+               if not self.isAuthed():
+                       self._msg = "Not authenticated"
+                       return False
+
+               # Strip leading 1 from 11 digit dialing
+               if len(number) == 11 and number[0] == 1:
+                       number = number[1:]
+
+               try:
+                       callSuccessPage = self._browser.download(
+                               GCDialer._clicktocallURL % (self._accessToken, number),
+                               None, {'Referer' : 'http://www.grandcentral.com/mobile/messages'} )
+
+                       if GCDialer._gcDialingStrRe.search(callSuccessPage) is not None:
+                               return True
+                       else:
+                               self._msg = "Grand Central returned an error"
+                               return False
+               except:
+                       pass
+       
+               self._msg = "Unknown Error"
+               return False
+
+       def clear_caches(self):
+               """
+               @todo Fill this in
+               """
+               pass
+
+       def reset(self):
+               self._lastAuthed = 0.0
+               self._browser.cookies.clear()
+               self._browser.cookies.save()
+
+       def getAccountNumber(self):
+               """
+               @returns The grand central phone number
+               """
+               return self._accountNum
+
+       def validate(self, number):
+               """
+               @returns If This number be called ( syntax validation only )
+               """
+               return GCDialer._validateRe.match(number) is not None
+
        def setSaneCallback(self):
                """
                Try to set a sane default callback number on these preferences
@@ -144,8 +177,8 @@ class GCDialer(object):
 
        def getCallbackNumbers(self):
                """
-               @returns a dictionary mapping call back numbers to descriptions. These results
-               are cached for 30 minutes.
+               @returns a dictionary mapping call back numbers to descriptions
+               @note These results are cached for 30 minutes.
                """
                print "getCallbackNumbers"
                if time.time() - self._lastAuthed < 1800 or self.isAuthed():
@@ -155,67 +188,54 @@ class GCDialer(object):
 
        def setCallbackNumber(self, callbacknumber):
                """
-               set the number that grandcental calls
-               this should be a proper 10 digit number
+               Set the number that grandcental calls
+               @param callbacknumber should be a proper 10 digit number
                """
                print "setCallbackNumber %s" % (callbacknumber)
                try:
                        callbackPostData = urllib.urlencode({'a_t' : self._accessToken, 'default_number' : callbacknumber })
-                       self._lastData = self._browser.download(GCDialer._setforwardURL, callbackPostData)
+                       callbackSetPage = self._browser.download(GCDialer._setforwardURL, callbackPostData)
                        self._browser.cookies.save()
                except:
                        pass
 
        def getCallbackNumber(self):
+               """
+               @returns Current callback number or None
+               """
                for c in self._browser.cookies:
                        if c.name == "pda_forwarding_number":
                                return c.value
                return None
 
-       def reset(self):
-               self._lastAuthed = 0.0
-               self._browser.cookies.clear()
-               self._browser.cookies.save()
-
-       def validate(self, number):
-               """
-               Can this number be called ( syntax validation only )
-               """
-               return GCDialer._validateRe.match(number) is not None
-
-       def dial(self, number):
+       def get_recent(self):
                """
-               This is the main function responsible for initating the callback
+               @returns Iterable of (Phone Number, Description)
                """
-               # If the number is not valid throw exception
-               if self.validate(number) is False:
-                       raise ValueError('number is not valid')
-
-               # No point if we don't have the magic cookie
-               if not self.isAuthed():
-                       return False
-
-               # Strip leading 1 from 11 digit dialing
-               if len(number) == 11 and number[0] == 1:
-                       number = number[1:]
+               try:
+                       recentCallsPage = self._browser.download(GCDialer._inboxallURL)
+                       for match in self._inboxRe.finditer(recentCallsPage):
+                               yield (match.group(4), "%s on %s from/to %s - %s" % (match.group(1).capitalize(), match.group(2), match.group(3), match.group(4)))
+               except:
+                       pass
 
+       def _grabToken(self, data):
+               "Pull the magic cookie from the datastream"
+               atGroup = GCDialer._accessTokenRe.search(data)
                try:
-                       self._lastData = self._browser.download(
-                               GCDialer._clicktocallURL % (self._accessToken, number),
-                               None, {'Referer' : 'http://www.grandcentral.com/mobile/messages'} )
+                       self._accessToken = atGroup.group(1)
+               except:
+                       pass
 
-                       if GCDialer._gcDialingStrRe.search(self._lastData) is not None:
-                               return True
-                       else:
-                               return False
+               anGroup = GCDialer._accountNumRe.search(data)
+               try:
+                       self._accountNum = anGroup.group(1)
                except:
                        pass
-               return False
 
-       def get_recent(self):
+               self._callbackNumbers = {}
                try:
-                       self._lastData = self._browser.download(GCDialer._inboxallURL)
-                       for match in self._inboxRe.finditer(self._lastData):
-                               yield (match.group(4), "%s on %s from/to %s - %s" % (match.group(1).capitalize(), match.group(2), match.group(3), match.group(4)))
+                       for match in GCDialer._callbackRe.finditer(data):
+                               self._callbackNumbers[match.group(1)] = match.group(2)
                except:
                        pass