import urllib2
import time
import warnings
+import traceback
from browser_emu import MozillaEmulator
return True
try:
- forwardSelectionPage = self._browser.download(GCDialer._forwardselectURL)
+ forwardSelectionPage = self._browser.download(self._forwardselectURL)
except urllib2.URLError, e:
- raise RuntimeError("%s is not accesible" % GCDialer._forwardselectURL)
+ warnings.warn(traceback.format_exc())
+ raise RuntimeError("%s is not accesible" % self._forwardselectURL)
self._browser.cookies.save()
- if GCDialer._isLoginPageRe.search(forwardSelectionPage) is None:
- self._grab_token(forwardSelectionPage)
- self._lastAuthed = time.time()
- return True
+ if self._isLoginPageRe.search(forwardSelectionPage) is not None:
+ return False
- return False
+ self._grab_token(forwardSelectionPage)
+ self._lastAuthed = time.time()
+ return True
def login(self, username, password):
"""
loginPostData = urllib.urlencode( {'username' : username , 'password' : password } )
try:
- loginSuccessOrFailurePage = self._browser.download(GCDialer._loginURL, loginPostData)
+ loginSuccessOrFailurePage = self._browser.download(self._loginURL, loginPostData)
except urllib2.URLError, e:
- raise RuntimeError("%s is not accesible" % GCDialer._loginURL)
+ warnings.warn(traceback.format_exc())
+ raise RuntimeError("%s is not accesible" % self._loginURL)
return self.is_authed()
"""
This is the main function responsible for initating the callback
"""
- # If the number is not valid throw exception
if not self.is_valid_syntax(number):
- raise ValueError('number is not valid')
-
- # No point if we don't have the magic cookie
- if not self.is_authed():
+ raise ValueError('Number is not valid: "%s"' % number)
+ elif not self.is_authed():
raise RuntimeError("Not Authenticated")
- # Strip leading 1 from 11 digit dialing
if len(number) == 11 and number[0] == 1:
+ # Strip leading 1 from 11 digit dialing
number = number[1:]
try:
callSuccessPage = self._browser.download(
- GCDialer._clicktocallURL % (self._accessToken, number),
+ self._clicktocallURL % (self._accessToken, number),
None,
{'Referer' : 'http://www.grandcentral.com/mobile/messages'}
)
except urllib2.URLError, e:
- raise RuntimeError("%s is not accesible" % GCDialer._clicktocallURL)
+ warnings.warn(traceback.format_exc())
+ raise RuntimeError("%s is not accesible" % self._clicktocallURL)
- if GCDialer._gcDialingStrRe.search(callSuccessPage) is None:
+ if self._gcDialingStrRe.search(callSuccessPage) is None:
raise RuntimeError("Grand Central returned an error")
return True
numbers = self.get_callback_numbers()
for number, description in numbers.iteritems():
- if not re.compile(r"""1747""").match(number) is None:
+ if re.compile(r"""1747""").match(number) is not None:
self.set_callback_number(number)
return
for number, description in numbers.iteritems():
- if not re.compile(r"""gizmo""", re.I).search(description) is None:
+ if re.compile(r"""gizmo""", re.I).search(description) is not None:
self.set_callback_number(number)
return
for number, description in numbers.iteritems():
- if not re.compile(r"""computer""", re.I).search(description) is None:
+ if re.compile(r"""computer""", re.I).search(description) is not None:
self.set_callback_number(number)
return
'default_number': callbacknumber
})
try:
- callbackSetPage = self._browser.download(GCDialer._setforwardURL, callbackPostData)
+ callbackSetPage = self._browser.download(self._setforwardURL, callbackPostData)
except urllib2.URLError, e:
- raise RuntimeError("%s is not accesible" % GCDialer._setforwardURL)
+ warnings.warn(traceback.format_exc())
+ raise RuntimeError("%s is not accesible" % self._setforwardURL)
self._browser.cookies.save()
return True
@returns Iterable of (personsName, phoneNumber, date, action)
"""
try:
- recentCallsPage = self._browser.download(GCDialer._inboxallURL)
+ recentCallsPage = self._browser.download(self._inboxallURL)
except urllib2.URLError, e:
- raise RuntimeError("%s is not accesible" % GCDialer._inboxallURL)
+ warnings.warn(traceback.format_exc())
+ raise RuntimeError("%s is not accesible" % self._inboxallURL)
for match in self._inboxRe.finditer(recentCallsPage):
phoneNumber = match.group(4)
if self.__contacts is None:
self.__contacts = []
- contactsPagesUrls = [GCDialer._contactsURL]
+ contactsPagesUrls = [self._contactsURL]
for contactsPageUrl in contactsPagesUrls:
try:
contactsPage = self._browser.download(contactsPageUrl)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % contactsPageUrl)
for contact_match in self._contactsRe.finditer(contactsPage):
contactId = contact_match.group(1)
@returns Iterable of (Phone Type, Phone Number)
"""
try:
- detailPage = self._browser.download(GCDialer._contactDetailURL + '/' + contactId)
+ detailPage = self._browser.download(self._contactDetailURL + '/' + contactId)
except urllib2.URLError, e:
- raise RuntimeError("%s is not accesible" % GCDialer._contactDetailURL)
+ warnings.warn(traceback.format_exc())
+ raise RuntimeError("%s is not accesible" % self._contactDetailURL)
for detail_match in self._contactDetailPhoneRe.finditer(detailPage):
phoneType = detail_match.group(1)
def _grab_token(self, data):
"Pull the magic cookie from the datastream"
- atGroup = GCDialer._accessTokenRe.search(data)
+ atGroup = self._accessTokenRe.search(data)
self._accessToken = atGroup.group(1)
- anGroup = GCDialer._accountNumRe.search(data)
+ anGroup = self._accountNumRe.search(data)
self._accountNum = anGroup.group(1)
self._callbackNumbers = {}
- for match in GCDialer._callbackRe.finditer(data):
+ for match in self._callbackRe.finditer(data):
self._callbackNumbers[match.group(1)] = match.group(2)
+
+
+def test_backend(username, password):
+ import pprint
+ backend = GCDialer()
+ print "Authenticated: ", backend.is_authed()
+ print "Login?: ", backend.login(username, password)
+ print "Authenticated: ", backend.is_authed()
+ print "Token: ", backend._token
+ print "Account: ", backend.get_account_number()
+ print "Callback: ", backend.get_callback_number()
+ # print "All Callback: ",
+ # pprint.pprint(backend.get_callback_numbers())
+ # print "Recent: ",
+ # pprint.pprint(list(backend.get_recent()))
+ # print "Contacts: ",
+ # for contact in backend.get_contacts():
+ # print contact
+ # pprint.pprint(list(backend.get_contact_details(contact[0])))
+
+ return backend
import threading
import time
import warnings
+import traceback
import gobject
import gtk
if phonenumber is None or phonenumber is "":
return ""
+ phonenumber = make_ugly(phonenumber)
+
if len(phonenumber) < 3:
return phonenumber
self._prettynumber = make_pretty(self._phonenumber)
self._numberdisplay.set_label("<span size='30000' weight='bold'>%s</span>" % (self._prettynumber))
except TypeError, e:
+ warnings.warn(traceback.format_exc())
self._errorDisplay.push_message(e.message)
def clear(self):
try:
callbackNumbers = self._backend.get_callback_numbers()
except RuntimeError, e:
+ warnings.warn(traceback.format_exc())
self._errorDisplay.push_message(e.message)
return
try:
callbackNumber = self._backend.get_callback_number()
except RuntimeError, e:
+ warnings.warn(traceback.format_exc())
self._errorDisplay.push_message(e.message)
return
self._callbackCombo.get_child().set_text(make_pretty(callbackNumber))
else:
self._backend.set_callback_number(text)
except RuntimeError, e:
+ warnings.warn(traceback.format_exc())
self._errorDisplay.push_message(e.message)
try:
recentItems = self._backend.get_recent()
except RuntimeError, e:
+ warnings.warn(traceback.format_exc())
gtk.gdk.threads_enter()
try:
self._errorDisplay.push_message(e.message)
gtk.gdk.threads_leave()
self._recenttime = 0.0
recentItems = []
+
for personsName, phoneNumber, date, action in recentItems:
description = "%s on %s from/to %s - %s" % (action.capitalize(), date, personsName, phoneNumber)
item = (phoneNumber, description)
try:
contacts = addressBook.get_contacts()
except RuntimeError, e:
+ warnings.warn(traceback.format_exc())
contacts = []
self._contactstime = 0.0
gtk.gdk.threads_enter()
try:
contactDetails = self._addressBook.get_contact_details(contactId)
except RuntimeError, e:
+ warnings.warn(traceback.format_exc())
contactDetails = []
self._contactstime = 0.0
self._errorDisplay.push_message(e.message)
+#!/usr/bin/python
+
+# DialCentral - Front end for Google's Grand Central service.
+# Copyright (C) 2008 Eric Warnke ericew AT gmail DOT com
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
import urllib2
import time
import warnings
+import traceback
from xml.etree import ElementTree
return safe_eval(flattened)
else:
def parse_json(flattened):
- return simplejson.loads(json)
+ return simplejson.loads(flattened)
class GVDialer(object):
try:
inboxPage = self._browser.download(self._inboxURL)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % self._inboxURL)
self._browser.cookies.save()
if self._isNotLoginPageRe.search(inboxPage) is not None:
return False
+ self._grab_account_info()
self._lastAuthed = time.time()
return True
Attempt to login to grandcentral
@returns Whether login was successful or not
"""
- #if self.is_authed():
- # return True
+ if self.is_authed():
+ return True
loginPostData = urllib.urlencode({
'Email' : username,
try:
loginSuccessOrFailurePage = self._browser.download(self._loginURL, loginPostData)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % self._loginURL)
- #self._grab_account_info(loginSuccessOrFailurePage)
- self._grab_account_info()
return self.is_authed()
def logout(self):
}
callSuccessPage = self._browser.download(self._clicktocallURL, clickToCallData, None, otherData)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % self._clicktocallURL)
if self._gvDialingStrRe.search(callSuccessPage) is None:
try:
callbackSetPage = self._browser.download(self._setforwardURL, callbackPostData)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % self._setforwardURL)
self._browser.cookies.save()
try:
allRecentData = self._grab_json(url)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % self._clicktocallURL)
for recentCallData in allRecentData["messages"].itervalues():
try:
contactsPage = self._browser.download(contactsPageUrl)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % self._clicktocallURL)
for contact_match in self._contactsRe.finditer(contactsPage):
contactId = contact_match.group(1)
try:
detailPage = self._browser.download(self._contactDetailURL + '/' + contactId)
except urllib2.URLError, e:
+ warnings.warn(traceback.format_exc())
raise RuntimeError("%s is not accesible" % self._clicktocallURL)
for detail_match in self._contactDetailPhoneRe.finditer(detailPage):
self._callbackNumbers = {}
for match in self._callbackRe.finditer(callbackPage):
self._callbackNumbers[match.group(2)] = match.group(1)
+
if len(self._callbackNumber) == 0:
self.set_sane_callback()