Files
project-kino/runtime-current/kino/app-src/backend/app/schemas.py

117 lines
2.9 KiB
Python

from datetime import datetime
from typing import Any
from pydantic import AnyHttpUrl, BaseModel, Field
class ProbeRequest(BaseModel):
url: AnyHttpUrl
class AnalyzeRequest(BaseModel):
url: AnyHttpUrl
class BrowserCapturedCandidate(BaseModel):
url: str
title: str | None = None
name: str | None = None
content_type: str | None = None
type: str | None = None
quality: str | None = None
class BrowserCaptureRequest(BaseModel):
page_url: AnyHttpUrl | None = None
candidates: list[BrowserCapturedCandidate] = Field(default_factory=list, max_length=80)
class MediaCandidateResponse(BaseModel):
url: str
kind: str
title: str | None = None
source: str
content_type: str | None = None
content_length: int | None = None
file_size: str | None = None
quality: str | None = None
allowed: bool = True
reason: str | None = None
metadata: dict[str, Any] = Field(default_factory=dict)
class AnalyzeResponse(BaseModel):
page_url: str
candidates: list[MediaCandidateResponse]
class InteractiveAnalyzeStartRequest(BaseModel):
url: AnyHttpUrl
class InteractiveAnalyzeClickRequest(BaseModel):
x: float = Field(ge=0)
y: float = Field(ge=0)
class InteractiveAnalyzeKeyRequest(BaseModel):
key: str = Field(min_length=1, max_length=40)
class InteractiveAnalyzeResponse(BaseModel):
session_id: str
page_url: str
screenshot: str
viewport: dict[str, int]
candidates: list[MediaCandidateResponse]
ublock_origin: bool = False
class ProbeResponse(BaseModel):
provider: str
title: str | None = None
description: str | None = None
thumbnail: str | None = None
duration_seconds: int | None = None
external_id: str | None = None
allowed: bool = True
class ImportRequest(BaseModel):
url: AnyHttpUrl
target_profile: str = Field(default="clip", pattern="^(film|serie|clip)$")
title: str | None = Field(default=None, max_length=180)
year: int | None = Field(default=None, ge=1888, le=2200)
series_title: str | None = Field(default=None, max_length=180)
season: int | None = Field(default=None, ge=1, le=200)
episode: int | None = Field(default=None, ge=1, le=1000)
episode_title: str | None = Field(default=None, max_length=180)
target_library: str | None = Field(default=None, max_length=80) # legacy API alias
max_height: int = Field(default=1080, ge=144, le=2160)
audio_only: bool = False
class ImportJobResponse(BaseModel):
id: int
source_id: int
title: str | None = None
status: str
target_library: str
target_path: str | None = None
progress: float
error: str | None = None
created_at: datetime
updated_at: datetime
class SourceResponse(BaseModel):
id: int
kind: str
url: str
title: str | None = None
provider: str | None = None
external_id: str | None = None
created_at: datetime