release: bump version to 0.26.0

This commit is contained in:
rayd1o
2026-04-12 04:36:38 +08:00
parent a359d94127
commit 812c825dc6
22 changed files with 2153 additions and 7 deletions

View File

@@ -1,3 +1,4 @@
from copy import deepcopy
from datetime import UTC, datetime
from typing import Optional
@@ -13,6 +14,7 @@ from app.models.datasource import DataSource
from app.models.system_setting import SystemSetting
from app.models.user import User
from app.services.scheduler import sync_datasource_job
from app.services.tv_streams import DEFAULT_TV_SETTINGS, get_tv_settings_payload, normalize_tv_settings
router = APIRouter()
@@ -36,6 +38,7 @@ DEFAULT_SETTINGS = {
"max_login_attempts": 5,
"password_policy": "medium",
},
"tv": DEFAULT_TV_SETTINGS,
}
@@ -67,8 +70,34 @@ class CollectorSettingsUpdate(BaseModel):
frequency_minutes: int = Field(default=60, ge=1, le=10080)
class TVStreamSourceUpdate(BaseModel):
id: str = Field(min_length=1, max_length=100)
name: str = Field(min_length=1, max_length=200)
provider: str = Field(default="Unknown", max_length=100)
region: str = Field(default="Global", max_length=100)
language: str = Field(default="und", max_length=32)
source_type: str = Field(default="iframe", pattern="^(iframe|hls|video|external|youtube)$")
embed_url: str = ""
stream_url: str = ""
homepage_url: str = ""
poster_url: str = ""
youtube_video_id: str = ""
youtube_channel: str = ""
is_enabled: bool = True
is_fallback: bool = False
sort_order: int = Field(default=10, ge=0, le=9999)
collector_source: Optional[str] = None
notes: str = ""
class TVSettingsUpdate(BaseModel):
default_source_id: str = Field(default=DEFAULT_TV_SETTINGS["default_source_id"], min_length=1)
auto_fallback: bool = True
sources: list[TVStreamSourceUpdate] = Field(default_factory=list)
def merge_with_defaults(category: str, payload: Optional[dict]) -> dict:
merged = DEFAULT_SETTINGS[category].copy()
merged = deepcopy(DEFAULT_SETTINGS[category])
if payload:
merged.update(payload)
return merged
@@ -195,6 +224,25 @@ async def update_security_settings(
return {"status": "updated", "security": payload}
@router.get("/tv")
async def get_tv_settings(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
return {"tv": await get_tv_settings_payload(db)}
@router.put("/tv")
async def update_tv_settings(
settings: TVSettingsUpdate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
payload = normalize_tv_settings(settings.model_dump())
saved = await save_setting_payload(db, "tv", payload)
return {"status": "updated", "tv": normalize_tv_settings(saved)}
@router.get("/collectors")
async def get_collector_settings(
current_user: User = Depends(get_current_user),
@@ -240,6 +288,7 @@ async def get_all_settings(
"system": setting_payloads["system"],
"notifications": setting_payloads["notifications"],
"security": setting_payloads["security"],
"tv": await get_tv_settings_payload(db),
"collectors": [serialize_collector(datasource) for datasource in datasources],
"generated_at": to_iso8601_utc(datetime.now(UTC)),
}