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. """
 """ Product and helpers. """
 from .product import product
 from .product import product
-from .product import product_builder
+from .product import product_factory
 from .product_loader import product_loader
 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):
 class exists_exception(Exception):
     def __init__(self, name: str):
     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
         return True
         
         
         
         
-class product_builder:
+class product_factory:
     """
     """
     This is builder of the product. It helps to handle validation of the 
     This is builder of the product. It helps to handle validation of the 
     product params, and modify exists product with validators.
     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
 import sqlmodel.sql._expression_select_cls
 
 
 from .product import product
 from .product import product
-from .product import product_builder
+from .product import product_factory
 from .validator import barcode_validator
 from .validator import barcode_validator
 from .validator import name_validator
 from .validator import name_validator
 from .validator import description_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")
 connection = sqlmodel.create_engine("sqlite:///002-product.db")
 sqlmodel.SQLModel.metadata.create_all(connection)
 sqlmodel.SQLModel.metadata.create_all(connection)
 
 
-builder = assets.product_builder()
+builder = assets.product_factory()
 builder.name = "Sample name"
 builder.name = "Sample name"
 builder.author = "Simple UwU Artist"
 builder.author = "Simple UwU Artist"
 builder.description = "This is simple description"
 builder.description = "This is simple description"
@@ -52,7 +52,7 @@ with assets.product_loader(connection) as loader:
 with assets.product_loader(connection) as loader:
 with assets.product_loader(connection) as loader:
     print("Updating:")
     print("Updating:")
     
     
-    builder = assets.product_builder(loader.get_by_barcode("123456789012"))
+    builder = assets.product_factory(loader.get_by_barcode("123456789012"))
     builder.stock_count = 200
     builder.stock_count = 200
     product = builder.result
     product = builder.result
     loader.store(product)
     loader.store(product)
@@ -64,7 +64,7 @@ with assets.product_loader(connection) as loader:
 with assets.product_loader(connection) as loader:
 with assets.product_loader(connection) as loader:
     print("Get from stock:")
     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()
     builder.get_from_stock()
 
 
     product = builder.result
     product = builder.result