Digitale bierlijst

model.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. """
  2. Provides access to the models stored in the database, via the server.
  3. """
  4. from typing import NamedTuple
  5. from urllib.parse import urljoin
  6. import requests
  7. from . import logger
  8. LOG = logger.getLogger("model")
  9. SERVER_URL = "http://127.0.0.1:5000"
  10. class Person(NamedTuple):
  11. """ Represents a Person, as retrieved from the database. """
  12. name: str
  13. person_id: int = None
  14. consumptions: dict = {}
  15. def add_consumption(self, type_id: str) -> bool:
  16. """ Register a consumption for this Person. """
  17. req = requests.post(
  18. urljoin(SERVER_URL, f"people/{self.person_id}/add_consumption/{type_id}")
  19. )
  20. try:
  21. data = req.json()
  22. if "error" in data:
  23. LOG.error(
  24. "Could not add consumption for %s (%s): %s",
  25. self.person_id,
  26. req.status_code,
  27. data,
  28. )
  29. return False
  30. self.consumptions.update(data["person"]["consumptions"])
  31. return True
  32. except ValueError:
  33. LOG.error(
  34. "Did not get JSON on adding Consumption (%s): %s",
  35. req.status_code,
  36. req.content,
  37. )
  38. return False
  39. def create(self) -> "Person":
  40. """ Create a new Person from the current attributes. As tuples are
  41. immutable, a new Person with the correct id is returned. """
  42. req = requests.post(
  43. urljoin(SERVER_URL, "people"), json={"person": {"name": self.name}}
  44. )
  45. try:
  46. data = req.json()
  47. except ValueError:
  48. LOG.error(
  49. "Did not get JSON on adding Person (%s): %s",
  50. req.status_code,
  51. req.content,
  52. )
  53. return None
  54. if "error" in data or req.status_code != 201:
  55. LOG.error("Could not create Person (%s): %s", req.status_code, data)
  56. return None
  57. return Person.from_dict(data["person"])
  58. @classmethod
  59. def get(cls, person_id: int) -> "Person":
  60. """ Retrieve a Person by id. """
  61. req = requests.get(urljoin(SERVER_URL, f"/people/{person_id}"))
  62. try:
  63. data = req.json()
  64. if "error" in data:
  65. LOG.warning(
  66. "Could not get person %s (%s): %s", person_id, req.status_code, data
  67. )
  68. return None
  69. return Person.from_dict(data["person"])
  70. except ValueError:
  71. LOG.error(
  72. "Did not get JSON from server on getting Person (%s): %s",
  73. req.status_code,
  74. req.content,
  75. )
  76. return None
  77. @classmethod
  78. def get_all(cls) -> ["Person"]:
  79. """ Get all active People. """
  80. req = requests.get(urljoin(SERVER_URL, "/people"))
  81. try:
  82. data = req.json()
  83. if "error" in data:
  84. LOG.warning("Could not get people (%s): %s", req.status_code, data)
  85. return [Person.from_dict(item) for item in data["people"]]
  86. except ValueError:
  87. LOG.error(
  88. "Did not get JSON from server on getting People (%s): %s",
  89. req.status_code,
  90. req.content,
  91. )
  92. return None
  93. @classmethod
  94. def from_dict(cls, data: dict) -> "Person":
  95. """ Reconstruct a Person object from a dict. """
  96. return Person(
  97. name=data["name"],
  98. person_id=data["person_id"],
  99. consumptions=data["consumptions"],
  100. )
  101. class ConsumptionType(NamedTuple):
  102. """ Represents a stored ConsumptionType. """
  103. name: str
  104. consumption_type_id: int = None
  105. icon: str = None
  106. def create(self) -> "Person":
  107. """ Create a new ConsumptionType from the current attributes. As tuples
  108. are immutable, a new ConsumptionType with the correct id is returned.
  109. """
  110. req = requests.post(
  111. urljoin(SERVER_URL, "consumption_types"),
  112. json={"consumption_type": {"name": self.name, "icon": self.icon}},
  113. )
  114. try:
  115. data = req.json()
  116. except ValueError:
  117. LOG.error(
  118. "Did not get JSON on adding ConsumptionType (%s): %s",
  119. req.status_code,
  120. req.content,
  121. )
  122. return None
  123. if "error" in data or req.status_code != 201:
  124. LOG.error(
  125. "Could not create ConsumptionType (%s): %s", req.status_code, data
  126. )
  127. return None
  128. return Person.from_dict(data["consumption_type"])
  129. @classmethod
  130. def get(cls, consumption_type_id: int) -> "ConsumptionType":
  131. """ Retrieve a ConsumptionType by id. """
  132. req = requests.get(
  133. urljoin(SERVER_URL, f"/consumption_types/{consumption_type_id}")
  134. )
  135. try:
  136. data = req.json()
  137. if "error" in data:
  138. LOG.warning(
  139. "Could not get consumption type %s (%s): %s",
  140. consumption_type_id,
  141. req.status_code,
  142. data,
  143. )
  144. return None
  145. return cls.from_dict(data["consumption_type"])
  146. except ValueError:
  147. LOG.error(
  148. "Did not get JSON from server on getting consumption type (%s): %s",
  149. req.status_code,
  150. req.content,
  151. )
  152. return None
  153. @classmethod
  154. def get_all(cls) -> ["ConsumptionType"]:
  155. """ Get all active ConsumptionTypes. """
  156. req = requests.get(urljoin(SERVER_URL, "/consumption_types"))
  157. try:
  158. data = req.json()
  159. if "error" in data:
  160. LOG.warning(
  161. "Could not get consumption types (%s): %s", req.status_code, data
  162. )
  163. return [cls.from_dict(item) for item in data["consumption_types"]]
  164. except ValueError:
  165. LOG.error(
  166. "Did not get JSON from server on getting ConsumptionTypes (%s): %s",
  167. req.status_code,
  168. req.content,
  169. )
  170. return None
  171. @classmethod
  172. def from_dict(cls, data: dict) -> "ConsumptionType":
  173. """ Reconstruct a ConsumptionType from a dict. """
  174. return ConsumptionType(
  175. name=data["name"],
  176. consumption_type_id=data["consumption_type_id"],
  177. icon=data.get("icon"),
  178. )