tab2ledger/tab
2019-06-25 01:03:30 +02:00

97 lines
2.4 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
import itertools
import sys
import os
import requests
ME = os.getenv("TAB_ME")
TOKEN = os.getenv("TAB_TOKEN")
BASE_URI = os.getenv("TAB_BASE_URI", default="https://tab.zeus.gent")
TAP_ACCOUNT = os.getenv("LEDGER_TAP_ACCOUNT", default="Expenses:Zeuskelder:Drinks and snacks")
FOOD_ACCOUNT = os.getenv("LEDGER_FOOD_ACCOUNT", default="Expenses:Zeuskelder:Food")
TAB2LEDGER_NAME = "tab2ledger"
TAB2LEDGER_VERSION = "1.0"
TAB2LEDGER_URL = "https://git.zeus.gent/midgard/tab2ledger"
USER_AGENT = os.getenv("TAB2LEDGER_USER_AGENT", default=f"{TAB2LEDGER_NAME} {TAB2LEDGER_VERSION} ({TAB2LEDGER_URL})")
def formatted_price(cents):
return f"{cents / 100}"
def balance_assertion(balance):
return \
f"= {formatted_price(balance)}" \
if balance is not None else ""
def formatted_transaction(transaction, me, balance_after=None):
issuer = transaction["issuer"]
debtor = transaction["debtor"]
date = transaction["time"][:10]
amount = formatted_price(transaction["amount"])
message = (
transaction["message"].replace("1 ", "").replace(" and ", " en ")
if issuer == "Tap" else
transaction["message"]
).strip()
header = f"{date} {message}"
assertion = balance_assertion(balance_after)
if debtor == me:
# If the issuer wasn't Tap, we assume the money we gave was for food manual change to the
# output required if it wasn't
to_account = TAP_ACCOUNT if issuer == "Tap" else FOOD_ACCOUNT
to_line = f"{to_account} {amount}"
from_line = f"tab {assertion}"
else:
to_line = f"tab {amount} {assertion}"
from_line = f"; {debtor}"
return "\n".join([
header,
"\t" + to_line.rstrip(),
"\t" + from_line.rstrip()
])
def formatted_transactions(transactions, final_balance, me):
all_but_last = itertools.islice(transactions, len(transactions) - 1)
return [
*(formatted_transaction(t, me) for t in all_but_last),
formatted_transaction(transactions[-1], me, final_balance)
]
def main(me, token, file=sys.stdout):
def get(path):
return requests.get(
f"{BASE_URI}{path}",
headers={
"Accept": "application/json", "Authorization": f"Token token={token}",
"User-Agent": USER_AGENT
}
).json()
balance = get(f"/users/{me}")["balance"]
transactions = get(f"/users/{me}/transactions")
print(
"\n\n".join(formatted_transactions(transactions, balance, me)),
file=file
)
if __name__ == "__main__":
main(ME, TOKEN)