117 lines
4.5 KiB
Python
117 lines
4.5 KiB
Python
"""CLI: Take a set of coins from a piggy bank."""
|
|
|
|
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.piggybank import PiggyBank
|
|
from piggybank.cli import EPILOGUE
|
|
from piggybank.currencies import CURRENCIES, DEFAULT_CURRENCY, \
|
|
BaseCurrencyError, print_supported_currencies
|
|
from piggybank.util import add_common_arguments_to_parser
|
|
|
|
__all__ = ["main"]
|
|
|
|
DEFAULT_COIN_CENTERING: int = 10
|
|
|
|
|
|
def print_summary(piggybank: PiggyBank,
|
|
centering: int = DEFAULT_COIN_CENTERING) -> None:
|
|
"""Print summarised info on 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"]])
|
|
# cline_len = len(cline)
|
|
|
|
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])
|
|
print(f"┃ {tr.timestamp} ┃{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 have same currency")
|
|
|
|
add_common_arguments_to_parser(parser, include_reverse_flag=False)
|
|
|
|
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)
|