Tableau de bord de suivi de l'avancement des indicateurs

Le principe est que l'avancement de la rédaction des fiches, les commentaires, les questionnements se voient à travers un tableur de données CSV - "\\NEXTE\Alteris\Production\AL_Inventaire_Structure.csv"
Il est mis en place par un script PYTHON généré par Gemini.
Ce script est évolutif - notamment pour y inserer les renvois vers les fiches Bookstack ou autre.
Ne pas changer de place le script (conçu en chemin relatif pour le NAS)- le tableur créé est lui mobile.
Extrait du tableur de suivi de l'avancement des indicateurs
 
 
 
le script évolutif 
import os
import csv
import re
# --- CONFIGURATION DYNAMIQUE ---
# Le script regarde là où il est enregistré
script_dir = os.path.dirname(os.path.abspath(__file__))
# On définit le nom du dossier Obsidian (qui doit être dans le même dossier que le script)
folder_name = "Obsidian_Alteris"
base_dir = os.path.join(script_dir, folder_name)
# Le CSV sera créé au même endroit que le script
output_file = os.path.join(script_dir, "AL_Inventaire_Structure.csv")
data_inventory = []
print(f"--- PILOTAGE ALTERIS ---")
print(f"Recherche du coffre dans : {base_dir}")
if not os.path.exists(base_dir):
    print(f"ERREUR : Le dossier '{folder_name}' est introuvable.")
    print(f"Vérifiez que ce script est bien placé à côté du dossier du NAS.")
else:
    # ... (Le reste du code reste identique pour l'extraction et le tri) ...
    for root, dirs, files in os.walk(base_dir):
        for file in files:
            if file.endswith(".md") and not file.startswith("00_"):
                file_path = os.path.join(root, file)
                try:
                    with open(file_path, "r", encoding="utf-8") as f:
                        content = f.read()
                        id_sql = re.search(r"ID_SQL:\s*(.*)", content)
                        nature = re.search(r"Nature:\s*(.*)", content)
                        statut = re.search(r"Statut:\s*(.*)", content)
                        
                        id_val = id_sql.group(1).strip() if id_sql else "999"
                        nature_val = nature.group(1).strip() if nature else "Inconnue"
                        
                        parts = file_path.split(os.sep)
                        thematique = "Inconnue"
                        if "Impacts" in parts:
                            thematique = parts[parts.index("Impacts")-1]
                        elif "Symptomes" in parts:
                            thematique = parts[parts.index("Symptomes")-1]
                        
                        data_inventory.append({
                            "THEMATIQUE": thematique,
                            "NATURE": nature_val,
                            "ID_SQL": id_val,
                            "NOM_INDICATEUR": file.replace(".md", ""),
                            "STATUT": statut.group(1).strip() if statut else "A rédiger"
                        })
                except Exception as e:
                    pass
    # Tri et écriture
    data_inventory.sort(key=lambda x: (x['THEMATIQUE'], x['NATURE'], x['ID_SQL']))
    
    if data_inventory:
        with open(output_file, "w", encoding="utf-8-sig", newline="") as csvfile:
            fieldnames = ["THEMATIQUE", "NATURE", "ID_SQL", "NOM_INDICATEUR", "STATUT"]
            writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=";")
            writer.writeheader()
            current_thematique = ""
            for row in data_inventory:
                if current_thematique != "" and row["THEMATIQUE"] != current_thematique:
                    writer.writerow({k: "" for k in fieldnames})
                writer.writerow(row)
                current_thematique = row["THEMATIQUE"]
        print(f"SUCCÈS ! Inventaire mis à jour dans ce dossier.")