from argparse import ArgumentParser from datetime import datetime, timezone import json import sqlite3 import sys def load_isodate(s): return datetime.fromisoformat(s).replace(microsecond=0).timestamp() def load_bill(data, user_map, b_id, db, after=None): if data['kind'] == 'NORMAL': btype = 0 elif data['kind'] == 'BALANCE': btype = 1 else: raise ValueError('bad bill kind: %s' % data['kind']) c_date = load_isodate(data['created_at']) p_date = load_isodate(data['payed_at']) desc = data['descr'] amount = -float(data['amount']) payer = user_map[data['payed_by']['id']] if after is not None and c_date < after: return c = db.execute( 'INSERT INTO bills(budget, payer, amount, payed_at, created_at, type, desc) ' 'VALUES (?, ?, ?, ?, ?, ?, ?)', (b_id, payer, amount, p_date, c_date, btype, desc)) t_id = c.lastrowid for a in data['alloc']: ower = user_map[a['ower']['id']] weight = a['weight'] if not weight: continue weight = float(weight) db.execute('INSERT INTO bill_allocs(bill, member, weight) VALUES (?, ?, ?)', (t_id, ower, weight)) if __name__ == '__main__': parser = ArgumentParser(description='load tricount dump into albus') parser.add_argument("-u", "--user", help="TRICOUNT_ID:ALBUS_ID mapping", action="append", dest="user_map") parser.add_argument("-b", "--budget", help="albus budget ID", action="store", required=True) parser.add_argument("-i", "--input", help="input json dump", action="store", required=True) parser.add_argument("--db", help="db path", action="store", required=True) parser.add_argument("--after", help="date filter", action="store") args = parser.parse_args() if args.after is not None: after = datetime.fromisoformat(args.after) else: after = None user_map = {} for opt in args.user_map: (t,a) = opt.split(':') user_map[int(t)] = int(a) b_id = args.budget if args.input == '-': fd = sys.stdin else: fd = open(args.input) data = json.load(fd) db = sqlite3.connect(args.db) bills = data['bills'] bills.sort(key=lambda u: datetime.fromisoformat(u['payed_at']).timestamp()) for b in bills: load_bill(b, user_map, b_id, db, after) db.commit() db.close()