Plain text is worth it
Posted on January 07, 2018 • 2 min read
hledger
is one of my favorite pieces of
software. Written in haskell, it allows you
to
balance your books by
recording transactions in a
simple plain text format, which looks like
this:
2018/01/01 Supermarket
Expenses:Groceries $45
Assets:Cash $-45
Expenses go up, assets go down, balance is maintained. My discipline on this
front waxes and wanes, but no matter how out of whack my books are at any given
time, I always manage to balance them in January so that filing taxes for the
previous year is slightly less brutal. Normally this is a bit tedious, as I've
only automated the process with enough duct tape and bash
to get the job done.
Something like this (using reckon
to
properly categorize new transactions) is typical:
reckon -l 2017.ledger -f some_bank.csv -a "Assets:Some Bank" >> 2017.ledger
Too cheap to pay my banks' extortionate fees
for
automatically downloading my own data,
I typically download either .qfx
, .ofx
, or .csv
from their sites and
massage it into the ledger
format.
Citi made a bad website for Costco
Costco dumped AmEx a couple of years ago and started offering Visa cards provided by Citi.
The default transaction view is sane; that is, you can see all of the transactions for a given time period via tabular HTML. There is a "Print Screen" button. There is a search form with a dropdown that allows you to view individual statements. However, there is no "Download Transactions" button. I stared at this view for quite a while, assuming I was missing something. Apparently, what I was missing was the "Spend Summary" link, which takes you to a page that looks like:
Almost unbelievably, it's only possible to download a single category from this
view. You cannot download an entire "Year to Date" .csv
!
Back to the JSON
Returning to the HTML transaction view, it was a relief to see that the tabular
transaction view was populated by a mere XHR
call. Firefox's network monitor
lets you save a .har
file containing a
record of the data transferred during the browser session.
Now that I actually had a way to download a complete log of transactions, the
only thing left was to write an abomination that combined the power of jq
,
perl -pie
, and reckon
to output proper ledger
files:
#!/usr/bin/env bash
set -euxo pipefail
HAR=$1
function har2csv() {
jq -r '
.log.entries[] |
select(.response.content.mimeType == "application/json") |
.response.content.text |
fromjson |
.accountActivity.postedTransactionJournals[] |
.columns |
map(.activityColumn) |
flatten |
del(.[] | nulls) |
map(gsub("[\\n]"; "")) |
map("\"" + . + "\"") |
join (",")'
}
function clean() {
tr '|' ' ' | perl -p -i -e 's/\$ //'
}
reckon -f <(cat $HAR | har2csv | clean) \
--date-format '%B. %e, %Y %T' \
-u -i "$@"
Thanks Citi!