Last active
January 5, 2017 17:11
-
-
Save ixs/7276435ca4be41d47afe74a08594eef4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Super cheap IGH activity parser. | |
# GPLv3 or newer. | |
# Copyright 2017 Andreas Thienemann | |
# | |
# Go to the ihg page to the "Account Activity" field. Select "All activity" and "365 days". | |
# Then click on "Print my account activity". This should open a new window, copy and paste | |
# everything into a text file called ihg-data.txt. | |
# | |
# Then run this python-script. | |
# The logic to differentiate between IC and non-IC hotel is simple: If the hotel name is | |
# the same as the city name, it's an IC. For the ICs where this is not the case there's a | |
# list at the top of the file called ics_names that can be used to add more hotel names | |
# that should be seen as ICs. | |
# | |
import pprint | |
import locale | |
import sys | |
import copy | |
# Names of IC hotels in case the "name == city" logic doesn't work. | |
ics_names = ( | |
"Mark Hopkins San Francisco", | |
"Chicago Magnificent Mile", | |
"Stephen F. Austin", | |
"D\xc3\xbcsseldorf", | |
"Kansas City At The Plaza", | |
) | |
rawl = [] | |
with open("ihg-data.txt", "r") as f: | |
rawl = f.read().split('\n') | |
have_data = False | |
stays_raw = [] | |
stay_data = "" | |
for line in rawl: | |
if line.startswith("Elite Qualifying Points") and have_data == False: | |
have_data = True | |
continue | |
if have_data: | |
stay_data += line + "\n" | |
tokens = line.split() | |
ttokens = line.split("\t") | |
if len(tokens) > 0 and tokens[0] in ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec") and len(ttokens) > 1 and ttokens[2] in ("Earn", "Other"): | |
stays_raw.append("\n".join(stay_data.split("\n")[:-2])) | |
stay_data = line + "\n" | |
# Throw away first stay, wrong parse | |
stays_raw = stays_raw[1:] | |
stay_struct = { | |
"posted": None, | |
"type": None, | |
"description": None, | |
"points": 0, | |
"eqp": 0, | |
"checkin": None, | |
"checkout": None, | |
"nights": 0, | |
"r_nights": 0, | |
"nq_nights": 0, | |
"hotel": None, | |
"city": None, | |
} | |
stays = [] | |
for stay_raw in stays_raw: | |
tokens = [] | |
stay = copy.deepcopy(stay_struct) | |
lines = stay_raw.split("\n") | |
for line in lines: | |
tokens.extend(line.split("\t")) | |
stay["posted"] = tokens[0] | |
stay["type"] = tokens[2] | |
stay["description"] = tokens[4] | |
try: | |
stay["points"] = int(tokens[5].split()[0].replace(",", "")) | |
stay["eqp"] = int(tokens[6].split()[0].replace(",", "")) | |
stay["hotel"] = tokens[9] | |
stay["city"] = tokens[10].split(",")[0] | |
stay["checkin"] = tokens[13] | |
stay["checkout"] = tokens[15] | |
type = tokens[16].split(":")[0].strip() | |
if type == "Reward Night": | |
stay["r_nights"] = tokens[17] | |
elif type == "Non-Qualifying Nights": | |
stay["nq_nights"] = tokens[17] | |
elif type == "Qualifying Nights": | |
stay["nights"] = tokens[17] | |
except: | |
pass | |
# print "error", tokens | |
if stay["description"] in ("Qualifying Stay", "Overlapping Stay"): | |
stays.append(stay) | |
#for stay in stays: | |
# print(chr(27) + "[2J") | |
# pprint.pprint(stay) | |
# t = raw_input("Press Enter to continue...") | |
# Calculation | |
nights = 0 | |
r_nights = 0 | |
nq_nights = 0 | |
ic_nights = 0 | |
o_nights = 0 | |
ics = {} | |
hotels = {} | |
eqp_total = 0 | |
ic_eqp = 0 | |
o_eqp = 0 | |
for stay in stays: | |
nights += int(stay["nights"]) | |
r_nights += int(stay["r_nights"]) | |
nq_nights += int(stay["nq_nights"]) | |
eqp_total += stay["eqp"] | |
if stay["hotel"] == stay["city"] or stay["hotel"] in ics_names: | |
ics[stay["hotel"]] = None | |
ic_nights += int(stay["nights"]) | |
ic_eqp += stay["eqp"] | |
else: | |
hotels[stay["hotel"]] = None | |
o_nights += int(stay["nights"]) | |
o_eqp += stay["eqp"] | |
fmt = "{:30} {:>7}" | |
print(fmt.format("Total EQ nights:", nights)) | |
print(fmt.format("IC nights:", ic_nights)) | |
print(fmt.format("non-IC nights:", o_nights)) | |
print(fmt.format("Total Reward nights:", r_nights)) | |
print(fmt.format("Total NQ nights:", nq_nights)) | |
print(fmt.format("Total EQP:", eqp_total)) | |
print(fmt.format("IC EQP:", ic_eqp)) | |
print(fmt.format("non-IC EQP:", o_eqp)) | |
print(fmt.format("Number of different ICs:", len(ics.keys()))) | |
print(fmt.format("Number of different non-ICs:", len(hotels.keys()))) | |
print "ICs stayed at:", ics.keys() | |
print "non-ICs stayed at:", hotels.keys() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment