""" Watchlist management routes for Ohm Stream Downloader API. """ import re import json from typing import List, Optional from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Response, Request, Query from fastapi.templating import Jinja2Templates from app.download_manager import DownloadManager from app.downloaders import get_downloader from app.models import DownloadRequest from app.models.auth import User from app.models.watchlist import ( WatchlistItem, WatchlistItemCreate, WatchlistItemUpdate, WatchlistSettings, WatchlistStatus, ) from app.routers.router_auth import get_current_user_from_token router = APIRouter(prefix="/api/watchlist", tags=["watchlist"]) templates = Jinja2Templates(directory="templates") def get_download_manager() -> DownloadManager: from main import download_manager return download_manager @router.post("", response_model=WatchlistItem) async def add_to_watchlist( item_data: WatchlistItemCreate, response: Response, current_user: User = Depends(get_current_user_from_token), ): """Add an anime to the watchlist""" from main import watchlist_manager try: existing = watchlist_manager.get_by_anime_url(item_data.anime_url, current_user.id) item = watchlist_manager.add(current_user.id, item_data) msg = f"'{item.anime_title}' ajouté à la watchlist" if not existing else f"'{item.anime_title}' est déjà dans la watchlist" toast_type = "success" if not existing else "info" response.headers["HX-Trigger"] = json.dumps({"show-toast": {"message": msg, "type": toast_type}}) return item except Exception as e: from logging import getLogger logger = getLogger(__name__) logger.error(f"Error adding to watchlist: {e}", exc_info=True) raise HTTPException(status_code=500, detail=str(e)) @router.get("", response_model=List[WatchlistItem]) async def get_watchlist( request: Request, status: Optional[WatchlistStatus] = None, html: bool = Query(False), current_user: User = Depends(get_current_user_from_token), ): """Get user's watchlist (supports HTML for HTMX)""" from main import watchlist_manager items = watchlist_manager.get_all(user_id=current_user.id, status=status) if html or request.headers.get("HX-Request"): return templates.TemplateResponse( "components/watchlist_items_list.html", {"request": request, "items": items} ) return items @router.get("/settings", response_model=WatchlistSettings) async def get_watchlist_settings( current_user: User = Depends(get_current_user_from_token), ): """Get global watchlist settings""" from main import watchlist_manager return watchlist_manager.get_settings() @router.put("/settings", response_model=WatchlistSettings) async def update_watchlist_settings( settings: WatchlistSettings, response: Response, current_user: User = Depends(get_current_user_from_token), ): """Update global watchlist settings""" from main import auto_download_scheduler, watchlist_manager try: updated_settings = watchlist_manager.update_settings(settings) if auto_download_scheduler.is_running(): auto_download_scheduler.update_interval(updated_settings.check_interval_hours) response.headers["HX-Trigger"] = json.dumps({"show-toast": {"message": "Paramètres de la watchlist mis à jour", "type": "success"}}) return updated_settings except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/{item_id}", response_model=WatchlistItem) async def get_watchlist_item( item_id: str, current_user: User = Depends(get_current_user_from_token), ): """Get a specific watchlist item""" from main import watchlist_manager item = watchlist_manager.get_by_id(item_id) if not item or item.user_id != current_user.id: raise HTTPException(status_code=404, detail="Item not found") return item @router.put("/{item_id}", response_model=WatchlistItem) async def update_watchlist_item( item_id: str, update_data: WatchlistItemUpdate, response: Response, current_user: User = Depends(get_current_user_from_token), ): """Update a watchlist item""" from main import watchlist_manager item = watchlist_manager.get_by_id(item_id) if not item or item.user_id != current_user.id: raise HTTPException(status_code=404, detail="Item not found") updated_item = watchlist_manager.update(item_id, update_data) response.headers["HX-Trigger"] = json.dumps({"show-toast": {"message": f"'{updated_item.anime_title}' mis à jour", "type": "success"}}) return updated_item @router.delete("/{item_id}") async def delete_from_watchlist( item_id: str, response: Response, current_user: User = Depends(get_current_user_from_token), ): """Remove an anime from the watchlist""" from main import watchlist_manager item = watchlist_manager.get_by_id(item_id) if not item or item.user_id != current_user.id: raise HTTPException(status_code=404, detail="Item not found") title = item.anime_title if watchlist_manager.delete(item_id): response.headers["HX-Trigger"] = json.dumps({"show-toast": {"message": f"'{title}' supprimé de la watchlist", "type": "info"}}) # HTMX will handle removing the element if target is specified in the frontend return Response(status_code=204) raise HTTPException(status_code=500, detail="Failed to delete item") @router.post("/check", response_model=List) async def check_watchlist_now( background_tasks: BackgroundTasks, response: Response, current_user: User = Depends(get_current_user_from_token), ): """Trigger an immediate check for new episodes""" from main import auto_download_scheduler background_tasks.add_task(auto_download_scheduler.trigger_check_now) response.headers["HX-Trigger"] = json.dumps({"show-toast": {"message": "Vérification de la watchlist lancée en arrière-plan", "type": "info"}}) return {"status": "success", "message": "Check triggered"} @router.get("/stats/summary") async def get_watchlist_stats( current_user: User = Depends(get_current_user_from_token), ): """Get watchlist statistics for the user""" from main import watchlist_manager return watchlist_manager.get_stats(current_user.id)