1
0
mirror of https://github.com/pyro2927/SouthwestCheckin.git synced 2025-12-06 01:13:19 +00:00

Working on basic support for GMail

This commit is contained in:
pyro2927
2017-03-05 23:15:14 -07:00
parent f5f6e5100a
commit 67bf6d3374
4 changed files with 138 additions and 56 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
*.pyc
*.swp
*.swp
client_secret.json

View File

@@ -12,63 +12,63 @@ from math import trunc
# Pulled from proxying the Southwest iOS App
headers = {'Host': 'mobile.southwest.com', 'Content-Type': 'application/vnd.swacorp.com.mobile.reservations-v1.0+json', 'X-API-Key': 'l7xxab4b3533b8d54bad9df230deb96a6f90', 'Accept': '*/*'}
reservation_number = sys.argv[1]
first_name = sys.argv[2]
last_name = sys.argv[3]
# Find our existing record
url = "https://mobile.southwest.com/api/extensions/v1/mobile/reservations/record-locator/{}?first-name={}&last-name={}".format(reservation_number, first_name, last_name)
r = requests.get(url, headers=headers)
body = r.json()
# Confirm this reservation is found
if 'httpStatusCode' in body and body['httpStatusCode'] == 'NOT_FOUND':
print(body['message'])
else:
now = datetime.now(pytz.utc).astimezone(get_localzone())
tomorrow = now + timedelta(days=1)
date = now
airport = ""
# Get the correct flight information
for leg in body['itinerary']['originationDestinations']:
departure_time = leg['segments'][0]['departureDateTime']
airport = leg['segments'][0]['originationAirportCode']
date = parse(departure_time)
# Stop when we reach a future flight
if date > now:
break
print("Flight information found, departing {} at {}".format(airport, date.strftime('%b %d %I:%M%p')))
# Wait until checkin time
if date > tomorrow:
delta = (date-tomorrow).total_seconds()
m, s = divmod(delta, 60)
h, m = divmod(m, 60)
print("Too early to check in. Waiting {} hours, {} minutes, {} seconds".format(trunc(h), trunc(m), s))
time.sleep(delta)
print("Attempting check-in...")
# Get our passengers to get boarding passes for
passengers = []
for passenger in body['passengers']:
passengers.append({'firstName': passenger['secureFlightName']['firstName'], 'lastName': passenger['secureFlightName']['lastName']})
# Check in
headers['Content-Type'] = 'application/vnd.swacorp.com.mobile.boarding-passes-v1.0+json'
url = "https://mobile.southwest.com/api/extensions/v1/mobile/reservations/record-locator/{}/boarding-passes".format(reservation_number)
r = requests.post(url, headers=headers, json={'names': passengers})
def checkin(first_name, last_name, reservation_number):
# Find our existing record
url = "https://mobile.southwest.com/api/extensions/v1/mobile/reservations/record-locator/{}?first-name={}&last-name={}".format(reservation_number, first_name, last_name)
r = requests.get(url, headers=headers)
body = r.json()
if 'httpStatusCode' in body and body['httpStatusCode'] == 'FORBIDDEN':
# Confirm this reservation is found
if 'httpStatusCode' in body and body['httpStatusCode'] == 'NOT_FOUND':
print(body['message'])
else:
# Spit out info about boarding number
for checkinDocument in body['passengerCheckInDocuments']:
for doc in checkinDocument['checkinDocuments']:
print("You got {}{}!".format(doc['boardingGroup'], doc['boardingGroupNumber']))
now = datetime.now(pytz.utc).astimezone(get_localzone())
tomorrow = now + timedelta(days=1)
date = now
airport = ""
# Get the correct flight information
for leg in body['itinerary']['originationDestinations']:
departure_time = leg['segments'][0]['departureDateTime']
airport = leg['segments'][0]['originationAirportCode']
date = parse(departure_time)
# Stop when we reach a future flight
if date > now:
break
print("Flight information found, departing {} at {}".format(airport, date.strftime('%b %d %I:%M%p')))
# Wait until checkin time
if date > tomorrow:
delta = (date-tomorrow).total_seconds()
m, s = divmod(delta, 60)
h, m = divmod(m, 60)
print("Too early to check in. Waiting {} hours, {} minutes, {} seconds".format(trunc(h), trunc(m), s))
time.sleep(delta)
print("Attempting check-in...")
# Get our passengers to get boarding passes for
passengers = []
for passenger in body['passengers']:
passengers.append({'firstName': passenger['secureFlightName']['firstName'], 'lastName': passenger['secureFlightName']['lastName']})
# Check in
headers['Content-Type'] = 'application/vnd.swacorp.com.mobile.boarding-passes-v1.0+json'
url = "https://mobile.southwest.com/api/extensions/v1/mobile/reservations/record-locator/{}/boarding-passes".format(reservation_number)
r = requests.post(url, headers=headers, json={'names': passengers})
body = r.json()
if 'httpStatusCode' in body and body['httpStatusCode'] == 'FORBIDDEN':
print(body['message'])
else:
# Spit out info about boarding number
for checkinDocument in body['passengerCheckInDocuments']:
for doc in checkinDocument['checkinDocuments']:
print("You got {}{}!".format(doc['boardingGroup'], doc['boardingGroupNumber']))
if __name__ == '__main__':
main(sys.argv[1], sys.argv[2], sys.argv[3])

79
gmail.py Normal file
View File

@@ -0,0 +1,79 @@
from __future__ import print_function
import base64
import httplib2
import os
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from scrapy.selector import Selector
from scrapy.http import HtmlResponse
import checkin
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'SW Checking App'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'sw-checkin.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def main():
""" Pulling Southwest emails from GMail """
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
results = service.users().messages().list(userId='me').execute()
messages = results.get('messages', [])
if not messages:
print('No emails found.')
else:
for message in messages:
r = service.users().messages().get(userId='me',id=message['id'],format='full').execute()
if "Southwest" in r['snippet'] and r['payload']['body'].has_key('data'):
body = base64.urlsafe_b64decode(r['payload']['body']['data'].encode('UTF-8'))
selector = Selector(text=body)
divs = selector.css('span[style*="23972a"]::text').extract()
if len(divs) > 0:
conf = divs[0].replace("\r", "").replace("\n", "").strip()
name = selector.css('div[style*="13px"]::text').extract()[13]
last_name, first_name = name.strip().split('/')
checkin.checkin(first_name, last_name, conf)
if __name__ == '__main__':
main()

View File

@@ -3,3 +3,5 @@ python-dateutil
pytz
requests
tzlocal
google-api-python-client
scrapy