feat: add typed qBittorrent scheduled polling

This commit is contained in:
Developer
2026-07-14 15:22:34 +00:00
parent eac9b5d33d
commit a9488af0b4
22 changed files with 2036 additions and 56 deletions
@@ -0,0 +1,69 @@
"""API models for backend scheduled actions."""
from __future__ import annotations
from typing import Any, Literal
from pydantic import BaseModel, Field
class SchedulerStatus(BaseModel):
service_id: str
action_key: str
worker_running: bool
enabled: bool
running: bool = False
poll_interval_seconds: int = Field(ge=5, le=300)
sample_retention_seconds: int = Field(ge=60, le=86_400)
sample_max_rows: int = Field(ge=60, le=1_200)
next_run_at: int | None = None
last_attempt_at: int | None = None
last_success_at: int | None = None
last_error: str = ""
consecutive_failures: int = 0
backoff_until: int | None = None
is_stale: bool = False
class SchedulerRun(BaseModel):
id: str
service_id: str
action_key: str
trigger: Literal["schedule", "manual"]
started_at: int
finished_at: int | None = None
status: Literal["running", "success", "failure", "cancelled"]
attempt: int = 0
duration_ms: int | None = None
error: str = ""
created_at: int
class SchedulerRunsResponse(BaseModel):
items: list[SchedulerRun]
total: int
limit: int
offset: int
class SchedulerSample(BaseModel):
ts: int
dl_speed: int
up_speed: int
class SchedulerSamplesResponse(BaseModel):
service_id: str
window_seconds: int
samples: list[SchedulerSample]
class SchedulerManualRunResponse(BaseModel):
run: SchedulerRun
status: SchedulerStatus
class SchedulerActionResult(BaseModel):
"""Internal-friendly result payload exposed for diagnostics/tests."""
data: dict[str, Any] = Field(default_factory=dict)