1
0
Fork 0
PiggyBank/piggybank/cli/show.py

122 lines
4.9 KiB
Python

"""CLI: Show summarised information on a piggybank."""
from argparse import ArgumentParser
from os.path import exists
from sys import exit, stderr
from piggybank import print_program_version, PIGGYBANK_FILE_EXTENSION
from piggybank.cli import EPILOGUE
from piggybank.currencies import CURRENCIES, DEFAULT_CURRENCY, \
BaseCurrencyError, print_supported_currencies
from piggybank.piggybank import PiggyBank
__all__ = ["main"]
DEFAULT_COIN_CENTERING: int = 10
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():
"""An entry point for a show command."""
parser = ArgumentParser(prog="piggybank-show",
description="Show information on a piggy bank.",
epilog=EPILOGUE)
parser.add_argument("file", type=str,
help="a piggy bank file name. Missing .pb extension"
"will be added")
parser.add_argument("-t", "--transactions", action="store_true",
help="print a list of transactions as well")
parser.add_argument("-m", "--merge", action="append",
type=str, metavar="FILE",
help="merge multiple files to show how much do you"
"have across them. They all should be of same currency")
parser.add_argument("-v", "--version", action="store_true",
help="show program's version and license and exit")
parser.add_argument("--list-currencies", action="store_true",
help="list all supported currencies and exit")
args = parser.parse_args()
if args.version:
print_program_version()
exit()
if args.list_currencies:
print_supported_currencies()
exit()
try:
piggybank = PiggyBank.from_file(args.file)
if args.merge:
for _file in args.merge:
merge_piggybank = PiggyBank.from_file(_file)
piggybank += merge_piggybank
print(_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)