Add formatters and basic python packaging files
This commit is contained in:
parent
be075ce3e6
commit
a8632ce2ef
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,4 +3,5 @@ ghostdriver.log
|
|||||||
*.pyc
|
*.pyc
|
||||||
.env
|
.env
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
|
*.egg-info
|
||||||
|
|
||||||
|
51
formatters/console.py
Normal file
51
formatters/console.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
class ConsoleFormatter(object):
|
||||||
|
"""Formats data to be printed to a console."""
|
||||||
|
|
||||||
|
def __init__(self, account_data):
|
||||||
|
self.account_data = account_data
|
||||||
|
|
||||||
|
def as_string(self):
|
||||||
|
result = ''
|
||||||
|
for account in self.account_data['accounts']:
|
||||||
|
name = account['name']
|
||||||
|
balance = account['balance']
|
||||||
|
transactions = account['transactions']
|
||||||
|
result += name + '\n'
|
||||||
|
result += '=' * len(name) + '\n'
|
||||||
|
result += 'date,description,amount\n'
|
||||||
|
for transaction in transactions:
|
||||||
|
if 'CHANGE' in transaction['description']:
|
||||||
|
continue
|
||||||
|
result += str(transaction['date']) + ','
|
||||||
|
result += str(transaction['description']) + ','
|
||||||
|
result += str(transaction['amount']) + '\n'
|
||||||
|
result += 'Balance: ' + balance + '\n'
|
||||||
|
result += '\n'
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
from selenium import webdriver
|
||||||
|
from scrapers.bank_of_america import BankOfAmericaBankScraper
|
||||||
|
from getpass import getpass
|
||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
cache_filename = '/tmp/cache'
|
||||||
|
data = ''
|
||||||
|
if os.path.exists(cache_filename):
|
||||||
|
with open(cache_filename, 'rb') as cache_file:
|
||||||
|
data = pickle.load(cache_file)
|
||||||
|
else:
|
||||||
|
with open(cache_filename, 'wb') as cache_file:
|
||||||
|
driver = webdriver.PhantomJS()
|
||||||
|
scraper = BankOfAmericaBankScraper(driver)
|
||||||
|
credentials = (input("username: "), getpass("password: "))
|
||||||
|
data = scraper.get_data(credentials)
|
||||||
|
pickle.dump(data, cache_file)
|
||||||
|
print(ConsoleFormatter(data).as_string())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
0
scrapers/__init__.py
Normal file
0
scrapers/__init__.py
Normal file
@ -6,7 +6,7 @@ from selenium import webdriver
|
|||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
from common import BankWebAuthenticator, BankScraper
|
from scrapers.common import BankWebAuthenticator, BankScraper
|
||||||
|
|
||||||
|
|
||||||
class BankOfAmericaWebAuthenticator(BankWebAuthenticator):
|
class BankOfAmericaWebAuthenticator(BankWebAuthenticator):
|
||||||
@ -63,15 +63,20 @@ class BankOfAmericaBankScraper(BankScraper):
|
|||||||
name = account['name']
|
name = account['name']
|
||||||
self.driver.get(self.ACCOUNTS_URL)
|
self.driver.get(self.ACCOUNTS_URL)
|
||||||
self.driver.find_element_by_id(name).click()
|
self.driver.find_element_by_id(name).click()
|
||||||
soup = BeautifulSoup(self.driver.page_source)
|
account['transactions'] = []
|
||||||
rows = soup.select('.transaction-records tr')
|
|
||||||
transactions = [self._tr_to_transaction(row) for row in rows]
|
for i in range(3):
|
||||||
account['transactions'] = [e for e in transactions if e] # filter None
|
soup = BeautifulSoup(self.driver.page_source)
|
||||||
|
rows = soup.select('.transaction-records tr')
|
||||||
|
transactions = [self._tr_to_transaction(row) for row in rows]
|
||||||
|
account['transactions'] += [e for e in transactions if e] # filter None
|
||||||
|
self.driver.find_element_by_partial_link_text('Previous').click()
|
||||||
return account
|
return account
|
||||||
|
|
||||||
def _tr_to_transaction(self, tr):
|
def _tr_to_transaction(self, tr):
|
||||||
try:
|
try:
|
||||||
date = tr.select('.date-action span')[0].text.strip()
|
tr.select('.date-action a')
|
||||||
|
date = tr.select('.date-action > span')[0].text.strip()
|
||||||
description = tr.select('.transTitleForEditDesc')[0].text.strip()
|
description = tr.select('.transTitleForEditDesc')[0].text.strip()
|
||||||
amount = tr.select('.amount')[0].text.strip()
|
amount = tr.select('.amount')[0].text.strip()
|
||||||
return {
|
return {
|
||||||
|
10
setup.py
Normal file
10
setup.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from distutils.core import setup
|
||||||
|
|
||||||
|
setup(name='librebudget',
|
||||||
|
version='1.0',
|
||||||
|
description='Free personal finance tool',
|
||||||
|
author='Ian Naval',
|
||||||
|
author_email='ianonavy@gmail.com',
|
||||||
|
url='https://git.ianonavy.com/ianonavy/librebudget',
|
||||||
|
packages=['scrapers', 'librebudget'],
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user