Extract absolute episodes handling to functions

This commit is contained in:
Zoe Roux 2024-01-07 01:45:00 +01:00
parent 8318a87d5d
commit d10eb66542

View File

@ -50,7 +50,6 @@ class TheMovieDatabase(Provider):
10752: Genre.WAR, 10752: Genre.WAR,
37: Genre.WESTERN, 37: Genre.WESTERN,
} }
self.absolute_episode_cache = {}
@property @property
def name(self) -> str: def name(self) -> str:
@ -453,42 +452,21 @@ class TheMovieDatabase(Provider):
# 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.
(_, _) = tvdb_season, tvdb_episode (_, _) = tvdb_season, tvdb_episode
if not show_id in self.absolute_episode_cache: if absolute is not None and (season is None or episode_nbr is None):
await self.get_absolute_order(show_id) (season, episode_nbr) = await self.get_episode_from_absolute(
show_id, absolute
if ( )
absolute is not None
and (season is None or episode_nbr is None)
and show_id in self.absolute_episode_cache
and self.absolute_episode_cache[show_id] is not None
# Using absolute - 1 since the array is 0based (absolute episode 1 is at index 0)
and len(self.absolute_episode_cache[show_id]) >= absolute
):
season = self.absolute_episode_cache[show_id][absolute - 1]["season_number"]
episode_nbr = self.absolute_episode_cache[show_id][absolute - 1][
"episode_number"
]
if season is None or episode_nbr is None: if season is None or episode_nbr is None:
# Some shows don't have absolute numbering because the default one is absolute on tmdb (for example detetive conan) # Some shows don't have absolute numbering because the default one is absolute on tmdb (for example detetive conan)
season = 1 season = 1
episode_nbr = absolute episode_nbr = absolute
if ( if season is None or episode_nbr is None:
absolute is None raise ProviderError("Could not guess season or episode number of the episode %s %d-%d (%d)", name, season, episode_nbr, absolute)
and show_id in self.absolute_episode_cache
and self.absolute_episode_cache[show_id] if absolute is None:
): absolute = await self.get_absolute_number(show_id, season, episode_nbr)
absolute = next(
(
# The + 1 is to go from 0based index to 1based absolute number
i + 1
for i, x in enumerate(self.absolute_episode_cache[show_id])
if x["episode_number"] == episode_nbr
and x["season_number"] == season
),
None,
)
async def for_language(lng: str) -> Episode: async def for_language(lng: str) -> Episode:
episode = await self.get( episode = await self.get(
@ -566,7 +544,15 @@ class TheMovieDatabase(Provider):
return results[0] return results[0]
@cache(ttl=timedelta(days=1))
async def get_absolute_order(self, show_id: str): async def get_absolute_order(self, show_id: str):
"""
TheMovieDb does not allow to fetch an episode by an absolute number but it
support groups where you can list episodes. One type is the absolute group
where everything should be on one season, this method tries to find a complete
absolute-ordered group and return it
"""
try: try:
groups = await self.get(f"tv/{show_id}/episode_groups") groups = await self.get(f"tv/{show_id}/episode_groups")
ep_count = max((x["episode_count"] for x in groups["results"]), default=0) ep_count = max((x["episode_count"] for x in groups["results"]), default=0)
@ -581,16 +567,43 @@ class TheMovieDatabase(Provider):
) )
if group_id is None: if group_id is None:
self.absolute_episode_cache[show_id] = None return None
return
group = await self.get(f"tv/episode_group/{group_id}") group = await self.get(f"tv/episode_group/{group_id}")
grp = next(iter(group["groups"]), None) grp = next(iter(group["groups"]), None)
self.absolute_episode_cache[show_id] = grp["episodes"] if grp else None return grp["episodes"] if grp else None
except Exception as e: except Exception as e:
logging.exception( logging.exception(
"Could not retrieve absolute ordering information", exc_info=e "Could not retrieve absolute ordering information", exc_info=e
) )
async def get_episode_from_absolute(self, show_id: str, absolute: int):
absgrp = await self.get_absolute_order(show_id)
if absgrp is not None and len(absgrp) >= absolute:
# Using absolute - 1 since the array is 0based (absolute episode 1 is at index 0)
season = absgrp[absolute - 1]["season_number"]
episode_nbr = absgrp[absolute - 1]["episode_number"]
return (season, episode_nbr)
# TODO: if no group exist, simulate one by checking each season ep count and substracting the right amount to get an ep
# This means that we assume that each season should be played in order with no special episodes.
return (None, None)
async def get_absolute_number(self, show_id: str, season: int, episode_nbr: int):
absgrp = await self.get_absolute_order(show_id)
if absgrp is None:
# TODO: if no group exist, simulate one by checking each season ep count and adding the right amount to get an ep
# This means that we assume that each season should be played in order with no special episodes.
return None
return next(
(
# The + 1 is to go from 0based index to 1based absolute number
i + 1
for i, x in enumerate(absgrp)
if x["episode_number"] == episode_nbr and x["season_number"] == season
),
None,
)
async def identify_collection( async def identify_collection(
self, provider_id: str, *, language: list[str] self, provider_id: str, *, language: list[str]
) -> Collection: ) -> Collection: