Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Login crash (May 2017). Add USER_AGENT setting. #40

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f6f5df1
Add USER_AGENT setting.
chris001 Feb 8, 2017
984e343
Use settings USER_AGENT
chris001 Feb 8, 2017
077b106
Fix LOGIN error. Add USER_AGENT.
chris001 May 22, 2017
58bc9f4
Remove GALX (removed by GV june 2017).
chris001 Jun 20, 2017
c605c96
Add *.pyc (compiled python) files to gitignore
chris001 Jun 20, 2017
cc2d752
Bug fix for compatibility with Python 3.
chris001 Jun 20, 2017
ffbae58
Remove galx. Fix typo ) instead of }
chris001 Jun 21, 2017
3e42664
Add requirements.txt
chris001 Jun 21, 2017
b0e71e1
Add .travis.yml (#2)
chris001 Jun 21, 2017
badec6e
Add name to README (#3)
chris001 Jun 21, 2017
ebda0da
Update install
chris001 Jun 21, 2017
e43d9b8
Test travis with intentional syntax error
chris001 Jun 21, 2017
71ca5c1
Fix intentional syntax error test of travis
chris001 Jun 21, 2017
664cf1d
Add sudo to copy in .travis.yml
chris001 Jun 21, 2017
3e55ba9
Test only python 2, 3 and nightly.
chris001 Jun 21, 2017
a3fe18a
Test only python 2 and nightly (3.9).
chris001 Jun 21, 2017
8b993a4
Test on trusty (14.04) in docker container.
chris001 Jun 21, 2017
8c5b1d6
Fix travis install to run on container.
chris001 Jun 21, 2017
c3d37e2
Add tests folder. Update .travis.yml
chris001 Jun 21, 2017
a2aac5c
.travis.yml
chris001 Jun 21, 2017
aca2508
.travis.yml
chris001 Jun 21, 2017
d1a44d5
test_call
chris001 Jun 21, 2017
0a45042
test_delete
chris001 Jun 21, 2017
d30ca5d
test_call test_delete
chris001 Jun 21, 2017
3fe838b
tests.
chris001 Jun 21, 2017
fa5a9a1
tests.
chris001 Jun 21, 2017
85c772f
requirements.
chris001 Jun 21, 2017
451cb01
requirements. bs4.
chris001 Jun 21, 2017
81804e8
Update README.rst
chris001 Jun 22, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
build/
build/*
*.pyc
.idea/
.idea/*
23 changes: 23 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
dist: trusty # trusty = ubuntu 14.04
sudo: false # false = docker container environment
language: python
python:
- "2.7"
- "3.4"
- "nightly" # currently points to 3.9-dev
# command to install dependencies
matrix:
allow_failures:
- python: "3.4"
- python: "nightly"
install:
- "pip install -r requirements.txt"
- "pip install -r tests/requirements.txt"
- "python setup.py install"
- "export PATH=$PATH:."
- "cp -p bin/gvoice ."
# command to run tests
script: pytest

# script: python -B test/test.py
# https://github.com/finnrayment/dash-h
14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Python Google Voice

Joe McCall & Justin Quick

Updates by Chris Coleman @ Espace Networks

Exposing the Google Voice "API" to the Python language
-------------------------------------------------------

Expand All @@ -11,3 +13,15 @@ You can use the Python API or command line script to schedule calls, check for n
Works for Python 2 and Python 3

Full documentation is available up at http://sphinxdoc.github.com/pygooglevoice/

CURRENT STATUS:

The two-step auth is broken, and appears to need rewriting, in light of the major new version of GVoice.

** I invite everyone who is using this software and enjoying my recent bug fixes and feature additions, to visit my gofundme page, where anyone who is interested in supporting my serious efforts to fix and develop this software further, can make a contribution to help cover my running costs.

Thank you to everyone who will support. It's because of you that I can do this and make this software work again!

- Chris Coleman @ Espace Networks **

https://www.gofundme.com/espacenetworks-pygooglevoice
4 changes: 2 additions & 2 deletions googlevoice/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def __init__(self):
except IOError:
return

def get(self, option, section='gvoice'):
def get(self, option, section='gvoice', **kwargs):
try:
return ConfigParser.get(self, section, option).strip() or None
return ConfigParser.get(self, section, option, **kwargs).strip() or None
except NoOptionError:
return

Expand Down
10 changes: 7 additions & 3 deletions googlevoice/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@
}

DEBUG = False
LOGIN = 'https://accounts.google.com/ServiceLogin?service=grandcentral&passive=1209600&continue=https://www.google.com/voice&followup=https://www.google.com/voice&ltmpl=open'
LOGIN_POST = 'https://accounts.google.com/signin/challenge/sl/password?service=grandcentral&continue=https://www.google.com/voice&followup=https://www.google.com/voice&ltmpl=open'

LOGIN = 'https://accounts.google.com/ServiceLogin?continue=https://www.google.com/voice&rip=1&nojavascript=1&followup=https://www.google.com/voice&service=grandcentral&ltmpl=open&flowName=GlifWebSignIn&flowEntry=Identifier'
LOGIN_POST = 'https://accounts.google.com/signin/challenge/sl/password?service=grandcentral&continue=https://www.google.com/voice/redirection/voice&followup=https://www.google.com/voice&ltmpl=open'

USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36'

SMSAUTH = 'https://accounts.google.com/SmsAuth'
FEEDS = ('inbox', 'starred', 'all', 'spam', 'trash', 'voicemail', 'sms',
'recorded', 'placed', 'received', 'missed')
Expand Down Expand Up @@ -67,4 +71,4 @@
XML_RECORDED = XML_RECENT + 'recorded/'
XML_PLACED = XML_RECENT + 'placed/'
XML_RECEIVED = XML_RECENT + 'received/'
XML_MISSED = XML_RECENT + 'missed/'
XML_MISSED = XML_RECENT + 'missed/'
12 changes: 6 additions & 6 deletions googlevoice/voice.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,21 +72,21 @@ def login(self, email=None, passwd=None, smsKey=None):

content = self.__do_page('login').read()
# holy hackjob
galx = re.search(r"type=\"hidden\"\s+name=\"GALX\"\s+value=\"(.+)\"", content).group(1)
# galx = re.search(r"type=\"hidden\"\s+name=\"GALX\"\s+value=\"(.+)\"", content).group(1)
gxf = re.search(r"type=\"hidden\"\s+name=\"gxf\"\s+value=\"(.+)\"", content).group(1)
result = self.__do_page('login_post', {'Email': email, 'Passwd': passwd, 'GALX': galx, 'gxf': gxf})
result = self.__do_page('login_post', {'Email': email, 'Passwd': passwd, 'gxf': gxf})

if result.geturl().startswith(getattr(settings, "SMSAUTH")):
content = self.__smsAuth(smsKey)

try:
smsToken = re.search(r"name=\"smsToken\"\s+value=\"([^\"]+)\"", content).group(1)
galx = re.search(r"name=\"GALX\"\s+value=\"([^\"]+)\"", content).group(1)
content = self.__do_page('login', {'smsToken': smsToken, 'service': "grandcentral", 'GALX': galx})
# galx = re.search(r"name=\"GALX\"\s+value=\"([^\"]+)\"", content).group(1)
content = self.__do_page('login', {'smsToken': smsToken, 'service': "grandcentral", })
except AttributeError:
raise LoginError

del smsKey, smsToken, galx, gxf
del smsKey, smsToken, gxf # , galx

del email, passwd

Expand Down Expand Up @@ -261,7 +261,7 @@ def __do_page(self, page, data=None, headers={}, terms={}):
page = page.upper()
if isinstance(data, dict) or isinstance(data, tuple):
data = urlencode(data)
headers.update({'User-Agent': 'PyGoogleVoice/0.5'})
headers.update({'User-Agent': getattr(settings, "USER_AGENT")})
if log:
log.debug('%s?%s - %s' % (getattr(settings, page)[22:], data or '', headers))
if page in ('DOWNLOAD', 'XML_SEARCH'):
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BeautifulSoup4
Empty file added tests/requirements.txt
Empty file.
19 changes: 19 additions & 0 deletions tests/test_call.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from googlevoice import Voice
from googlevoice.util import input


def test_call():
# assert inc(3) == 5

voice = Voice()
# voice.login()

outgoingNumber = "18005551212" # input('Number to call: ')
forwardingNumber = None # input('Number to call from [optional]: ') or None

#voice.call(outgoingNumber, forwardingNumber)

#if input('Calling now... cancel?[y/N] ').lower() == 'y':
# voice.cancel(outgoingNumber, forwardingNumber)

assert 1 == 1
11 changes: 11 additions & 0 deletions tests/test_delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from googlevoice import Voice

def test_delete():
voice = Voice()
# voice.login()

#for message in voice.sms().messages:
# if message.isRead:
# message.delete()

assert 1 == 1
12 changes: 12 additions & 0 deletions tests/test_download-mp3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from googlevoice import Voice

def test_download_mp3():
download_dir = '.'

voice = Voice()
# voice.login()

#for message in voice.voicemail().messages:
# message.download(download_dir)

assert 1 == 1
12 changes: 12 additions & 0 deletions tests/test_folders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from googlevoice import Voice,util,settings

def test_folders():
voice = Voice()
# voice.login()

#for feed in settings.FEEDS:
# util.print_(feed.title())
# for message in getattr(voice, feed)().messages:
# util.print_('\t', message)

assert 1 == 1
43 changes: 43 additions & 0 deletions tests/test_parse_sms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#
# SMS test via Google Voice
#
# John Nagle
# [email protected]
#
from googlevoice import Voice
import sys
from bs4 import BeautifulSoup


def extractsms(htmlsms):
"""
extractsms -- extract SMS messages from BeautifulSoup tree of Google Voice SMS HTML.

Output is a list of dictionaries, one per message.
"""
msgitems = [] # accum message items here
# Extract all conversations by searching for a DIV with an ID at top level.
tree = BeautifulSoup.BeautifulSoup(htmlsms) # parse HTML into tree
conversations = tree.findAll("div", attrs={"id": True}, recursive=False)
for conversation in conversations:
# For each conversation, extract each row, which is one SMS message.
rows = conversation.findAll(attrs={"class": "gc-message-sms-row"})
for row in rows: # for all rows
# For each row, which is one message, extract all the fields.
msgitem = {"id": conversation["id"]} # tag this message with conversation ID
spans = row.findAll("span", attrs={"class": True}, recursive=False)
for span in spans: # for all spans in row
cl = span["class"].replace('gc-message-sms-', '')
msgitem[cl] = (" ".join(span.findAll(text=True))).strip() # put text in dict
msgitems.append(msgitem) # add msg dictionary to list
return msgitems

def test_parse_sms():
voice = Voice()
#voice.login()

#voice.sms()
#for msg in extractsms(voice.sms.html):
# print str(msg)

assert 1 == 1
9 changes: 9 additions & 0 deletions tests/test_phones.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from googlevoice import Voice,util

def test_phones():
voice = Voice()
#voice.login()

#util.pprint(voice.phones)

assert 1 == 1
12 changes: 12 additions & 0 deletions tests/test_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from googlevoice import Voice,util

def test_search():
voice = Voice()
#voice.login()

#folder = voice.search(util.input('Search query: '))

#util.print_('Found %s messages: ', len(folder))
#util.pprint(folder.messages)

assert 1 == 1
9 changes: 9 additions & 0 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from googlevoice import Voice,util

def test_settings():
voice = Voice()
#voice.login()

#util.pprint(voice.settings)

assert 1 == 1
13 changes: 13 additions & 0 deletions tests/test_sms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from googlevoice import Voice
from googlevoice.util import input

def test_sms():
voice = Voice()
#voice.login()

phoneNumber = "18005551212" #input('Number to send message to: ')
text = "Hello, world." #input('Message text: ')

#voice.send_sms(phoneNumber, text)

assert 1 == 1
10 changes: 10 additions & 0 deletions tests/voicemail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from googlevoice import Voice,util

def test_voicemail():
voice = Voice()
#voice.login()

#for message in voice.voicemail().messages:
# util.print_(message)

assert 1 == 1