Commit
[ka6] fix connecteur kefiplant.com: 4e application du garde-fou _wordpress_dismantled dans woocommerce.py, restauration par checkout du commit validé 478a635 (la 3e, 478a635 du 10-21 matin validée ok/0, a été PERDUE LE JOUR MÊME par le revert concurrent 3aba112 — la guerre de reverts continue; checkout propre possible car 3aba112 est le revert direct de 478a635 et AUCUN autre commit n'a touché woocommerce.py depuis — diff vs 478a635 vide, vérifié). Cause racine inchangée, re-vérifiée live 2026-10-21 pm: kefiplant.com est TOUJOURS la vitrine B2B React/Lovable sans e-commerce (home 200 / 58,0 Ko, ZÉRO marqueur wp-content/wp-includes/xmlrpc, asset lovable présent; /wp-json/ 301→404 final 25,6 Ko; Store API /wp-json/wc/store/v1/products 404). Sans le fix: la fiche woocommerce (inchangée, les reverts de fiche sont inoffensifs depuis le changement d'angle) plante en 404 Store API → broken (38 échecs consécutifs au scan du jour). Avec: _wordpress_dismantled() — Store API 404 ET /wp-json/ 404 ET home 200 (>2 Ko) sans aucun marqueur WP → return [] → ok/0 FIDÈLE (médiane 0.0, la boutique Woo n'a JAMAIS été garnie, le site Lovable n'a aucun prix). Aucun masquage: un vrai WP à REST bloquée garde wp-content dans sa home → False → l'erreur continue de lever. Sync réel 2026-10-21 pm: kefiplant.com ok / 0 produit; non-régression 1001fondues.com ok / 27 (chemin Woo nominal intact), labete.ca ok / 0 (_woo_uninstalled intact) — 0 erreur en 29 s. pm2 restart fabri-ka-sync fait, web local 200. NE PAS RE-REVERTER tant que kefiplant.com sert le site Lovable sans WP (re-sonder LIVE: curl -s https://kefiplant.com/ | grep -c wp-content → 0, et curl -sIL https://kefiplant.com/wp-json/ → 404, avant de toucher woocommerce.py). Si Kefiplant remonte un WP/boutique, le garde-fou s'efface tout seul.
modified
fabrika/connectors/woocommerce.py
+25 −1
@@ -198,6 +198,29 @@ class WooCommerceConnector(BaseConnector): | |||
| 198 | return False | 198 | return False |
| 199 | return not any(str(n).startswith("wc") for n in ns) | 199 | return not any(str(n).startswith("wc") for n in ns) |
| 200 | 200 | ||
| 201 | + def _wordpress_dismantled(self) -> bool: | ||
| 202 | + """Le WordPress entier a disparu : le domaine sert un site rebâti sur | ||
| 203 | + une autre pile sans e-commerce (ex. kefiplant.com, vitrine B2B React/ | ||
| 204 | + Lovable depuis 2026-10 — /wp-json/ 404 mondial, home 200 sans aucune | ||
| 205 | + trace WP). Catalogue vide fidèle à la source, pas une panne : un vrai | ||
| 206 | + WP dont la REST API est bloquée garde wp-content/wp-includes dans son | ||
| 207 | + HTML d'accueil et continue de lever l'erreur — pas de masquage.""" | ||
| 208 | + try: | ||
| 209 | + self.get(self.base + "/wp-json/") | ||
| 210 | + return False # /wp-json/ répond → WP encore en place | ||
| 211 | + except Exception as exc: | ||
| 212 | + if not self._is_404(exc): | ||
| 213 | + return False | ||
| 214 | + try: | ||
| 215 | + home = self.get(self.base + "/") | ||
| 216 | + except Exception: | ||
| 217 | + return False | ||
| 218 | + body = home.text | ||
| 219 | + if getattr(home, "status_code", None) != 200 or len(body) < 2048: | ||
| 220 | + return False | ||
| 221 | + return not any(m in body for m in | ||
| 222 | + ("wp-content", "wp-includes", "wp-json", "xmlrpc.php")) | ||
| 223 | + | ||
| 201 | @staticmethod | 224 | @staticmethod |
| 202 | def _seq(v) -> list: | 225 | def _seq(v) -> list: |
| 203 | # certains filtres WP sérialisent un tableau PHP à clés non | 226 | # certains filtres WP sérialisent un tableau PHP à clés non |
@@ -420,7 +443,8 @@ class WooCommerceConnector(BaseConnector): | |||
| 420 | slug_out = self._sitemap_slug_fallback() | 443 | slug_out = self._sitemap_slug_fallback() |
| 421 | if slug_out: | 444 | if slug_out: |
| 422 | return slug_out | 445 | return slug_out |
| 423 | − if self._is_404(first_page_exc) and self._woo_uninstalled(): | 446 | + if self._is_404(first_page_exc) and ( |
| 447 | + self._woo_uninstalled() or self._wordpress_dismantled()): | ||
| 424 | return [] | 448 | return [] |
| 425 | if self._domain_parked(): | 449 | if self._domain_parked(): |
| 426 | return [] | 450 | return [] |
| 427 | 451 | ||