130 lines
4.4 KiB
Python
130 lines
4.4 KiB
Python
"""Scheduler API Routes - Manage scheduled tasks."""
|
|
|
|
import logging
|
|
from typing import Optional, List, Dict, Any
|
|
from fastapi import APIRouter, Form
|
|
from fastapi.responses import JSONResponse
|
|
from core.scheduler import add_job, remove_job, get_jobs
|
|
|
|
logger = logging.getLogger("syllabus")
|
|
router = APIRouter(prefix="/api/schedule", tags=["Scheduler"])
|
|
|
|
|
|
@router.post("/add", description="Add a scheduled task")
|
|
async def add_scheduled_task(
|
|
job_id: str = Form(...),
|
|
task: str = Form(...),
|
|
cron: str = Form(...),
|
|
show: Optional[str] = Form(None),
|
|
season: Optional[int] = Form(None),
|
|
specials: bool = Form(False)
|
|
) -> JSONResponse:
|
|
"""
|
|
Add a scheduled task.
|
|
|
|
**Tasks:**
|
|
- `download_show`: Download specific show/season (requires: show, season)
|
|
- `download_latest`: Download latest season (requires: show)
|
|
- `update_series`: Update series list (no params needed)
|
|
- `update_posters`: Force re-download all show posters (no params needed)
|
|
|
|
**Cron Format:** (minute hour day month day_of_week)
|
|
- `0 2 * * *` = Daily at 2 AM
|
|
- `0 */6 * * *` = Every 6 hours
|
|
- `0 0 * * 0` = Weekly on Sunday at midnight
|
|
"""
|
|
try:
|
|
# Validate task type
|
|
valid_tasks = ["download_show", "download_latest", "update_series", "update_posters"]
|
|
if task not in valid_tasks:
|
|
return JSONResponse(
|
|
status_code=400,
|
|
content={"status": "error", "message": f"Invalid task. Must be one of: {valid_tasks}"}
|
|
)
|
|
|
|
# Build kwargs based on task
|
|
kwargs = {}
|
|
if task == "download_show":
|
|
if not show or season is None:
|
|
return JSONResponse(
|
|
status_code=400,
|
|
content={"status": "error", "message": "download_show requires 'show' and 'season'"}
|
|
)
|
|
kwargs = {"show": show, "season": season, "specials": specials}
|
|
elif task == "download_latest":
|
|
if not show:
|
|
return JSONResponse(
|
|
status_code=400,
|
|
content={"status": "error", "message": "download_latest requires 'show'"}
|
|
)
|
|
kwargs = {"show": show}
|
|
|
|
# Add the job
|
|
success = add_job(job_id, task, cron, kwargs)
|
|
if success:
|
|
return JSONResponse(
|
|
status_code=201,
|
|
content={
|
|
"status": "success",
|
|
"message": f"Job '{job_id}' scheduled",
|
|
"job_id": job_id,
|
|
"task": task,
|
|
"cron": cron
|
|
}
|
|
)
|
|
else:
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"status": "error", "message": "Failed to add job"}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error adding scheduled task: {e}")
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"status": "error", "message": str(e)}
|
|
)
|
|
|
|
|
|
@router.delete("/remove/{job_id}", description="Remove a scheduled task")
|
|
async def remove_scheduled_task(job_id: str) -> JSONResponse:
|
|
"""Remove a scheduled task by ID."""
|
|
try:
|
|
success = remove_job(job_id)
|
|
if success:
|
|
return JSONResponse(
|
|
status_code=200,
|
|
content={"status": "success", "message": f"Job '{job_id}' removed"}
|
|
)
|
|
else:
|
|
return JSONResponse(
|
|
status_code=404,
|
|
content={"status": "error", "message": f"Job '{job_id}' not found"}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error removing scheduled task: {e}")
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"status": "error", "message": str(e)}
|
|
)
|
|
|
|
|
|
@router.get("/list", description="List all scheduled tasks")
|
|
async def list_scheduled_tasks() -> JSONResponse:
|
|
"""Get list of all scheduled tasks."""
|
|
try:
|
|
jobs = get_jobs()
|
|
return JSONResponse(
|
|
status_code=200,
|
|
content={
|
|
"status": "success",
|
|
"count": len(jobs),
|
|
"jobs": jobs
|
|
}
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"Error listing scheduled tasks: {e}")
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={"status": "error", "message": str(e)}
|
|
)
|