spb/fabri-ka Public
Agrégateur de produits québécois — www.fabri-ka.com
HTML 57.9%
Python 18.6%
TypeScript 15.6%
CSS 7.8%
1# -----------------------------------------------------------------------------2# Fabri-Ka — Agrégateur de produits québécois3# Auteur : Simon-Pierre Boucher — contact@spboucher.ai4# connectors/woocommerce.py : connecteur générique WooCommerce — catalogue5# complet via la Store API publique /wp-json/wc/store/v1/products.6# -----------------------------------------------------------------------------7from __future__ import annotations89from ..schema import Product10from .base import BaseConnector111213class WooCommerceConnector(BaseConnector):14 platform = "woocommerce"1516 def _get_items(self, url: str):17 """JSON direct, sinon Scrapfly (Cloudflare & cie) en dernier recours."""18 try:19 r = self.get(url)20 return r.json()21 except Exception as exc:22 from . import scrapfly23 if scrapfly.available():24 return scrapfly.scrapfly_json(url)25 raise exc2627 def fetch(self) -> list[Product]:28 out: list[Product] = []29 page = 130 while page <= self.max_pages:31 items = self._get_items(f"{self.base}/wp-json/wc/store/v1/products?per_page=100&page={page}")32 if not isinstance(items, list) or not items:33 break34 for it in items:35 prices = it.get("prices") or {}36 unit = 10 ** int(prices.get("currency_minor_unit", 2))37 def money(v):38 try:39 return int(v) / unit if v not in (None, "") else None40 except (TypeError, ValueError):41 return None42 price = money(prices.get("price"))43 pr = prices.get("price_range") or {}44 pmin, pmax = money(pr.get("min_amount")), money(pr.get("max_amount"))45 cats = [c.get("name", "") for c in (it.get("categories") or [])]46 out.append(Product(47 store_id=self.store_id,48 external_id=str(it["id"]),49 url=it.get("permalink", ""),50 title=it.get("name", ""),51 description=it.get("short_description") or it.get("description") or "",52 price=pmin or price,53 price_max=pmax or price,54 compare_at_price=money(prices.get("regular_price"))55 if prices.get("sale_price") and prices.get("sale_price") != prices.get("regular_price")56 else None,57 currency=prices.get("currency_code", "CAD"),58 images=[im.get("src", "") for im in (it.get("images") or [])],59 product_type=", ".join(cats),60 tags=[t.get("name", "") for t in (it.get("tags") or [])],61 available=bool(it.get("is_in_stock", True)),62 ))63 if len(items) < 100:64 break65 page += 166 return out67