mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 20:24:27 -04:00
Move models to new scanner module
This commit is contained in:
parent
a35b38755d
commit
f403004842
@ -1,35 +0,0 @@
|
|||||||
from dataclasses import asdict, dataclass, field
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from providers.utils import ProviderError, select_translation, select_image
|
|
||||||
|
|
||||||
from .metadataid import MetadataID
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class CollectionTranslation:
|
|
||||||
name: str
|
|
||||||
overview: Optional[str] = None
|
|
||||||
posters: list[str] = field(default_factory=list)
|
|
||||||
logos: list[str] = field(default_factory=list)
|
|
||||||
thumbnails: list[str] = field(default_factory=list)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Collection:
|
|
||||||
external_id: dict[str, MetadataID]
|
|
||||||
translations: dict[str, CollectionTranslation] = field(default_factory=dict)
|
|
||||||
|
|
||||||
def to_kyoo(self):
|
|
||||||
trans = select_translation(self)
|
|
||||||
if trans is None:
|
|
||||||
raise ProviderError(
|
|
||||||
"Could not find translations for the collection. Aborting"
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
**asdict(self),
|
|
||||||
**asdict(trans),
|
|
||||||
"poster": select_image(self, "posters"),
|
|
||||||
"thumbnail": select_image(self, "thumbnails"),
|
|
||||||
"logo": select_image(self, "logos"),
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class Genre(str, Enum):
|
|
||||||
ACTION = "Action"
|
|
||||||
ADVENTURE = "Adventure"
|
|
||||||
ANIMATION = "Animation"
|
|
||||||
COMEDY = "Comedy"
|
|
||||||
CRIME = "Crime"
|
|
||||||
DOCUMENTARY = "Documentary"
|
|
||||||
DRAMA = "Drama"
|
|
||||||
FAMILY = "Family"
|
|
||||||
FANTASY = "Fantasy"
|
|
||||||
HISTORY = "History"
|
|
||||||
HORROR = "Horror"
|
|
||||||
MUSIC = "Music"
|
|
||||||
MYSTERY = "Mystery"
|
|
||||||
ROMANCE = "Romance"
|
|
||||||
SCIENCE_FICTION = "ScienceFiction"
|
|
||||||
THRILLER = "Thriller"
|
|
||||||
WAR = "War"
|
|
||||||
WESTERN = "Western"
|
|
||||||
KIDS = "Kids"
|
|
||||||
NEWS = "News"
|
|
||||||
REALITY = "Reality"
|
|
||||||
SOAP = "Soap"
|
|
||||||
TALK = "Talk"
|
|
||||||
POLITICS = "Politics"
|
|
||||||
|
|
||||||
def to_kyoo(self):
|
|
||||||
return self.value
|
|
@ -1,81 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import os
|
|
||||||
from datetime import date
|
|
||||||
from itertools import chain
|
|
||||||
from langcodes import Language
|
|
||||||
from typing import TYPE_CHECKING, Literal, Any, Optional
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from providers.types.movie import Movie
|
|
||||||
from providers.types.show import Show
|
|
||||||
from providers.types.season import Season
|
|
||||||
from providers.types.episode import Episode
|
|
||||||
from providers.types.collection import Collection
|
|
||||||
|
|
||||||
|
|
||||||
def format_date(date: date | int | None) -> str | None:
|
|
||||||
if date is None:
|
|
||||||
return None
|
|
||||||
if isinstance(date, int):
|
|
||||||
return f"{date}-01-01"
|
|
||||||
return date.isoformat()
|
|
||||||
|
|
||||||
|
|
||||||
def normalize_lang(lang: str) -> str:
|
|
||||||
return str(Language.get(lang))
|
|
||||||
|
|
||||||
|
|
||||||
# For now, the API of kyoo only support one language so we remove the others.
|
|
||||||
default_languages = os.environ.get("LIBRARY_LANGUAGES", "").split(",")
|
|
||||||
media_prefer_original_language = (
|
|
||||||
os.environ.get("MEDIA_PREFER_ORIGINAL_LANGUAGE", "false").lower() == "true"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def sort_translations(
|
|
||||||
value: Movie | Show | Season | Episode | Collection,
|
|
||||||
*,
|
|
||||||
prefer_orginal=False,
|
|
||||||
):
|
|
||||||
from providers.types.movie import Movie
|
|
||||||
from providers.types.show import Show
|
|
||||||
|
|
||||||
if (
|
|
||||||
prefer_orginal
|
|
||||||
and (isinstance(value, Movie) or isinstance(value, Show))
|
|
||||||
and value.original_language
|
|
||||||
and value.original_language in value.translations
|
|
||||||
):
|
|
||||||
yield value.translations[value.original_language]
|
|
||||||
for lang in default_languages:
|
|
||||||
if lang in value.translations:
|
|
||||||
yield value.translations[lang]
|
|
||||||
|
|
||||||
|
|
||||||
def select_translation(
|
|
||||||
value: Movie | Show | Season | Episode | Collection, *, prefer_orginal=False
|
|
||||||
) -> Optional[Any]:
|
|
||||||
return next(sort_translations(value, prefer_orginal=prefer_orginal), None)
|
|
||||||
|
|
||||||
|
|
||||||
def select_image(
|
|
||||||
value: Movie | Show | Season | Collection,
|
|
||||||
kind: Literal["posters", "thumbnails", "logos", "trailers"],
|
|
||||||
) -> str | None:
|
|
||||||
return next(
|
|
||||||
chain(
|
|
||||||
*(
|
|
||||||
getattr(trans, kind)
|
|
||||||
for trans in sort_translations(
|
|
||||||
value, prefer_orginal=media_prefer_original_language
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ProviderError(RuntimeError):
|
|
||||||
def __init__(self, *args: object) -> None:
|
|
||||||
super().__init__(*args)
|
|
32
scanner/scanner/models/collection.py
Normal file
32
scanner/scanner/models/collection.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from dataclasses import asdict, dataclass, field
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from providers.types.genre import Genre
|
||||||
|
from .metadataid import MetadataID
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CollectionTranslation:
|
||||||
|
name: str
|
||||||
|
descrpition: Optional[str]
|
||||||
|
tagline: Optional[str]
|
||||||
|
aliases: Optional[str]
|
||||||
|
tags: Optional[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)
|
30
scanner/scanner/models/genre.py
Normal file
30
scanner/scanner/models/genre.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class Genre(str, Enum):
|
||||||
|
ACTION = "action"
|
||||||
|
ADVENTURE = "adventure"
|
||||||
|
ANIMATION = "animation"
|
||||||
|
COMEDY = "comedy"
|
||||||
|
CRIME = "crime"
|
||||||
|
DOCUMENTARY = "documentary"
|
||||||
|
DRAMA = "drama"
|
||||||
|
FAMILY = "family"
|
||||||
|
FANTASY = "fantasy"
|
||||||
|
HISTORY = "history"
|
||||||
|
HORROR = "horror"
|
||||||
|
MUSIC = "music"
|
||||||
|
MYSTERY = "mystery"
|
||||||
|
ROMANCE = "romance"
|
||||||
|
SCIENCE_FICTION = "science-fiction"
|
||||||
|
THRILLER = "thriller"
|
||||||
|
WAR = "war"
|
||||||
|
WESTERN = "western"
|
||||||
|
KIDS = "kids"
|
||||||
|
REALITY = "reality"
|
||||||
|
POLITICS = "politics"
|
||||||
|
SOAP = "soap"
|
||||||
|
TALK = "talk"
|
||||||
|
|
||||||
|
def to_kyoo(self):
|
||||||
|
return self.value
|
@ -6,6 +6,3 @@ from typing import Optional
|
|||||||
class MetadataID:
|
class MetadataID:
|
||||||
data_id: str
|
data_id: str
|
||||||
link: Optional[str]
|
link: Optional[str]
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
self.data_id = str(self.data_id)
|
|
28
scanner/scanner/utils.py
Normal file
28
scanner/scanner/utils.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from pydantic import BaseModel, ConfigDict
|
||||||
|
from pydantic.alias_generators import to_camel
|
||||||
|
from datetime import date
|
||||||
|
from langcodes import Language
|
||||||
|
|
||||||
|
|
||||||
|
def format_date(date: date | int | None) -> str | None:
|
||||||
|
if date is None:
|
||||||
|
return None
|
||||||
|
if isinstance(date, int):
|
||||||
|
return f"{date}-01-01"
|
||||||
|
return date.isoformat()
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_lang(lang: str) -> str:
|
||||||
|
return str(Language.get(lang))
|
||||||
|
|
||||||
|
|
||||||
|
class ProviderError(RuntimeError):
|
||||||
|
def __init__(self, *args: object) -> None:
|
||||||
|
super().__init__(*args)
|
||||||
|
|
||||||
|
|
||||||
|
class Model(BaseModel):
|
||||||
|
model_config = ConfigDict(
|
||||||
|
use_enum_values=True,
|
||||||
|
alias_generator=to_camel,
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user