Created
July 24, 2017 18:52
-
-
Save wiomoc/7fb36f2ca3f97b5d6280fdd2a545c707 to your computer and use it in GitHub Desktop.
Load the recent Polygo Mastercard transactions
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 | |
import argparse | |
import requests | |
import re | |
import string | |
import time | |
try: | |
from BeautifulSoup import BeautifulSoup | |
except ImportError: | |
from bs4 import BeautifulSoup | |
#PUT YOUR CARD HERE | |
nr = '' | |
cvc = '' | |
expiryDateMonth = '' | |
expiryDateYear = '' | |
def valid_date(s): | |
try: | |
return time.strptime(s, '%d.%m.%y') | |
except ValueError: | |
msg = "Not a valid date: '{0}'.".format(s) | |
raise argparse.ArgumentTypeError(msg) | |
parser = argparse.ArgumentParser(description='Load the recent PolyGo Payment transactions') | |
parser.add_argument('-s', '--startdate', | |
help='The Start Date - format DD.MM.YY', | |
type=valid_date) | |
parser.add_argument('--supa', help='Output in SUPA format', | |
action='store_true') | |
args = parser.parse_args() | |
url = 'https://www.kreditkartenbanking.de' | |
def clean_string(stri): | |
return filter(lambda x: x in string.printable, stri).replace('\n', | |
'').replace('\t', '').replace(' ', ' ').strip() | |
sess = requests.session() | |
logonpage = sess.get(url + '/ssc/cas/dispatch.do?bt_PRELON=1&ref=2000_SSC&service=COS') | |
form = BeautifulSoup(logonpage.text, 'lxml').body.find('form', | |
attrs={'name': 'preLogonForm'}) | |
action = form['action'] | |
token = form.find('input', | |
attrs={'name': 'org.apache.struts.taglib.html.TOKEN'})['value'] | |
redirect = sess.post(url + '/ssc/cas/' + action, data={ | |
'org.apache.struts.taglib.html.TOKEN': token, | |
'ref': '2000_SSC', | |
'service': 'COS', | |
'authType': '2', | |
'user': nr, | |
'expiryDateMonth': expiryDateMonth, | |
'expiryDateYear': expiryDateYear, | |
'cvv2': cvc, | |
'intred': 'PARAM_intred_NOT_FOUND', | |
'postprocess': 'PARAM_postprocess_NOT_FOUND', | |
'registration': 'false', | |
'bt_LOGON': 'Starten', | |
}) | |
html = BeautifulSoup(redirect.text, 'lxml').body | |
if html.find('td', attrs={'class': 'taberror'}): | |
print 'Error: Falsche Anmeldedaten' | |
exit() | |
form = html.find('form', attrs={'name': 'service'}) | |
landingAction = form['action'] | |
ticket = form.find('input', attrs={'name': 'ticket'})['value'] | |
ref = form.find('input', attrs={'name': 'ref'})['value'] | |
clientCode = form.find('input', attrs={'name': 'clientCode'})['value'] | |
landingPage = sess.post(landingAction, data={'ticket': ticket, | |
'ref': ref, 'clientCode': clientCode}) | |
html = BeautifulSoup(landingPage.text, 'lxml').body | |
action = html.find('td', attrs={'id': 'unav1'}).noscript.a['href'] | |
balancetext = html.find(text=re.compile(r'Kontostand aktuell:')).parent.parent.find('td', | |
attrs={'class': 'tabdata'}).string | |
match = re.match(r"EUR[\s]*(\s\d+),(\d+)", clean_string(balancetext)) | |
balance = int(match.group(1)) + int(match.group(2)) / 100.0 | |
transactionsPage = sess.get(url + '/ssc/cos_std/' + action) | |
html = BeautifulSoup(transactionsPage.text, 'lxml').body | |
table = html.find('td', attrs={'class': 'tabName'}).find_all('tr', | |
class_=re.compile('tabdata')) | |
transactions = [] | |
for i in range(0, len(table), 2): | |
parts = table[i].find_all('td') | |
if len(parts) != 4: | |
break | |
parts2 = table[i + 1].find_all('td') | |
entry = { | |
'date': time.strptime(clean_string(parts[0].string), '%d.%m.%Y' | |
), | |
'bookdate': time.strptime(clean_string(parts2[0].string), | |
'%d.%m.%Y'), | |
'name': clean_string(parts[1].string), | |
'price': float(clean_string(parts[2].string).replace(',', '.' | |
)), | |
'desc': clean_string(parts2[1].nobr.string), | |
} | |
if parts[3].string == '-': | |
entry['price'] *= -1 | |
if not args.startdate or args.startdate <= entry['date'] \ | |
or args.startdate <= entry['bookdate']: | |
transactions.append(entry) | |
if args.supa: | |
import csv | |
import sys | |
writer = csv.DictWriter(sys.stdout, delimiter='\t', quotechar='\n', | |
quoting=csv.QUOTE_MINIMAL, fieldnames=[ | |
'Id', | |
'OwnrAcctCcy', | |
'OwnrAcctIBAN', | |
'OwnrAcctNo', | |
'OwnrAcctBIC', | |
'OwnrAcctBankCode', | |
'BookgDt', | |
'ValDt', | |
'Amt', | |
'AmtCcy', | |
'CdtDbtInd', | |
'EndToEndId', | |
'PmtInfId', | |
'MndtId', | |
'CdtrId', | |
'RmtInf', | |
'BookgTxt', | |
'PrimaNotaNo', | |
'BankRef', | |
'BkTxCd', | |
'RmtdNm', | |
'RmtdAcctCtry', | |
'RmtdAcctIBAN', | |
'RmtdAcctNo', | |
'RmtdAcctBIC', | |
'RmtdAcctBankCode', | |
'Category', | |
'Notes', | |
'BookgSts', | |
'GVC', | |
'GVCExtension', | |
'BtchBookg', | |
'BtchId', | |
'RmtdUltmtNm', | |
]) | |
writer.writeheader() | |
for transaction in transactions: | |
writer.writerow({ | |
'OwnrAcctCcy': 'EUR', | |
'OwnrAcctNo': nr, | |
'BookgDt': time.strftime('%Y-%m-%d', transaction['bookdate']), | |
'ValDt': time.strftime('%Y-%m-%d', transaction['date']), | |
'Amt': (transaction['price'] if transaction['price'] > 0 else -transaction['price']), | |
'AmtCcy': 'EUR', | |
'CdtDbtInd': ('CRDT' if transaction['price'] > 0 else 'DBIT'), | |
'RmtInf': transaction['name'], | |
'BookgTxt': transaction['desc'], | |
}) | |
else: | |
from texttable import Texttable | |
t = Texttable(max_width=100) | |
t.set_deco(Texttable.HEADER) | |
t.header(['Date', 'Bookdate', 'Usage', 'Description', 'Amount']) | |
for transaction in transactions: | |
t.add_row([time.strftime('%d.%m.%y', transaction['date']), | |
time.strftime('%d.%m.%y', transaction['bookdate']), | |
transaction['name'], transaction['desc'], '%.2f Euro' | |
% transaction['price']]) | |
print t.draw() | |
print '\nBalance: ' + str(balance) + ' Euro' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment