Add xem show overrides

This commit is contained in:
Zoe Roux 2024-01-05 16:43:28 +01:00
parent 813d998bfb
commit 1b140661ba
3 changed files with 50 additions and 8 deletions

View File

@ -1,5 +1,6 @@
import asyncio import asyncio
import logging import logging
from sys import orig_argv
from aiohttp import ClientSession from aiohttp import ClientSession
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Awaitable, Callable, Dict, List, Optional, Any, TypeVar from typing import Awaitable, Callable, Dict, List, Optional, Any, TypeVar
@ -222,6 +223,7 @@ class TheMovieDatabase(Provider):
ret.external_id = await self._idmapper.get_movie(ret.external_id) ret.external_id = await self._idmapper.get_movie(ret.external_id)
return ret return ret
@cache(ttl=timedelta(days=1))
async def identify_show( async def identify_show(
self, self,
show_id: str, show_id: str,
@ -375,12 +377,36 @@ class TheMovieDatabase(Provider):
) )
@cache(ttl=timedelta(days=1)) @cache(ttl=timedelta(days=1))
async def search_show(self, name: str, year: Optional[int]): async def search_show(self, name: str, year: Optional[int]) -> PartialShow:
search_results = ( search_results = (
await self.get("search/tv", params={"query": name, "year": year}) await self.get("search/tv", params={"query": name, "year": year})
)["results"] )["results"]
if len(search_results) == 0: if len(search_results) == 0:
raise ProviderError(f"No result for a tv show named: {name}") (new_name, tvdbid) = await self._xem.get_show_override("tvdb", name)
if new_name is None or tvdbid is None or name.lower() == new_name.lower():
raise ProviderError(f"No result for a tv show named: {name}")
ret = PartialShow(
name=new_name,
original_language=None,
external_id={
"tvdb": MetadataID(tvdbid, link=None),
},
)
ret.external_id = await self._idmapper.get_show(
ret.external_id, required=[self.name]
)
if self.name in ret.external_id:
return ret
logging.warn(
"Could not map xem exception to themoviedb, searching instead for %s",
new_name,
)
nret = await self.search_show(new_name, year)
nret.external_id = {**ret.external_id, **nret.external_id}
return nret
search = self.get_best_result(search_results, name, year) search = self.get_best_result(search_results, name, year)
show_id = search["id"] show_id = search["id"]
return PartialShow( return PartialShow(
@ -393,7 +419,6 @@ class TheMovieDatabase(Provider):
}, },
) )
async def identify_episode( async def identify_episode(
self, self,
name: str, name: str,
@ -405,8 +430,10 @@ class TheMovieDatabase(Provider):
language: list[str], language: list[str],
) -> Episode: ) -> Episode:
show = await self.search_show(name, year) show = await self.search_show(name, year)
if show.original_language not in language: if show.original_language and show.original_language not in language:
language.append(show.original_language) language.append(show.original_language)
# Keep it for xem overrides of season/episode
old_name = name
name = show.name name = show.name
show_id = show.external_id[self.name].data_id show_id = show.external_id[self.name].data_id
@ -414,14 +441,14 @@ class TheMovieDatabase(Provider):
# For example when name is "Jojo's bizzare adventure - Stone Ocean", with season None, # For example when name is "Jojo's bizzare adventure - Stone Ocean", with season None,
# We want something like season 6 ep 3. # We want something like season 6 ep 3.
if season is None and absolute is not None: if season is None and absolute is not None:
ids = await self._idmapper.get_show(show.external_id, required=["tmdbid"]) ids = await self._idmapper.get_show(show.external_id, required=["tvdb"])
if ids["tvdb"] is not None: if ids["tvdb"] is not None:
( (
tvdb_season, tvdb_season,
tvdb_episode, tvdb_episode,
absolute, absolute,
) = await self._xem.get_episode_override( ) = await self._xem.get_episode_override(
"tvdb", ids["tvdb"].data_id, name, absolute "tvdb", ids["tvdb"].data_id, old_name, absolute
) )
# Most of the time, tvdb absolute and tmdb absolute are in think so we use that as our souce of truth. # Most of the time, tvdb absolute and tmdb absolute are in think so we use that as our souce of truth.
# tvdb_season/episode are not in sync with tmdb so we discard those and use our usual absolute order fetching. # tvdb_season/episode are not in sync with tmdb so we discard those and use our usual absolute order fetching.

View File

@ -22,6 +22,7 @@ class TheXem:
params={ params={
"origin": provider, "origin": provider,
"seasonNumbers": 1, # 1 here means true "seasonNumbers": 1, # 1 here means true
"defaultNames": 1,
}, },
) as r: ) as r:
r.raise_for_status() r.raise_for_status()
@ -55,13 +56,27 @@ class TheXem:
raise ProviderError("Could not fetch xem mapping") raise ProviderError("Could not fetch xem mapping")
return ret["data"] return ret["data"]
async def get_show_override(
self, provider: Literal["tvdb"] | Literal["anidb"], show_name: str
):
map = await self.get_map(provider)
for [id, v] in map.items():
# Only the first element is a string (the show name) so we need to ignore the type hint
master_show_name: str = v[0] # type: ignore
for x in v[1:]:
[(name, season)] = x.items()
if show_name.lower() == name.lower():
return master_show_name, id
return None, None
async def get_season_override( async def get_season_override(
self, provider: Literal["tvdb"] | Literal["anidb"], id: str, show_name: str self, provider: Literal["tvdb"] | Literal["anidb"], id: str, show_name: str
): ):
map = await self.get_map(provider) map = await self.get_map(provider)
if id not in map: if id not in map:
return None return None
for x in map[id]: # Ignore the first element, this is the show name has a string
for x in map[id][1:]:
[(name, season)] = x.items() [(name, season)] = x.items()
# TODO: replace .lower() with something a bit smarter # TODO: replace .lower() with something a bit smarter
if show_name.lower() == name.lower(): if show_name.lower() == name.lower():

View File

@ -10,7 +10,7 @@ from .metadataid import MetadataID
@dataclass @dataclass
class PartialShow: class PartialShow:
name: str name: str
original_language: str original_language: Optional[str]
external_id: dict[str, MetadataID] external_id: dict[str, MetadataID]