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
4 h agolast push
Python 38.4% HTML 30.3% TypeScript 17.2% CSS 11% JavaScript 3.2%

Revert "[ka6] fix connecteur artisansduvitrail.com: la Store API Woo de ce site sérialise parfois un tableau PHP à clés non séquentielles en objet JSON ({"1": {...}} au lieu de [{...}]) — constaté sur le champ images de 2 produits sur 2092, ce qui faisait planter _parse_item ('str' object has no attribute 'get') et cassait tout le sync depuis 3 passages. Ajout du helper _seq() dans woocommerce.py (dict → list(values())) appliqué aux champs liste de _parse_item (images, categories, tags, brands, variations, attributes/terms). Sync réel: artisansduvitrail.com ok / 2092 produits (médiane 2091, +2 ~3 -0); non-régression artisandulac.ca (451 produits, 0 erreur, = volume prod)"

This reverts commit 33728a410c5ab3b2b12996aabc608a4363cf2440.
Simon-Pierre Boucher committed 21 days ago (Sep 6, 2026) parent 33728a4

1 changed file +7 −19

modified fabrika/connectors/woocommerce.py +7 −19
@@ -161,15 +161,6 @@ 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 −
173 164 def _parse_item(self, it: dict) -> Product:
174 165 """Mappe un produit Store API (liste ou fiche unitaire) vers Product."""
175 166 prices = it.get("prices") or {}
@@ -182,9 +173,8 @@ class WooCommerceConnector(BaseConnector):
182 173 price = money(prices.get("price"))
183 174 pr = prices.get("price_range") or {}
184 175 pmin, pmax = money(pr.get("min_amount")), money(pr.get("max_amount"))
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")]
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")]
188 178 det: dict = {}
189 179 try:
190 180 if float(it.get("average_rating") or 0) > 0:
@@ -207,8 +197,8 @@ class WooCommerceConnector(BaseConnector):
207 197 def _nm(x):
208 198 return x.get("name", "") if isinstance(x, dict) else str(x)
209 199 attributes = []
210 − for a in self._seq(it.get("attributes")):
211 − terms = self._seq(a.get("terms")) if isinstance(a, dict) else []
200 + for a in (it.get("attributes") or []):
201 + terms = a.get("terms") or [] if isinstance(a, dict) else []
212 202 attributes.append({"name": _nm(a),
213 203 "terms": [_nm(t) for t in terms]})
214 204 if attributes:
@@ -221,7 +211,7 @@ class WooCommerceConnector(BaseConnector):
221 211 det["on_sale"] = True
222 212 if cats:
223 213 det["categories"] = [c for c in cats if c]
224 − variations = self._seq(it.get("variations"))
214 + variations = it.get("variations") or []
225 215 if variations:
226 216 det["variations"] = len(variations)
227 217 vout = []
@@ -251,11 +241,9 @@ class WooCommerceConnector(BaseConnector):
251 241 if prices.get("sale_price") and prices.get("sale_price") != prices.get("regular_price")
252 242 else None,
253 243 currency=prices.get("currency_code", "CAD"),
254 − images=[im.get("src", "") for im in self._seq(it.get("images"))
255 − if isinstance(im, dict)],
244 + images=[im.get("src", "") for im in (it.get("images") or [])],
256 245 product_type=", ".join(cats),
257 − tags=[t.get("name", "") for t in self._seq(it.get("tags"))
258 − if isinstance(t, dict)],
246 + tags=[t.get("name", "") for t in (it.get("tags") or [])],
259 247 vendor=brands[0] if brands else "",
260 248 available=bool(it.get("is_in_stock", True)),
261 249 details=det,
262 250