Browse Source

Sync with laptop.

Cixo Develop 6 months ago
parent
commit
81a659c6e0

+ 2 - 1
assets/__init__.py

@@ -10,5 +10,6 @@ from .exception import validator_exception
 
 """ Product and helpers. """
 from .product import product
-from .product import product_builder
+from .product import product_factory
 from .product_loader import product_loader
+

+ 22 - 0
assets/app_route.py

@@ -0,0 +1,22 @@
+import sqlalchemy.engine.base
+
+class app_route:
+    def __init__(self, connection: sqlalchemy.engine.base.Engine) -> None:
+        self.__connection = connection
+
+    @property
+    def _connection(self) -> sqlalchemy.engine.base.Engine:
+        return self.__connection
+
+    def _success(self, **kwargs) -> dict:
+        return self.__response("success", **kwargs)
+
+    def _fail(self, cause: str, **kwargs) -> dict:
+        kwargs["cause"] = cause
+
+        return self.__response("fail", cause)
+
+    def __response(self, result: str, **kwargs) -> dict:
+        kwargs["result"] = result
+        
+        return kwargs

+ 11 - 1
assets/exception.py

@@ -4,4 +4,14 @@ class validator_exception(Exception):
 
 class exists_exception(Exception):
     def __init__(self, name: str):
-        super().__init__("Item with this " + name + " already in database.")
+        super().__init__("Item with this " + name + " already in database.")
+
+class not_ready_exception(Exception):
+    def __init__(self, target: any):
+        dump = str(target)
+        what = str(type(target))
+        
+        info = "Can not work, because " + what + " is not raeady.\n"
+        info = info + "Dump:\n" + what + "\n\n"
+
+        super().__init__(info)

+ 1 - 1
assets/product.py

@@ -84,7 +84,7 @@ class product(sqlmodel.SQLModel, table = True):
         return True
         
         
