From 7720cee7b2753c1658c8740a75f5aa5ee9ce864f Mon Sep 17 00:00:00 2001 From: Eliton Jorge Date: Wed, 26 Jun 2024 10:16:22 -0300 Subject: [PATCH] Add product characteristics and add new html lines on description (#516) --- marketplace/clients/vtex/client.py | 10 +++++++ .../rules/categories_by_seller_gbarbosa.py | 30 +++++++++++++++++++ .../services/vtex/private/products/service.py | 3 ++ .../services/vtex/utils/data_processor.py | 15 +++++++--- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/marketplace/clients/vtex/client.py b/marketplace/clients/vtex/client.py index ac0f09ab..ac0dbb8e 100644 --- a/marketplace/clients/vtex/client.py +++ b/marketplace/clients/vtex/client.py @@ -171,3 +171,13 @@ def list_all_active_products(self, domain): current_from += step return list(unique_skus) + + # API throttling + @rate_limit_and_retry_on_exception( + get_domain_from_args, calls_per_period=VTEX_CALLS_PER_PERIOD, period=VTEX_PERIOD + ) + def get_product_specification(self, product_id, domain): + url = f"https://{domain}/api/catalog_system/pvt/products/{product_id}/specification" + headers = self._get_headers() + response = self.make_request(url, method="GET", headers=headers) + return response.json() diff --git a/marketplace/services/vtex/business/rules/categories_by_seller_gbarbosa.py b/marketplace/services/vtex/business/rules/categories_by_seller_gbarbosa.py index 88d159a5..fc891801 100644 --- a/marketplace/services/vtex/business/rules/categories_by_seller_gbarbosa.py +++ b/marketplace/services/vtex/business/rules/categories_by_seller_gbarbosa.py @@ -7,10 +7,24 @@ class CategoriesBySeller(Rule): def apply(self, product: FacebookProductDTO, **kwargs) -> bool: seller_id = kwargs.get("seller_id") + service = kwargs.get("service") + domain = kwargs.get("domain") + if self._is_home_appliance(product): # Only seller gbarbosab101 can have appliances if seller_id != "gbarbosab101": return False + + # current_description = product.description + specifications = self._product_specification(product, service, domain) + combined_description = f"{product.description}\n{specifications}" + + # Ensure the combined description does not exceed 9999 characters + if len(combined_description) > 9999: + combined_description = combined_description[:9999] + + product.description = combined_description + # If the product is not an appliance, it can be added by any seller return True @@ -25,3 +39,19 @@ def _get_categories(self, product: FacebookProductDTO) -> set: def _is_home_appliance(self, product: FacebookProductDTO) -> bool: product_categories = self._get_categories(product) return bool(self.HOME_APPLIANCES_CATEGORIES.intersection(product_categories)) + + def _product_specification( + self, product: FacebookProductDTO, service, domain + ) -> str: + product_id = product.product_details.get("ProductId") + specification_text = "Características: " + specifications = service.get_product_specification(product_id, domain) + + specification_parts = [] + for specification in specifications: + name = specification.get("Name") + value = ", ".join(specification.get("Value", [])) + specification_parts.append(f"{name} - {value}") + + specification_text += "\n ".join(specification_parts) + "." + return specification_text diff --git a/marketplace/services/vtex/private/products/service.py b/marketplace/services/vtex/private/products/service.py index 03841d0e..6a6fe85a 100644 --- a/marketplace/services/vtex/private/products/service.py +++ b/marketplace/services/vtex/private/products/service.py @@ -112,6 +112,9 @@ def update_webhook_product_info( return updated_products_dto + def get_product_specification(self, product_id, domain): + return self.client.get_product_specification(product_id, domain) + # ================================ # Private Methods # ================================ diff --git a/marketplace/services/vtex/utils/data_processor.py b/marketplace/services/vtex/utils/data_processor.py index ccad5986..7442766c 100644 --- a/marketplace/services/vtex/utils/data_processor.py +++ b/marketplace/services/vtex/utils/data_processor.py @@ -44,15 +44,18 @@ def __init__(self): @staticmethod def clean_text(text: str) -> str: """Cleans up text by removing HTML tags, replacing quotes with empty space, - replacing commas with semicolons, and normalizing whitespace.""" + replacing commas with semicolons, and normalizing whitespace but keeping new lines. + """ # Remove HTML tags text = re.sub(r"<[^>]*>", "", text) # Replace double and single quotes with empty space text = text.replace('"', "").replace("'", " ") # Replace commas with semicolons text = text.replace(",", ";") - # Normalize new lines and carriage returns to space and remove excessive whitespace - text = re.sub(r"\s+", " ", text.strip()) + # Normalize new lines and carriage returns to a single newline + text = re.sub(r"\r\n|\r|\n", "\n", text) + # Remove excessive whitespace but keep new lines + text = re.sub(r"[ \t]+", " ", text.strip()) # Remove bullet points text = text.replace("•", "") return text @@ -224,7 +227,11 @@ def process_single_sku(self, sku_id): if not self._validate_product_dto(product_dto): continue - params = {"seller_id": seller_id} + params = { + "seller_id": seller_id, + "service": self.service, + "domain": self.domain, + } all_rules_applied = True for rule in self.rules: if not rule.apply(product_dto, **params):