"""CLI: Show summarised information on a piggybank.""" from re import match from sys import argv, exit, stderr from piggybank import print_program_version, PIGGYBANK_FILE_EXTENSION from piggybank.configuration import Configuration from piggybank.cli import handle_default_arguments from piggybank.currencies import CURRENCIES, \ BaseCurrencyError from piggybank.piggybank import PiggyBank __all__ = ["main"] USAGE_SHOW: str = "Usage: piggybank-show FILE [with t,transactions]\n\n" \ "Show statistics about a piggybank.\n" \ "FILE -- .pb file name of your piggybank;\n" \ "with (t|transaction) -- also list all transactions.\n" DEFAULT_COIN_CENTERING: int = 10 def parse_show_arguments(args): r = r"^(?P\S+)(?= with (?Pt|transactions))?" argd = match(r, args) if not argd is None: argd = argd.groupdict() return { "file": argd["file"], "transactions": argd["transactions"] is None } def print_summary(piggybank: PiggyBank, centering: int = DEFAULT_COIN_CENTERING) -> None: """Print summarised information on a piggy bank. Prints a table with totals of how much coins of which face value are in a piggy bank; A total sum converted to its currency for each face value and overall total sum in a currency of a piggy bank.""" def print_separator(left="┣", lmiddle="╋", rmiddle="╋", right="┫"): line = rmiddle.join('━' * centering for _ in range(CURRENCIES[piggybank.currency]['count'])) print(f"{left}{'━'*27}{lmiddle}{line}{right}") cc, cs, ct = piggybank.count, piggybank.sum, piggybank.total cline = "┃".join([f'{l:^{centering}}' for l in CURRENCIES[piggybank.currency]["names"]]) cline_len = len(cline) print_separator(left="┏", lmiddle="┳", rmiddle="━", right="┓") print(f"┃{'currency':^27}┃" f"{CURRENCIES[piggybank.currency]['name']:^{cline_len}}┃") print_separator(rmiddle="┳") print(f"┃{'face values':^27}┃{cline}┃") print_separator() print(f"┃{'amount':^27}┃{'┃'.join([f'{c:^{centering}}' for c in cc])}┃") print_separator() print(f"┃{'sum':^27}┃" f"{'┃'.join(['{:^{}.2f}'.format(c / 100, centering) for c in cs])}┃") print_separator(rmiddle="┻") print(f"┃{'total':^27}┃{'{:^{}.2f}'.format(ct / 100, cline_len)}┃") print_separator(left="┗", lmiddle="┻", rmiddle="━", right="┛") def print_transactions(piggybank, centering=DEFAULT_COIN_CENTERING): """Print a list of all transactions stored in a piggy bank.""" def print_separator(left="┏", middle="┳", right="┓"): line = middle.join('━' * centering for _ in range(CURRENCIES[piggybank.currency]['count'])) print(f"{left}━━━━━━━━━━━━━━━━━━━━━{middle}━━━━━{middle}{line}{right}") cline = "┃".join([f'{l:^{centering}}' for l in CURRENCIES[piggybank.currency]["names"]]) print_separator() print(f"┃{'Timestamp':^21}┃ I/O ┃{cline}┃") print_separator("┣", "╋", "┫") for tr in piggybank.transactions: coin_line = "┃".join([f'{c:^{centering}}' for c in tr.coins]) ts = tr.timestamp.replace("T", " ") print(f"┃ {ts} ┃{tr.direction:^5}┃{coin_line}┃") print_separator("┗", "┻", "┛") def main() -> None: handle_default_arguments(' '.join(argv), lambda: print(USAGE_SHOW)) args = parse_show_arguments(' '.join(argv)) try: piggybank = PiggyBank.from_file(args["file"]) print_summary(piggybank) if args["transactions"]: print_transactions(piggybank) except BaseCurrencyError as err: print(f"{type(err).__name__}:", err, file=stderr) except FileNotFoundError as err: print(f"{type(err).__name__}:", f"{err} doesn't exist.", file=stderr) except Exception as err: print(f"Something went exceptionally wrong. Error:", f"{type(err).__name__}:", err, file=stderr)