-class product_builder:
+class product_factory:
     """
     This is builder of the product. It helps to handle validation of the 
     product params, and modify exists product with validators.

+ 93 - 0
assets/product_app.py

@@ -0,0 +1,93 @@
+import typing
+
+from .app_route import app_route
+from .product import product 
+from .product import product_factory
+from .product_loader import product_loader
+from .product_response import product_response
+from .product_builder import product_builder
+
+class product_app(app_route):
+    def all(self) -> dict:
+        with self.__products_database as loader:
+            return self.__collection(loader.load_all())
+
+    def get_barcode(self, target: str) -> dict:
+        with self.__products_database as loader:
+            return self.__single(loader.get_by_barcode(target))
+
+    def get_name(self, target: str) -> dict:
+        with self.__products_database as loader:
+            return self.__single(loader.get_by_name(target))
+
+    def search_name(self, target: str) -> dict:
+        with self.__products_database as loader:
+            return self.__collection(loader.search_by_name(target))
+
+    def search_author(self, target: str) -> dict:
+        with self.__products_database as loader:
+            return self.__collection(loader.search_by_author(target))
+
+    def check_barcode(self, target: str) -> dict:
+        with self.__products_database as loader:
+            return self.__exists(loader.barcode_in_use(target))
+
+    def check_name(self, target: str) -> dict:
+        with self.__products_database as loader:
+            return self.__exists(loader.name_in_use(target))
+
+    def create(self, send: dict) -> dict:
+        with self.__products_database as loader:
+            target = product_builder().modify(send).result
+            result = loader.store(target)
+
+            return self.__modify(result, "Can nod create product.")
+
+    def update(self, send: dict) -> dict:
+        barcode = send["target_barcode"] if "target_barcode" in send else None
+        name = send["target_name"] if "target_name" in send else None
+
+        if barcode is not None and name is not None:
+            return self._fail("Give only one, name OR by barcode.")
+
+        if barcode is None and name is None:
+            return self._fail("Identify target by name or barcode.")
+
+        with self.__products_database as loader:
+            if barcode is not None:
+                target = loader.get_by_barcode(barcode)
+            else:
+                target = loader.get_by_name(name)
+
+            if target is None:
+                return self._fail("Not found product to update.")
+
+            updated = product_builder(target).modify(send).result
+            result = loader.store(updated)
+
+            return self.__modify(result, "Can not update product.")
+
+    def delete(self, send: dict) -> dict:
+
+
+    def __modify(self, result: bool, cause: str) -> dict:
+        if result:
+            return self._success()
+        else:
+            return self._fail(cause)
+
+    def __exists(self, result: bool) -> dict:
+        return self._success(exists = result)
+
+    def __single(self, target: product) -> dict:
+        if target is None:
+            return self._fail("Can not found product in database.")
+
+        return self.__success(product = product_response(target))
+
+    def __collection(self, target: typing.Iterable[product]) -> dict:
+        return self.__success(collection = product_response(target))
+
+    @property
+    def __products_database(self) -> product_loader:
+        return product_loader(self._connection)

+ 38 - 0
assets/product_builder.py

@@ -0,0 +1,38 @@
+from .product import product
+from .product import product_factory
+
+class product_builder:
+    def __init__(self, target: product | None = None) -> None:
+        self.__target = target
+
+        if self.__target is None:
+            self.__target = product()
+
+    def modify(self, target: dict) -> object:
+        factory = product_factory(target)
+
+        if "name" in target:
+            factory.name = target["name"]
+
+        if "description" in target:
+            factory.description = target["description"]
+
+        if "author" in target:
+            factory.author = target["author"]
+
+        if "image" in target:
+            factory.image = target["image"]
+
+        if "stock_count" in target:
+            factory.stock_count = target["stock_count"]
+
+        if "barcode" in target:
+            factory.barcode = target["barcode"]
+
+        self.__target = factory.result    
+
+        return self
+
+    @property
+    def result(self) -> product:
+        return self.__target

+ 1 - 1
assets/product_loader.py

@@ -3,7 +3,7 @@ import sqlmodel
 import sqlmodel.sql._expression_select_cls
 
 from .product import product
-from .product import product_builder
+from .product import product_factory
 from .validator import barcode_validator
 from .validator import name_validator
 from .validator import description_validator

+ 43 - 0
assets/product_response.py

@@ -0,0 +1,43 @@
+import typing
+import collections.abc
+
+from .product import product
+from .exception import not_ready_exception
+
+class product_response:
+    def __new__(
+        cls, 
+        target: product | typing.Iterable[product]
+    ) -> list | dict:
+        if isinstance(target, product):
+            return cls.single(target)
+
+        if isinstance(target, collections.abc.Iterable):
+            return cls.collection(target)
+
+        raise TypeError("Bad type for product response generator.")
+
+
+    def single(target: product) -> dict:
+        if not product.ready:
+            raise not_ready_exception(target)
+
+        return {
+            "name": product.name,
+            "description": product.description,
+            "author": product.author,
+            "image": product.image,
+            "stock_count": product.stock_count,
+            "barcode": product.barcode
+        }
+
+    def collection(targets: typing.Iterable[product]) -> list:
+        result = list()
+
+        for count in targets:
+            if not isinstance(count, product):
+                raise TypeError("Products iterable must contain products.")
+
+            result.append(product_response.single(count))
+
+        return result

+ 3 - 3
tests/002-product.py

@@ -20,7 +20,7 @@ drop_database()
 connection = sqlmodel.create_engine("sqlite:///002-product.db")
 sqlmodel.SQLModel.metadata.create_all(connection)
 
-builder = assets.product_builder()
+builder = assets.product_factory()
 builder.name = "Sample name"
 builder.author = "Simple UwU Artist"
 builder.description = "This is simple description"
@@ -52,7 +52,7 @@ with assets.product_loader(connection) as loader:
 with assets.product_loader(connection) as loader:
     print("Updating:")
     
-    builder = assets.product_builder(loader.get_by_barcode("123456789012"))
+    builder = assets.product_factory(loader.get_by_barcode("123456789012"))
     builder.stock_count = 200
     product = builder.result
     loader.store(product)
@@ -64,7 +64,7 @@ with assets.product_loader(connection) as loader:
 with assets.product_loader(connection) as loader:
     print("Get from stock:")
     
-    builder = assets.product_builder(loader.get_by_barcode("123456789012"))
+    builder = assets.product_factory(loader.get_by_barcode("123456789012"))
     builder.get_from_stock()
 
     product = builder.result