mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-08 10:44:20 -04:00
Fix scanning with partial absolute groups on tmdb (#459)
This commit is contained in:
commit
c52d818a1d
@ -197,6 +197,11 @@ class Matcher:
|
|||||||
kind: Literal["collection", "movie", "episode", "show", "season"],
|
kind: Literal["collection", "movie", "episode", "show", "season"],
|
||||||
kyoo_id: str,
|
kyoo_id: str,
|
||||||
):
|
):
|
||||||
|
async def id_movie(movie: dict, id: dict):
|
||||||
|
ret = await self._provider.identify_movie(id["dataId"])
|
||||||
|
ret.path = movie["path"]
|
||||||
|
return ret
|
||||||
|
|
||||||
async def id_season(season: dict, id: dict):
|
async def id_season(season: dict, id: dict):
|
||||||
ret = await self._provider.identify_season(
|
ret = await self._provider.identify_season(
|
||||||
id["dataId"], season["seasonNumber"]
|
id["dataId"], season["seasonNumber"]
|
||||||
@ -217,7 +222,7 @@ class Matcher:
|
|||||||
"collection": lambda _, id: self._provider.identify_collection(
|
"collection": lambda _, id: self._provider.identify_collection(
|
||||||
id["dataId"]
|
id["dataId"]
|
||||||
),
|
),
|
||||||
"movie": lambda _, id: self._provider.identify_movie(id["dataId"]),
|
"movie": id_movie,
|
||||||
"show": lambda _, id: self._provider.identify_show(id["dataId"]),
|
"show": lambda _, id: self._provider.identify_show(id["dataId"]),
|
||||||
"season": id_season,
|
"season": id_season,
|
||||||
"episode": id_episode,
|
"episode": id_episode,
|
||||||
|
@ -157,7 +157,7 @@ class TitleNumberFixup(Rule):
|
|||||||
def when(self, matches: Matches, context) -> Any:
|
def when(self, matches: Matches, context) -> Any:
|
||||||
episodes: List[Match] = matches.named("episode") # type: ignore
|
episodes: List[Match] = matches.named("episode") # type: ignore
|
||||||
|
|
||||||
if len(episodes) < 2:
|
if len(episodes) < 2 or all(x.value == episodes[0].value for x in episodes):
|
||||||
return
|
return
|
||||||
|
|
||||||
to_remove = []
|
to_remove = []
|
||||||
@ -169,24 +169,25 @@ class TitleNumberFixup(Rule):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# do not fixup if there was a - or any separator between the title and the episode number
|
# do not fixup if there was a - or any separator between the title and the episode number
|
||||||
holes = matches.holes(title.end, episode.start)
|
holes: List[Match] = matches.holes(title.end, episode.start) # type: ignore
|
||||||
if holes:
|
if holes:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
to_remove.extend([title, episode])
|
to_remove.extend([title, episode])
|
||||||
new_title = copy(title)
|
new_title = copy(title)
|
||||||
new_title.end = episode.end
|
new_title.end = episode.end
|
||||||
new_title.value = f"{title.value} {episode.value}"
|
|
||||||
|
|
||||||
# If an hole was created to parse the episode at the current pos, merge it back into the title
|
nmatch: List[Match] = matches.next(episode) # type: ignore
|
||||||
holes = matches.holes(episode.end)
|
if nmatch:
|
||||||
if holes and holes[0].start == episode.end:
|
end = (
|
||||||
val: str = holes[0].value
|
nmatch[0].initiator.start
|
||||||
if "-" in val:
|
if isinstance(nmatch[0].initiator, Match)
|
||||||
val, *_ = val.split("-")
|
else nmatch[0].start
|
||||||
val = val.rstrip()
|
)
|
||||||
new_title.value = f"{new_title.value}{val}"
|
# If an hole was created to parse the episode at the current pos, merge it back into the title
|
||||||
new_title.end += len(val)
|
holes: List[Match] = matches.holes(start=episode.end, end=end) # type: ignore
|
||||||
|
if holes and holes[0].start == episode.end:
|
||||||
|
new_title.end = holes[0].end
|
||||||
|
|
||||||
to_add.append(new_title)
|
to_add.append(new_title)
|
||||||
return [to_remove, to_add]
|
return [to_remove, to_add]
|
||||||
@ -357,7 +358,9 @@ class SeasonYearDedup(Rule):
|
|||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
priority = POST_PROCESS
|
# This rules does the opposite of the YearSeason rule of guessit (with POST_PROCESS priority)
|
||||||
|
# To overide it, we need the -1. (rule: https://github.com/guessit-io/guessit/blob/develop/guessit/rules/processors.py#L195)
|
||||||
|
priority = POST_PROCESS - 1
|
||||||
consequence = [RemoveMatch]
|
consequence = [RemoveMatch]
|
||||||
|
|
||||||
def when(self, matches: Matches, context) -> Any:
|
def when(self, matches: Matches, context) -> Any:
|
||||||
|
@ -559,6 +559,7 @@ class TheMovieDatabase(Provider):
|
|||||||
absolute-ordered group and return it
|
absolute-ordered group and return it
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
show = await self.identify_show(show_id)
|
||||||
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)
|
||||||
@ -577,7 +578,22 @@ class TheMovieDatabase(Provider):
|
|||||||
if group_id is None:
|
if group_id is None:
|
||||||
return None
|
return None
|
||||||
group = await self.get(f"tv/episode_group/{group_id}")
|
group = await self.get(f"tv/episode_group/{group_id}")
|
||||||
return [ep for grp in group["groups"] for ep in grp["episodes"]]
|
absgrp = [ep for grp in group["groups"] for ep in grp["episodes"]]
|
||||||
|
logger.warn(
|
||||||
|
f"Incomplete absolute group for show {show_id}. Filling missing values by assuming season/episode order is ascending"
|
||||||
|
)
|
||||||
|
complete_abs = absgrp + [
|
||||||
|
{"season_number": s.season_number, "episode_number": e}
|
||||||
|
for s in show.seasons
|
||||||
|
# ignore specials not specified in the absgrp
|
||||||
|
if s.season_number > 0
|
||||||
|
for e in range(1, s.episodes_count)
|
||||||
|
if not any(
|
||||||
|
x["season_number"] == s.season_number and x["episode_number"] == e
|
||||||
|
for x in absgrp
|
||||||
|
)
|
||||||
|
]
|
||||||
|
return complete_abs
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(
|
logger.exception(
|
||||||
"Could not retrieve absolute ordering information", exc_info=e
|
"Could not retrieve absolute ordering information", exc_info=e
|
||||||
@ -642,17 +658,17 @@ class TheMovieDatabase(Provider):
|
|||||||
if absolute is not None:
|
if absolute is not None:
|
||||||
return absolute
|
return absolute
|
||||||
# assume we use tmdb weird absolute by default (for example, One Piece S21E800, the first
|
# assume we use tmdb weird absolute by default (for example, One Piece S21E800, the first
|
||||||
# episode of S21 si not reset to 0 but keep increasing so it can be 800
|
# episode of S21 is not reset to 0 but keep increasing so it can be 800
|
||||||
start = next(
|
start = next(
|
||||||
(x["episode_number"] for x in absgrp if x["season_number"] == season), None
|
(x["episode_number"] for x in absgrp if x["season_number"] == season), None
|
||||||
)
|
)
|
||||||
if start is None or start <= episode_nbr:
|
if start is not None and start <= episode_nbr:
|
||||||
raise ProviderError(
|
# add back the continuous number (imagine the user has one piece S21e31
|
||||||
f"Could not guess absolute number of episode {show_id} s{season} e{episode_nbr}"
|
# but tmdb registered it as S21E831 since S21's first ep is 800
|
||||||
)
|
return await self.get_absolute_number(show_id, season, episode_nbr + start)
|
||||||
# add back the continuous number (imagine the user has one piece S21e31
|
raise ProviderError(
|
||||||
# but tmdb registered it as S21E831 since S21's first ep is 800
|
f"Could not guess absolute number of episode {show_id} s{season} e{episode_nbr}"
|
||||||
return await self.get_absolute_number(show_id, season, episode_nbr + start)
|
)
|
||||||
|
|
||||||
async def identify_collection(self, provider_id: str) -> Collection:
|
async def identify_collection(self, provider_id: str) -> Collection:
|
||||||
languages = self.get_languages()
|
languages = self.get_languages()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user