Agrégateur de produits québécois — www.fabri-ka.com
Python 38.4%
HTML 30.3%
TypeScript 17.2%
CSS 11%
JavaScript 3.2%
1#!/usr/bin/env python32"""Backfill du statut « présumée fermée » depuis l'historique sync_log.34Le mécanisme durable vit dans fabrika/ingest.py (compteur fail_streak,5seuil CLOSE_AFTER_FAILS, réintégration automatique au premier sync réussi).6Ce script rejoue l'historique existant : pour chaque boutique activée, on7compte les échecs consécutifs depuis le dernier sync réussi ; au-delà du8seuil, statut appliqué + produits dépubliés (réversible).910Usage : .venv/bin/python scripts/backfill_closures.py [--dry-run]11"""12import argparse13import sys14from pathlib import Path1516ROOT = Path(__file__).resolve().parent.parent17sys.path.insert(0, str(ROOT))1819from fabrika import db # noqa: E40220from fabrika.ingest import CLOSE_AFTER_FAILS # noqa: E402212223def main():24 ap = argparse.ArgumentParser()25 ap.add_argument("--dry-run", action="store_true")26 args = ap.parse_args()2728 con = db.connect()29 stores = con.execute(30 "SELECT id, name, product_count FROM stores "31 "WHERE enabled=1 AND catalog_endpoint<>''").fetchall()32 closed, updated = [], 033 for sid, name, pc in stores:34 rows = con.execute(35 "SELECT status FROM sync_log WHERE store_id=? "36 "ORDER BY ts DESC LIMIT 100", (sid,)).fetchall()37 streak = 038 for (status,) in rows:39 if status == "error":40 streak += 141 elif status == "ok":42 break43 # presumed_closed / autres statuts : neutres44 con.execute("UPDATE stores SET fail_streak=? WHERE id=?", (streak, sid))45 updated += 146 if streak >= CLOSE_AFTER_FAILS:47 closed.append((sid, name, streak, pc))48 if not args.dry_run:49 con.execute("UPDATE stores SET presumed_closed=1, product_count=0 "50 "WHERE id=?", (sid,))51 con.execute("UPDATE products SET active=0 WHERE store_id=?", (sid,))52 db.log_sync(con, sid, 0, 0, 0, 0, "presumed_closed",53 f"backfill historique : {streak} échecs consécutifs")54 if not args.dry_run:55 con.commit()56 con.close()57 print(f"fail_streak recalculé pour {updated} boutiques")58 print(f"présumées fermées ({'dry-run' if args.dry_run else 'appliqué'}) : "59 f"{len(closed)}")60 for sid, name, streak, pc in closed:61 print(f" - {sid} «{name}» : {streak} échecs consécutifs, "62 f"{pc} produits dépubliés")636465if __name__ == "__main__":66 main()67