feat: Implement scheduling functionality for playlist synchronization

- Added a new scheduler module using APScheduler to manage scheduled sync jobs.
- Introduced cron expression validation and job scheduling based on user-defined settings.
- Enhanced frontend to support schedule settings, including cron, daily, and weekly modes.
- Updated API service to handle fetching and saving schedule settings.
- Modified StrategySelector component to include schedule management UI.
- Added new types for schedule settings and modes in the frontend.
- Updated requirements to include APScheduler for scheduling capabilities.
This commit is contained in:
2025-11-29 10:49:35 +09:00
parent 40f818bd2c
commit 7dae8647e6
9 changed files with 765 additions and 182 deletions
+49
View File
@@ -14,9 +14,14 @@ from app.utils.local_playlist import load_local_playlist, scan_local_playlists
from app.utils.logger import logger
from app.utils.playlist_merge import SyncMode, TEST_PLAYLIST_DIR, sync_all_playlists
from app.utils.plex_client import plex_client
from app.utils.scheduler import start_scheduler, update_scheduler_job, get_next_run_time, validate_cron_expression
app = FastAPI()
@app.on_event("startup")
async def startup_event():
start_scheduler()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
@@ -107,6 +112,50 @@ class ConnectRequest(BaseModel):
library_name: str | None = None
class ScheduleSettings(BaseModel):
mode: str
cronExpression: str
dailyTime: str
weeklyDays: list[int]
weeklyTime: str
autoWatch: bool
@app.get("/api/schedule")
async def get_schedule():
next_run = get_next_run_time()
next_run_str = next_run.strftime("%Y-%m-%d %H:%M:%S") if next_run else None
return {
"mode": server_config.schedule_mode,
"cronExpression": server_config.schedule_cron,
"dailyTime": server_config.schedule_daily_time,
"weeklyDays": server_config.schedule_weekly_days,
"weeklyTime": server_config.schedule_weekly_time,
"autoWatch": server_config.schedule_auto_watch,
"nextRun": next_run_str
}
@app.put("/api/schedule")
async def save_schedule(settings: ScheduleSettings):
# Validate Cron if mode is CRON
if settings.mode == "CRON" and settings.cronExpression.strip():
if not validate_cron_expression(settings.cronExpression):
raise HTTPException(status_code=400, detail="Invalid Cron expression format")
server_config.set_schedule(
mode=settings.mode,
cron=settings.cronExpression,
daily_time=settings.dailyTime,
weekly_days=settings.weeklyDays,
weekly_time=settings.weeklyTime,
auto_watch=settings.autoWatch
)
update_scheduler_job()
return {"status": "success", "message": "Schedule updated"}
class ConnectResponse(BaseModel):
token: str
serverInfo: dict