hisham-cmd commited on
Commit
e4d325b
·
verified ·
1 Parent(s): 5bd1426

Upload app/services/external_catalog.py

Browse files
Files changed (1) hide show
  1. app/services/external_catalog.py +75 -0
app/services/external_catalog.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import random
4
+ import httpx
5
+ from typing import List, Dict, Any
6
+ from sqlalchemy.orm import Session
7
+ from app.models.product import Product, ProductImage, Category
8
+
9
+ class ExternalCatalogService:
10
+ """Service to bridge external data sources (Apify, Shopify, Search) to the local store."""
11
+
12
+ def __init__(self, db: Session):
13
+ self.db = db
14
+ self.discovery_file = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "discovered_products.json")
15
+
16
+ async def fetch_real_products(self, query: str, category_name: str | None = None) -> List[Dict[str, Any]]:
17
+ """
18
+ Fetches real products from the discovery pool or simulated search tools.
19
+ """
20
+ if os.path.exists(self.discovery_file):
21
+ with open(self.discovery_file, "r", encoding="utf-8") as f:
22
+ pool = json.load(f)
23
+ # Filter results based on query relevance (simple keyword match for simulation)
24
+ results = [p for p in pool if query.lower() in p["title"].lower() or query.lower() in p.get("name_ar", "").lower()]
25
+ return results[:10]
26
+
27
+ # Fallback to empty if no pool exists
28
+ return []
29
+
30
+ async def create_product_from_external(self, data: Dict[str, Any], category_id: int | None = None) -> Product:
31
+ """
32
+ Transforms external product JSON (from Shopify/Amazon/Zara) into a local Product entry.
33
+ """
34
+ # Auto-detect category if not provided
35
+ final_category_id = category_id
36
+ if not final_category_id:
37
+ cat_name = data.get("category_name")
38
+ if cat_name:
39
+ cat = self.db.query(Category).filter(Category.name_ar == cat_name).first()
40
+ if cat:
41
+ final_category_id = cat.id
42
+
43
+ # Use child of category 1 (Uncategorized) as fallback if still None
44
+ if not final_category_id:
45
+ final_category_id = 1
46
+
47
+ product = Product(
48
+ name_ar=data.get("name_ar", data.get("title", "منتج جديد")),
49
+ name_en=data.get("name_en", data.get("title", "New Product")),
50
+ description_ar=data.get("description", ""),
51
+ description_en=data.get("description", ""),
52
+ price=float(data.get("price", 0)),
53
+ compare_price=float(data.get("compare_price", 0)) or float(data.get("price", 0)) * 1.2,
54
+ stock=random.randint(5, 50),
55
+ category_id=final_category_id,
56
+ rating=float(data.get("rating", 4.5)),
57
+ rating_count=random.randint(5, 100),
58
+ specs=data.get("specs", {}),
59
+ is_active=True,
60
+ is_featured=random.choice([True, False])
61
+ )
62
+ self.db.add(product)
63
+ self.db.flush()
64
+
65
+ images = data.get("images", [])
66
+ for i, img_url in enumerate(images):
67
+ prod_img = ProductImage(
68
+ product_id=product.id,
69
+ image_url=img_url,
70
+ alt_text=product.name_ar,
71
+ sort_order=i
72
+ )
73
+ self.db.add(prod_img)
74
+
75
+ return product