Created
October 7, 2014 06:16
-
-
Save burghardt/f7e101f59fc501f73307 to your computer and use it in GitHub Desktop.
IdeaBank overnight deposit automation
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/env python | |
# -*- coding: utf-8 -*- | |
# Copyright © 2014, Krzysztof Burghardt <krzysztof@burghardt.pl> | |
# I, the copyright holder of this work, hereby publish it under | |
# the following licenses: GFDL, CC-BY-SA, GPL, 2BSD | |
import re | |
import sys | |
import cgi | |
import StringIO | |
from BeautifulSoup import BeautifulSoup | |
from mechanize import ParseResponse, urlopen, urljoin | |
class IdeaBankClient(object): | |
baseUrl = 'https://secure.ideabank.pl/' | |
def login(self, account, password): | |
self.account = account | |
self.password = password | |
self.getLoginForm() | |
self.sendLoginForm() | |
self.sendPasswordForm() | |
def getLoginForm(self): | |
response = urlopen(urljoin(self.baseUrl, '')) | |
forms = ParseResponse(response, backwards_compat=False) | |
self.form = forms[0] | |
def sendLoginForm(self): | |
self.form['login'] = self.account | |
response = urlopen(self.form.click()) | |
forms = ParseResponse(response, backwards_compat=False) | |
self.form = forms[0] | |
def sendPasswordForm(self): | |
passwordList = list(self.password) | |
regex = re.compile('^pass_\d+$') | |
for control in self.form.controls: | |
if control.name: | |
if regex.match(control.name): | |
passwordIndex = int(control.name.split('_')[1]) | |
self.form[control.name] = passwordList[passwordIndex] | |
response = urlopen(self.form.click()) | |
forms = ParseResponse(response, backwards_compat=False) | |
self.form = forms[0] | |
def __getCellContent(self, td): | |
return td.contents[0].strip().replace(" ", "") | |
def getAccountBalance(self, accountNumber): | |
response = urlopen(urljoin(self.baseUrl, '/accounts/index')) | |
page = BeautifulSoup(response.read()) | |
tables = page.findAll('table', {'id':'data'}) | |
balanceAvailable = 0.0 | |
for table in tables: | |
td = table.find('td', {'class':'cell1'}) | |
currentAccountNumber = self.__getCellContent(td) | |
if currentAccountNumber == accountNumber: | |
td = table.find('td', {'class':'cell4'}) | |
balanceAvailable = self.__getCellContent(td) | |
break | |
return float(balanceAvailable) | |
def createDeposit(self, offer, account, balance): | |
self.chooseDeposit(offer) | |
self.requestDeposit(account, balance) | |
self.comfirmDeposit() | |
def chooseDeposit(self, offer): | |
response = urlopen(urljoin(self.baseUrl, '/deposits/newDeposit')) | |
page = BeautifulSoup(response.read()) | |
img = page.find('img', {'alt':offer}) | |
try: | |
self.offerUrl = img['onclick'].split('\'')[1] | |
except: | |
raise RuntimeError('cannot find deposit offer') | |
def __parseFormsAndReturnPage(self, response): | |
pageRaw = response.read() | |
pageIO = StringIO.StringIO(pageRaw) | |
pageIO.seek(0) | |
pageIO.geturl = response.geturl | |
forms = ParseResponse(pageIO, backwards_compat=False) | |
self.form = forms[0] | |
page = BeautifulSoup(pageRaw) | |
return page | |
def __insertHiddenBankingInput(self, page): | |
banking = page.find('input', {'id':'banking'}) | |
self.form.new_control('hidden','banking',{'value':banking['value']}) | |
self.form.fixup() | |
def requestDeposit(self, account, balance): | |
response = urlopen(urljoin(self.baseUrl, self.offerUrl)) | |
page = self.__parseFormsAndReturnPage(response) | |
self.form['amount'] = str(balance) | |
self.form['nrb_out'] = [account] | |
self.__insertHiddenBankingInput(page) | |
def comfirmDeposit(self): | |
response = urlopen(self.form.click()) | |
page = self.__parseFormsAndReturnPage(response) | |
self.__insertHiddenBankingInput(page) | |
response = urlopen(self.form.click()) | |
encoding = 'utf-8' | |
message = u"Wniosek o lokatę złożony pomyślnie." | |
for name, value in response.info().items(): | |
if name.lower() == 'content-type': | |
_, params = cgi.parse_header(value) | |
encoding = params.get('charset', 'utf-8') | |
pageRaw = response.read().decode(encoding) | |
if re.search(message, pageRaw, re.MULTILINE) is None: | |
raise RuntimeError('cannot confirm deposit opening') | |
def main(): | |
bankAccount = '12345678' | |
bankPassword = '012345678901234567890' | |
checkingAccountNumber = '00 1111 2222 3333 4444 5555 6666'.replace(" ", "") | |
savingAccountNumber = '99 8888 7777 6666 5555 4444 3333'.replace(" ", "") | |
ib = IdeaBankClient() | |
ib.login(bankAccount, bankPassword) | |
checkingAccountBalance = ib.getAccountBalance(checkingAccountNumber) | |
print("Checking account balance is %s PLN" % (checkingAccountBalance)) | |
savingsAccountBalance = ib.getAccountBalance(savingAccountNumber) | |
print("Savings account balance is %s PLN" % (savingsAccountBalance)) | |
depositMinimal = 1000 | |
depositLimit = 20000 | |
if savingsAccountBalance < depositMinimal: | |
print("Not enough to open deposit") | |
return -1 | |
if savingsAccountBalance > depositLimit: | |
print("Maximal amount is %s, %s left" % (depositLimit, savingsAccountBalance - depositLimit)) | |
savingsAccountBalance = depositLimit | |
try: | |
ib.createDeposit('Lokata PING PONG', savingAccountNumber, savingsAccountBalance) | |
print("Requested deposit created") | |
return 0 | |
except Exception, e: | |
print("Unable to open deposit: %s" % str(e)) | |
return -2 | |
if __name__ == '__main__': | |
sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment