from __future__ import annotations from typing import Any from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from app.features.core.schemas import Pagination from app.features.core.utils import parse_int from app.features.ytdlp.mini_filter import match_str class Condition(BaseModel): model_config = ConfigDict(str_strip_whitespace=True, from_attributes=True) id: int | None = None name: str = Field(min_length=1) filter: str = "" cli: str = "" extras: dict[str, Any] = Field(default_factory=dict) enabled: bool = True priority: int = 0 description: str = "" @field_validator("filter") @classmethod def _validate_filter(cls, value: str) -> str: try: match_str(value, {}) except Exception as exc: msg: str = f"Invalid filter. '{exc!s}'." raise ValueError(msg) from exc return value @field_validator("cli") @classmethod def _validate_cli(cls, value: str) -> str: if not value: return "" try: from app.features.ytdlp.utils import arg_converter arg_converter(args=value) except ModuleNotFoundError: return value except Exception as exc: msg: str = f"Invalid command options for yt-dlp. '{exc!s}'." raise ValueError(msg) from exc 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("enabled", mode="before") @classmethod def _validate_enabled(cls, value: Any) -> bool: if not isinstance(value, bool): msg: str = "Enabled must be a boolean." raise ValueError(msg) return value @model_validator(mode="after") def _validate_cli_or_extras(self) -> Condition: if not self.cli and not self.extras: msg: str = "Either cli or extras must be set." raise ValueError(msg) return self class ConditionPatch(Condition): """ Model for patching Condition fields. All fields are optional. """ name: str | None = None filter: str | None = None cli: str | None = None extras: dict[str, Any] | None = None enabled: bool | None = None priority: int | None = None description: str | None = None @model_validator(mode="after") def _validate_cli_or_extras(self) -> ConditionPatch: return self class ConditionList(BaseModel): model_config = ConfigDict(from_attributes=True) items: list[Condition] = Field(default_factory=list) pagination: Pagination