Add most metadata information from themoviedb

This commit is contained in:
Zoe Roux 2023-03-21 15:43:52 +09:00
parent 541a7c9e2b
commit 1167cfa3a4
2 changed files with 74 additions and 24 deletions

View File

@ -1,7 +1,10 @@
import asyncio import asyncio
from datetime import datetime
import logging import logging
from aiohttp import ClientSession from aiohttp import ClientSession
from typing import Optional, Any from typing import Callable, Dict, Optional, Any
from providers.types.genre import Genre
from ..provider import Provider from ..provider import Provider
from ..types.movie import Movie, MovieTranslation from ..types.movie import Movie, MovieTranslation
@ -23,34 +26,75 @@ class TheMovieDatabase(Provider):
r.raise_for_status() r.raise_for_status()
return await r.json() return await r.json()
def get_image(
self, images: list[Dict[str, Any]], filter: Callable[[Dict[str, Any]], bool]
) -> list[str]:
return [
f"https://image.tmdb.org/t/p/original{x['file_path']}"
for x in images
if x["file_path"] and filter(x)
]
async def identify_movie( async def identify_movie(
self, name: str, year: Optional[int], *, language: list[str] self, name: str, year: Optional[int], *, language: list[str]
) -> Movie: ) -> Movie:
movie_id = ( search = (await self.get("search/movie", params={"query": name, "year": year}))[
await self.get("search/movie", params={"query": name, "year": year}) "results"
)["results"][0]["id"] ][0]
movie_id = search["id"]
async def for_language(lng: str) -> Movie: async def for_language(lng: str) -> Movie:
movie = await self.get( movie = await self.get(
f"/movie/{movie_id}", params={"language": lng, "append_to_response": ""} f"/movie/{movie_id}",
params={
"language": lng,
"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)
ret = Movie( ret = Movie(
aliases=[], aliases=list(map(lambda x: x["title"], movie["alternative_titles"])),
release_date=None, release_date=datetime.strptime(
status=Status.UNKNOWN, movie["release_date"], "%Y-%m-%d"
studio=None, ).date(),
genres=[], status=Status.FINISHED
posters=[], if movie["Status"] == "Released"
thumbnails=[], else Status.PLANNED,
logos=[], studios=list(map(lambda x: x["name"], movie["production_companies"])),
trailers=[], genres=list(map(lambda x: Genre(x["name"]), movie["genres"])),
original_posters=self.get_image(
movie["images"]["posters"],
lambda x: x["iso_639_1"] == search["original_language"],
),
thumbnails=self.get_image(
movie["images"]["backdrops"],
lambda x: x["iso_639_1"] == lng,
),
# TODO: Add external IDs.
# TODO: Add cast information
) )
translation = MovieTranslation( translation = MovieTranslation(
name=movie["title"], name=movie["title"],
keywords=[], tagline=movie["tagline"],
keywords=list(map(lambda x: x["name"], movie["keywords"])),
overview=movie["overview"], overview=movie["overview"],
posters=self.get_image(
movie["images"]["posters"],
lambda x: x["iso_639_1"] == lng,
),
logos=self.get_image(
movie["images"]["logos"],
lambda x: x["iso_639_1"] == lng,
),
trailers=[
f"https://www.youtube.com/watch?v{x['key']}"
for x in movie["videos"]["results"]
if x["type"] == "Trailer" and x["site"] == "YouTube"
],
) )
ret.translations = {lng: translation} ret.translations = {lng: translation}
return ret return ret

View File

@ -1,6 +1,6 @@
import os import os
from dataclasses import asdict, dataclass, field from dataclasses import asdict, dataclass, field
from datetime import datetime from datetime import date
from typing import Optional from typing import Optional
from .genre import Genre from .genre import Genre
@ -10,22 +10,27 @@ from .status import Status
@dataclass @dataclass
class MovieTranslation: class MovieTranslation:
name: str name: str
tagline: Optional[str] = None
keywords: list[str] = field(default_factory=list) keywords: list[str] = field(default_factory=list)
overview: Optional[str] = None 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)
@dataclass @dataclass
class Movie: class Movie:
aliases: list[str] = field(default_factory=list) aliases: list[str] = field(default_factory=list)
release_date: Optional[datetime | int] = None release_date: Optional[date | int] = None
status: Status = Status.UNKNOWN status: Status = Status.UNKNOWN
studio: Optional[int | str] = None studios: list[str] = field(default_factory=list)
genres: list[Genre] = field(default_factory=list) genres: list[Genre] = field(default_factory=list)
posters: list[str] = field(default_factory=list)
thumbnails: list[str] = field(default_factory=list) thumbnails: list[str] = field(default_factory=list)
logos: list[str] = field(default_factory=list) # Original poster in the show's language
trailers: list[str] = field(default_factory=list) original_posters: list[str] = field(default_factory=list)
path: Optional[str] = None path: Optional[str] = None
# TODO: handle staff # TODO: handle staff
@ -39,10 +44,11 @@ class Movie:
return { return {
**asdict(self), **asdict(self),
**asdict(self.translations[default_language]), **asdict(self.translations[default_language]),
"poster": next(iter(self.posters), None), "poster": next(iter(self.original_posters), None),
"thumbnail": next(iter(self.thumbnails), None), "thumbnail": next(iter(self.thumbnails), None),
"logo": next(iter(self.logos), None), "logo": next(iter(self.translations[default_language].logos), None),
"trailer": next(iter(self.trailers), None), "trailer": next(iter(self.translations[default_language].trailers), None),
"studio": next(iter(self.studios), None),
"start_air": self.release_date, "start_air": self.release_date,
"title": self.translations[default_language].name, "title": self.translations[default_language].name,
"isMovie": True, "isMovie": True,