From 9febb0de412d02c0456bb7499d62d7f7c35f3ef2 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Thu, 8 May 2025 01:31:41 +0200 Subject: [PATCH] Type movie & all related types --- api/src/models/collections.ts | 2 +- api/src/models/movie.ts | 2 +- api/src/models/serie.ts | 2 +- scanner/pyproject.toml | 12 ++++ scanner/scanner/models/collection.py | 45 +++++++------- scanner/scanner/models/genre.py | 3 - scanner/scanner/models/metadataid.py | 7 +-- scanner/scanner/models/movie.py | 91 +++++++++++++--------------- scanner/scanner/models/staff.py | 35 +++++++++++ scanner/scanner/models/studio.py | 23 ++++--- scanner/scanner/models/videos.py | 11 ++-- 11 files changed, 135 insertions(+), 98 deletions(-) create mode 100644 scanner/scanner/models/staff.py diff --git a/api/src/models/collections.ts b/api/src/models/collections.ts index f3221ae3..7da75645 100644 --- a/api/src/models/collections.ts +++ b/api/src/models/collections.ts @@ -65,7 +65,7 @@ export const FullCollection = t.Intersect([ export type FullCollection = Prettify; export const SeedCollection = t.Composite([ - t.Omit(BaseCollection, ["kind", "startAir", "endAir", "nextRefresh"]), + t.Omit(BaseCollection, ["startAir", "endAir", "nextRefresh"]), t.Object({ slug: t.String({ format: "slug" }), originalLanguage: Language({ diff --git a/api/src/models/movie.ts b/api/src/models/movie.ts index d107474a..c575ae5d 100644 --- a/api/src/models/movie.ts +++ b/api/src/models/movie.ts @@ -72,7 +72,7 @@ export const FullMovie = t.Intersect([ export type FullMovie = Prettify; export const SeedMovie = t.Composite([ - t.Omit(BaseMovie, ["kind", "nextRefresh"]), + t.Omit(BaseMovie, ["nextRefresh"]), t.Object({ slug: t.String({ format: "slug", examples: ["bubble"] }), originalLanguage: Language({ diff --git a/api/src/models/serie.ts b/api/src/models/serie.ts index e16a0ea6..46a2d153 100644 --- a/api/src/models/serie.ts +++ b/api/src/models/serie.ts @@ -88,7 +88,7 @@ export const FullSerie = t.Intersect([ export type FullSerie = Prettify; export const SeedSerie = t.Composite([ - t.Omit(BaseSerie, ["kind", "nextRefresh"]), + t.Omit(BaseSerie, ["nextRefresh"]), t.Object({ slug: t.String({ format: "slug" }), originalLanguage: Language({ diff --git a/scanner/pyproject.toml b/scanner/pyproject.toml index ce8becbf..fba26d31 100644 --- a/scanner/pyproject.toml +++ b/scanner/pyproject.toml @@ -3,3 +3,15 @@ indent-style = "tab" [tool.pyright] reportAbstractUsage = false +reportUnannotatedClassAttribute = false +enableTypeIgnoreComments = true +reportIgnoreCommentWithoutRule = false +reportUnknownArgumentType = false +reportUnknownVariableType = false +reportMissingParameterType = false +reportUnknownParameterType = false +reportUnknownMemberType = false +reportAny = false +reportExplicitAny = false +reportMissingTypeStubs = false +reportUnknownLambdaType = false diff --git a/scanner/scanner/models/collection.py b/scanner/scanner/models/collection.py index 58a237c4..69a08840 100644 --- a/scanner/scanner/models/collection.py +++ b/scanner/scanner/models/collection.py @@ -1,32 +1,31 @@ -from dataclasses import asdict, dataclass, field -from typing import Optional +from __future__ import annotations -from providers.types.genre import Genre -from .metadataid import MetadataID +from langcodes import Language + +from ..utils import Model +from .genre import Genre +from .metadataid import MetadataId -@dataclass -class CollectionTranslation: +class Collection(Model): + slug: str + original_language: Language + genres: list[Genre] + rating: int | None + external_id: dict[str, MetadataId] + + translations: dict[str, CollectionTranslation] = {} + + +class CollectionTranslation(Model): name: str - descrpition: Optional[str] - tagline: Optional[str] - aliases: Optional[str] - tags: Optional[str] + latin_name: str | None + description: str | None + tagline: str | None + aliases: list[str] + tags: list[str] posters: list[str] thumbnails: list[str] banner: list[str] logos: list[str] - - -@dataclass -class Collection: - slug: str - original_language: str - genres: list[Genre] - rating: Optional[int] - external_id: dict[str, MetadataID] - translations: dict[str, CollectionTranslation] = field(default_factory=dict) - - def to_kyoo(self): - return asdict(self) diff --git a/scanner/scanner/models/genre.py b/scanner/scanner/models/genre.py index 652f702e..1ba8eda8 100644 --- a/scanner/scanner/models/genre.py +++ b/scanner/scanner/models/genre.py @@ -25,6 +25,3 @@ class Genre(str, Enum): POLITICS = "politics" SOAP = "soap" TALK = "talk" - - def to_kyoo(self): - return self.value diff --git a/scanner/scanner/models/metadataid.py b/scanner/scanner/models/metadataid.py index e89bebab..0b93d3cc 100644 --- a/scanner/scanner/models/metadataid.py +++ b/scanner/scanner/models/metadataid.py @@ -1,14 +1,13 @@ -from typing import Optional from ..utils import Model class MetadataId(Model): data_id: str - link: Optional[str] = None + link: str | None = None class EpisodeId(Model): serie_id: str - season: Optional[int] + season: int | None episode: int - link: Optional[str] = None + link: str | None = None diff --git a/scanner/scanner/models/movie.py b/scanner/scanner/models/movie.py index 0a984e39..04a1d35e 100644 --- a/scanner/scanner/models/movie.py +++ b/scanner/scanner/models/movie.py @@ -1,14 +1,16 @@ -from dataclasses import asdict, dataclass, field +from __future__ import annotations + from datetime import date -from typing import Optional from enum import Enum -from providers.utils import select_translation, select_image +from langcodes import Language +from ..utils import Model from .collection import Collection from .genre import Genre +from .metadataid import MetadataId +from .staff import Staff from .studio import Studio -from .metadataid import MetadataID class Status(str, Enum): @@ -17,50 +19,43 @@ class Status(str, Enum): PLANNED = "planned" -@dataclass -class MovieTranslation: - name: str - tagline: Optional[str] = None - tags: list[str] = field(default_factory=list) - overview: Optional[str] = None - - posters: list[str] = field(default_factory=list) - logos: list[str] = field(default_factory=list) - trailers: list[str] = field(default_factory=list) - thumbnails: list[str] = field(default_factory=list) - - -@dataclass -class Movie: - original_language: Optional[str] - aliases: list[str] - air_date: Optional[date | int] - status: Status - rating: int - runtime: Optional[int] - studios: list[Studio] +class Movie(Model): + slug: str + original_language: Language | None genres: list[Genre] - # TODO: handle staff - # staff: list[Staff] - external_id: dict[str, MetadataID] + rating: int | None + status: Status + runtime: int | None + air_date: date | None - path: Optional[str] = None - # The title of this show according to it's filename (None only for ease of use in providers) - file_title: Optional[str] = None - collections: list[Collection] = field(default_factory=list) - translations: dict[str, MovieTranslation] = field(default_factory=dict) + external_id: dict[str, MetadataId] + translations: dict[str, MovieTranslation] = {} + videos: list[str] = [] + collections: list[Collection] = [] + studios: list[Studio] = [] + staff: list[Staff] = [] - def to_kyoo(self): - trans = select_translation(self) or MovieTranslation(name=self.file_title or "") - return { - **asdict(self), - **asdict(trans), - "poster": select_image(self, "posters"), - "thumbnail": select_image(self, "thumbnails"), - "logo": select_image(self, "logos"), - "trailer": select_image(self, "trailers"), - "studio": next((x.to_kyoo() for x in self.studios), None), - "genres": [x.to_kyoo() for x in self.genres], - "collections": None, - "file_title": None, - } + +class MovieTranslation(Model): + name: str + latin_name: str | None + description: str | None + tagline: str | None + aliases: list[str] + tags: list[str] + + posters: list[str] + thumbnails: list[str] + banner: list[str] + logos: list[str] + trailers: list[str] + + +class SearchMovie(Model): + slug: str + name: str + description: str | None + air_date: date | None + poster: str + original_language: Language | None + external_id: dict[str, MetadataId] diff --git a/scanner/scanner/models/staff.py b/scanner/scanner/models/staff.py new file mode 100644 index 00000000..759a48da --- /dev/null +++ b/scanner/scanner/models/staff.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +from enum import Enum + +from ..utils import Model +from .metadataid import MetadataId + + +class Role(str, Enum): + ACTOR = "actor" + DIRECTOR = "director" + WRITTER = "writter" + PRODUCER = "producer" + MUSIC = "music" + OTHER = "other" + + +class Staff(Model): + kind: Role + character: Character | None + staff: Person + + +class Character(Model): + name: str + latin_name: str | None + image: str | None + + +class Person(Model): + slug: str + name: str + latin_name: str | None + image: str | None + external_id: dict[str, MetadataId] diff --git a/scanner/scanner/models/studio.py b/scanner/scanner/models/studio.py index 0ed11f6a..ffd83336 100644 --- a/scanner/scanner/models/studio.py +++ b/scanner/scanner/models/studio.py @@ -1,16 +1,15 @@ -from dataclasses import asdict, dataclass, field +from __future__ import annotations -from .metadataid import MetadataID +from ..utils import Model +from .metadataid import MetadataId -@dataclass -class Studio: +class Studio(Model): + slug: str + external_id: dict[str, MetadataId] + translations: dict[str, StudioTranslations] = {} + + +class StudioTranslations(Model): name: str - logos: list[str] = field(default_factory=list) - external_id: dict[str, MetadataID] = field(default_factory=dict) - - def to_kyoo(self): - return { - **asdict(self), - "logo": next(iter(self.logos), None), - } + logo: str | None diff --git a/scanner/scanner/models/videos.py b/scanner/scanner/models/videos.py index 3751fb00..459723e8 100644 --- a/scanner/scanner/models/videos.py +++ b/scanner/scanner/models/videos.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Literal, Optional +from typing import Any, Literal from ..utils import Model from .extra import ExtraKind @@ -21,7 +21,7 @@ class VideoInfo(Model): class Guess(Model, extra="allow"): title: str kind: Literal["episode"] | Literal["movie"] | Literal["extra"] - extra_kind: Optional[ExtraKind] + extra_kind: ExtraKind | None years: list[int] episodes: list[Guess.Episode] external_id: dict[str, str] @@ -31,11 +31,11 @@ class Guess(Model, extra="allow"): history: list[Guess] = [] class Episode(Model): - season: Optional[int] + season: int | None episode: int -Guess.model_rebuild() +_ = Guess.model_rebuild() class For(Model): @@ -65,13 +65,14 @@ class For(Model): class Video(Model): path: str rendering: str - part: Optional[int] + part: int | None version: int = 1 guess: Guess for_: list[ For.Slug | For.ExternalId | For.Movie | For.Episode | For.Order | For.Special ] = [] + class VideoCreated(Resource): guess: Guess entries: list[Resource]