product_app.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. import typing
  2. import sqlalchemy
  3. import sqlalchemy.engine.base
  4. from .app_route import app_route_database
  5. from .product import product
  6. from .product import product_factory
  7. from .product_loader import product_loader
  8. from .product_response import product_response
  9. from .product_builder import product_builder
  10. from .exception import bad_request_exception
  11. from .exception import not_found_exception
  12. from .exception import access_denied_exception
  13. from .users_collection import users_collection
  14. from .image import image
  15. from .directory_image import directory_image
  16. class product_app(app_route_database):
  17. def __init__(
  18. self,
  19. connection: sqlalchemy.engine.base.Engine,
  20. users: users_collection,
  21. images: directory_image
  22. ) -> None:
  23. super().__init__(connection)
  24. self.__users_collection = users
  25. self.__response = product_response(images)
  26. self.__images_manager = images
  27. def all(self) -> dict:
  28. try:
  29. with self.__products_database as loader:
  30. return self.__collection(loader.load_all())
  31. except Exception as error:
  32. return self._fail(str(error))
  33. def get_barcode(self, target: str) -> dict:
  34. try:
  35. with self.__products_database as loader:
  36. return self.__single(loader.get_by_barcode(target))
  37. except Exception as error:
  38. return self._fail(str(error))
  39. def get_name(self, target: str) -> dict:
  40. try:
  41. with self.__products_database as loader:
  42. return self.__single(loader.get_by_name(target))
  43. except Exception as error:
  44. return self._fail(str(error))
  45. def search_name(self, target: str) -> dict:
  46. try:
  47. with self.__products_database as loader:
  48. return self.__collection(loader.search_by_name(target))
  49. except Exception as error:
  50. return self._fail(str(error))
  51. def search_author(self, target: str) -> dict:
  52. try:
  53. with self.__products_database as loader:
  54. return self.__collection(loader.search_by_author(target))
  55. except Exception as error:
  56. return self._fail(str(error))
  57. def check_barcode(self, target: str) -> dict:
  58. try:
  59. with self.__products_database as loader:
  60. return self.__exists(loader.barcode_in_use(target))
  61. except Exception as error:
  62. return self._fail(str(error))
  63. def check_name(self, target: str) -> dict:
  64. try:
  65. with self.__products_database as loader:
  66. return self.__exists(loader.name_in_use(target))
  67. except Exception as error:
  68. return self._fail(str(error))
  69. def __image(self, send: dict) -> image | None:
  70. if not "image" in send:
  71. return None
  72. return image(send["image"])
  73. def create(self, send: dict) -> dict:
  74. try:
  75. if not self.__logged_in(send):
  76. raise access_denied_exception()
  77. target = product_builder().modify(send).result
  78. image = self.__image(send)
  79. if image is None:
  80. raise bad_request_exception("not contain image")
  81. with self.__products_database as loader:
  82. result = loader.store(target)
  83. if not result:
  84. return self.__modify(result, "Can not create product.")
  85. try:
  86. self.__images_manager.save(image, target)
  87. except Exception as error:
  88. loader.drop(target)
  89. raise error
  90. return self._success()
  91. except Exception as error:
  92. return self._fail(str(error))
  93. def __logged_in(self, send: dict) -> bool:
  94. if not "apikey" in send:
  95. return False
  96. return self.__users.get(send["apikey"]) is not None
  97. def __select_by_sended(
  98. self,
  99. send: dict,
  100. loader: product_loader
  101. ) -> product | None:
  102. barcode = None
  103. name = None
  104. if "target_barcode" in send:
  105. barcode = send["target_barcode"]
  106. if "target_name" in send:
  107. name = send["target_name"]
  108. if barcode is not None and name is not None:
  109. content = "Give only one, target_name or target_barcode"
  110. raise bad_request_exception(content)
  111. if barcode is None and name is None:
  112. content = "Give target_barcode or target_name"
  113. raise bad_request_exception(content)
  114. result = None
  115. if barcode is not None:
  116. result = loader.get_by_barcode(barcode)
  117. if name is not None:
  118. result = loader.get_by_name(name)
  119. if result is None:
  120. raise not_found_exception()
  121. return result
  122. def update(self, send: dict) -> dict:
  123. try:
  124. if not self.__logged_in(send):
  125. raise access_denied_exception()
  126. with self.__products_database as loader:
  127. target = self.__select_by_sended(send, loader)
  128. old = target.save_copy()
  129. updated = product_builder(target).modify(send).result
  130. if not loader.store(updated):
  131. return self._fail("Can not update product.")
  132. try:
  133. self.__images_manager.update(old, updated)
  134. except Exception as error:
  135. updated.restore_copy(old)
  136. if not loader.store(updated):
  137. error = "Image caould be moved. Can not restore "
  138. error = error + "previous product. Fatal error."
  139. return self._fail(error)
  140. raise error
  141. return self._success()
  142. except Exception as error:
  143. return self._fail(str(error))
  144. def update_image(self, send: dict) -> dict:
  145. try:
  146. if not self.__logged_in(send):
  147. raise access_denied_exception()
  148. image = self.__image(send)
  149. if image is None:
  150. raise bad_request_exception("Not found image in request.")
  151. with self.__products_database as loader:
  152. target = self.__select_by_sended(send, loader)
  153. self.__images_manager.drop(target)
  154. self.__images_manager.save(image, target)
  155. return self._success()
  156. except Exception as error:
  157. return self._fail(str(error))
  158. def delete(self, send: dict) -> dict:
  159. try:
  160. if not self.__logged_in(send):
  161. raise access_denied_exception()
  162. with self.__products_database as loader:
  163. target = self.__select_by_sended(send, loader)
  164. copy = target.save_copy()
  165. if not loader.drop(target):
  166. return self._fail("Can not delete product.")
  167. self.__images_manager.drop(copy)
  168. return self._success()
  169. except Exception as error:
  170. return self._fail(str(error))
  171. def __modify(self, result: bool, cause: str) -> dict:
  172. if result:
  173. return self._success()
  174. else:
  175. return self._fail(cause)
  176. def __exists(self, result: bool) -> dict:
  177. return self._success(exists = result)
  178. def __single(self, target: product) -> dict:
  179. if target is None:
  180. return self._fail("Can not found product in database.")
  181. return self._success(product = self.__response.single(target))
  182. def __collection(self, target: typing.Iterable[product]) -> dict:
  183. return self._success(collection = self.__response.collection(target))
  184. @property
  185. def __users(self) -> users_collection:
  186. return self.__users_collection
  187. @property
  188. def __products_database(self) -> product_loader:
  189. return product_loader(self._connection)