#!/usr/bin/env python3 import datetime import ofxtools import json import logging import sys import csv import xml.etree.ElementTree as ET from ofxtools import OFXClient from ofxtools.Client import StmtRq, CcStmtEndRq, CcStmtRq from functools import namedtuple def get_transactions(data): Transaction = namedtuple("Transaction", ["details", "date", "description", "amount", "type", "balance", "slip"]) root = ET.fromstring(data) ts = [] for statement in root.iter("STMTTRN"): description, date, amount = "", "", "" for child in statement: if child.tag == "TRNAMT": amount = child.text elif child.tag == "DTPOSTED": d = datetime.datetime.strptime(child.text[:8], "%Y%m%d") date = d.strftime("%m/%d/%Y") elif child.tag == "NAME": if description: description = child.text + " " + description else: description = child.text elif child.tag == "MEMO": if description: description = description + " " + child.text else: description = child.text t = Transaction("-", date, description, amount, "-", "-", "-") ts.append(t) return ts def process_account(client, secret, year, name, accttype, acctid, csv_file): dtstart = datetime.datetime(int(year), 1, 1, tzinfo=ofxtools.utils.UTC) dtend = datetime.datetime(int(year), 12, 31, tzinfo=ofxtools.utils.UTC) if accttype.upper() in ("CHECKING", "SAVINGS"): rq = StmtRq(acctid=acctid, accttype=accttype.upper(), dtstart=dtstart, dtend=dtend) else: rq = CcStmtRq(acctid=acctid, dtstart=dtstart, dtend=dtend) response = client.request_statements(secret, rq) data = response.read().decode() # with open(csv_file.replace(".csv", ".xml"), "w") as f: # f.write(data) transactions = get_transactions(data) with open(csv_file, "w") as f: csv_writer = csv.writer(f) csv_writer.writerow(["details", "date", "description", "amount", "type", "balance", "slip"]) for t in transactions: csv_writer.writerow(t) #if t.date.startswith(year): def get_client(url, userid, org, fid, clientuid, bankid, version, **kwargs): return OFXClient(url, userid=userid, org=org, fid=fid, clientuid=clientuid, bankid=bankid, version=version, prettyprint=True) def main(config): client = get_client(**config["client"]) year = config["year"] secret = config["secret"] for account in config["accounts"]: name = account["name"] logging.info(f"Processing {name}.") process_account(client, secret, year, **account) if __name__ == "__main__": try: config_file = sys.argv[1] except IndexError: config_file = "gather.json" with open(config_file, 'r') as f: config = json.load(f) main(config)