mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Add tvdb episode identify
This commit is contained in:
parent
1c483fa14f
commit
a6b6067b0b
@ -111,7 +111,7 @@ class Matcher:
|
|||||||
episode = await self._provider.search_episode(
|
episode = await self._provider.search_episode(
|
||||||
title,
|
title,
|
||||||
season=season,
|
season=season,
|
||||||
episode_nbr=episode_nbr,
|
episode_nbr=episode_nbr if season is not None else None,
|
||||||
absolute=episode_nbr if season is None else None,
|
absolute=episode_nbr if season is None else None,
|
||||||
year=year,
|
year=year,
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
from datetime import timedelta
|
import asyncio
|
||||||
|
from datetime import timedelta, datetime
|
||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import Optional, Any
|
from typing import Optional, Any, Literal
|
||||||
|
|
||||||
from matcher.cache import cache
|
from matcher.cache import cache
|
||||||
|
|
||||||
@ -33,6 +34,12 @@ class TVDB(Provider):
|
|||||||
self._pin = pin
|
self._pin = pin
|
||||||
self._languages = languages
|
self._languages = languages
|
||||||
|
|
||||||
|
def two_to_three_lang(self, lang: str) -> str:
|
||||||
|
return lang
|
||||||
|
|
||||||
|
def three_to_two_lang(self, lang: str) -> str:
|
||||||
|
return lang
|
||||||
|
|
||||||
@cache(ttl=timedelta(days=30))
|
@cache(ttl=timedelta(days=30))
|
||||||
async def login(self) -> str:
|
async def login(self) -> str:
|
||||||
async with self._client.post(
|
async with self._client.post(
|
||||||
@ -45,15 +52,16 @@ class TVDB(Provider):
|
|||||||
|
|
||||||
async def get(
|
async def get(
|
||||||
self,
|
self,
|
||||||
path: str,
|
path: Optional[str] = None,
|
||||||
*,
|
*,
|
||||||
|
fullPath: Optional[str] = None,
|
||||||
params: dict[str, Any] = {},
|
params: dict[str, Any] = {},
|
||||||
not_found_fail: Optional[str] = None,
|
not_found_fail: Optional[str] = None,
|
||||||
):
|
):
|
||||||
token = await self.login()
|
token = await self.login()
|
||||||
params = {k: v for k, v in params.items() if v is not None}
|
params = {k: v for k, v in params.items() if v is not None}
|
||||||
async with self._client.get(
|
async with self._client.get(
|
||||||
f"{self.base}/{path}",
|
fullPath or f"{self.base}/{path}",
|
||||||
params={"api_key": self._api_key, **params},
|
params={"api_key": self._api_key, **params},
|
||||||
headers={"Authorization": f"Bearer {token}"},
|
headers={"Authorization": f"Bearer {token}"},
|
||||||
) as r:
|
) as r:
|
||||||
@ -66,6 +74,30 @@ class TVDB(Provider):
|
|||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return "tvdb"
|
return "tvdb"
|
||||||
|
|
||||||
|
async def search_show(self, name: str, year: Optional[int]) -> Show:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@cache(ttl=timedelta(days=1))
|
||||||
|
async def get_episodes(
|
||||||
|
self,
|
||||||
|
show_id: str,
|
||||||
|
order: Literal["default", "absolute"],
|
||||||
|
language: Optional[str] = None,
|
||||||
|
):
|
||||||
|
path = f"/series/{show_id}/episodes/{order}"
|
||||||
|
if language is not None:
|
||||||
|
path += f"/{language}"
|
||||||
|
ret = await self.get(
|
||||||
|
path, not_found_fail=f"Could not find show with id {show_id}"
|
||||||
|
)
|
||||||
|
episodes = ret["data"]["episodes"]
|
||||||
|
next = ret["links"]["next"]
|
||||||
|
while next != None:
|
||||||
|
ret = await self.get(fullPath=next)
|
||||||
|
next = ret["links"]["next"]
|
||||||
|
episodes += ret["data"]
|
||||||
|
return episodes
|
||||||
|
|
||||||
async def search_episode(
|
async def search_episode(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
@ -85,4 +117,77 @@ class TVDB(Provider):
|
|||||||
episode_nbr: Optional[int],
|
episode_nbr: Optional[int],
|
||||||
absolute: Optional[int],
|
absolute: Optional[int],
|
||||||
) -> Episode:
|
) -> Episode:
|
||||||
return await self.get(f"")
|
flang, slang, *olang = [*self._languages, None]
|
||||||
|
episodes = await self.get_episodes(show_id, order="default", language=flang)
|
||||||
|
show = episodes["data"]
|
||||||
|
ret = next(
|
||||||
|
filter(
|
||||||
|
(lambda x: x["seasonNumber"] == 1 and x["number"] == absolute)
|
||||||
|
if absolute is not None
|
||||||
|
else (
|
||||||
|
lambda x: x["seasonNumber"] == season and x["number"] == episode_nbr
|
||||||
|
),
|
||||||
|
episodes["episodes"],
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
if ret == None:
|
||||||
|
raise ProviderError(
|
||||||
|
f"Could not retrive episode {show['name']} s{season}e{episode_nbr}, absolute {absolute}"
|
||||||
|
)
|
||||||
|
absolutes = await self.get_episodes(
|
||||||
|
show_id, order="absolute", language=slang or flang
|
||||||
|
)
|
||||||
|
abs = next(filter(lambda x: x["id"] == ret["id"], absolutes["episodes"]))
|
||||||
|
|
||||||
|
otrans = await asyncio.gather(
|
||||||
|
*(
|
||||||
|
self.get_episodes(show_id, order="default", language=lang)
|
||||||
|
for lang in olang
|
||||||
|
if lang is not None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
translations = {
|
||||||
|
lang: EpisodeTranslation(
|
||||||
|
name=val["name"],
|
||||||
|
overview=val["overview"],
|
||||||
|
)
|
||||||
|
for (lang, val) in zip(
|
||||||
|
self._languages,
|
||||||
|
[
|
||||||
|
ret,
|
||||||
|
abs,
|
||||||
|
*(
|
||||||
|
next(x for x in e["episodes"] if x["id"] == ret["id"])
|
||||||
|
for e in otrans
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Episode(
|
||||||
|
show=PartialShow(
|
||||||
|
name=show["name"],
|
||||||
|
original_language=self.three_to_two_lang(show["originalLanguage"]),
|
||||||
|
external_id={
|
||||||
|
self.name: MetadataID(
|
||||||
|
show_id, f"https://thetvdb.com/series/{show['slug']}"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
season_number=ret["seasonNumber"],
|
||||||
|
episode_number=ret["number"],
|
||||||
|
absolute_number=abs["number"],
|
||||||
|
runtime=ret["runtime"],
|
||||||
|
release_date=datetime.strptime(ret["aired"], "%Y-%m-%d").date(),
|
||||||
|
thumbnail=f"https://artworks.thetvdb.com{ret['image']}",
|
||||||
|
external_id={
|
||||||
|
self.name: EpisodeID(
|
||||||
|
show_id,
|
||||||
|
ret["seasonNumber"],
|
||||||
|
ret["number"],
|
||||||
|
f"https://thetvdb.com/series/{show_id}/episodes/{ret['id']}",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
translations=translations,
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user