spb/fabri-ka Public
Agrégateur de produits québécois — www.fabri-ka.com
HTML 57.9%
Python 18.6%
TypeScript 15.6%
CSS 7.8%
1#!/usr/bin/env python32"""Génère la section §6 (statistiques finales) de research_report.md."""3import json4import sqlite35import os6from collections import Counter78ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))9reg = json.load(open(os.path.join(ROOT, "data", "stores.json")))["stores"]10con = sqlite3.connect(os.path.join(ROOT, "data", "fabrika.db"))1112lines = []13n = len(reg)14ecom = sum(1 for s in reg if s["ecommerce"])15connectable = sum(1 for s in reg if s["catalog_endpoint"])16by_class = Counter(s["origin_class"] for s in reg)17by_status = Counter(s["status"] for s in reg)18by_region = Counter(s["region"] or "(inconnue)" for s in reg)19by_platform = Counter(s["platform"] or "custom/inconnu" for s in reg if s["ecommerce"])20multi_src = sum(1 for s in reg if len(s.get("discovery_sources", [])) >= 2)2122nprod = con.execute("SELECT COUNT(*) FROM products WHERE active=1").fetchone()[0]23nstores_live = con.execute("SELECT COUNT(DISTINCT store_id) FROM products WHERE active=1").fetchone()[0]2425# candidats bruts26cand = sum(1 for _ in open(os.path.join(ROOT, "data", "enriched", "candidates.jsonl")))2728lines.append(f"""### Totaux2930| Mesure | Valeur |31|---|---|32| Domaines candidats découverts (bruts, dédupliqués) | {cand} |33| Boutiques québécoises actives vérifiées (dataset final) | **{n}** |34| — avec fonctionnalité ecommerce détectée | {ecom} |35| — avec catalogue public connectable (Shopify/Woo/Squarespace) | {connectable} |36| — corroborées par ≥ 2 sources indépendantes | {multi_src} |37| Produits agrégés dans Fabri-Ka (catalogues complets) | **{nprod}** |38| Boutiques avec produits en ligne dans Fabri-Ka | {nstores_live} |3940### Classification d'origine4142| Classe | Définition | Boutiques |43|---|---|---|""")44defs = {"A": "Fabriqué/cultivé/transformé au Québec", "B": "Conçu au Québec",45 "C": "Détaillant québécois", "D": "Mixte", "E": "Incertain"}46for c in "ABCDE":47 lines.append(f"| {c} | {defs[c]} | {by_class.get(c, 0)} |")4849lines.append(f"""50Statuts : {dict(by_status)}5152### Par région administrative5354| Région | Boutiques |55|---|---|""")56for r, v in by_region.most_common():57 lines.append(f"| {r} | {v} |")5859lines.append("""60### Plateformes ecommerce (boutiques avec ecommerce)6162| Plateforme | Boutiques |63|---|---|""")64for p, v in by_platform.most_common():65 lines.append(f"| {p} | {v} |")6667out = "\n".join(lines) + "\n"68rp = os.path.join(ROOT, "deliverables", "research_report.md")69txt = open(rp).read()70marker = "*(section générée automatiquement — voir ci-dessous)*"71txt = txt.split(marker)[0] + marker + "\n\n" + out72open(rp, "w").write(txt)73print(out[:800])74