Files
ledgerpy/getofx.py

95 lines
3.1 KiB
Python

#!/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)