Spaces:
Sleeping
Sleeping
| # src/expon/presentation/interfaces/rest/controllers/presentation_controller.py | |
| from fastapi import APIRouter, UploadFile, File, Depends, HTTPException, status | |
| from sqlalchemy.orm import Session | |
| from uuid import UUID | |
| from src.expon.shared.infrastructure.dependencies import get_db | |
| from src.expon.iam.infrastructure.authorization.sfs.auth_bearer import get_current_user | |
| from src.expon.presentation.application.internal.commandservices.audio_upload_service import AudioUploadService | |
| from src.expon.presentation.application.internal.queryservices.presentation_query_service import PresentationQueryService | |
| from src.expon.presentation.infrastructure.persistence.jpa.repositories.presentation_repository import PresentationRepository | |
| from src.expon.presentation.infrastructure.services.storage.local_storage_service import LocalStorageService | |
| from src.expon.presentation.domain.services.transcription_service import TranscriptionService | |
| from src.expon.presentation.domain.services.multimodal_service import MultimodalService # ← CAMBIO | |
| from src.expon.presentation.interfaces.rest.responses.presentation_response import ( | |
| PresentationResponse, | |
| AudioMetadataResponse, | |
| PresentationSummaryResponse | |
| ) | |
| from src.expon.feedback.infrastructure.persistence.jpa.feedback_repository import FeedbackRepository | |
| from src.expon.feedback.interfaces.rest.feedback_response import FeedbackResponse | |
| from src.expon.presentation.infrastructure.services.storage.supabase_storage_service import generate_signed_audio_url | |
| router = APIRouter() | |
| def upload_presentation( | |
| file: UploadFile = File(...), | |
| db: Session = Depends(get_db), | |
| current_user=Depends(get_current_user) | |
| ): | |
| try: | |
| contents = file.file.read() | |
| if not contents: | |
| raise HTTPException(status_code=400, detail="El archivo está vacío.") | |
| file.file.seek(0) | |
| repository = PresentationRepository(db) | |
| storage_service = LocalStorageService() | |
| transcription_service = TranscriptionService() | |
| multimodal_service = MultimodalService() # ← CAMBIO | |
| service = AudioUploadService( | |
| storage_service=storage_service, | |
| transcription_service=transcription_service, | |
| multimodal_service=multimodal_service, # ← CAMBIO | |
| repository=repository | |
| ) | |
| presentation = service.upload_and_analyze(file, current_user.id) | |
| return PresentationResponse( | |
| id=presentation.id, | |
| transcript=presentation.transcript, | |
| dominant_emotion=presentation.dominant_emotion, | |
| emotion_probabilities=presentation.emotion_probabilities, | |
| confidence=presentation.confidence, | |
| filename=presentation.filename, | |
| metadata=AudioMetadataResponse( | |
| duration=presentation.metadata.duration, | |
| sample_rate=presentation.metadata.sample_rate, | |
| language=presentation.metadata.language | |
| ), | |
| created_at=presentation.created_at | |
| ) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Error al procesar el archivo: {str(e)}") | |
| def get_presentations_summary( | |
| db: Session = Depends(get_db), | |
| current_user=Depends(get_current_user) | |
| ): | |
| repository = PresentationRepository(db) | |
| query_service = PresentationQueryService(repository) | |
| presentations = query_service.get_presentations_by_user(current_user.id) | |
| return [ | |
| PresentationSummaryResponse( | |
| id=p.id, | |
| filename=p.filename, | |
| dominant_emotion=p.dominant_emotion, | |
| confidence=p.confidence, | |
| created_at=p.created_at | |
| ) for p in presentations | |
| ] | |
| def get_presentation_by_id( | |
| presentation_id: UUID, | |
| db: Session = Depends(get_db), | |
| current_user=Depends(get_current_user) | |
| ): | |
| repository = PresentationRepository(db) | |
| query_service = PresentationQueryService(repository) | |
| presentation = query_service.get_presentation_by_id_and_user(presentation_id, current_user.id) | |
| if presentation is None: | |
| raise HTTPException(status_code=404, detail="Presentación no encontrada") | |
| return PresentationResponse( | |
| id=presentation.id, | |
| transcript=presentation.transcript, | |
| dominant_emotion=presentation.dominant_emotion, | |
| emotion_probabilities=presentation.emotion_probabilities, | |
| confidence=presentation.confidence, | |
| filename=presentation.filename, | |
| metadata=AudioMetadataResponse( | |
| duration=presentation.metadata.duration, | |
| sample_rate=presentation.metadata.sample_rate, | |
| language=presentation.metadata.language | |
| ), | |
| created_at=presentation.created_at | |
| ) | |
| def delete_presentation( | |
| presentation_id: UUID, | |
| db: Session = Depends(get_db), | |
| current_user=Depends(get_current_user) | |
| ): | |
| repository = PresentationRepository(db) | |
| presentation = repository.get_by_id_and_user(presentation_id, current_user.id) | |
| if presentation is None: | |
| raise HTTPException(status_code=404, detail="Presentación no encontrada") | |
| # Eliminar archivo local | |
| storage_service = LocalStorageService() | |
| storage_service.delete(presentation.filename) | |
| # Eliminar de base de datos | |
| repository.delete(presentation) | |
| def get_feedback_by_presentation( | |
| presentation_id: UUID, | |
| db: Session = Depends(get_db) | |
| ): | |
| repo = FeedbackRepository(db) | |
| feedback = repo.get_by_presentation(presentation_id) | |
| if feedback is None: | |
| raise HTTPException(status_code=404, detail="Feedback no encontrado") | |
| return feedback | |
| def get_audio_signed_url( | |
| presentation_id: UUID, | |
| db: Session = Depends(get_db), | |
| current_user=Depends(get_current_user) | |
| ): | |
| """ | |
| Retorna una URL firmada temporal del audio asociado a la presentación. | |
| """ | |
| repository = PresentationRepository(db) | |
| presentation = repository.get_by_id_and_user(presentation_id, current_user.id) | |
| if presentation is None: | |
| raise HTTPException(status_code=404, detail="Presentación no encontrada") | |
| if not presentation.audio_path: | |
| raise HTTPException(status_code=404, detail="No hay un audio asociado a esta presentación") | |
| try: | |
| signed_url = generate_signed_audio_url(presentation.audio_path) | |
| return {"url": signed_url} | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Error generando URL firmada: {str(e)}") |