Add metadataid, original language metadata and genres

This commit is contained in:
Zoe Roux 2023-03-22 18:21:57 +09:00
parent 1167cfa3a4
commit c894f33c11
4 changed files with 60 additions and 40 deletions

View File

@ -112,9 +112,9 @@ namespace Kyoo.Authentication
IssuerSigningKey = key IssuerSigningKey = key
}, out SecurityToken _); }, out SecurityToken _);
} }
catch (Exception ex) catch (Exception)
{ {
throw new SecurityTokenException(ex.Message); throw new SecurityTokenException("Invalid refresh token");
} }
if (principal.Claims.First(x => x.Type == Claims.Type).Value != "refresh") if (principal.Claims.First(x => x.Type == Claims.Type).Value != "refresh")

View File

@ -5,6 +5,7 @@ from aiohttp import ClientSession
from typing import Callable, Dict, Optional, Any from typing import Callable, Dict, Optional, Any
from providers.types.genre import Genre from providers.types.genre import Genre
from providers.types.metadataid import MetadataID
from ..provider import Provider from ..provider import Provider
from ..types.movie import Movie, MovieTranslation from ..types.movie import Movie, MovieTranslation
@ -17,6 +18,26 @@ class TheMovieDatabase(Provider):
self._client = client self._client = client
self.base = "https://api.themoviedb.org/3" self.base = "https://api.themoviedb.org/3"
self.api_key = api_key self.api_key = api_key
self.genre_map = {
28: Genre.ACTION,
12: Genre.ADVENTURE,
16: Genre.ANIMATION,
35: Genre.COMEDY,
80: Genre.CRIME,
99: Genre.DOCUMENTARY,
18: Genre.DRAMA,
10751: Genre.FAMILY,
14: Genre.FANTASY,
36: Genre.HISTORY,
27: Genre.HORROR,
10402: Genre.MUSIC,
9648: Genre.MYSTERY,
10749: Genre.ROMANCE,
878: Genre.SCIENCE_FICTION,
53: Genre.THRILLER,
10752: Genre.WAR,
37: Genre.WESTERN,
}
async def get(self, path: str, *, params: dict[str, Any] = {}): async def get(self, path: str, *, params: dict[str, Any] = {}):
params = {k: v for k, v in params.items() if v is not None} params = {k: v for k, v in params.items() if v is not None}
@ -26,13 +47,11 @@ class TheMovieDatabase(Provider):
r.raise_for_status() r.raise_for_status()
return await r.json() return await r.json()
def get_image( def get_image(self, images: list[Dict[str, Any]]) -> list[str]:
self, images: list[Dict[str, Any]], filter: Callable[[Dict[str, Any]], bool]
) -> list[str]:
return [ return [
f"https://image.tmdb.org/t/p/original{x['file_path']}" f"https://image.tmdb.org/t/p/original{x['file_path']}"
for x in images for x in images
if x["file_path"] and filter(x) if x["file_path"]
] ]
async def identify_movie( async def identify_movie(
@ -42,6 +61,8 @@ class TheMovieDatabase(Provider):
"results" "results"
][0] ][0]
movie_id = search["id"] movie_id = search["id"]
if search["original_language"] not in language:
language.append(search["original_language"])
async def for_language(lng: str) -> Movie: async def for_language(lng: str) -> Movie:
movie = await self.get( movie = await self.get(
@ -49,47 +70,41 @@ class TheMovieDatabase(Provider):
params={ params={
"language": lng, "language": lng,
"append_to_response": "alternative_titles,videos,credits,keywords,images", "append_to_response": "alternative_titles,videos,credits,keywords,images",
"include_image_language": ",".join(
[lng, search["original_language"]]
),
}, },
) )
logging.debug("TMDb responded: %s", movie) logging.debug("TMDb responded: %s", movie)
# TODO: Use collection data
ret = Movie( ret = Movie(
aliases=list(map(lambda x: x["title"], movie["alternative_titles"])), original_language=movie["original_language"],
aliases=[x["title"] for x in movie["alternative_titles"]["titles"]],
release_date=datetime.strptime( release_date=datetime.strptime(
movie["release_date"], "%Y-%m-%d" movie["release_date"], "%Y-%m-%d"
).date(), ).date(),
status=Status.FINISHED status=Status.FINISHED
if movie["Status"] == "Released" if movie["status"] == "Released"
else Status.PLANNED, else Status.PLANNED,
studios=list(map(lambda x: x["name"], movie["production_companies"])), studios=list(map(lambda x: x["name"], movie["production_companies"])),
genres=list(map(lambda x: Genre(x["name"]), movie["genres"])), genres=[self.genre_map[x["id"]] for x in movie["genres"] if x["id"] in self.genre_map],
original_posters=self.get_image( external_id={
movie["images"]["posters"], "themoviedatabase": MetadataID(
lambda x: x["iso_639_1"] == search["original_language"], movie["id"], f"https://www.themoviedb.org/movie/{movie['id']}"
), ),
thumbnails=self.get_image( "imdb": MetadataID(
movie["images"]["backdrops"], movie["imdb_id"],
lambda x: x["iso_639_1"] == lng, f"https://www.imdb.com/title/{movie['imdb_id']}",
), ),
# TODO: Add external IDs. }
# TODO: Add cast information # TODO: Add cast information
) )
translation = MovieTranslation( translation = MovieTranslation(
name=movie["title"], name=movie["title"],
tagline=movie["tagline"], tagline=movie["tagline"],
keywords=list(map(lambda x: x["name"], movie["keywords"])), keywords=list(map(lambda x: x["name"], movie["keywords"]["keywords"])),
overview=movie["overview"], overview=movie["overview"],
posters=self.get_image( posters=self.get_image(movie["images"]["posters"]),
movie["images"]["posters"], logos=self.get_image(movie["images"]["logos"]),
lambda x: x["iso_639_1"] == lng, thumbnails=self.get_image(movie["images"]["backdrops"]),
),
logos=self.get_image(
movie["images"]["logos"],
lambda x: x["iso_639_1"] == lng,
),
trailers=[ trailers=[
f"https://www.youtube.com/watch?v{x['key']}" f"https://www.youtube.com/watch?v{x['key']}"
for x in movie["videos"]["results"] for x in movie["videos"]["results"]

View File

@ -0,0 +1,7 @@
from dataclasses import dataclass
@dataclass
class MetadataID:
id: str
link: str

View File

@ -5,6 +5,7 @@ from typing import Optional
from .genre import Genre from .genre import Genre
from .status import Status from .status import Status
from .metadataid import MetadataID
@dataclass @dataclass
@ -17,24 +18,21 @@ class MovieTranslation:
posters: list[str] = field(default_factory=list) posters: list[str] = field(default_factory=list)
logos: list[str] = field(default_factory=list) logos: list[str] = field(default_factory=list)
trailers: list[str] = field(default_factory=list) trailers: list[str] = field(default_factory=list)
thumbnails: list[str] = field(default_factory=list)
@dataclass @dataclass
class Movie: class Movie:
original_language: Optional[str] = None
aliases: list[str] = field(default_factory=list) aliases: list[str] = field(default_factory=list)
release_date: Optional[date | int] = None release_date: Optional[date | int] = None
status: Status = Status.UNKNOWN status: Status = Status.UNKNOWN
path: Optional[str] = None
studios: list[str] = field(default_factory=list) studios: list[str] = field(default_factory=list)
genres: list[Genre] = field(default_factory=list) genres: list[Genre] = field(default_factory=list)
thumbnails: list[str] = field(default_factory=list)
# Original poster in the show's language
original_posters: list[str] = field(default_factory=list)
path: Optional[str] = None
# TODO: handle staff # TODO: handle staff
# staff: list[Staff] # staff: list[Staff]
external_id: dict[str, MetadataID] = field(default_factory=dict)
translations: dict[str, MovieTranslation] = field(default_factory=dict) translations: dict[str, MovieTranslation] = field(default_factory=dict)
@ -44,12 +42,12 @@ class Movie:
return { return {
**asdict(self), **asdict(self),
**asdict(self.translations[default_language]), **asdict(self.translations[default_language]),
"poster": next(iter(self.original_posters), None), "poster": next(iter(self.translations[default_language].posters), None),
"thumbnail": next(iter(self.thumbnails), None), "thumbnail": next(iter(self.translations[default_language].thumbnails), None),
"logo": next(iter(self.translations[default_language].logos), None), "logo": next(iter(self.translations[default_language].logos), None),
"trailer": next(iter(self.translations[default_language].trailers), None), "trailer": next(iter(self.translations[default_language].trailers), None),
"studio": next(iter(self.studios), None), "studio": next(iter(self.studios), None),
"start_air": self.release_date, "startAir": self.release_date,
"title": self.translations[default_language].name, "title": self.translations[default_language].name,
"isMovie": True, "isMovie": True,
} }