2025-06-05 09:28:49 +02:00

156 lines
6.3 KiB
Python

# 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"<!---- AUTO-BEGIN:TABLEAU-FABRICANTS -->.*?<!---- AUTO-END:TABLEAU-FABRICANTS -->",
f"<!---- AUTO-BEGIN:TABLEAU-FABRICANTS -->\n{tableau_final}\n<!---- AUTO-END:TABLEAU-FABRICANTS -->",
md,
flags=re.DOTALL
)
else:
md_modifie = re.sub(
r"<!---- AUTO-BEGIN:TABLEAU-ASSEMBLEURS -->.*?<!---- AUTO-END:TABLEAU-ASSEMBLEURS -->",
f"<!---- AUTO-BEGIN:TABLEAU-ASSEMBLEURS -->\n{tableau_final}\n<!---- AUTO-END:TABLEAU-ASSEMBLEURS -->",
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"<!---- AUTO-BEGIN:SECTION-IHH -->.*?<!---- AUTO-END:SECTION-IHH -->",
f"<!---- AUTO-BEGIN:SECTION-IHH -->\n{ihh_section}\n<!---- AUTO-END:SECTION-IHH -->",
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