#!/usr/bin/env python3 """Fusionne sources/registry-*.csv → sources/registry.csv, sources/normes-*.csv → sources/normes-matrice.csv, references/lib-*.bib → references/library.bib (clés dédoublonnées, la première occurrence gagne ; library.bib hérité d'abord). Idempotent : les fichiers fusionnés sont reconstruits à partir des fichiers sources + de la partie « héritée » de library.bib.""" import csv, re, pathlib, sys ROOT = pathlib.Path(__file__).resolve().parents[1] # --- registre hdr = "id,type,titre,organisme,version_ou_date,url,date_consultation,statut,utilise_dans,notes".split(",") rows = [] for f in sorted((ROOT / "sources").glob("registry-*.csv")): with f.open(encoding="utf-8") as fh: r = csv.DictReader(fh) for row in r: rows.append({k: (row.get(k) or "").strip() for k in hdr}) seen = set(); out = [] for row in rows: if row["id"] in seen or not row["id"]: continue seen.add(row["id"]); out.append(row) with (ROOT / "sources/registry.csv").open("w", encoding="utf-8", newline="") as fh: w = csv.DictWriter(fh, fieldnames=hdr); w.writeheader(); w.writerows(out) print(f"registry.csv : {len(out)} sources ({sum(1 for r in out if r['statut']=='verifie')} vérifiées)") # --- normes hdrn = "id,domaine,disposition,texte_source,reference_precise,effet_sur_evaluation,version_verifiee,date_consultation,chapitres".split(",") nrows = [] for f in sorted((ROOT / "sources").glob("normes-*.csv")): if f.name == "normes-matrice.csv": continue with f.open(encoding="utf-8") as fh: for row in csv.DictReader(fh): nrows.append({k: (row.get(k) or "").strip() for k in hdrn}) with (ROOT / "sources/normes-matrice.csv").open("w", encoding="utf-8", newline="") as fh: w = csv.DictWriter(fh, fieldnames=hdrn); w.writeheader(); w.writerows(nrows) print(f"normes-matrice.csv : {len(nrows)} dispositions") # --- bib lib = ROOT / "references/library.bib" txt = lib.read_text(encoding="utf-8") marker = "\n% ===== ENTRÉES VÉRIFIÉES (phase 1, fusion automatique de lib-*.bib) =====\n" base = txt.split(marker)[0].rstrip() + "\n" def keys(s): return re.findall(r"^@\w+\s*\{\s*([^,\s]+)\s*,", s, re.M) have = set(keys(base)); added = []; dup = [] for f in sorted((ROOT / "references").glob("lib-*.bib")): s = f.read_text(encoding="utf-8") # découpe en entrées parts = re.split(r"(?m)^(?=@\w+\s*\{)", s) for p in parts: m = re.match(r"@\w+\s*\{\s*([^,\s]+)\s*,", p) if not m: continue k = m.group(1) if k in have: dup.append(f"{f.name}:{k}"); continue have.add(k); added.append(p.strip() + "\n") lib.write_text(base + marker + "\n".join(added), encoding="utf-8") print(f"library.bib : {len(have)} clés ({len(added)} ajoutées ; doublons ignorés : {len(dup)})") if dup: print(" doublons :", ", ".join(dup[:20]))