mirror of
https://github.com/Ladebeze66/llm_ticket3.git
synced 2025-12-16 00:36:52 +01:00
383 lines
14 KiB
Python
383 lines
14 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Script principal d'orchestration du processus d'analyse de tickets.
|
|
Ce script permet d'exécuter toutes les étapes du traitement ou des étapes individuelles.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import argparse
|
|
import subprocess
|
|
import logging
|
|
from typing import Dict, List, Any, Optional
|
|
import shutil
|
|
|
|
# Configuration du logger
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
handlers=[
|
|
logging.FileHandler("processus_complet.log"),
|
|
logging.StreamHandler()
|
|
]
|
|
)
|
|
logger = logging.getLogger("processus_complet")
|
|
|
|
def executer_commande(commande: List[str], description: str) -> bool:
|
|
"""
|
|
Exécute une commande système et gère les erreurs.
|
|
|
|
Args:
|
|
commande: Liste des éléments de la commande à exécuter
|
|
description: Description de la commande pour le journal
|
|
|
|
Returns:
|
|
True si la commande s'est exécutée avec succès, False sinon
|
|
"""
|
|
try:
|
|
logger.info(f"Exécution: {description}")
|
|
logger.debug(f"Commande: {' '.join(commande)}")
|
|
|
|
resultat = subprocess.run(commande, check=True, capture_output=True, text=True)
|
|
|
|
logger.info(f"Succès: {description}")
|
|
logger.debug(f"Sortie: {resultat.stdout}")
|
|
|
|
return True
|
|
except subprocess.CalledProcessError as e:
|
|
logger.error(f"Échec: {description}")
|
|
logger.error(f"Code de sortie: {e.returncode}")
|
|
logger.error(f"Erreur: {e.stderr}")
|
|
return False
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors de l'exécution de la commande: {str(e)}")
|
|
return False
|
|
|
|
def etape_extraction(ticket_dir: str, output_dir: str) -> bool:
|
|
"""
|
|
Exécute l'étape d'extraction des données du ticket.
|
|
|
|
Args:
|
|
ticket_dir: Répertoire contenant les données brutes du ticket
|
|
output_dir: Répertoire où sauvegarder les données extraites
|
|
|
|
Returns:
|
|
True si l'extraction a réussi, False sinon
|
|
"""
|
|
script_path = os.path.join("scripts", "extract_ticket.py")
|
|
|
|
if not os.path.exists(script_path):
|
|
logger.error(f"Script d'extraction non trouvé: {script_path}")
|
|
return False
|
|
|
|
commande = [
|
|
sys.executable,
|
|
script_path,
|
|
ticket_dir,
|
|
"--output-dir", output_dir,
|
|
"--verbose"
|
|
]
|
|
|
|
return executer_commande(commande, "Extraction des données du ticket")
|
|
|
|
def etape_filtrage_images(ticket_dir: str) -> bool:
|
|
"""
|
|
Exécute l'étape de filtrage des images pertinentes.
|
|
|
|
Args:
|
|
ticket_dir: Répertoire contenant les données du ticket
|
|
|
|
Returns:
|
|
True si le filtrage a réussi, False sinon
|
|
"""
|
|
script_path = os.path.join("scripts", "filter_images.py")
|
|
|
|
if not os.path.exists(script_path):
|
|
logger.error(f"Script de filtrage d'images non trouvé: {script_path}")
|
|
return False
|
|
|
|
commande = [
|
|
sys.executable,
|
|
script_path,
|
|
"--dossier-ticket", ticket_dir,
|
|
"--output", os.path.join(ticket_dir, "filter_report.json"),
|
|
"--verbose"
|
|
]
|
|
|
|
return executer_commande(commande, "Filtrage des images pertinentes")
|
|
|
|
def etape_analyse_images(ticket_dir: str, rapport_filtrage: str) -> bool:
|
|
"""
|
|
Exécute l'étape d'analyse des images pertinentes.
|
|
|
|
Args:
|
|
ticket_dir: Répertoire contenant les données du ticket
|
|
rapport_filtrage: Chemin vers le rapport de filtrage d'images
|
|
|
|
Returns:
|
|
True si l'analyse a réussi, False sinon
|
|
"""
|
|
script_path = os.path.join("scripts", "analyze_image_contexte.py")
|
|
ticket_info_path = os.path.join(ticket_dir, "ticket_info.json")
|
|
|
|
if not os.path.exists(script_path):
|
|
logger.error(f"Script d'analyse d'images non trouvé: {script_path}")
|
|
return False
|
|
|
|
# Charger le rapport de filtrage
|
|
try:
|
|
with open(rapport_filtrage, 'r', encoding='utf-8') as f:
|
|
filtre_data = json.load(f)
|
|
|
|
images_pertinentes = filtre_data.get("images_pertinentes", [])
|
|
if not images_pertinentes:
|
|
logger.info("Aucune image pertinente à analyser")
|
|
return True
|
|
except Exception as e:
|
|
logger.error(f"Erreur lors du chargement du rapport de filtrage: {str(e)}")
|
|
return False
|
|
|
|
# Créer le répertoire pour les rapports d'analyse d'images
|
|
images_analyses_dir = os.path.join(ticket_dir, "images_analyses")
|
|
os.makedirs(images_analyses_dir, exist_ok=True)
|
|
|
|
# Analyser chaque image pertinente
|
|
succes = True
|
|
for image_path in images_pertinentes:
|
|
image_name = os.path.basename(image_path)
|
|
output_base = os.path.join(images_analyses_dir, image_name)
|
|
|
|
commande = [
|
|
sys.executable,
|
|
script_path,
|
|
"--image", image_path,
|
|
"--ticket-info", ticket_info_path,
|
|
"--output", output_base + "_analyse",
|
|
"--verbose"
|
|
]
|
|
|
|
if not executer_commande(commande, f"Analyse de l'image {image_name}"):
|
|
succes = False
|
|
|
|
return succes
|
|
|
|
def etape_analyse_ticket(ticket_dir: str, rapport_filtrage: str) -> bool:
|
|
"""
|
|
Exécute l'étape d'analyse du contenu du ticket.
|
|
|
|
Args:
|
|
ticket_dir: Répertoire contenant les données du ticket
|
|
rapport_filtrage: Chemin vers le rapport de filtrage d'images
|
|
|
|
Returns:
|
|
True si l'analyse a réussi, False sinon
|
|
"""
|
|
script_path = os.path.join("scripts", "analyze_ticket.py")
|
|
messages_path = os.path.join(ticket_dir, "messages.json")
|
|
|
|
if not os.path.exists(script_path):
|
|
logger.error(f"Script d'analyse de ticket non trouvé: {script_path}")
|
|
return False
|
|
|
|
commande = [
|
|
sys.executable,
|
|
script_path,
|
|
"--messages", messages_path,
|
|
"--images-rapport", rapport_filtrage,
|
|
"--output", ticket_dir,
|
|
"--verbose"
|
|
]
|
|
|
|
return executer_commande(commande, "Analyse du contenu du ticket")
|
|
|
|
def etape_questions_reponses(ticket_dir: str) -> bool:
|
|
"""
|
|
Exécute l'étape d'extraction des questions et réponses.
|
|
|
|
Args:
|
|
ticket_dir: Répertoire contenant les données du ticket
|
|
|
|
Returns:
|
|
True si l'extraction a réussi, False sinon
|
|
"""
|
|
script_path = os.path.join("scripts", "extract_question_reponse.py")
|
|
messages_path = os.path.join(ticket_dir, "messages.json")
|
|
output_path = os.path.join(ticket_dir, "questions_reponses.md")
|
|
|
|
if not os.path.exists(script_path):
|
|
logger.error(f"Script d'extraction des questions-réponses non trouvé: {script_path}")
|
|
return False
|
|
|
|
commande = [
|
|
sys.executable,
|
|
script_path,
|
|
"--messages", messages_path,
|
|
"--output", output_path,
|
|
"--verbose"
|
|
]
|
|
|
|
return executer_commande(commande, "Extraction des questions et réponses")
|
|
|
|
def processus_complet(ticket_code: str, dossier_source: str = None, dossier_sortie: str = None) -> bool:
|
|
"""
|
|
Exécute le processus complet d'analyse d'un ticket.
|
|
|
|
Args:
|
|
ticket_code: Code du ticket à analyser
|
|
dossier_source: Dossier contenant les tickets bruts (par défaut: output/)
|
|
dossier_sortie: Dossier où sauvegarder les résultats (par défaut: output_processed/)
|
|
|
|
Returns:
|
|
True si le processus s'est exécuté avec succès, False sinon
|
|
"""
|
|
# Définir les dossiers par défaut si non spécifiés
|
|
if dossier_source is None:
|
|
dossier_source = "output"
|
|
|
|
if dossier_sortie is None:
|
|
dossier_sortie = "output_processed"
|
|
|
|
# Construire les chemins
|
|
ticket_dir_source = os.path.join(dossier_source, f"ticket_{ticket_code}")
|
|
ticket_dir_sortie = os.path.join(dossier_sortie, f"ticket_{ticket_code}")
|
|
|
|
# Vérifier que le dossier source existe
|
|
if not os.path.exists(ticket_dir_source):
|
|
logger.error(f"Dossier source non trouvé: {ticket_dir_source}")
|
|
return False
|
|
|
|
# Créer le dossier de sortie s'il n'existe pas
|
|
os.makedirs(ticket_dir_sortie, exist_ok=True)
|
|
|
|
# 1. Extraction des données
|
|
if not etape_extraction(ticket_dir_source, ticket_dir_sortie):
|
|
logger.error("Échec de l'étape d'extraction")
|
|
return False
|
|
|
|
# 2. Filtrage des images
|
|
if not etape_filtrage_images(ticket_dir_sortie):
|
|
logger.error("Échec de l'étape de filtrage des images")
|
|
return False
|
|
|
|
# 3. Analyse des images pertinentes
|
|
rapport_filtrage = os.path.join(ticket_dir_sortie, "filter_report.json")
|
|
if not etape_analyse_images(ticket_dir_sortie, rapport_filtrage):
|
|
logger.error("Échec de l'étape d'analyse des images")
|
|
return False
|
|
|
|
# 4. Analyse du contenu du ticket
|
|
if not etape_analyse_ticket(ticket_dir_sortie, rapport_filtrage):
|
|
logger.error("Échec de l'étape d'analyse du ticket")
|
|
return False
|
|
|
|
# 5. Extraction des questions et réponses
|
|
if not etape_questions_reponses(ticket_dir_sortie):
|
|
logger.error("Échec de l'étape d'extraction des questions et réponses")
|
|
return False
|
|
|
|
logger.info(f"Processus complet terminé avec succès pour le ticket {ticket_code}")
|
|
logger.info(f"Résultats disponibles dans: {ticket_dir_sortie}")
|
|
|
|
return True
|
|
|
|
def main():
|
|
"""
|
|
Point d'entrée du script.
|
|
"""
|
|
parser = argparse.ArgumentParser(description="Exécute le processus d'analyse de tickets de support.")
|
|
parser.add_argument("--ticket", "-t", required=True, help="Code du ticket à analyser (ex: T0167)")
|
|
parser.add_argument("--source", "-s", help="Dossier source contenant les tickets bruts (par défaut: output/)")
|
|
parser.add_argument("--output", "-o", help="Dossier de sortie pour les résultats (par défaut: output_processed/)")
|
|
parser.add_argument("--etapes", "-e", choices=["extraction", "filtrage", "analyse_images", "analyse_ticket", "questions_reponses", "tout"],
|
|
default="tout", help="Étapes à exécuter")
|
|
parser.add_argument("--verbose", "-v", action="store_true", help="Afficher plus d'informations")
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Configurer le niveau de log
|
|
if args.verbose:
|
|
logging.getLogger().setLevel(logging.DEBUG)
|
|
|
|
# Récupérer le code du ticket
|
|
ticket_code = args.ticket
|
|
if ticket_code.startswith("ticket_"):
|
|
ticket_code = ticket_code[7:]
|
|
|
|
# Définir les dossiers source et sortie
|
|
dossier_source = args.source or "output"
|
|
dossier_sortie = args.output or "output_processed"
|
|
|
|
# Construire les chemins
|
|
ticket_dir_source = os.path.join(dossier_source, f"ticket_{ticket_code}")
|
|
ticket_dir_sortie = os.path.join(dossier_sortie, f"ticket_{ticket_code}")
|
|
|
|
# Vérifier que le dossier source existe
|
|
if not os.path.exists(ticket_dir_source):
|
|
logger.error(f"Dossier source non trouvé: {ticket_dir_source}")
|
|
sys.exit(1)
|
|
|
|
# Exécuter les étapes demandées
|
|
if args.etapes == "tout":
|
|
if processus_complet(ticket_code, dossier_source, dossier_sortie):
|
|
print(f"Processus complet terminé avec succès pour le ticket {ticket_code}")
|
|
print(f"Résultats disponibles dans: {ticket_dir_sortie}")
|
|
else:
|
|
print(f"Échec du processus pour le ticket {ticket_code}")
|
|
sys.exit(1)
|
|
else:
|
|
# Créer le dossier de sortie s'il n'existe pas
|
|
os.makedirs(ticket_dir_sortie, exist_ok=True)
|
|
|
|
# Exécuter l'étape spécifique
|
|
if args.etapes == "extraction":
|
|
if etape_extraction(ticket_dir_source, ticket_dir_sortie):
|
|
print("Étape d'extraction terminée avec succès")
|
|
else:
|
|
print("Échec de l'étape d'extraction")
|
|
sys.exit(1)
|
|
|
|
elif args.etapes == "filtrage":
|
|
if etape_filtrage_images(ticket_dir_sortie):
|
|
print("Étape de filtrage des images terminée avec succès")
|
|
else:
|
|
print("Échec de l'étape de filtrage des images")
|
|
sys.exit(1)
|
|
|
|
elif args.etapes == "analyse_images":
|
|
rapport_filtrage = os.path.join(ticket_dir_sortie, "filter_report.json")
|
|
if not os.path.exists(rapport_filtrage):
|
|
logger.error(f"Rapport de filtrage non trouvé: {rapport_filtrage}")
|
|
print("Veuillez d'abord exécuter l'étape de filtrage des images")
|
|
sys.exit(1)
|
|
|
|
if etape_analyse_images(ticket_dir_sortie, rapport_filtrage):
|
|
print("Étape d'analyse des images terminée avec succès")
|
|
else:
|
|
print("Échec de l'étape d'analyse des images")
|
|
sys.exit(1)
|
|
|
|
elif args.etapes == "analyse_ticket":
|
|
rapport_filtrage = os.path.join(ticket_dir_sortie, "filter_report.json")
|
|
if not os.path.exists(rapport_filtrage):
|
|
logger.error(f"Rapport de filtrage non trouvé: {rapport_filtrage}")
|
|
print("Veuillez d'abord exécuter l'étape de filtrage des images")
|
|
sys.exit(1)
|
|
|
|
if etape_analyse_ticket(ticket_dir_sortie, rapport_filtrage):
|
|
print("Étape d'analyse du ticket terminée avec succès")
|
|
else:
|
|
print("Échec de l'étape d'analyse du ticket")
|
|
sys.exit(1)
|
|
|
|
elif args.etapes == "questions_reponses":
|
|
if etape_questions_reponses(ticket_dir_sortie):
|
|
print("Étape d'extraction des questions et réponses terminée avec succès")
|
|
else:
|
|
print("Échec de l'étape d'extraction des questions et réponses")
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |