mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-04-05 11:47:50 +08:00
Merge pull request #4356 from TimoYoung/v2
This commit is contained in:
@@ -5,6 +5,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app import schemas
|
||||
from app.chain.media import MediaChain
|
||||
from app.chain.tvdb import TvdbChain
|
||||
from app.chain.subscribe import SubscribeChain
|
||||
from app.core.metainfo import MetaInfo
|
||||
from app.core.security import verify_apikey
|
||||
@@ -520,87 +521,87 @@ def arr_series_lookup(term: str, _: Annotated[str, Depends(verify_apikey)], db:
|
||||
"""
|
||||
# 季信息
|
||||
seas: List[int] = []
|
||||
|
||||
# tvdbid 列表
|
||||
tvdbids: List[int] = []
|
||||
# 获取TVDBID
|
||||
if not term.startswith("tvdb:"):
|
||||
mediainfo = MediaChain().recognize_media(meta=MetaInfo(term),
|
||||
mtype=MediaType.TV)
|
||||
if not mediainfo:
|
||||
return [SonarrSeries()]
|
||||
|
||||
# 季信息
|
||||
if mediainfo.seasons:
|
||||
seas = list(mediainfo.seasons)
|
||||
title = term.replace("+", " ")
|
||||
tvdbids = TvdbChain().get_tvdbid_by_name(title=title)
|
||||
else:
|
||||
tvdbid = int(term.replace("tvdb:", ""))
|
||||
tvdbids.append(tvdbid)
|
||||
|
||||
sonarr_series_list = []
|
||||
for tvdbid in tvdbids:
|
||||
# 查询TVDB信息
|
||||
tvdbinfo = MediaChain().tvdb_info(tvdbid=tvdbid)
|
||||
if not tvdbinfo:
|
||||
return [SonarrSeries()]
|
||||
continue
|
||||
|
||||
# 季信息
|
||||
sea_num = tvdbinfo.get('season')
|
||||
# 季信息(只取默认季类型,排除特别季)
|
||||
sea_num = len([season for season in tvdbinfo.get('seasons') if
|
||||
season['type']['id'] == tvdbinfo.get('defaultSeasonType') and season['number'] > 0])
|
||||
if sea_num:
|
||||
seas = list(range(1, int(sea_num) + 1))
|
||||
|
||||
# 根据TVDB查询媒体信息
|
||||
mediainfo = MediaChain().recognize_media(meta=MetaInfo(tvdbinfo.get('seriesName')),
|
||||
mediainfo = MediaChain().recognize_media(meta=MetaInfo(tvdbinfo.get('name')),
|
||||
mtype=MediaType.TV)
|
||||
if not mediainfo:
|
||||
continue
|
||||
# 查询是否存在
|
||||
exists = MediaChain().media_exists(mediainfo)
|
||||
if exists:
|
||||
hasfile = True
|
||||
else:
|
||||
hasfile = False
|
||||
|
||||
# 查询是否存在
|
||||
exists = MediaChain().media_exists(mediainfo)
|
||||
if exists:
|
||||
hasfile = True
|
||||
else:
|
||||
hasfile = False
|
||||
|
||||
# 查询订阅信息
|
||||
seasons: List[dict] = []
|
||||
subscribes = Subscribe.get_by_tmdbid(db, mediainfo.tmdb_id)
|
||||
if subscribes:
|
||||
# 已监控
|
||||
monitored = True
|
||||
# 已监控季
|
||||
sub_seas = [sub.season for sub in subscribes]
|
||||
for sea in seas:
|
||||
if sea in sub_seas:
|
||||
seasons.append({
|
||||
"seasonNumber": sea,
|
||||
"monitored": True,
|
||||
})
|
||||
else:
|
||||
# 查询订阅信息
|
||||
seasons: List[dict] = []
|
||||
subscribes = Subscribe.get_by_tmdbid(db, mediainfo.tmdb_id)
|
||||
if subscribes:
|
||||
# 已监控
|
||||
monitored = True
|
||||
# 已监控季
|
||||
sub_seas = [sub.season for sub in subscribes]
|
||||
for sea in seas:
|
||||
if sea in sub_seas:
|
||||
seasons.append({
|
||||
"seasonNumber": sea,
|
||||
"monitored": True,
|
||||
})
|
||||
else:
|
||||
seasons.append({
|
||||
"seasonNumber": sea,
|
||||
"monitored": False,
|
||||
})
|
||||
subid = subscribes[-1].id
|
||||
else:
|
||||
subid = None
|
||||
monitored = False
|
||||
for sea in seas:
|
||||
seasons.append({
|
||||
"seasonNumber": sea,
|
||||
"monitored": False,
|
||||
})
|
||||
subid = subscribes[-1].id
|
||||
else:
|
||||
subid = None
|
||||
monitored = False
|
||||
for sea in seas:
|
||||
seasons.append({
|
||||
"seasonNumber": sea,
|
||||
"monitored": False,
|
||||
})
|
||||
sonarr_series = SonarrSeries(
|
||||
id=subid,
|
||||
title=mediainfo.title,
|
||||
seasonCount=len(seasons),
|
||||
seasons=seasons,
|
||||
remotePoster=mediainfo.get_poster_image(),
|
||||
year=mediainfo.year,
|
||||
tmdbId=mediainfo.tmdb_id,
|
||||
tvdbId=tvdbid,
|
||||
imdbId=mediainfo.imdb_id,
|
||||
profileId=1,
|
||||
languageProfileId=1,
|
||||
monitored=monitored,
|
||||
hasFile=hasfile,
|
||||
)
|
||||
sonarr_series_list.append(sonarr_series)
|
||||
|
||||
return [SonarrSeries(
|
||||
id=subid,
|
||||
title=mediainfo.title,
|
||||
seasonCount=len(seasons),
|
||||
seasons=seasons,
|
||||
remotePoster=mediainfo.get_poster_image(),
|
||||
year=mediainfo.year,
|
||||
tmdbId=mediainfo.tmdb_id,
|
||||
tvdbId=mediainfo.tvdb_id,
|
||||
imdbId=mediainfo.imdb_id,
|
||||
profileId=1,
|
||||
languageProfileId=1,
|
||||
qualityProfileId=1,
|
||||
isAvailable=True,
|
||||
monitored=monitored,
|
||||
hasFile=hasfile
|
||||
)]
|
||||
return sonarr_series_list if sonarr_series_list else [SonarrSeries()]
|
||||
|
||||
|
||||
@arr_router.get("/series/{tid}", summary="剧集详情")
|
||||
|
||||
13
app/chain/tvdb.py
Normal file
13
app/chain/tvdb.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from typing import List
|
||||
from app.chain import ChainBase
|
||||
from app.utils.singleton import Singleton
|
||||
|
||||
|
||||
class TvdbChain(ChainBase, metaclass=Singleton):
|
||||
"""
|
||||
Tvdb处理链,单例运行
|
||||
"""
|
||||
|
||||
def get_tvdbid_by_name(self, title: str) -> List[int]:
|
||||
tvdb_info_list = self.run_module("search_tvdb", title=title)
|
||||
return [int(item["tvdb_id"]) for item in tvdb_info_list]
|
||||
@@ -111,7 +111,8 @@ class ConfigModel(BaseModel):
|
||||
# TMDB API Key
|
||||
TMDB_API_KEY: str = "db55323b8d3e4154498498a75642b381"
|
||||
# TVDB API Key
|
||||
TVDB_API_KEY: str = "6b481081-10aa-440c-99f2-21d17717ee02"
|
||||
TVDB_V4_API_KEY: str = "ed2aa66b-7899-4677-92a7-67bc9ce3d93a"
|
||||
TVDB_V4_API_PIN: str = ""
|
||||
# Fanart开关
|
||||
FANART_ENABLE: bool = True
|
||||
# Fanart API Key
|
||||
|
||||
@@ -3,19 +3,45 @@ from typing import Optional, Tuple, Union
|
||||
from app.core.config import settings
|
||||
from app.log import logger
|
||||
from app.modules import _ModuleBase
|
||||
from app.modules.thetvdb import tvdbapi
|
||||
from app.modules.thetvdb import tvdb_v4_official
|
||||
from app.schemas.types import ModuleType, MediaRecognizeType
|
||||
from app.utils.http import RequestUtils
|
||||
|
||||
|
||||
class TheTvDbModule(_ModuleBase):
|
||||
tvdb: tvdbapi.Tvdb = None
|
||||
tvdb: tvdb_v4_official.TVDB = None
|
||||
|
||||
def init_module(self) -> None:
|
||||
self.tvdb = tvdbapi.Tvdb(apikey=settings.TVDB_API_KEY,
|
||||
cache=False,
|
||||
select_first=True,
|
||||
proxies=settings.PROXY)
|
||||
self._initialize_tvdb_session()
|
||||
|
||||
def _initialize_tvdb_session(self) -> None:
|
||||
"""
|
||||
创建或刷新 TVDB 登录会话
|
||||
"""
|
||||
try:
|
||||
self.tvdb = tvdb_v4_official.TVDB(apikey=settings.TVDB_V4_API_KEY, pin=settings.TVDB_V4_API_PIN)
|
||||
except Exception as e:
|
||||
logger.error(f"TVDB 登录失败: {str(e)}")
|
||||
|
||||
def _handle_tvdb_call(self, func, *args, **kwargs):
|
||||
"""
|
||||
包裹 TVDB 调用,处理 token 失效情况并尝试重新初始化
|
||||
"""
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except ValueError as e:
|
||||
# 检查错误信息中是否包含 token 失效相关描述
|
||||
if "Unauthorized" in str(e):
|
||||
logger.warning("TVDB Token 可能已失效,正在尝试重新登录...")
|
||||
self._initialize_tvdb_session()
|
||||
return func(*args, **kwargs)
|
||||
elif "NotFoundException" in str(e):
|
||||
logger.warning("TVDB 剧集不存在")
|
||||
return None
|
||||
else:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"TVDB 调用出错: {str(e)}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def get_name() -> str:
|
||||
@@ -43,18 +69,17 @@ class TheTvDbModule(_ModuleBase):
|
||||
return 4
|
||||
|
||||
def stop(self):
|
||||
self.tvdb.close()
|
||||
pass
|
||||
|
||||
def test(self) -> Tuple[bool, str]:
|
||||
"""
|
||||
测试模块连接性
|
||||
"""
|
||||
ret = RequestUtils(proxies=settings.PROXY).get_res("https://api.thetvdb.com/series/81189")
|
||||
if ret and ret.status_code == 200:
|
||||
try:
|
||||
self._handle_tvdb_call(self.tvdb.get_series, 81189)
|
||||
return True, ""
|
||||
elif ret:
|
||||
return False, f"无法连接 api.thetvdb.com,错误码:{ret.status_code}"
|
||||
return False, "api.thetvdb.com 网络连接失败"
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||
pass
|
||||
@@ -67,6 +92,21 @@ class TheTvDbModule(_ModuleBase):
|
||||
"""
|
||||
try:
|
||||
logger.info(f"开始获取TVDB信息: {tvdbid} ...")
|
||||
return self.tvdb[tvdbid].data
|
||||
return self._handle_tvdb_call(self.tvdb.get_series_extended, tvdbid)
|
||||
except Exception as err:
|
||||
logger.error(f"获取TVDB信息失败: {str(err)}")
|
||||
return None
|
||||
|
||||
def search_tvdb(self, title: str) -> list:
|
||||
"""
|
||||
用标题搜索TVDB剧集
|
||||
:param title: 标题
|
||||
:return: TVDB信息
|
||||
"""
|
||||
try:
|
||||
logger.info(f"开始用标题搜索TVDB剧集: {title} ...")
|
||||
res = self._handle_tvdb_call(self.tvdb.search, title)
|
||||
return [item for item in res if item.get("type") == "series"]
|
||||
except Exception as err:
|
||||
logger.error(f"用标题搜索TVDB剧集失败: {str(err)}")
|
||||
return []
|
||||
|
||||
465
app/modules/thetvdb/tvdb_v4_official.py
Normal file
465
app/modules/thetvdb/tvdb_v4_official.py
Normal file
@@ -0,0 +1,465 @@
|
||||
"""Official python package for using the tvdb v4 api"""
|
||||
|
||||
__author__ = "Weylin Wagnon"
|
||||
__version__ = "1.0.12"
|
||||
|
||||
import json
|
||||
import string
|
||||
import urllib
|
||||
import urllib.request
|
||||
from http import HTTPStatus
|
||||
from urllib.error import HTTPError
|
||||
|
||||
|
||||
class Auth:
|
||||
def __init__(self, url, apikey, pin=""):
|
||||
loginInfo = {"apikey": apikey}
|
||||
if pin != "":
|
||||
loginInfo["pin"] = pin
|
||||
|
||||
loginInfoBytes = json.dumps(loginInfo, indent=2).encode("utf-8")
|
||||
req = urllib.request.Request(url, data=loginInfoBytes)
|
||||
req.add_header("Content-Type", "application/json")
|
||||
try:
|
||||
with urllib.request.urlopen(req, data=loginInfoBytes) as response:
|
||||
res = json.load(response)
|
||||
self.token = res["data"]["token"]
|
||||
except HTTPError as e:
|
||||
res = json.load(e)
|
||||
raise Exception("Code:{}, {}".format(e, res["message"]))
|
||||
|
||||
def get_token(self):
|
||||
return self.token
|
||||
|
||||
|
||||
class Request:
|
||||
def __init__(self, auth_token):
|
||||
self.auth_token = auth_token
|
||||
self.links = None
|
||||
|
||||
def make_request(self, url, if_modified_since=None):
|
||||
req = urllib.request.Request(url)
|
||||
req.add_header("Authorization", "Bearer {}".format(self.auth_token))
|
||||
if if_modified_since:
|
||||
req.add_header("If-Modified-Since", "{}".format(if_modified_since))
|
||||
try:
|
||||
with urllib.request.urlopen(req) as response:
|
||||
res = json.load(response)
|
||||
except HTTPError as e:
|
||||
try:
|
||||
if e.code == HTTPStatus.NOT_MODIFIED:
|
||||
return {
|
||||
"code": HTTPStatus.NOT_MODIFIED.real,
|
||||
"message": "Not-Modified",
|
||||
}
|
||||
res = json.load(e)
|
||||
except:
|
||||
res = {}
|
||||
data = res.get("data", None)
|
||||
if data is not None and res.get("status", "failure") != "failure":
|
||||
self.links = res.get("links", None)
|
||||
return data
|
||||
msg = res.get("message", None)
|
||||
if not msg:
|
||||
msg = "UNKNOWN FAILURE"
|
||||
raise ValueError("failed to get " + url + "\n " + str(msg))
|
||||
|
||||
|
||||
class Url:
|
||||
def __init__(self):
|
||||
self.base_url = "https://api4.thetvdb.com/v4/"
|
||||
|
||||
def construct(
|
||||
self, url_sect, url_id=None, url_subsect=None, url_lang=None, **query
|
||||
):
|
||||
url = self.base_url + url_sect
|
||||
if url_id:
|
||||
url += "/" + str(url_id)
|
||||
if url_subsect:
|
||||
url += "/" + url_subsect
|
||||
if url_lang:
|
||||
url += "/" + url_lang
|
||||
if query:
|
||||
query = {var: val for var, val in query.items() if val is not None}
|
||||
if query:
|
||||
url += "?" + urllib.parse.urlencode(query)
|
||||
return url
|
||||
|
||||
|
||||
class TVDB:
|
||||
def __init__(self, apikey: str, pin=""):
|
||||
self.url = Url()
|
||||
login_url = self.url.construct("login")
|
||||
self.auth = Auth(login_url, apikey, pin)
|
||||
auth_token = self.auth.get_token()
|
||||
self.request = Request(auth_token)
|
||||
|
||||
def get_req_links(self) -> dict:
|
||||
return self.request.links
|
||||
|
||||
def get_artwork_statuses(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of artwork statuses"""
|
||||
url = self.url.construct("artwork/statuses", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_artwork_types(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of artwork types"""
|
||||
url = self.url.construct("artwork/types", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_artwork(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns an artwork dictionary"""
|
||||
url = self.url.construct("artwork", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_artwork_extended(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns an artwork extended dictionary"""
|
||||
url = self.url.construct("artwork", id, "extended", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_awards(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of awards"""
|
||||
url = self.url.construct("awards", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_award(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns an award dictionary"""
|
||||
url = self.url.construct("awards", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_award_extended(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns an award extended dictionary"""
|
||||
url = self.url.construct("awards", id, "extended", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_award_categories(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of award categories"""
|
||||
url = self.url.construct("awards/categories", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_award_category(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns an award category dictionary"""
|
||||
url = self.url.construct("awards/categories", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_award_category_extended(
|
||||
self, id: int, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns an award category extended dictionary"""
|
||||
url = self.url.construct("awards/categories", id, "extended", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_content_ratings(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of content ratings"""
|
||||
url = self.url.construct("content/ratings", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_countries(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of countries"""
|
||||
url = self.url.construct("countries", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_companies(self, page=None, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of companies"""
|
||||
url = self.url.construct("companies", page=page, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_company_types(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of company types"""
|
||||
url = self.url.construct("companies/types", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_company(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a company dictionary"""
|
||||
url = self.url.construct("companies", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_series(self, page=None, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of series"""
|
||||
url = self.url.construct("series", page=page, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_series(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a series dictionary"""
|
||||
url = self.url.construct("series", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_series_by_slug(
|
||||
self, slug: string, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a series dictionary"""
|
||||
url = self.url.construct("series/slug", slug, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_series_extended(
|
||||
self, id: int, meta=None, short=False, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a series extended dictionary"""
|
||||
url = self.url.construct("series", id, "extended", meta=meta, short=short)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_series_episodes(
|
||||
self,
|
||||
id: int,
|
||||
season_type: str = "default",
|
||||
page: int = 0,
|
||||
lang: str = None,
|
||||
meta=None,
|
||||
if_modified_since=None,
|
||||
**kwargs
|
||||
) -> dict:
|
||||
"""Returns a series episodes dictionary"""
|
||||
url = self.url.construct(
|
||||
"series", id, "episodes/" + season_type, lang, page=page, meta=meta, **kwargs
|
||||
)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_series_translation(
|
||||
self, id: int, lang: str, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a series translation dictionary"""
|
||||
url = self.url.construct("series", id, "translations", lang, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_series_artworks(
|
||||
self, id: int, lang: str, type=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a series record with an artwork array"""
|
||||
url = self.url.construct("series", id, "artworks", lang=lang, type=type)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_series_nextAired(self, id: int, if_modified_since=None) -> dict:
|
||||
"""Returns a series extended dictionary"""
|
||||
url = self.url.construct("series", id, "nextAired")
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_movies(self, page=None, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of movies"""
|
||||
url = self.url.construct("movies", page=page, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_movie(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a movie dictionary"""
|
||||
url = self.url.construct("movies", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_movie_by_slug(
|
||||
self, slug: string, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a movie dictionary"""
|
||||
url = self.url.construct("movies/slug", slug, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_movie_extended(
|
||||
self, id: int, meta=None, short=False, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a movie extended dictionary"""
|
||||
url = self.url.construct("movies", id, "extended", meta=meta, short=short)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_movie_translation(
|
||||
self, id: int, lang: str, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a movie translation dictionary"""
|
||||
url = self.url.construct("movies", id, "translations", lang, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_seasons(self, page=None, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of seasons"""
|
||||
url = self.url.construct("seasons", page=page, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_season(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a season dictionary"""
|
||||
url = self.url.construct("seasons", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_season_extended(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a season extended dictionary"""
|
||||
url = self.url.construct("seasons", id, "extended", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_season_types(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of season types"""
|
||||
url = self.url.construct("seasons/types", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_season_translation(
|
||||
self, id: int, lang: str, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns a seasons translation dictionary"""
|
||||
url = self.url.construct("seasons", id, "translations", lang, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_episodes(self, page=None, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of episodes"""
|
||||
url = self.url.construct("episodes", page=page, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_episode(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns an episode dictionary"""
|
||||
url = self.url.construct("episodes", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_episode_extended(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns an episode extended dictionary"""
|
||||
url = self.url.construct("episodes", id, "extended", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_episode_translation(
|
||||
self, id: int, lang: str, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns an episode translation dictionary"""
|
||||
url = self.url.construct("episodes", id, "translations", lang, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
get_episodes_translation = (
|
||||
get_episode_translation # Support the old name of the function.
|
||||
)
|
||||
|
||||
def get_all_genders(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of genders"""
|
||||
url = self.url.construct("genders", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_genres(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of genres"""
|
||||
url = self.url.construct("genres", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_genre(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a genres dictionary"""
|
||||
url = self.url.construct("genres", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_languages(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of languages"""
|
||||
url = self.url.construct("languages", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_people(self, page=None, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of people"""
|
||||
url = self.url.construct("people", page=page, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_person(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a people dictionary"""
|
||||
url = self.url.construct("people", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_person_extended(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a people extended dictionary"""
|
||||
url = self.url.construct("people", id, "extended", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_person_translation(
|
||||
self, id: int, lang: str, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns an people translation dictionary"""
|
||||
url = self.url.construct("people", id, "translations", lang, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_character(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a character dictionary"""
|
||||
url = self.url.construct("characters", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_people_types(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of people types"""
|
||||
url = self.url.construct("people/types", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
get_all_people_types = get_people_types # Support the old function name
|
||||
|
||||
def get_source_types(self, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of source types"""
|
||||
url = self.url.construct("sources/types", meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
get_all_sourcetypes = get_source_types # Support the old function name
|
||||
|
||||
# kwargs accepts args such as: page=2, action='update', type='artwork'
|
||||
def get_updates(self, since: int, **kwargs) -> list:
|
||||
"""Returns a list of updates"""
|
||||
url = self.url.construct("updates", since=since, **kwargs)
|
||||
return self.request.make_request(url)
|
||||
|
||||
def get_all_tag_options(self, page=None, meta=None, if_modified_since=None) -> list:
|
||||
"""Returns a list of tag options"""
|
||||
url = self.url.construct("tags/options", page=page, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_tag_option(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a tag option dictionary"""
|
||||
url = self.url.construct("tags/options", id, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_all_lists(self, page=None, meta=None) -> dict:
|
||||
url = self.url.construct("lists", page=page, meta=meta)
|
||||
return self.request.make_request(url)
|
||||
|
||||
def get_list(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
url = self.url.construct("lists", id, meta=meta)
|
||||
return self.request.make_request(url), if_modified_since
|
||||
|
||||
def get_list_by_slug(self, slug: string, meta=None, if_modified_since=None) -> dict:
|
||||
"""Returns a movie dictionary"""
|
||||
url = self.url.construct("lists/slug", slug, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_list_extended(self, id: int, meta=None, if_modified_since=None) -> dict:
|
||||
url = self.url.construct("lists", id, "extended", meta=meta)
|
||||
return self.request.make_request(url), if_modified_since
|
||||
|
||||
def get_list_translation(
|
||||
self, id: int, lang: str, meta=None, if_modified_since=None
|
||||
) -> dict:
|
||||
"""Returns an list translation dictionary"""
|
||||
url = self.url.construct("lists", id, "translations", lang, meta=meta)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_inspiration_types(self, meta=None, if_modified_since=None) -> dict:
|
||||
url = self.url.construct("inspiration/types", meta=meta)
|
||||
return self.request.make_request(url), if_modified_since
|
||||
|
||||
def search(self, query, **kwargs) -> list:
|
||||
"""Returns a list of search results"""
|
||||
url = self.url.construct("search", query=query, **kwargs)
|
||||
return self.request.make_request(url)
|
||||
|
||||
def search_by_remote_id(self, remoteid: str) -> list:
|
||||
"""Returns a list of search results by remote id exact match"""
|
||||
url = self.url.construct("search/remoteid", remoteid)
|
||||
return self.request.make_request(url)
|
||||
|
||||
def get_tags(self, slug: str, if_modified_since=None) -> dict:
|
||||
"""Returns a tag option dictionary"""
|
||||
url = self.url.construct("entities", url_subsect=slug)
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_entities_types(self, if_modified_since=None) -> dict:
|
||||
"""Returns a entities types dictionary"""
|
||||
url = self.url.construct("entities")
|
||||
return self.request.make_request(url, if_modified_since)
|
||||
|
||||
def get_user_by_id(self, id: int) -> dict:
|
||||
"""Returns a user info dictionary"""
|
||||
url = self.url.construct("user", id)
|
||||
return self.request.make_request(url)
|
||||
|
||||
def get_user(self) -> dict:
|
||||
"""Returns a user info dictionary"""
|
||||
url = self.url.construct("user")
|
||||
return self.request.make_request(url)
|
||||
|
||||
def get_user_favorites(self) -> dict:
|
||||
"""Returns a user info dictionary"""
|
||||
url = self.url.construct('user/favorites')
|
||||
return self.request.make_request(url)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tvdb = TVDB("ed2aa66b-7899-4677-92a7-67bc9ce3d93a")
|
||||
query = "romance in the alley"
|
||||
res = tvdb.search(query)
|
||||
print(res)
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user