Use xem mapping to retrive back episode number/season number

This commit is contained in:
Zoe Roux 2024-01-05 03:27:17 +01:00
parent d063bd479c
commit 5d7fc1ca0c
2 changed files with 60 additions and 6 deletions

View File

@ -384,8 +384,11 @@ class TheMovieDatabase(Provider):
if search["original_language"] not in language:
language.append(search["original_language"])
if season is None:
season = await self._xem.get_season_override("tvdb", tvdbid, name)
# Handle weird season names overrides from thexem.
# For example when name is "Jojo's bizzare adventure - Stone Ocean", with season None,
# We want something like season 6 ep 3.
if season is None and absolute is not None:
(season, episode, absolute) = await self._xem.get_episode_override("tvdb", tvdbid, name, absolute)
if not show_id in self.absolute_episode_cache:
await self.get_absolute_order(show_id)

View File

@ -1,11 +1,9 @@
import asyncio
import logging
from typing import Dict, List, Literal, Tuple
from typing import Dict, List, Literal
from aiohttp import ClientSession
from datetime import timedelta, datetime
from functools import wraps
from providers.types.episode import Episode
from providers.utils import ProviderError
@ -47,12 +45,36 @@ class TheXem:
},
) as r:
r.raise_for_status()
ret = (await r.json())
ret = await r.json()
if "data" not in ret or ret["result"] == "failure":
logging.error("Could not fetch xem metadata. Error: %s", ret["message"])
raise ProviderError("Could not fetch xem metadata")
return ret["data"]
@cache(ttl=timedelta(days=1))
async def get_show_map(
self, provider: Literal["tvdb"] | Literal["anidb"], id: str
) -> List[
Dict[
Literal["scene"] | Literal["tvdb"] | Literal["anidb"],
Dict[Literal["season"] | Literal["episode"] | Literal["absolute"], int],
]
]:
logging.info("Fetching from thexem the map of %s (%s)", id, provider)
async with self._client.get(
f"{self.base}/map/all",
params={
"id": id,
"origin": provider,
},
) as r:
r.raise_for_status()
ret = await r.json()
if "data" not in ret or ret["result"] == "failure":
logging.error("Could not fetch xem mapping. Error: %s", ret["message"])
raise ProviderError("Could not fetch xem mapping")
return ret["data"]
async def get_season_override(
self, provider: Literal["tvdb"] | Literal["anidb"], id: str, show_name: str
):
@ -65,3 +87,32 @@ class TheXem:
if show_name.lower() == name.lower():
return season
return None
async def get_episode_override(
self,
provider: Literal["tvdb"] | Literal["anidb"],
id: str,
show_name: str,
episode: int,
):
master_season = await self.get_season_override(provider, id, show_name)
# master season is not always a direct translation with a tvdb season, we need to translate that back
map = await self.get_show_map(provider, id)
ep = next(
(
x
for x in map
if x["scene"]["season"] == master_season
and x["scene"]["episode"] == episode
),
None,
)
if ep is None:
logging.warning(
"Could not get xem mapping for show %s, falling back to identifier mapping.",
show_name,
)
return [master_season, episode, None]
# Only tvdb has a proper absolute handling so we always use this one.
return (ep[provider]["season"], ep[provider]["episode"], ep["tvdb"]["absolute"])