feat: Add filtering, searching, and sorting to extraction retrieval endpoints

This commit is contained in:
JSC
2025-08-17 01:44:43 +02:00
parent 3326e406f8
commit 66d22df7dd
3 changed files with 126 additions and 11 deletions

View File

@@ -13,6 +13,7 @@ from app.core.logging import get_logger
from app.models.sound import Sound
from app.repositories.extraction import ExtractionRepository
from app.repositories.sound import SoundRepository
from app.repositories.user import UserRepository
from app.services.playlist import PlaylistService
from app.services.sound_normalizer import SoundNormalizerService
from app.utils.audio import get_audio_duration, get_file_hash, get_file_size
@@ -32,6 +33,7 @@ class ExtractionInfo(TypedDict):
error: str | None
sound_id: int | None
user_id: int
user_name: str | None
created_at: str
updated_at: str
@@ -44,6 +46,7 @@ class ExtractionService:
self.session = session
self.extraction_repo = ExtractionRepository(session)
self.sound_repo = SoundRepository(session)
self.user_repo = UserRepository(session)
self.playlist_service = PlaylistService(session)
# Ensure required directories exist
@@ -66,6 +69,12 @@ class ExtractionService:
logger.info("Creating extraction for URL: %s (user: %d)", url, user_id)
try:
# Get user information
user = await self.user_repo.get_by_id(user_id)
if not user:
msg = f"User {user_id} not found"
raise ValueError(msg)
# Create the extraction record without service detection for fast response
extraction_data = {
"url": url,
@@ -92,6 +101,7 @@ class ExtractionService:
"error": extraction.error,
"sound_id": extraction.sound_id,
"user_id": extraction.user_id,
"user_name": user.name,
"created_at": extraction.created_at.isoformat(),
"updated_at": extraction.updated_at.isoformat(),
}
@@ -554,7 +564,7 @@ class ExtractionService:
status_filter: str | None = None,
) -> list[ExtractionInfo]:
"""Get all extractions for a user with filtering, search, and sorting."""
extractions = await self.extraction_repo.get_user_extractions_filtered(
extraction_user_tuples = await self.extraction_repo.get_user_extractions_filtered(
user_id=user_id,
search=search,
sort_by=sort_by,
@@ -574,15 +584,27 @@ class ExtractionService:
"error": extraction.error,
"sound_id": extraction.sound_id,
"user_id": extraction.user_id,
"user_name": user.name,
"created_at": extraction.created_at.isoformat(),
"updated_at": extraction.updated_at.isoformat(),
}
for extraction in extractions
for extraction, user in extraction_user_tuples
]
async def get_pending_extractions(self) -> list[ExtractionInfo]:
"""Get all pending extractions."""
extractions = await self.extraction_repo.get_pending_extractions()
async def get_all_extractions(
self,
search: str | None = None,
sort_by: str = "created_at",
sort_order: str = "desc",
status_filter: str | None = None,
) -> list[ExtractionInfo]:
"""Get all extractions with filtering, search, and sorting."""
extraction_user_tuples = await self.extraction_repo.get_all_extractions_filtered(
search=search,
sort_by=sort_by,
sort_order=sort_order,
status_filter=status_filter,
)
return [
{
@@ -596,8 +618,32 @@ class ExtractionService:
"error": extraction.error,
"sound_id": extraction.sound_id,
"user_id": extraction.user_id,
"user_name": user.name,
"created_at": extraction.created_at.isoformat(),
"updated_at": extraction.updated_at.isoformat(),
}
for extraction in extractions
for extraction, user in extraction_user_tuples
]
async def get_pending_extractions(self) -> list[ExtractionInfo]:
"""Get all pending extractions."""
extraction_user_tuples = await self.extraction_repo.get_pending_extractions()
return [
{
"id": extraction.id
or 0, # Should never be None for existing extraction
"url": extraction.url,
"service": extraction.service,
"service_id": extraction.service_id,
"title": extraction.title,
"status": extraction.status,
"error": extraction.error,
"sound_id": extraction.sound_id,
"user_id": extraction.user_id,
"user_name": user.name,
"created_at": extraction.created_at.isoformat(),
"updated_at": extraction.updated_at.isoformat(),
}
for extraction, user in extraction_user_tuples
]