update torob api

This commit is contained in:
Parsa Nazer
2026-05-28 10:33:07 +03:30
parent 8960744a81
commit 2b1c2b72c1
+45 -12
View File
@@ -2,7 +2,7 @@ from __future__ import annotations
import logging
import math
from urllib.parse import urlparse
from urllib.parse import parse_qs, urlparse
import jwt
from django.conf import settings
@@ -80,6 +80,18 @@ def _extract_slug_from_url(value: str) -> str | None:
return path.split("/")[-1]
def _extract_variant_id_from_url(value: str) -> str | None:
query = urlparse(value).query
if not query:
return None
params = parse_qs(query)
variant_values = params.get("variant") or []
if not variant_values:
return None
candidate = variant_values[0].strip()
return candidate or None
def _variant_page_unique(product: ProductModel, variant: ProductVariant) -> str:
return f"{product.pk}_{variant.pk}"
@@ -109,13 +121,15 @@ def _absolute_url(request, value: str) -> str:
return request.build_absolute_uri(value)
def _shop_product_url(request, product: ProductModel) -> str:
def _shop_product_url(request, product: ProductModel, variant: ProductVariant | None = None) -> str:
domain = getattr(settings, "DOMAIN", None) or getattr(settings, "API_DOMAIN", None) or request.get_host()
if domain.startswith("http://") or domain.startswith("https://"):
base = domain.rstrip("/")
else:
base = f"https://{domain}".rstrip("/")
url = f"{base}/product/{product.slug}/"
if variant is not None:
url = f"{url}?variant={variant.pk}"
# Per spec: page_url max 1500 chars
return url[:1500]
@@ -140,9 +154,6 @@ def _variant_spec(variant: ProductVariant | None) -> dict:
if variant.color:
spec.setdefault("color", variant.color)
if variant.in_stock is not None:
spec.setdefault("in_stock", variant.in_stock)
return spec
@@ -213,7 +224,7 @@ def _serialize_variant(request, product: ProductModel, variant: ProductVariant)
payload = {
"page_unique": _variant_page_unique(product, variant),
"page_url": _shop_product_url(request, product),
"page_url": _shop_product_url(request, product, variant),
"product_group_id": str(product.pk),
"title": _truncate_text(product.name, 500),
"subtitle": _truncate_text(product.meta_description, 500),
@@ -222,11 +233,11 @@ def _serialize_variant(request, product: ProductModel, variant: ProductVariant)
"category_name": _truncate_text(product.category.name if product.category else None, 200),
"image_links": _product_image_links(request, product, variant),
"spec": _variant_spec(variant),
"guarantee": None,
"guarantee": _truncate_text(variant.guarantee, 200),
"short_desc": _truncate_text(product.description, 500),
"date_added": _variant_date_added(product, variant),
"date_updated": _variant_date_updated(product, variant),
"seller_name": product.shop.shop_name if product.shop else None,
# "seller_name": product.shop.shop_name if product.shop else None,
}
if old_price is not None and old_price > current_price:
@@ -336,27 +347,49 @@ class TorobProductSyncView(APIView):
for product in products
}
ordered_products = []
ordered_lookups: list[tuple[ProductModel, str | None]] = []
for url in requested_urls:
slug = _extract_slug_from_url(url)
normalized_url = _normalize_url(url)
variant_id = _extract_variant_id_from_url(url)
product = product_by_slug.get(slug) if slug else None
if product is None:
product = product_by_url.get(normalized_url)
if product is not None and product not in ordered_products:
ordered_products.append(product)
if product is None:
continue
ordered_lookups.append((product, variant_id))
serialized_products = []
for product in ordered_products:
seen: set[str] = set()
for product, variant_id in ordered_lookups:
variants = list(product.variants.all())
if not variants:
continue
if variant_id:
variant = next((v for v in variants if str(v.pk) == variant_id), None)
if not variant:
continue
image_links = _product_image_links(request, product, variant)
if not image_links:
continue
page_unique = _variant_page_unique(product, variant)
if page_unique in seen:
continue
seen.add(page_unique)
serialized_products.append(_serialize_variant(request, product, variant))
continue
variants.sort(key=_variant_sort_key)
for variant in variants:
image_links = _product_image_links(request, product, variant)
# Skip variants without images as per spec requirement
if not image_links:
continue
page_unique = _variant_page_unique(product, variant)
if page_unique in seen:
continue
seen.add(page_unique)
serialized_products.append(_serialize_variant(request, product, variant))
return Response(