# ----------------------------------------------------------------------------- # Fabri-Ka — Agrégateur de produits québécois # Auteur : Simon-Pierre Boucher — contact@spboucher.ai # connectors/woocommerce.py : connecteur générique WooCommerce — catalogue # complet via la Store API publique /wp-json/wc/store/v1/products. # ----------------------------------------------------------------------------- from __future__ import annotations from ..schema import Product from .base import BaseConnector class WooCommerceConnector(BaseConnector): platform = "woocommerce" def _get_items(self, url: str): """JSON direct, sinon Scrapfly (Cloudflare & cie) en dernier recours.""" try: r = self.get(url) return r.json() except Exception as exc: from . import scrapfly if scrapfly.available(): return scrapfly.scrapfly_json(url) raise exc def fetch(self) -> list[Product]: out: list[Product] = [] page = 1 while page <= self.max_pages: items = self._get_items(f"{self.base}/wp-json/wc/store/v1/products?per_page=100&page={page}") if not isinstance(items, list) or not items: break for it in items: prices = it.get("prices") or {} unit = 10 ** int(prices.get("currency_minor_unit", 2)) def money(v): try: return int(v) / unit if v not in (None, "") else None except (TypeError, ValueError): return None price = money(prices.get("price")) pr = prices.get("price_range") or {} pmin, pmax = money(pr.get("min_amount")), money(pr.get("max_amount")) cats = [c.get("name", "") for c in (it.get("categories") or [])] out.append(Product( store_id=self.store_id, external_id=str(it["id"]), url=it.get("permalink", ""), title=it.get("name", ""), description=it.get("short_description") or it.get("description") or "", price=pmin or price, price_max=pmax or price, compare_at_price=money(prices.get("regular_price")) if prices.get("sale_price") and prices.get("sale_price") != prices.get("regular_price") else None, currency=prices.get("currency_code", "CAD"), images=[im.get("src", "") for im in (it.get("images") or [])], product_type=", ".join(cats), tags=[t.get("name", "") for t in (it.get("tags") or [])], available=bool(it.get("is_in_stock", True)), )) if len(items) < 100: break page += 1 return out