Digitale bierlijst

model.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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,
  19. f'people/{self.person_id}/add_consumption/{type_id}')
  20. )
  21. try:
  22. data = req.json()
  23. if 'error' in data:
  24. LOG.error(
  25. 'Could not add consumption for %s (%s): %s',
  26. self.person_id, req.status_code, data
  27. )
  28. return False
  29. self.consumptions.update(data['person']['consumptions'])
  30. return True
  31. except ValueError:
  32. LOG.error(
  33. 'Did not get JSON on adding Consumption (%s): %s',
  34. req.status_code, req.content
  35. )
  36. return False
  37. def create(self) -> 'Person':
  38. ''' Create a new Person from the current attributes. As tuples are
  39. immutable, a new Person with the correct id is returned. '''
  40. req = requests.post(
  41. urljoin(SERVER_URL, "people"), json={"person": {"name": self.name}}
  42. )
  43. try:
  44. data = req.json()
  45. except ValueError:
  46. LOG.error(
  47. 'Did not get JSON on adding Person (%s): %s',
  48. req.status_code, req.content
  49. )
  50. return None
  51. if 'error' in data or req.status_code != 201:
  52. LOG.error(
  53. 'Could not create Person (%s): %s',
  54. req.status_code, data
  55. )
  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',
  67. person_id, req.status_code, data
  68. )
  69. return None
  70. return Person.from_dict(data['person'])
  71. except ValueError:
  72. LOG.error(
  73. 'Did not get JSON from server on getting Person (%s): %s',
  74. req.status_code, 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(
  85. 'Could not get people (%s): %s',
  86. req.status_code, data
  87. )
  88. return [Person.from_dict(item) for item in data['people']]
  89. except ValueError:
  90. LOG.error(
  91. 'Did not get JSON from server on getting People (%s): %s',
  92. req.status_code, req.content
  93. )
  94. return None
  95. @classmethod
  96. def from_dict(cls, data: dict) -> 'Person':
  97. ''' Reconstruct a Person object from a dict. '''
  98. return Person(
  99. name = data['name'],
  100. person_id = data['person_id'],
  101. consumptions = data['consumptions']
  102. )
  103. class ConsumptionType(NamedTuple):
  104. ''' Represents a stored ConsumptionType. '''
  105. name: str
  106. consumption_type_id: int = None
  107. icon: str = None
  108. def create(self) -> 'Person':
  109. ''' Create a new ConsumptionType from the current attributes. As tuples
  110. are immutable, a new ConsumptionType with the correct id is returned.
  111. '''
  112. req = requests.post(
  113. urljoin(SERVER_URL, "consumption_types"), json={"consumption_type":
  114. {"name": self.name, "icon": self.icon}}
  115. )
  116. try:
  117. data = req.json()
  118. except ValueError:
  119. LOG.error(
  120. 'Did not get JSON on adding ConsumptionType (%s): %s',
  121. req.status_code, req.content
  122. )
  123. return None
  124. if 'error' in data or req.status_code != 201:
  125. LOG.error(
  126. 'Could not create ConsumptionType (%s): %s',
  127. req.status_code, data
  128. )
  129. return None
  130. return Person.from_dict(data['consumption_type'])
  131. @classmethod
  132. def get(cls, consumption_type_id: int) -> 'ConsumptionType':
  133. ''' Retrieve a ConsumptionType by id. '''
  134. req = requests.get(urljoin(SERVER_URL,
  135. f'/consumption_types/{consumption_type_id}'))
  136. try:
  137. data = req.json()
  138. if 'error' in data:
  139. LOG.warning(
  140. 'Could not get consumption type %s (%s): %s',
  141. consumption_type_id, req.status_code, data
  142. )
  143. return None
  144. return cls.from_dict(data['consumption_type'])
  145. except ValueError:
  146. LOG.error(
  147. 'Did not get JSON from server on getting consumption type (%s): %s',
  148. req.status_code, req.content
  149. )
  150. return None
  151. @classmethod
  152. def get_all(cls) -> ['ConsumptionType']:
  153. ''' Get all active ConsumptionTypes. '''
  154. req = requests.get(urljoin(SERVER_URL, '/consumption_types'))
  155. try:
  156. data = req.json()
  157. if 'error' in data:
  158. LOG.warning(
  159. 'Could not get consumption types (%s): %s',
  160. req.status_code, data
  161. )
  162. return [cls.from_dict(item) for item in data['consumption_types']]
  163. except ValueError:
  164. LOG.error(
  165. 'Did not get JSON from server on getting ConsumptionTypes (%s): %s',
  166. req.status_code, req.content
  167. )
  168. return None
  169. @classmethod
  170. def from_dict(cls, data: dict) -> 'ConsumptionType':
  171. ''' Reconstruct a ConsumptionType from a dict. '''
  172. return ConsumptionType(
  173. name = data['name'],
  174. consumption_type_id = data['consumption_type_id'],
  175. icon = data.get('icon')
  176. )