- Remove committed .coverage and test-results/ (196K screenshots); gitignore them - Fix hardcoded /home/userpath + venv/bin/python in test_endpoints.py (relative backend dir + sys.executable) - Fix concatenated 'import json' in settings.py; bare excepts -> Exception; SQLAlchemy-safe is_active.is_(True); __all__ on models/schemas barrels - ruff clean (93 fixes), MIT LICENSE, PLAN.md -> docs/, README Tests section - 300 tests pass, 93.7% coverage
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
from pydantic import BaseModel
|
|
from ..db.database import get_db
|
|
from ..models.mood import MoodCategory
|
|
from ..schemas.mood import MoodCategoryResponse, MoodPlaylistResponse
|
|
from ..services.mood_engine import analyze_song_mood, get_mood_playlist, seed_mood_categories
|
|
|
|
|
|
class SetMoodRequest(BaseModel):
|
|
mood: str
|
|
|
|
router = APIRouter(prefix="/api/mood", tags=["mood"])
|
|
|
|
|
|
@router.get("/categories", response_model=List[MoodCategoryResponse])
|
|
def list_mood_categories(db: Session = Depends(get_db)):
|
|
seed_mood_categories(db)
|
|
categories = db.query(MoodCategory).all()
|
|
return [MoodCategoryResponse.model_validate(c) for c in categories]
|
|
|
|
|
|
@router.post("/analyze")
|
|
def analyze_mood(song_id: Optional[str] = None, db: Session = Depends(get_db)):
|
|
if song_id:
|
|
return analyze_song_mood(song_id, db)
|
|
|
|
from ..models.song import Song
|
|
songs = db.query(Song).all()
|
|
results = []
|
|
for song in songs:
|
|
results.append(analyze_song_mood(song.id, db))
|
|
return {"analyzed": len(results), "results": results}
|
|
|
|
|
|
@router.get("/{mood}/playlist", response_model=MoodPlaylistResponse)
|
|
def get_mood_playlist_endpoint(mood: str, limit: int = Query(50, ge=1, le=200), db: Session = Depends(get_db)):
|
|
songs = get_mood_playlist(mood, db, limit)
|
|
|
|
song_responses = []
|
|
for s in songs:
|
|
from ..schemas.song import SongResponse
|
|
song_responses.append(SongResponse.model_validate(s))
|
|
|
|
return MoodPlaylistResponse(
|
|
mood=mood,
|
|
songs=song_responses,
|
|
total_songs=len(song_responses),
|
|
)
|
|
|
|
|
|
@router.post("/save")
|
|
def save_mood_playlist(mood: str, name: Optional[str] = None, db: Session = Depends(get_db)):
|
|
from ..models.playlist import Playlist
|
|
import uuid
|
|
|
|
playlist_id = str(uuid.uuid4())
|
|
playlist = Playlist(
|
|
id=playlist_id,
|
|
name=name or f"{mood} Playlist",
|
|
mood_category=mood.lower(),
|
|
)
|
|
db.add(playlist)
|
|
|
|
songs = get_mood_playlist(mood, db, 50)
|
|
from ..models.playlist import PlaylistSong
|
|
for i, song in enumerate(songs):
|
|
ps = PlaylistSong(playlist_id=playlist_id, song_id=song.id, position=i)
|
|
db.add(ps)
|
|
|
|
db.commit()
|
|
return {"id": playlist_id, "name": playlist.name, "songs": len(songs)}
|
|
|
|
|
|
@router.post("/set")
|
|
def set_mood(data: SetMoodRequest, db: Session = Depends(get_db)):
|
|
from ..models.settings import UserSetting
|
|
setting = db.query(UserSetting).filter(UserSetting.key == "default_mood").first()
|
|
if setting:
|
|
setting.value = data.mood
|
|
else:
|
|
setting = UserSetting(key="default_mood", value=data.mood)
|
|
db.add(setting)
|
|
db.commit()
|
|
return {"mood": data.mood} |