diff --git a/.gitignore b/.gitignore index cbe4ce0..e246058 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ ghostdriver.log *.pyc .env db.sqlite3 +*.egg-info diff --git a/formatters/console.py b/formatters/console.py new file mode 100644 index 0000000..62d0eaf --- /dev/null +++ b/formatters/console.py @@ -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() diff --git a/scrapers/__init__.py b/scrapers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scrapers/bank_of_america.py b/scrapers/bank_of_america.py index 3dfaf25..2514d45 100644 --- a/scrapers/bank_of_america.py +++ b/scrapers/bank_of_america.py @@ -6,7 +6,7 @@ from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from bs4 import BeautifulSoup -from common import BankWebAuthenticator, BankScraper +from scrapers.common import BankWebAuthenticator, BankScraper class BankOfAmericaWebAuthenticator(BankWebAuthenticator): @@ -63,15 +63,20 @@ class BankOfAmericaBankScraper(BankScraper): name = account['name'] self.driver.get(self.ACCOUNTS_URL) self.driver.find_element_by_id(name).click() - 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 + account['transactions'] = [] + + for i in range(3): + 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 def _tr_to_transaction(self, tr): 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() amount = tr.select('.amount')[0].text.strip() return { diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..865dcf4 --- /dev/null +++ b/setup.py @@ -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'], + ) \ No newline at end of file