tab2ledger/tab

118 lines
3.2 KiB
Plaintext
Raw Normal View History

2019-06-21 10:58:16 +00:00
#!/usr/bin/env python3
2019-08-07 18:20:52 +00:00
# tab2ledger
# Copyright © 2019 Midgard
#
# This program is free software: you can redistribute it and/or modify it under the terms of the
# GNU General Public License as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program.
# If not, see <http://www.gnu.org/licenses/>.
2019-06-21 10:58:16 +00:00
import itertools
import sys
import os
import requests
2019-06-21 11:06:51 +00:00
ME = os.getenv("TAB_ME")
TOKEN = os.getenv("TAB_TOKEN")
BASE_URI = os.getenv("TAB_BASE_URI", default="https://tab.zeus.gent")
2019-06-21 10:58:16 +00:00
2019-06-21 11:06:51 +00:00
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})")
2019-06-21 10:58:16 +00:00
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"]
creditor = transaction["creditor"]
date = transaction["time"][:10]
amount = formatted_price(transaction["amount"])
2019-06-21 10:58:16 +00:00
message = (
transaction["message"].replace("1 ", "").replace(" and ", " en ")
if issuer == "Tap" else
transaction["message"]
).strip()
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
2021-08-31 21:08:59 +00:00
if issuer == "Tap":
to_account = TAP_ACCOUNT
message = f"Zeus WPI | {message}"
else:
to_account = FOOD_ACCOUNT
message = f"{creditor} | {message}"
2019-06-21 10:58:16 +00:00
to_line = f"{to_account} {amount}"
2019-06-24 23:03:30 +00:00
from_line = f"tab {assertion}"
2019-06-21 10:58:16 +00:00
else:
2021-08-31 21:08:59 +00:00
message = f"{debtor} | {message}"
2019-06-21 10:58:16 +00:00
to_line = f"tab {amount} {assertion}"
2021-08-31 21:08:59 +00:00
from_line = f";"
header = f"{date} {message}"
2019-06-21 10:58:16 +00:00
return "\n".join([
header,
2019-06-24 23:03:30 +00:00
"\t" + to_line.rstrip(),
"\t" + from_line.rstrip()
2019-06-21 10:58:16 +00:00
])
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)
2019-06-21 14:10:39 +00:00
]
2019-06-21 10:58:16 +00:00
def main(me, token, file=sys.stdout):
def get(path):
return requests.get(
2019-06-21 11:06:51 +00:00
f"{BASE_URI}{path}",
headers={
"Accept": "application/json", "Authorization": f"Token token={token}",
"User-Agent": USER_AGENT
}
2019-06-21 10:58:16 +00:00
).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)