import click from piket_client.model import ServerStatus, NetworkError, Consumption, Settlement from prettytable import PrettyTable @click.group() def cli(): """Poke coco from the command line.""" pass @cli.command() def status(): """Show the current status of the server.""" status = ServerStatus.is_server_running() if isinstance(status, NetworkError): print_error(f"Failed to get data from server, error {status.value}") return print_ok("Server is available.") open_consumptions = ServerStatus.unsettled_consumptions() if isinstance(open_consumptions, NetworkError): print_error( f"Failed to get unsettled consumptions, error {open_consumptions.value}" ) return click.echo(f"There are {open_consumptions.amount} unsettled consumptions.") if open_consumptions.amount > 0: click.echo(f"First at: {open_consumptions.first_timestamp.strftime('%c')}") click.echo(f"Most recent at: {open_consumptions.last_timestamp.strftime('%c')}") @cli.group() def people(): pass @cli.group() def settlements(): pass @settlements.command("show") @click.argument("settlement_id", type=click.INT) def show_settlement(settlement_id: int) -> None: """Get and view the contents of a Settlement.""" s = Settlement.get(settlement_id) if isinstance(s, NetworkError): print_error(f"Could not get Settlement: {s.value}") return output_settlement_info(s) @settlements.command("create") @click.argument("name") def create_settlement(name: str) -> None: """Create a new Settlement.""" s = Settlement.create(name) if isinstance(s, NetworkError): print_error(f"Could not create Settlement: {s.value}") return output_settlement_info(s) def output_settlement_info(s: Settlement) -> None: click.echo(f'Settlement {s.settlement_id}, "{s.name}"') click.echo(f"Summary:") for key, value in s.consumption_summary.items(): click.echo(f" - {value['count']} {value['name']} ({key})") ct_name_by_id = {key: value["name"] for key, value in s.consumption_summary.items()} table = PrettyTable() table.field_names = ["Name", *ct_name_by_id.values()] table.sortby = "Name" table.align = "r" table.align["Name"] = "l" # type: ignore zero_fields = {k: "" for k in ct_name_by_id.values()} for item in s.per_person_counts.values(): r = {"Name": item["full_name"], **zero_fields} for key, value in item["counts"].items(): r[ct_name_by_id[key]] = value table.add_row(r.values()) print(table) def print_ok(msg: str) -> None: click.echo(click.style(msg, fg="green")) def print_error(msg: str) -> None: click.echo(click.style(msg, fg="red", bold=True), err=True) if __name__ == "__main__": cli()