mirror of
https://github.com/wahyd4/you-music.git
synced 2026-08-08 20:59:47 +10:00
133 lines
5.2 KiB
Python
133 lines
5.2 KiB
Python
from fastapi import APIRouter, Depends, BackgroundTasks
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
import logging
|
|
|
|
from app.db.session import get_db
|
|
from app.schemas.schemas import SettingsResponse, SettingsUpdate, ScanStatus
|
|
from app.models.models import AppSettings
|
|
from app.core.config import settings as app_settings
|
|
from app.services.scanner import full_scan, get_scan_status
|
|
from app.services.scheduler import update_scan_interval, enable_auto_scan
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
|
|
async def get_setting(db: AsyncSession, key: str) -> Optional[str]:
|
|
"""Get a setting value from database"""
|
|
result = await db.execute(select(AppSettings).where(AppSettings.key == key))
|
|
setting = result.scalar_one_or_none()
|
|
return setting.value if setting else None
|
|
|
|
|
|
async def set_setting(db: AsyncSession, key: str, value: str):
|
|
"""Set a setting value in database"""
|
|
result = await db.execute(select(AppSettings).where(AppSettings.key == key))
|
|
setting = result.scalar_one_or_none()
|
|
|
|
if setting:
|
|
setting.value = value
|
|
setting.updated_at = datetime.utcnow()
|
|
else:
|
|
setting = AppSettings(key=key, value=value)
|
|
db.add(setting)
|
|
|
|
await db.commit()
|
|
|
|
|
|
@router.get("/", response_model=SettingsResponse)
|
|
async def get_settings(db: AsyncSession = Depends(get_db)):
|
|
"""Get current application settings"""
|
|
|
|
# Get settings from database or use defaults
|
|
local_music_dir = await get_setting(db, "local_music_dir")
|
|
scan_interval = await get_setting(db, "scan_interval")
|
|
delete_missing = await get_setting(db, "delete_missing_files")
|
|
auto_scan = await get_setting(db, "auto_scan_enabled")
|
|
last_scan = await get_setting(db, "last_scan_at")
|
|
|
|
return SettingsResponse(
|
|
local_music_dir=local_music_dir or app_settings.LOCAL_MUSIC_DIR,
|
|
scan_interval=int(scan_interval) if scan_interval else app_settings.SCAN_INTERVAL,
|
|
delete_missing_files=delete_missing.lower() == "true" if delete_missing else app_settings.DELETE_MISSING_FILES,
|
|
auto_scan_enabled=auto_scan.lower() == "true" if auto_scan else app_settings.AUTO_SCAN_ENABLED,
|
|
last_scan_at=datetime.fromisoformat(last_scan) if last_scan else None
|
|
)
|
|
|
|
|
|
@router.put("/", response_model=SettingsResponse)
|
|
async def update_settings(
|
|
settings_update: SettingsUpdate,
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""Update application settings"""
|
|
|
|
# Update each setting if provided
|
|
if settings_update.local_music_dir is not None:
|
|
await set_setting(db, "local_music_dir", settings_update.local_music_dir)
|
|
app_settings.LOCAL_MUSIC_DIR = settings_update.local_music_dir
|
|
logger.info(f"Updated LOCAL_MUSIC_DIR to: {settings_update.local_music_dir}")
|
|
|
|
if settings_update.scan_interval is not None:
|
|
await set_setting(db, "scan_interval", str(settings_update.scan_interval))
|
|
app_settings.SCAN_INTERVAL = settings_update.scan_interval
|
|
update_scan_interval(settings_update.scan_interval)
|
|
logger.info(f"Updated scan_interval to: {settings_update.scan_interval}")
|
|
|
|
if settings_update.delete_missing_files is not None:
|
|
await set_setting(db, "delete_missing_files", str(settings_update.delete_missing_files))
|
|
app_settings.DELETE_MISSING_FILES = settings_update.delete_missing_files
|
|
logger.info(f"Updated delete_missing_files to: {settings_update.delete_missing_files}")
|
|
|
|
if settings_update.auto_scan_enabled is not None:
|
|
await set_setting(db, "auto_scan_enabled", str(settings_update.auto_scan_enabled))
|
|
app_settings.AUTO_SCAN_ENABLED = settings_update.auto_scan_enabled
|
|
|
|
# Update scheduler
|
|
interval = settings_update.scan_interval or app_settings.SCAN_INTERVAL
|
|
enable_auto_scan(settings_update.auto_scan_enabled, interval)
|
|
logger.info(f"Updated auto_scan_enabled to: {settings_update.auto_scan_enabled}")
|
|
|
|
# Return updated settings
|
|
return await get_settings(db)
|
|
|
|
|
|
@router.post("/scan")
|
|
async def trigger_manual_scan(
|
|
background_tasks: BackgroundTasks,
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""Trigger a manual music library scan"""
|
|
|
|
# Get delete_missing setting
|
|
delete_missing = await get_setting(db, "delete_missing_files")
|
|
delete = delete_missing.lower() == "true" if delete_missing else app_settings.DELETE_MISSING_FILES
|
|
|
|
# Run scan in background
|
|
background_tasks.add_task(full_scan, db, delete)
|
|
|
|
logger.info("Manual scan triggered")
|
|
return {"message": "Scan started", "status": "processing"}
|
|
|
|
|
|
@router.get("/scan-status", response_model=ScanStatus)
|
|
async def get_scan_status_endpoint():
|
|
"""Get current scan status"""
|
|
status = get_scan_status()
|
|
|
|
return ScanStatus(
|
|
is_scanning=status["is_scanning"],
|
|
progress=status["progress"],
|
|
total=status["total"],
|
|
current_file=status["current_file"],
|
|
started_at=status["started_at"],
|
|
completed_at=status["completed_at"],
|
|
files_added=status["files_added"],
|
|
files_updated=status["files_updated"],
|
|
files_missing=status["files_missing"],
|
|
errors=status["errors"]
|
|
)
|