Digitale bierlijst

cli.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import click
  2. from piket_client.model import (
  3. ServerStatus,
  4. NetworkError,
  5. Consumption,
  6. Settlement,
  7. ConsumptionType,
  8. )
  9. from prettytable import PrettyTable
  10. @click.group()
  11. def cli():
  12. """Poke coco from the command line."""
  13. pass
  14. @cli.command()
  15. def status():
  16. """Show the current status of the server."""
  17. status = ServerStatus.is_server_running()
  18. if isinstance(status, NetworkError):
  19. print_error(f"Failed to get data from server, error {status.value}")
  20. return
  21. print_ok("Server is available.")
  22. open_consumptions = ServerStatus.unsettled_consumptions()
  23. if isinstance(open_consumptions, NetworkError):
  24. print_error(
  25. f"Failed to get unsettled consumptions, error {open_consumptions.value}"
  26. )
  27. return
  28. click.echo(f"There are {open_consumptions.amount} unsettled consumptions.")
  29. if open_consumptions.amount > 0:
  30. click.echo(f"First at: {open_consumptions.first_timestamp.strftime('%c')}")
  31. click.echo(f"Most recent at: {open_consumptions.last_timestamp.strftime('%c')}")
  32. @cli.group()
  33. def people():
  34. pass
  35. @cli.group()
  36. def settlements():
  37. pass
  38. @settlements.command("show")
  39. @click.argument("settlement_id", type=click.INT)
  40. def show_settlement(settlement_id: int) -> None:
  41. """Get and view the contents of a Settlement."""
  42. s = Settlement.get(settlement_id)
  43. if isinstance(s, NetworkError):
  44. print_error(f"Could not get Settlement: {s.value}")
  45. return
  46. output_settlement_info(s)
  47. @settlements.command("create")
  48. @click.argument("name")
  49. def create_settlement(name: str) -> None:
  50. """Create a new Settlement."""
  51. s = Settlement.create(name)
  52. if isinstance(s, NetworkError):
  53. print_error(f"Could not create Settlement: {s.value}")
  54. return
  55. output_settlement_info(s)
  56. def output_settlement_info(s: Settlement) -> None:
  57. click.echo(f'Settlement {s.settlement_id}, "{s.name}"')
  58. click.echo(f"Summary:")
  59. for key, value in s.consumption_summary.items():
  60. click.echo(f" - {value['count']} {value['name']} ({key})")
  61. ct_name_by_id = {key: value["name"] for key, value in s.consumption_summary.items()}
  62. table = PrettyTable()
  63. table.field_names = ["Name", *ct_name_by_id.values()]
  64. table.sortby = "Name"
  65. table.align = "r"
  66. table.align["Name"] = "l" # type: ignore
  67. zero_fields = {k: "" for k in ct_name_by_id.values()}
  68. for item in s.per_person_counts.values():
  69. r = {"Name": item["full_name"], **zero_fields}
  70. for key, value in item["counts"].items():
  71. r[ct_name_by_id[key]] = value
  72. table.add_row(r.values())
  73. print(table)
  74. @cli.group()
  75. def consumption_types():
  76. pass
  77. @consumption_types.command("list")
  78. def list_consumption_types() -> None:
  79. active = ConsumptionType.get_all(active=True)
  80. inactive = ConsumptionType.get_all(active=False)
  81. if isinstance(active, NetworkError) or isinstance(inactive, NetworkError):
  82. print_error("Could not get consumption types!")
  83. return
  84. table = PrettyTable()
  85. table.field_names = ["ID", "Name", "Active"]
  86. table.sortby = "ID"
  87. for ct in active + inactive:
  88. table.add_row([ct.consumption_type_id, ct.name, ct.active])
  89. print(table)
  90. @consumption_types.command("create")
  91. @click.argument("name")
  92. def create_consumption_type(name: str) -> None:
  93. ct = ConsumptionType(name=name).create()
  94. if not isinstance(ct, NetworkError):
  95. print_ok(f'Created consumption type "{name}" with ID {ct.consumption_type_id}.')
  96. @consumption_types.command("activate")
  97. @click.argument("consumption_type_id", type=click.INT)
  98. def activate_consumption_type(consumption_type_id: int) -> None:
  99. ct = ConsumptionType.get(consumption_type_id)
  100. if isinstance(ct, NetworkError):
  101. print_error(f"Could not get ConsumptionType: {ct.value}")
  102. return
  103. result = ct.set_active(True)
  104. if not isinstance(result, NetworkError):
  105. print_ok(
  106. f"Consumption type {ct.consumption_type_id} ({ct.name}) is now active."
  107. )
  108. @consumption_types.command("deactivate")
  109. @click.argument("consumption_type_id", type=click.INT)
  110. def deactivate_consumption_type(consumption_type_id: int) -> None:
  111. ct = ConsumptionType.get(consumption_type_id)
  112. if isinstance(ct, NetworkError):
  113. print_error(f"Could not get ConsumptionType: {ct.value}")
  114. return
  115. result = ct.set_active(False)
  116. if not isinstance(result, NetworkError):
  117. print_ok(
  118. f"Consumption type {ct.consumption_type_id} ({ct.name}) is now inactive."
  119. )
  120. def print_ok(msg: str) -> None:
  121. click.echo(click.style(msg, fg="green"))
  122. def print_error(msg: str) -> None:
  123. click.echo(click.style(msg, fg="red", bold=True), err=True)
  124. if __name__ == "__main__":
  125. cli()