#!/usr/bin/env python3 import os import re import yaml import requests import argparse import logging # Import des fonctions de génération from app.fiches.generer import ( generer_fiche ) from app.fiches.utils.fiche_utils import load_seuils from utils.gitea import charger_arborescence_fiches from config import GITEA_TOKEN, FICHES_CRITICITE # Configuration du logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler("batch_generation.log"), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) def get_fiche_type(md_source): """Extrait le type de fiche depuis le frontmatter YAML.""" front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md_source) if not front_match: return "autre" context = yaml.safe_load(front_match.group(1)) return context.get("type_fiche", "autre") def get_indice_court(md_source): """Extrait l'indice court depuis le frontmatter YAML.""" front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md_source) if not front_match: return None context = yaml.safe_load(front_match.group(1)) return context.get("indice_court") def batch_generate_fiches(output_dir="", force_regenerate=False): """Génère toutes les fiches en batch en suivant un ordre de priorité.""" # Assurer que les répertoires de sortie existent if output_dir: os.makedirs(output_dir, exist_ok=True) # Toujours créer les répertoires nécessaires os.makedirs(os.path.join("Fiches"), exist_ok=True) os.makedirs(os.path.join("HTML"), exist_ok=True) os.makedirs(os.path.join("static", "Fiches"), exist_ok=True) # Charger les seuils try: seuils = load_seuils("assets/config.yaml") logger.info("Seuils chargés avec succès") except Exception as e: logger.error(f"Erreur lors du chargement des seuils: {e}") return # Charger l'arborescence des fiches try: arborescence = charger_arborescence_fiches() logger.info(f"Arborescence chargée: {len(arborescence)} dossiers trouvés") except Exception as e: logger.error(f"Erreur lors du chargement de l'arborescence: {e}") return # Créer une liste de toutes les fiches avec leurs informations toutes_fiches = [] for dossier, fiches in arborescence.items(): for fiche in fiches: toutes_fiches.append({ "dossier": dossier, "nom": fiche["nom"], "download_url": fiche["download_url"], "type": fiche.get("type", "autre") }) logger.info(f"Total de {len(toutes_fiches)} fiches à traiter") # Organisation des fiches par type pour respecter l'ordre de priorité fiches_par_type = { "criticite": [], "assemblage": [], "fabrication": [], "minerai": [], "autre": [] } # Télécharger et catégoriser les fiches headers = {"Authorization": f"token {GITEA_TOKEN}"} # Création des listes spécifiques pour faciliter le traitement ordonné fiches_criticite = [] autres_fiches = [] # Première étape : identifier les fiches de criticité logger.info("Identification des fiches de criticité...") for fiche in toutes_fiches: # Vérifier si c'est une fiche de criticité par deux méthodes est_criticite = False # Méthode 1: vérifier par le nom du fichier if fiche["nom"] in FICHES_CRITICITE: est_criticite = True logger.info(f"Fiche de criticité identifiée par nom: {fiche['nom']}") # Méthode 2: vérifier par le dossier elif fiche["dossier"] == "Criticités": est_criticite = True logger.info(f"Fiche de criticité identifiée par dossier: {fiche['nom']}") if est_criticite: fiches_criticite.append(fiche) else: autres_fiches.append(fiche) # Traiter d'abord les fiches de criticité logger.info(f"Traitement prioritaire des fiches de criticité ({len(fiches_criticite)} fiches)") criticite_count = 0 for fiche in fiches_criticite: try: # Télécharger la fiche de criticité reponse = requests.get(fiche["download_url"], headers=headers) reponse.raise_for_status() md_source = reponse.text # Générer immédiatement la fiche de criticité logger.info(f"Génération prioritaire de la fiche de criticité: {fiche['dossier']}/{fiche['nom']}") generer_fiche(md_source, fiche["dossier"], fiche["nom"], seuils) # Ajouter à la liste pour le décompte fiches_par_type["criticite"].append(fiche) criticite_count += 1 except Exception as e: logger.error(f"Erreur lors de la génération de la fiche de criticité {fiche['nom']}: {e}") logger.info(f"{criticite_count} fiches de criticité générées") # Maintenant catégoriser et traiter les fiches restantes (non-criticité) for fiche in autres_fiches: try: # Télécharger le contenu pour déterminer le type reponse = requests.get(fiche["download_url"], headers=headers) reponse.raise_for_status() md_source = reponse.text # Déterminer le type type_fiche = get_fiche_type(md_source) if type_fiche in fiches_par_type: fiches_par_type[type_fiche].append({**fiche, "md_source": md_source}) else: fiches_par_type["autre"].append({**fiche, "md_source": md_source}) except Exception as e: logger.error(f"Erreur lors du traitement de {fiche['nom']}: {e}") # Ordre de traitement pour les fiches restantes ordre_types = ["assemblage", "fabrication", "minerai", "autre"] # Générer les fiches restantes dans l'ordre spécifié for type_fiche in ordre_types: logger.info(f"Traitement des fiches de type '{type_fiche}' ({len(fiches_par_type[type_fiche])} fiches)") for fiche in fiches_par_type[type_fiche]: try: md_source = fiche["md_source"] dossier = fiche["dossier"] nom_fichier = fiche["nom"] # Vérifier si la génération est nécessaire html_path = os.path.join("HTML", dossier, os.path.splitext(nom_fichier)[0] + ".html") if force_regenerate or not os.path.exists(html_path): logger.info(f"Génération de {dossier}/{nom_fichier}") generer_fiche(md_source, dossier, nom_fichier, seuils) else: logger.info(f"Ignoré (déjà généré): {dossier}/{nom_fichier}") except Exception as e: logger.error(f"Erreur lors de la génération de {fiche['nom']}: {e}") logger.info("Génération batch terminée") def main(): parser = argparse.ArgumentParser(description="Générateur batch de fiches") parser.add_argument("--output", "-o", default="", help="Répertoire de sortie (laissez vide pour utiliser les dossiers de l'application)") parser.add_argument("--force", "-f", action="store_true", help="Forcer la régénération de toutes les fiches") args = parser.parse_args() logger.info(f"Démarrage de la génération batch (output: {args.output if args.output else 'dossiers par défaut'}, force: {args.force})") batch_generate_fiches(output_dir=args.output, force_regenerate=args.force) if __name__ == "__main__": main()