from __future__ import annotations from pathlib import Path from typing import Any from pydantic import BaseModel, ConfigDict, Field, PrivateAttr, field_validator from app.features.core.schemas import Pagination from app.features.core.utils import parse_int from app.features.presets.utils import preset_name from app.library.config import Config from app.library.Utils import create_cookies_file class Preset(BaseModel): model_config = ConfigDict(str_strip_whitespace=True, from_attributes=True) id: int | None = None name: str = Field(min_length=1) description: str = "" folder: str = "" template: str = "" cookies: str = "" cli: str = "" default: bool = False priority: int = 0 _cookies_file: Path | None = PrivateAttr(default=None) @field_validator("name", mode="before") @classmethod def _normalize_name(cls, value: Any) -> str: if not isinstance(value, str): msg: str = "Name must be a string." raise ValueError(msg) if not (value := preset_name(value)): msg = "Name cannot be empty." raise ValueError(msg) return value @field_validator("priority", mode="before") @classmethod def _normalize_priority(cls, value: Any) -> int: return parse_int(value, field="Priority", minimum=0) @field_validator("cli", mode="before") @classmethod def _validate_cli(cls, value: Any) -> str: if not value: return "" if not isinstance(value, str): msg: str = "CLI must be a string." raise ValueError(msg) value = value.strip() if not value: return "" try: from app.features.ytdlp.utils import arg_converter arg_converter(args=value, level=True) except Exception as e: msg = f"Invalid command options for yt-dlp: {e!s}" raise ValueError(msg) from e return value def get_cookies_file(self, config: Config | None = None) -> Path | None: if None is not self._cookies_file: return self._cookies_file if not self.cookies or self.id is None: return None config = config or Config.get_instance() self._cookies_file = create_cookies_file(self.cookies, Path(config.config_path) / "cookies" / f"{self.id}.txt") return self._cookies_file class PresetPatch(Preset): model_config = ConfigDict(str_strip_whitespace=True, from_attributes=True) name: str | None = None description: str | None = None folder: str | None = None template: str | None = None cookies: str | None = None cli: str | None = None priority: int | None = None class PresetList(BaseModel): model_config = ConfigDict(from_attributes=True) items: list[Preset] = Field(default_factory=list) pagination: Pagination