Frontend : filtres
This commit is contained in:
@@ -22,6 +22,9 @@ async def get_tracks(
|
||||
energy_min: Optional[float] = Query(None, ge=0, le=1),
|
||||
energy_max: Optional[float] = Query(None, ge=0, le=1),
|
||||
has_vocals: Optional[bool] = None,
|
||||
key: Optional[str] = None,
|
||||
instrument: Optional[str] = None,
|
||||
tempo_range: Optional[str] = Query(None, regex="^(slow|medium|fast)$"),
|
||||
sort_by: str = Query("analyzed_at", regex="^(analyzed_at|tempo_bpm|duration_seconds|filename|energy)$"),
|
||||
sort_desc: bool = True,
|
||||
db: Session = Depends(get_db),
|
||||
@@ -38,6 +41,9 @@ async def get_tracks(
|
||||
energy_min: Minimum energy
|
||||
energy_max: Maximum energy
|
||||
has_vocals: Filter by vocal presence
|
||||
key: Filter by musical key
|
||||
instrument: Filter by instrument
|
||||
tempo_range: Filter by tempo range (slow: <100, medium: 100-140, fast: >140)
|
||||
sort_by: Field to sort by
|
||||
sort_desc: Sort descending
|
||||
db: Database session
|
||||
@@ -45,6 +51,16 @@ async def get_tracks(
|
||||
Returns:
|
||||
Paginated list of tracks with total count
|
||||
"""
|
||||
# Convert tempo_range to bpm_min/bpm_max
|
||||
if tempo_range:
|
||||
if tempo_range == "slow":
|
||||
bpm_max = 100.0 if bpm_max is None else min(bpm_max, 100.0)
|
||||
elif tempo_range == "medium":
|
||||
bpm_min = 100.0 if bpm_min is None else max(bpm_min, 100.0)
|
||||
bpm_max = 140.0 if bpm_max is None else min(bpm_max, 140.0)
|
||||
elif tempo_range == "fast":
|
||||
bpm_min = 140.0 if bpm_min is None else max(bpm_min, 140.0)
|
||||
|
||||
tracks, total = crud.get_tracks(
|
||||
db=db,
|
||||
skip=skip,
|
||||
@@ -56,6 +72,8 @@ async def get_tracks(
|
||||
energy_min=energy_min,
|
||||
energy_max=energy_max,
|
||||
has_vocals=has_vocals,
|
||||
key=key,
|
||||
instrument=instrument,
|
||||
sort_by=sort_by,
|
||||
sort_desc=sort_desc,
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from typing import List, Optional, Dict, Tuple
|
||||
from uuid import UUID
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import or_, and_, func
|
||||
from sqlalchemy import or_, and_, func, any_
|
||||
|
||||
from .schema import AudioTrack
|
||||
from ..core.analyzer import AudioAnalysis
|
||||
@@ -103,6 +103,8 @@ def get_tracks(
|
||||
energy_min: Optional[float] = None,
|
||||
energy_max: Optional[float] = None,
|
||||
has_vocals: Optional[bool] = None,
|
||||
key: Optional[str] = None,
|
||||
instrument: Optional[str] = None,
|
||||
sort_by: str = "analyzed_at",
|
||||
sort_desc: bool = True,
|
||||
) -> Tuple[List[AudioTrack], int]:
|
||||
@@ -112,13 +114,15 @@ def get_tracks(
|
||||
db: Database session
|
||||
skip: Number of records to skip
|
||||
limit: Maximum number of records to return
|
||||
genre: Filter by genre
|
||||
genre: Filter by genre (searches in genre_primary, supports category matching)
|
||||
mood: Filter by mood
|
||||
bpm_min: Minimum BPM
|
||||
bpm_max: Maximum BPM
|
||||
energy_min: Minimum energy (0-1)
|
||||
energy_max: Maximum energy (0-1)
|
||||
has_vocals: Filter by vocal presence
|
||||
key: Filter by musical key
|
||||
instrument: Filter by instrument
|
||||
sort_by: Field to sort by
|
||||
sort_desc: Sort descending if True
|
||||
|
||||
@@ -129,10 +133,12 @@ def get_tracks(
|
||||
|
||||
# Apply filters
|
||||
if genre:
|
||||
# Match genre category (e.g., "Pop" matches "Pop---Ballad", "Pop---Indie Pop", etc.)
|
||||
query = query.filter(
|
||||
or_(
|
||||
AudioTrack.genre_primary.like(f"{genre}%"),
|
||||
AudioTrack.genre_primary == genre,
|
||||
AudioTrack.genre_secondary.contains([genre])
|
||||
AudioTrack.genre_secondary.any(genre)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -140,7 +146,7 @@ def get_tracks(
|
||||
query = query.filter(
|
||||
or_(
|
||||
AudioTrack.mood_primary == mood,
|
||||
AudioTrack.mood_secondary.contains([mood])
|
||||
AudioTrack.mood_secondary.any(mood)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -159,6 +165,12 @@ def get_tracks(
|
||||
if has_vocals is not None:
|
||||
query = query.filter(AudioTrack.has_vocals == has_vocals)
|
||||
|
||||
if key:
|
||||
query = query.filter(AudioTrack.key == key)
|
||||
|
||||
if instrument:
|
||||
query = query.filter(AudioTrack.instruments.any(instrument))
|
||||
|
||||
# Get total count before pagination
|
||||
total = query.count()
|
||||
|
||||
@@ -213,7 +225,7 @@ def search_tracks(
|
||||
search_query = search_query.filter(
|
||||
or_(
|
||||
AudioTrack.genre_primary == genre,
|
||||
AudioTrack.genre_secondary.contains([genre])
|
||||
AudioTrack.genre_secondary.any(genre)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -221,7 +233,7 @@ def search_tracks(
|
||||
search_query = search_query.filter(
|
||||
or_(
|
||||
AudioTrack.mood_primary == mood,
|
||||
AudioTrack.mood_secondary.contains([mood])
|
||||
AudioTrack.mood_secondary.any(mood)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -265,7 +277,7 @@ def get_similar_tracks(
|
||||
query = query.filter(
|
||||
or_(
|
||||
AudioTrack.genre_primary == ref_track.genre_primary,
|
||||
AudioTrack.genre_secondary.contains([ref_track.genre_primary])
|
||||
AudioTrack.genre_secondary.any(ref_track.genre_primary)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -274,7 +286,7 @@ def get_similar_tracks(
|
||||
query = query.filter(
|
||||
or_(
|
||||
AudioTrack.mood_primary == ref_track.mood_primary,
|
||||
AudioTrack.mood_secondary.contains([ref_track.mood_primary])
|
||||
AudioTrack.mood_secondary.any(ref_track.mood_primary)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user