SPB Git forge

spb/fabri-ka

Public

Agrégateur de produits québécois — www.fabri-ka.com

217commits 1branches 0releases
66.1 MBsize
maindefault branch
3 h agolast push
Python 38.4% HTML 30.3% TypeScript 17.2% CSS 11% JavaScript 3.2%

Reapply "[ka6] fix connecteur artisansduvitrail.com: helper _seq() dans woocommerce.py" — revert du revert bfcc188 qui avait annulé 33728a4 quelques minutes après son application (guerre de reverts concurrents, même pattern que foodcrayon/labete). Cause racine re-vérifiée live le 2026-09-06: la Store API Woo du site sérialise toujours un tableau PHP à clés non séquentielles en objet JSON ({"1": {...}} au lieu de [{...}]) sur le champ images de 2 produits sur 2092 (ids 58337 et 18714), ce qui fait planter _parse_item ('str' object has no attribute 'get') et casse tout le sync. _seq() (dict → list(values())) appliqué aux champs liste de _parse_item (images, categories, tags, brands, variations, attributes/terms). Ne pas re-reverter tant que le site sérialise ainsi.

Simon-Pierre Boucher committed 20 days ago (Sep 6, 2026) parent bfcc188

1 changed file +19 −7

modified fabrika/connectors/woocommerce.py +19 −7
@@ -161,6 +161,15 @@ class WooCommerceConnector(BaseConnector):
161 161 return False
162 162 return not any(str(n).startswith("wc") for n in ns)
163 163
164 + @staticmethod
165 + def _seq(v) -> list:
166 + # certains filtres WP sérialisent un tableau PHP à clés non
167 + # séquentielles en objet JSON ({"1": {...}} au lieu de [{...}]) —
168 + # constaté sur les images d'artisansduvitrail.com; tolérer les deux
169 + if isinstance(v, dict):
170 + return list(v.values())
171 + return v or []
172 +
164 173 def _parse_item(self, it: dict) -> Product:
165 174 """Mappe un produit Store API (liste ou fiche unitaire) vers Product."""
166 175 prices = it.get("prices") or {}
@@ -173,8 +182,9 @@ class WooCommerceConnector(BaseConnector):
173 182 price = money(prices.get("price"))
174 183 pr = prices.get("price_range") or {}
175 184 pmin, pmax = money(pr.get("min_amount")), money(pr.get("max_amount"))
176 − cats = [c.get("name", "") for c in (it.get("categories") or [])]
177 − brands = [b.get("name", "") for b in (it.get("brands") or []) if b.get("name")]
185 + cats = [c.get("name", "") for c in self._seq(it.get("categories")) if isinstance(c, dict)]
186 + brands = [b.get("name", "") for b in self._seq(it.get("brands"))
187 + if isinstance(b, dict) and b.get("name")]
178 188 det: dict = {}
179 189 try:
180 190 if float(it.get("average_rating") or 0) > 0:
@@ -197,8 +207,8 @@ class WooCommerceConnector(BaseConnector):
197 207 def _nm(x):
198 208 return x.get("name", "") if isinstance(x, dict) else str(x)
199 209 attributes = []
200 − for a in (it.get("attributes") or []):
201 − terms = a.get("terms") or [] if isinstance(a, dict) else []
210 + for a in self._seq(it.get("attributes")):
211 + terms = self._seq(a.get("terms")) if isinstance(a, dict) else []
202 212 attributes.append({"name": _nm(a),
203 213 "terms": [_nm(t) for t in terms]})
204 214 if attributes:
@@ -211,7 +221,7 @@ class WooCommerceConnector(BaseConnector):
211 221 det["on_sale"] = True
212 222 if cats:
213 223 det["categories"] = [c for c in cats if c]
214 − variations = it.get("variations") or []
224 + variations = self._seq(it.get("variations"))
215 225 if variations:
216 226 det["variations"] = len(variations)
217 227 vout = []
@@ -241,9 +251,11 @@ class WooCommerceConnector(BaseConnector):
241 251 if prices.get("sale_price") and prices.get("sale_price") != prices.get("regular_price")
242 252 else None,
243 253 currency=prices.get("currency_code", "CAD"),
244 − images=[im.get("src", "") for im in (it.get("images") or [])],
254 + images=[im.get("src", "") for im in self._seq(it.get("images"))
255 + if isinstance(im, dict)],
245 256 product_type=", ".join(cats),
246 − tags=[t.get("name", "") for t in (it.get("tags") or [])],
257 + tags=[t.get("name", "") for t in self._seq(it.get("tags"))
258 + if isinstance(t, dict)],
247 259 vendor=brands[0] if brands else "",
248 260 available=bool(it.get("is_in_stock", True)),
249 261 details=det,
250 262