feat: Add method to get extractions by status and implement user info retrieval in extraction service
Some checks failed
Backend CI / lint (push) Failing after 4m53s
Backend CI / test (push) Failing after 4m31s

This commit is contained in:
JSC
2025-08-24 13:24:48 +02:00
parent 28faca55bc
commit 16eb789539
5 changed files with 177 additions and 10 deletions

View File

@@ -168,12 +168,31 @@ class ExtractionService:
extraction_service_id = extraction.service_id
extraction_title = extraction.title
# Get user information for return value
try:
user = await self.user_repo.get_by_id(user_id)
user_name = user.name if user else None
except Exception:
logger.warning("Failed to get user %d for extraction", user_id)
user_name = None
logger.info("Processing extraction %d: %s", extraction_id, extraction_url)
try:
# Update status to processing
await self.extraction_repo.update(extraction, {"status": "processing"})
# Emit WebSocket event for processing start
await self._emit_extraction_event(
user_id,
{
"extraction_id": extraction_id,
"status": "processing",
"title": extraction_title or "Processing extraction...",
"url": extraction_url,
},
)
# Detect service info if not already available
if not extraction_service or not extraction_service_id:
logger.info("Detecting service info for extraction %d", extraction_id)
@@ -184,9 +203,16 @@ class ExtractionService:
raise ValueError(msg)
# Check if extraction already exists for this service
service_name = service_info["service"]
service_id_val = service_info["service_id"]
if not service_name or not service_id_val:
msg = "Service info is incomplete"
raise ValueError(msg)
existing = await self.extraction_repo.get_by_service_and_id(
service_info["service"],
service_info["service_id"],
service_name,
service_id_val,
)
if existing and existing.id != extraction_id:
error_msg = (
@@ -209,6 +235,16 @@ class ExtractionService:
extraction_service_id = service_info["service_id"]
extraction_title = service_info.get("title") or extraction_title
await self._emit_extraction_event(
user_id,
{
"extraction_id": extraction_id,
"status": "processing",
"title": extraction_title,
"url": extraction_url,
},
)
# Extract audio and thumbnail
audio_file, thumbnail_file = await self._extract_media(
extraction_id,
@@ -258,15 +294,20 @@ class ExtractionService:
},
)
logger.info("Successfully processed extraction %d", extraction_id)
except Exception as e:
error_msg = str(e)
logger.exception(
"Failed to process extraction %d: %s",
extraction_id,
error_msg,
# Emit WebSocket event for completion
await self._emit_extraction_event(
user_id,
{
"extraction_id": extraction_id,
"status": "completed",
"title": extraction_title,
"url": extraction_url,
"sound_id": sound_id,
},
)
else:
logger.info("Successfully processed extraction %d", extraction_id)
# Get updated extraction to get latest timestamps
updated_extraction = await self.extraction_repo.get_by_id(extraction_id)
return {
@@ -279,6 +320,7 @@ class ExtractionService:
"error": None,
"sound_id": sound_id,
"user_id": user_id,
"user_name": user_name,
"created_at": (
updated_extraction.created_at.isoformat()
if updated_extraction
@@ -291,6 +333,26 @@ class ExtractionService:
),
}
except Exception as e:
error_msg = str(e)
logger.exception(
"Failed to process extraction %d: %s",
extraction_id,
error_msg,
)
# Emit WebSocket event for failure
await self._emit_extraction_event(
user_id,
{
"extraction_id": extraction_id,
"status": "failed",
"title": extraction_title or "Extraction failed",
"url": extraction_url,
"error": error_msg,
},
)
# Update extraction with error
await self.extraction_repo.update(
extraction,
@@ -312,6 +374,7 @@ class ExtractionService:
"error": error_msg,
"sound_id": None,
"user_id": user_id,
"user_name": user_name,
"created_at": (
updated_extraction.created_at.isoformat()
if updated_extraction
@@ -549,6 +612,21 @@ class ExtractionService:
)
# Don't fail the extraction if playlist addition fails
async def _emit_extraction_event(self, user_id: int, data: dict) -> None:
"""Emit WebSocket event for extraction status updates to all users."""
try:
# Import here to avoid circular imports
from app.services.socket import socket_manager # noqa: PLC0415
await socket_manager.broadcast_to_all("extraction_status_update", data)
logger.debug(
"Broadcasted extraction event (initiated by user %d): %s",
user_id,
data["status"],
)
except Exception:
logger.exception("Failed to emit extraction event")
async def get_extraction_by_id(self, extraction_id: int) -> ExtractionInfo | None:
"""Get extraction information by ID."""
extraction = await self.extraction_repo.get_by_id(extraction_id)