# utils/translate_utils.py from deep_translator import GoogleTranslator import json import os from datetime import datetime import logging from typing import Optional logger = logging.getLogger("Translate") def fr_to_en(text: str) -> str: try: if not text.strip(): return "" return GoogleTranslator(source="fr", target="en").translate(text) except Exception as e: logger.error(f"Traduction FR->EN échouée: {e}") return "" def en_to_fr(text: str) -> str: try: if not text.strip(): return "" return GoogleTranslator(source="en", target="fr").translate(text) except Exception as e: logger.error(f"Traduction EN->FR échouée: {e}") return "" def determiner_repertoire_ticket(ticket_id: str): """ Détermine dynamiquement le répertoire du ticket. Args: ticket_id: str, le code du ticket Returns: str, le chemin du répertoire pour ce ticket ou None si non trouvé """ # Base de recherche des tickets output_dir = "output" # Format attendu du répertoire de ticket ticket_dir = f"ticket_{ticket_id}" ticket_path = os.path.join(output_dir, ticket_dir) if not os.path.exists(ticket_path): print(f"Répertoire de ticket non trouvé: {ticket_path}") return None # Trouver la dernière extraction (par date) extractions = [] for extraction in os.listdir(ticket_path): extraction_path = os.path.join(ticket_path, extraction) if os.path.isdir(extraction_path) and extraction.startswith(ticket_id): extractions.append(extraction_path) if not extractions: print(f"Aucune extraction trouvée pour le ticket {ticket_id}") return None # Trier par date de modification (plus récente en premier) extractions.sort(key=lambda x: os.path.getmtime(x), reverse=True) # Retourner le chemin de la dernière extraction return extractions[0] def sauvegarder_ocr_traduction( image_path: str, ticket_id: str, ocr_fr: str, ocr_en: str, ocr_en_back_fr: str = "", base_dir: Optional[str] = None # Utiliser Optional[str] ) -> None: """ Sauvegarde les résultats OCR + TRAD en JSON (par image) et ajoute une ligne dans un fichier texte global (append sécurisé). Utilise le répertoire de sortie output/ticket_X/X_YYYYMMDD_HHMMSS/X_rapports/pipeline pour la sauvegarde des données. """ try: image_name = os.path.basename(image_path) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") # Déterminer le répertoire de sortie basé sur le ticket_id if not base_dir: # Utiliser le répertoire de sortie approprié dans output extraction_dir = determiner_repertoire_ticket(ticket_id) if not extraction_dir: # Fallback vers reports si impossible de trouver le répertoire base_dir = "reports" rapport_dir = os.path.join(base_dir, ticket_id, "pipeline", "ocr_traduction") else: # Utiliser le répertoire rapports du ticket rapports_dir = os.path.join(extraction_dir, f"{ticket_id}_rapports") rapport_dir = os.path.join(rapports_dir, "pipeline", "ocr_traduction") else: rapport_dir = os.path.join(base_dir, ticket_id, "pipeline", "ocr_traduction") os.makedirs(rapport_dir, exist_ok=True) # Sauvegarde JSON (1 par image, réécrit à chaque passage) json_path = os.path.join(rapport_dir, f"{image_name}.json") result = { "image_name": image_name, "ocr_fr": ocr_fr, "translation_en": ocr_en, "translation_en_back_fr": ocr_en_back_fr, "metadata": { "ticket_id": ticket_id, "timestamp": timestamp, "source_module": "ocr_utils + translate_utils", "lang_detected": "fr" } } with open(json_path, "w", encoding="utf-8") as f: json.dump(result, f, ensure_ascii=False, indent=2) logger.info(f"Sauvegarde JSON OCR/TRAD réussie pour {image_name}") # Append TXT global sécurisé (évite l'écrasement) txt_path = os.path.join(rapport_dir, "ocr_traduction.txt") ligne = ( f"{image_name}\n" f"[FR] {ocr_fr or '_'}\n" f"[EN] {ocr_en or '_'}\n" f"[EN→FR] {ocr_en_back_fr or '_'}\n\n" ) with open(txt_path, "a", encoding="utf-8") as f: f.write(ligne) logger.info(f"Ligne ajoutée dans ocr_traduction.txt pour {image_name}") except Exception as e: logger.error(f"Erreur lors de la sauvegarde OCR+TRAD pour {image_path}: {e}")