feat:tvdb模块重写,更换tvdbv4 api,增加搜索能力

sonarr /series/lookup接口重写,直接用标题在tvdb查询剧集
This commit is contained in:
TimoYoung
2025-05-27 17:32:25 +08:00
parent f740fed5f2
commit fc96cfe8a0
6 changed files with 592 additions and 1183 deletions
+62 -61
View File
@@ -5,6 +5,7 @@ from sqlalchemy.orm import Session
from app import schemas from app import schemas
from app.chain.media import MediaChain from app.chain.media import MediaChain
from app.chain.tvdb import TvdbChain
from app.chain.subscribe import SubscribeChain from app.chain.subscribe import SubscribeChain
from app.core.metainfo import MetaInfo from app.core.metainfo import MetaInfo
from app.core.security import verify_apikey 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] = [] seas: List[int] = []
# tvdbid 列表
tvdbids: List[int] = []
# 获取TVDBID # 获取TVDBID
if not term.startswith("tvdb:"): if not term.startswith("tvdb:"):
mediainfo = MediaChain().recognize_media(meta=MetaInfo(term), title = term.replace("+", " ")
mtype=MediaType.TV) tvdbids = TvdbChain().get_tvdbid_by_name(title=title)
if not mediainfo:
return [SonarrSeries()]
# 季信息
if mediainfo.seasons:
seas = list(mediainfo.seasons)
else: else:
tvdbid = int(term.replace("tvdb:", "")) tvdbid = int(term.replace("tvdb:", ""))
tvdbids.append(tvdbid)
sonarr_series_list = []
for tvdbid in tvdbids:
# 查询TVDB信息 # 查询TVDB信息
tvdbinfo = MediaChain().tvdb_info(tvdbid=tvdbid) tvdbinfo = MediaChain().tvdb_info(tvdbid=tvdbid)
if not tvdbinfo: 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: if sea_num:
seas = list(range(1, int(sea_num) + 1)) seas = list(range(1, int(sea_num) + 1))
# 根据TVDB查询媒体信息 # 根据TVDB查询媒体信息
mediainfo = MediaChain().recognize_media(meta=MetaInfo(tvdbinfo.get('seriesName')), mediainfo = MediaChain().recognize_media(meta=MetaInfo(tvdbinfo.get('name')),
mtype=MediaType.TV) mtype=MediaType.TV)
if not mediainfo:
continue
# 查询是否存在
exists = MediaChain().media_exists(mediainfo)
if exists:
hasfile = True
else:
hasfile = False
# 查询是否存在 # 查询订阅信息
exists = MediaChain().media_exists(mediainfo) seasons: List[dict] = []
if exists: subscribes = Subscribe.get_by_tmdbid(db, mediainfo.tmdb_id)
hasfile = True if subscribes:
else: # 已监控
hasfile = False monitored = True
# 已监控季
# 查询订阅信息 sub_seas = [sub.season for sub in subscribes]
seasons: List[dict] = [] for sea in seas:
subscribes = Subscribe.get_by_tmdbid(db, mediainfo.tmdb_id) if sea in sub_seas:
if subscribes: seasons.append({
# 已监控 "seasonNumber": sea,
monitored = True "monitored": True,
# 已监控季 })
sub_seas = [sub.season for sub in subscribes] else:
for sea in seas: seasons.append({
if sea in sub_seas: "seasonNumber": sea,
seasons.append({ "monitored": False,
"seasonNumber": sea, })
"monitored": True, subid = subscribes[-1].id
}) else:
else: subid = None
monitored = False
for sea in seas:
seasons.append({ seasons.append({
"seasonNumber": sea, "seasonNumber": sea,
"monitored": False, "monitored": False,
}) })
subid = subscribes[-1].id sonarr_series = SonarrSeries(
else: id=subid,
subid = None title=mediainfo.title,
monitored = False seasonCount=len(seasons),
for sea in seas: seasons=seasons,
seasons.append({ remotePoster=mediainfo.get_poster_image(),
"seasonNumber": sea, year=mediainfo.year,
"monitored": False, 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( return sonarr_series_list if sonarr_series_list else [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
)]
@arr_router.get("/series/{tid}", summary="剧集详情") @arr_router.get("/series/{tid}", summary="剧集详情")
+13
View 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]
+2 -1
View File
@@ -111,7 +111,8 @@ class ConfigModel(BaseModel):
# TMDB API Key # TMDB API Key
TMDB_API_KEY: str = "db55323b8d3e4154498498a75642b381" TMDB_API_KEY: str = "db55323b8d3e4154498498a75642b381"
# TVDB API Key # 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开关
FANART_ENABLE: bool = True FANART_ENABLE: bool = True
# Fanart API Key # Fanart API Key
+50 -14
View File
@@ -3,19 +3,42 @@ from typing import Optional, Tuple, Union
from app.core.config import settings from app.core.config import settings
from app.log import logger from app.log import logger
from app.modules import _ModuleBase 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.schemas.types import ModuleType, MediaRecognizeType
from app.utils.http import RequestUtils
class TheTvDbModule(_ModuleBase): class TheTvDbModule(_ModuleBase):
tvdb: tvdbapi.Tvdb = None tvdb: tvdb_v4_official.TVDB = None
def init_module(self) -> None: def init_module(self) -> None:
self.tvdb = tvdbapi.Tvdb(apikey=settings.TVDB_API_KEY, self._initialize_tvdb_session()
cache=False,
select_first=True, def _initialize_tvdb_session(self) -> None:
proxies=settings.PROXY) """
创建或刷新 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 "failed to get" in str(e) or "Unauthorized" in str(e) or "NOT_MODIFIED" in str(e):
logger.warning("TVDB Token 可能已失效,正在尝试重新登录...")
self._initialize_tvdb_session()
return func(*args, **kwargs)
else:
raise
except Exception as e:
logger.error(f"TVDB 调用出错: {str(e)}")
raise
@staticmethod @staticmethod
def get_name() -> str: def get_name() -> str:
@@ -43,18 +66,17 @@ class TheTvDbModule(_ModuleBase):
return 4 return 4
def stop(self): def stop(self):
self.tvdb.close() pass
def test(self) -> Tuple[bool, str]: def test(self) -> Tuple[bool, str]:
""" """
测试模块连接性 测试模块连接性
""" """
ret = RequestUtils(proxies=settings.PROXY).get_res("https://api.thetvdb.com/series/81189") try:
if ret and ret.status_code == 200: self._handle_tvdb_call(self.tvdb.get_series, 81189)
return True, "" return True, ""
elif ret: except Exception as e:
return False, f"无法连接 api.thetvdb.com,错误码:{ret.status_code}" return False, str(e)
return False, "api.thetvdb.com 网络连接失败"
def init_setting(self) -> Tuple[str, Union[str, bool]]: def init_setting(self) -> Tuple[str, Union[str, bool]]:
pass pass
@@ -67,6 +89,20 @@ class TheTvDbModule(_ModuleBase):
""" """
try: try:
logger.info(f"开始获取TVDB信息: {tvdbid} ...") 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: except Exception as err:
logger.error(f"获取TVDB信息失败: {str(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} ...")
return self._handle_tvdb_call(self.tvdb.search, title)
except Exception as err:
logger.error(f"用标题搜索TVDB失败: {str(err)}")
return []
+465
View 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