e5b30741fe
- Filtre recommandations (all/anime/series) - Filtre dernieres sorties (all/anime/series) - Toggle categories anime/series (min 1 active) - Repertoire de telechargement personnalisable - Migration automatique des nouvelles colonnes SQLite - Template settings avec tous les nouveaux controles - Validation cote backend (400 si les deux categories desactivees) Closes #9, Closes #10, Closes #11, Closes #12
197 lines
7.0 KiB
Python
197 lines
7.0 KiB
Python
"""Application settings routes for Ohm Stream Downloader API"""
|
|
|
|
import json
|
|
from typing import List, Dict, Any, Optional
|
|
from fastapi import APIRouter, Depends, HTTPException, Request, Response
|
|
from fastapi.templating import Jinja2Templates
|
|
from sqlmodel import Session, select
|
|
|
|
from app.database import get_session
|
|
from app.models.auth import User, UserTable
|
|
from app.models.settings import AppSettings, AppSettingsTable, AppSettingsUpdate
|
|
from app.routers.router_auth import get_current_user_from_token, get_optional_user
|
|
from app.providers import get_anime_providers, get_series_providers
|
|
from app.providers_manager import providers_manager
|
|
|
|
router = APIRouter(prefix="/api/settings", tags=["settings"])
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
|
|
@router.get("", response_model=AppSettings)
|
|
async def get_settings(
|
|
current_user: User = Depends(get_current_user_from_token),
|
|
session: Session = Depends(get_session),
|
|
):
|
|
"""Get current application settings for the user"""
|
|
statement = select(AppSettingsTable).where(
|
|
AppSettingsTable.user_id == current_user.id
|
|
)
|
|
settings_obj = session.exec(statement).first()
|
|
|
|
if not settings_obj:
|
|
# Create default settings if they don't exist
|
|
settings_obj = AppSettingsTable(user_id=current_user.id)
|
|
session.add(settings_obj)
|
|
session.commit()
|
|
session.refresh(settings_obj)
|
|
|
|
return AppSettings(
|
|
default_lang=settings_obj.default_lang,
|
|
theme=settings_obj.theme,
|
|
disabled_providers=settings_obj.disabled_providers,
|
|
recommendations_filter=getattr(settings_obj, 'recommendations_filter', 'all'),
|
|
releases_filter=getattr(settings_obj, 'releases_filter', 'all'),
|
|
anime_enabled=getattr(settings_obj, 'anime_enabled', True),
|
|
series_enabled=getattr(settings_obj, 'series_enabled', True),
|
|
download_dir=getattr(settings_obj, 'download_dir', 'downloads'),
|
|
)
|
|
|
|
|
|
@router.patch("", response_model=AppSettings)
|
|
async def update_settings(
|
|
update_data: AppSettingsUpdate,
|
|
response: Response,
|
|
current_user: User = Depends(get_current_user_from_token),
|
|
session: Session = Depends(get_session),
|
|
):
|
|
"""Update application settings for the user"""
|
|
statement = select(AppSettingsTable).where(
|
|
AppSettingsTable.user_id == current_user.id
|
|
)
|
|
settings_obj = session.exec(statement).first()
|
|
|
|
if not settings_obj:
|
|
settings_obj = AppSettingsTable(user_id=current_user.id)
|
|
session.add(settings_obj)
|
|
|
|
if update_data.default_lang is not None:
|
|
settings_obj.default_lang = update_data.default_lang
|
|
if update_data.theme is not None:
|
|
settings_obj.theme = update_data.theme
|
|
if update_data.disabled_providers is not None:
|
|
settings_obj.disabled_providers = update_data.disabled_providers
|
|
if update_data.recommendations_filter is not None:
|
|
settings_obj.recommendations_filter = update_data.recommendations_filter
|
|
if update_data.releases_filter is not None:
|
|
settings_obj.releases_filter = update_data.releases_filter
|
|
if update_data.anime_enabled is not None:
|
|
# Prevent disabling both categories
|
|
if not update_data.anime_enabled and not getattr(settings_obj, 'series_enabled', True):
|
|
raise HTTPException(status_code=400, detail="Au moins une categorie doit rester active")
|
|
settings_obj.anime_enabled = update_data.anime_enabled
|
|
if update_data.series_enabled is not None:
|
|
# Prevent disabling both categories
|
|
if not update_data.series_enabled and not getattr(settings_obj, 'anime_enabled', True):
|
|
raise HTTPException(status_code=400, detail="Au moins une categorie doit rester active")
|
|
settings_obj.series_enabled = update_data.series_enabled
|
|
if update_data.download_dir is not None:
|
|
settings_obj.download_dir = update_data.download_dir
|
|
|
|
session.add(settings_obj)
|
|
session.commit()
|
|
session.refresh(settings_obj)
|
|
|
|
response.headers["HX-Trigger"] = json.dumps(
|
|
{"show-toast": {"message": "Paramètres enregistrés", "type": "success"}}
|
|
)
|
|
|
|
return settings_obj
|
|
|
|
|
|
@router.get("/providers/availability")
|
|
async def get_providers_availability(
|
|
current_user: User = Depends(get_current_user_from_token),
|
|
session: Session = Depends(get_session),
|
|
):
|
|
"""Get list of providers with their availability and enabled status"""
|
|
# Get user settings
|
|
statement = select(AppSettingsTable).where(
|
|
AppSettingsTable.user_id == current_user.id
|
|
)
|
|
settings_obj = session.exec(statement).first()
|
|
disabled_providers = settings_obj.disabled_providers if settings_obj else []
|
|
|
|
# Get health status
|
|
health_status = providers_manager.get_all_status()
|
|
|
|
# Combine anime and series providers
|
|
all_providers = {**get_anime_providers(), **get_series_providers()}
|
|
|
|
result = []
|
|
for pid, info in all_providers.items():
|
|
status_info = health_status.get(pid, {"status": "unknown"})
|
|
result.append(
|
|
{
|
|
"id": pid,
|
|
"name": info["name"],
|
|
"icon": info.get("icon", "🎬"),
|
|
"status": status_info["status"],
|
|
"enabled": pid not in disabled_providers,
|
|
"error": status_info.get("error"),
|
|
}
|
|
)
|
|
|
|
return result
|
|
|
|
|
|
@router.post("/providers/{provider_id}/toggle")
|
|
async def toggle_provider(
|
|
provider_id: str,
|
|
response: Response,
|
|
current_user: User = Depends(get_current_user_from_token),
|
|
session: Session = Depends(get_session),
|
|
):
|
|
"""Toggle a provider's enabled/disabled status"""
|
|
statement = select(AppSettingsTable).where(
|
|
AppSettingsTable.user_id == current_user.id
|
|
)
|
|
settings_obj = session.exec(statement).first()
|
|
|
|
if not settings_obj:
|
|
settings_obj = AppSettingsTable(user_id=current_user.id)
|
|
session.add(settings_obj)
|
|
|
|
disabled = settings_obj.disabled_providers
|
|
if provider_id in disabled:
|
|
disabled.remove(provider_id)
|
|
enabled = True
|
|
else:
|
|
disabled.append(provider_id)
|
|
enabled = False
|
|
|
|
settings_obj.disabled_providers = disabled
|
|
session.add(settings_obj)
|
|
session.commit()
|
|
|
|
status_text = "activé" if enabled else "désactivé"
|
|
response.headers["HX-Trigger"] = json.dumps(
|
|
{
|
|
"show-toast": {
|
|
"message": f"Fournisseur {provider_id} {status_text}",
|
|
"type": "success",
|
|
}
|
|
}
|
|
)
|
|
|
|
return {"id": provider_id, "enabled": enabled}
|
|
|
|
|
|
@router.get("/ui")
|
|
async def get_settings_ui(
|
|
request: Request,
|
|
current_user: Optional[User] = Depends(get_optional_user),
|
|
session: Session = Depends(get_session),
|
|
):
|
|
if current_user is None:
|
|
return templates.TemplateResponse(
|
|
"components/login_prompt.html", {"request": request}
|
|
)
|
|
|
|
settings = await get_settings(current_user, session)
|
|
providers = await get_providers_availability(current_user, session)
|
|
|
|
return templates.TemplateResponse(
|
|
"components/settings_section.html",
|
|
{"request": request, "settings": settings, "providers": providers},
|
|
)
|