# ========================================== # app_fixed.py - Calcul OCR v3.0 - Sessions isolées # ========================================== """ Application principale avec isolation des sessions utilisateurs """ import gradio as gr import warnings import os import gc import numpy as np from PIL import Image import simple_gpu warnings.filterwarnings("ignore") # Import avec structure claire : GPU ou CPU uniquement try: import torch if torch.cuda.is_available(): from image_processing_gpu import init_ocr_model, create_white_canvas, cleanup_memory print("📱 Interface: Mode GPU détecté - TrOCR") else: from image_processing_cpu import init_ocr_model, create_white_canvas, cleanup_memory print("📱 Interface: Mode CPU détecté - EasyOCR") except ImportError: from image_processing_cpu import init_ocr_model, create_white_canvas, cleanup_memory print("📱 Interface: Mode CPU détecté - EasyOCR") from game_engine import MathGame, export_to_clean_dataset print("🚀 Initialisation Calcul OCR v3.0...") print("🔄 Chargement modèle OCR...") init_ocr_model() print("✅ Modèle OCR prêt") def create_new_game_session(): """Crée une nouvelle instance de jeu pour chaque session""" return MathGame() def start_game_wrapper(duration: str, operation: str, difficulty: str, game_state) -> tuple: """Wrapper avec isolation de session""" if game_state is None: game_state = create_new_game_session() cleanup_memory() result = game_state.start_game(duration, operation, difficulty) return result + (game_state, "") # Retourner l'état mis à jour def next_question_wrapper(image_data, game_state) -> tuple: """Wrapper avec isolation de session""" if game_state is None: game_state = create_new_game_session() result = game_state.next_question(image_data) return result + (game_state,) # Retourner l'état mis à jour def export_current_session(game_state) -> str: """Export avec isolation de session""" if game_state is None: return "❌ Aucune session active" if not hasattr(game_state, 'session_data') or not game_state.session_data: return "❌ Aucune donnée de session à exporter" export_info = game_state.get_export_status() if export_info["status"] == "exported": return f"""✅ Session déjà exportée ! 📅 Exporté le: {export_info['timestamp'][:19].replace('T', ' ')} 📊 Résultat: {export_info['result'][:100]}... 💡 Jouez une nouvelle session pour contribuer davantage !""" if export_info["status"] == "exporting": return "⏳ Export en cours..." if not export_info["can_export"]: return "❌ Aucune donnée à exporter" game_state.mark_export_in_progress() try: result = export_to_clean_dataset(game_state.session_data) game_state.mark_export_completed(result) cleanup_memory() return result except Exception as e: game_state.export_status = "not_exported" return f"❌ Erreur export: {str(e)}" # Interface Gradio avec State management with gr.Blocks( title="🧮 Calcul OCR - Entraînement mathématiques", theme=gr.themes.Soft(), css=""" .gradio-container { max-width: 1200px !important; } .config-section { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px; border-radius: 10px; margin: 10px 0; } .dataset-info { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); color: white; padding: 15px; border-radius: 10px; margin: 10px 0; } .radio-group { background: #f8f9fa; padding: 10px; border-radius: 8px; margin: 5px 0; } """, head="" ) as demo: # ✅ STATE MANAGEMENT - Chaque utilisateur a sa propre instance game_state = gr.State(value=None) gr.Markdown( """ # 🧮 Entraînement au calcul mental avec OCR **Comment jouer :** 1. **Configurez** votre session ci-dessous 2. Cliquez sur **🚀 GO !** pour démarrer 3. **Écrivez** ✏️ votre réponse sur le tableau 4. Cliquez sur **➡️ NEXT !** pour la question suivante À la fin, vous pourrez consulter vos résultats et contribuer au dataset ouvert ! """ ) # Configuration de la session duration_choice = gr.Radio( choices=["30 secondes", "60 secondes"], value="30 secondes", label="**⏱️ Durée**" ) operation_choice = gr.Radio( choices=["×", "+", "-", "÷", "Aléatoire"], value="×", label="**🔢 Opération**" ) difficulty_choice = gr.Radio( choices=["Facile", "Difficile"], value="Facile", label="**🎯 Difficulté**" ) with gr.Row(): with gr.Column(scale=1): # Question question_display = gr.HTML( value='