import gradio as gr from core.audio_verifier import verify_audio from core.uploader import upload_audio from core.model_loader import is_ready def handle_verify(audio_path: str): """ Kiểm tra mẫu âm thanh. Returns: (status_text, btn_send_update, score) """ if not is_ready(): return ( "⏳ Model đang khởi động, thử lại sau vài giây...", gr.update(interactive=False), 0.0 ) if not audio_path: return ( "⚠️ Hãy ghi âm trước khi kiểm tra!", gr.update(interactive=False), 0.0 ) try: passed, score = verify_audio(audio_path) except RuntimeError as e: return str(e), gr.update(interactive=False), 0.0 except ValueError as e: return str(e), gr.update(interactive=False), 0.0 if passed: return ( f"✅ Hợp lệ! Điểm: {score:.2f} — Nhấn GỬI để lưu mẫu", gr.update(interactive=True), score ) else: return ( f"❌ Chưa đạt (Điểm: {score:.2f}). Hãy nói rõ hơn và thử lại!", gr.update(interactive=False), score ) def handle_upload(audio_path: str, score: float): """ Upload mẫu lên HuggingFace. Returns: (status_text, btn_send_update, audio_reset) """ if not audio_path: return ( "❌ Không có file để gửi.", gr.update(interactive=False), None ) try: filename = upload_audio(audio_path, score) return ( f"🎉 Gửi thành công ({filename})! Bạn có thể thu mẫu tiếp theo.", gr.update(interactive=False), None ) except Exception as e: return ( f"❌ Lỗi gửi: {e}", gr.update(interactive=True), audio_path ) def handle_reset(): """ Reset toàn bộ UI về trạng thái ban đầu. Returns: (audio_reset, status_text, btn_send_update, score_reset) """ return ( None, '🎙️ Sẵn sàng — Nhấn mic và đọc "Lumi ơi"', gr.update(interactive=False), 0.0 ) def handle_audio_change(): """Khi có file audio mới inject vào → disable nút Gửi.""" return gr.update(interactive=False)