# production.py # Ce module gère à la fois les fiches d'assemblage ET de fabrication. import re import yaml import streamlit as st from config import FICHES_CRITICITE def build_production_sections(md: str) -> str: """ Procédure pour construire et remplacer les sections des fiches de production. Cette fonction permet d'extraire les données du markdown, organiser les informations sur les pays d'implantation et acteurs, puis générer un tableau structuré dans l'intervention. Le code prend en charge deux types de fiches : fabrication et assemblage. Args: md (str): Fichier Markdown à traiter contenant la structure YAML des sections. Returns: str: Markdown modifié avec les tableaux construits selon le type de fiche. """ schema = None type_fiche = None front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md) if front_match: try: front_matter = yaml.safe_load(front_match.group(1)) schema = front_matter.get("schema") type_fiche = front_matter.get("type_fiche") if type_fiche not in ["assemblage", "fabrication"] or not schema: return md except Exception as e: st.error(f"Erreur lors du chargement du front matter: {e}") return md yaml_block = re.search(r"```yaml\n(.+?)\n```", md, re.DOTALL) if not yaml_block: return md # Capture le bloc YAML complet pour le supprimer plus tard yaml_block_full = yaml_block.group(0) try: yaml_data = yaml.safe_load(yaml_block.group(1)) except Exception as e: st.error(f"Erreur lors du chargement du YAML: {e}") return md if not isinstance(yaml_data, dict) or len(yaml_data) == 0: return md produit_key = list(yaml_data.keys())[0] produit_data = yaml_data[produit_key] pays_data = [] for pays_key, pays_info in produit_data.items(): nom_pays = pays_info.get('nom_du_pays', '') part_marche_pays = pays_info.get('part_de_marche', '0%') part_marche_num = float(part_marche_pays.strip('%')) acteurs = [] for acteur_key, acteur_info in pays_info.get('acteurs', {}).items(): nom_acteur = acteur_info.get('nom_de_l_acteur', '') part_marche_acteur = acteur_info.get('part_de_marche', '0%') pays_origine = acteur_info.get('pays_d_origine', '') part_marche_acteur_num = float(part_marche_acteur.strip('%')) acteurs.append({ 'nom': nom_acteur, 'part_marche': part_marche_acteur, 'part_marche_num': part_marche_acteur_num, 'pays_origine': pays_origine }) acteurs_tries = sorted(acteurs, key=lambda x: x['part_marche_num'], reverse=True) pays_data.append({ 'nom': nom_pays, 'part_marche': part_marche_pays, 'part_marche_num': part_marche_num, 'acteurs': acteurs_tries }) pays_tries = sorted(pays_data, key=lambda x: x['part_marche_num'], reverse=True) lignes_tableau = [ "| **Pays d'implantation** | **Entreprise** | **Pays d'origine** | **Part de marché** |", "| :-- | :-- | :-- | :-- |" ] for pays in pays_tries: for acteur in pays['acteurs']: part_marche_formattee = acteur['part_marche'].strip('%') + ' %' lignes_tableau.append( f"| {pays['nom']} | {acteur['nom']} | {acteur['pays_origine']} | {part_marche_formattee} |" ) part_marche_pays_formattee = pays['part_marche'].strip('%') + ' %' lignes_tableau.append( f"| **{pays['nom']}** | **Total** | **{pays['nom']}** | **{part_marche_pays_formattee}** |" ) tableau_final = "\n".join(lignes_tableau) if type_fiche == "fabrication": md_modifie = re.sub( r".*?", f"\n{tableau_final}\n", md, flags=re.DOTALL ) else: md_modifie = re.sub( r".*?", f"\n{tableau_final}\n", md, flags=re.DOTALL ) # Chercher et remplacer la section IHH si un schéma a été identifié if schema: # Charger le contenu de la fiche technique IHH try: # Essayer de lire le fichier depuis le système de fichiers with open(FICHES_CRITICITE["IHH"], "r", encoding="utf-8") as f: ihh_content = f.read() # Chercher la section IHH correspondant au schéma et au type de fiche # Format de la section : ## Assemblage/Fabrication - [Schema] if type_fiche == "fabrication": ihh_section_pattern = rf"## Fabrication - {schema}\s*\n### Indice de Herfindahl-Hirschmann[\s\S]*?(?=\n## |$)" else: # type_fiche == "assemblage" ihh_section_pattern = rf"## Assemblage - {schema}\s*\n### Indice de Herfindahl-Hirschmann[\s\S]*?(?=\n## |$)" ihh_section_match = re.search(ihh_section_pattern, ihh_content) if ihh_section_match: # Extraire la section complète sans le titre principal ihh_section = ihh_section_match.group(0).split("\n", 2)[2].strip() # Remplacer la section IHH dans la fiche d'assemblage md_modifie = re.sub( r".*?", f"\n{ihh_section}\n", md_modifie, flags=re.DOTALL ) else: # Si aucune section IHH n'est trouvée pour ce schéma, laisser la section existante st.warning(f"Aucune section IHH trouvée pour le schéma {schema} dans la fiche technique IHH.") except Exception as e: st.error(f"Erreur lors de la lecture/traitement de la fiche IHH: {e}") # Supprimer le bloc YAML du markdown final md_modifie = md_modifie.replace(yaml_block_full, "") return md_modifie