Files
Video-Station-plagin/com.synology.TMDBExample/util_themoviedb.py
2023-11-09 23:12:10 +03:00

258 lines
9.5 KiB
Python

import os
import urllib
import time
import json
import searchinc
import constant
def search_media(name, lang, limit, media_type, year):
page = 1
if media_type == 'movie':
search_func = _get_movie_search_data
elif media_type == 'tvshow' or media_type == 'tvshow_episode':
search_func = _get_tv_search_data
else:
return []
search_data = search_func(name, lang, year, page)
if not search_data.get('total_pages'):
return []
total_pages = search_data['total_pages']
total_result = parse_search_data(search_data, lang, limit, media_type, year)
while ((len(total_result) < limit) and page < total_pages):
page += 1
search_data = search_func(name, lang, year, page)
one_page_result = parse_search_data(search_data, lang, limit, media_type, year)
total_result.extend(one_page_result)
if (0 < limit) and (limit < len(total_result)):
total_result = total_result[0:limit]
return total_result
def parse_search_data(search_data, lang, limit, media_type, year):
if not search_data.get('results'):
return []
result = []
for item in search_data['results']:
data = {}
data['id'] = item['id']
if not _is_translation_available(data['id'], lang, media_type):
continue
data['lang'] = lang
if year and 'release_date' in item:
item_year = searchinc.parse_year(item['release_date'])
year_diff = abs(item_year - year)
if 2 <= year_diff and item_year:
continue
result.append(data)
if (0 < limit) and (limit <= len(result)):
break
return result
def _get_movie_search_data(name, lang, year, page):
api_key = constant.APIKEY
convert_lang = _convert_to_api_lang(lang)
nameEncode = urllib.parse.quote_plus(name)
cache_path = searchinc.get_plugin_data_directory(
constant.PLUGINID) + '/movie/query/' + nameEncode + '_' + str(year) + '_' + convert_lang + '_' + str(page) + '.json'
# example: https://api.themoviedb.org/3/search/movie?api_key=xxxxx&query=harry%20potter&language=cht&year=0&page=1
url = constant.THEMOVIEDB_URL + 'search/movie?api_key=' + api_key + '&query=' + nameEncode + '&language=' + \
convert_lang + '&year=' + str(year) + '&page=' + str(page)
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_EXPIRED_TIME)
def _get_movie_translation_data(item_id):
api_key = constant.APIKEY
cache_path = searchinc.get_plugin_data_directory(constant.PLUGINID) + '/movie/' + str(item_id) + '/translation.json'
# example: https://api.themoviedb.org/3/movie/671/translations?api_key=xxxxx
url = constant.THEMOVIEDB_URL + 'movie/' + str(item_id) + '/translations?api_key=' + api_key
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_EXPIRED_TIME)
def get_movie_detail_data(item_id, lang, expired_time):
api_key = constant.APIKEY
convert_lang = _convert_to_api_lang(lang)
cache_path = searchinc.get_plugin_data_directory(
constant.PLUGINID) + '/movie/' + str(item_id) + '/' + convert_lang + '.json'
# example: https://api.themoviedb.org/3/movie/671?api_key=xxxxx&append_to_response=credits,releases&language=zh-tw
url = constant.THEMOVIEDB_URL + 'movie/' + str(item_id) + '?api_key=' + api_key + \
'&language=' + convert_lang + '&append_to_response=credits,releases'
return _get_data_from_cache_or_download(url, cache_path, expired_time)
def get_movie_similar_data(item_id, lang, page):
api_key = constant.APIKEY
convert_lang = _convert_to_api_lang(lang)
cache_path = searchinc.get_plugin_data_directory(
constant.PLUGINID) + "/movie/" + str(item_id) + "/" + convert_lang + "_" + str(page) + "_similar.json"
# example: https://api.themoviedb.org/3/movie/671/similar?api_key=xxxxx&language=zh-tw&page=1
url = constant.THEMOVIEDB_URL + "movie/" + str(item_id) + "/similar?api_key=" + api_key + \
'&language=' + convert_lang + '&page=' + str(page)
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_LONG_EXPIRED_TIME)
def get_movie_collection_data(item_id, lang):
api_key = constant.APIKEY
convert_lang = _convert_to_api_lang(lang)
cache_path = searchinc.get_plugin_data_directory(
constant.PLUGINID) + "/movie/" + str(item_id) + "/" + convert_lang + "_collection.json"
# example: https://api.themoviedb.org/3/collection/1241?api_key=xxxxx&language=zh-tw
url = constant.THEMOVIEDB_URL + "collection/" + str(item_id) + '?api_key=' + api_key + '&language=' + convert_lang
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_LONG_EXPIRED_TIME)
def _get_tv_search_data(name, lang, year, page):
api_key = constant.APIKEY
convert_lang = _convert_to_api_lang(lang)
nameEncode = urllib.parse.quote_plus(name)
cache_path = searchinc.get_plugin_data_directory(
constant.PLUGINID) + '/tv/query/' + nameEncode + '_' + str(year) + '_' + convert_lang + '_' + str(page) + '.json'
# example: https://api.themoviedb.org/3/search/tv?api_key=xxxxx&query=superman&language=en&year=0&page=1
url = constant.THEMOVIEDB_URL + "search/tv?api_key=" + api_key + '&query=' + \
nameEncode + '&language=' + convert_lang + '&year=' + str(year) + '&page=' + str(page)
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_EXPIRED_TIME)
def get_tv_detail_data(item_id, lang):
api_key = constant.APIKEY
convert_lang = _convert_to_api_lang(lang)
cache_path = searchinc.get_plugin_data_directory(
constant.PLUGINID) + "/tv/" + str(item_id) + "/" + convert_lang + ".json"
# example: https://api.themoviedb.org/3/tv/1403?api_key=xxxxx&append_to_response=credits,content_ratings,external_ids&language=en
url = constant.THEMOVIEDB_URL + "tv/" + str(item_id) + '?api_key=' + api_key + '&language=' + \
convert_lang + '&append_to_response=credits,content_ratings,external_ids'
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_EXPIRED_TIME)
def get_tv_episode_detail_data(item_id, lang, season, episode):
api_key = constant.APIKEY
convert_lang = _convert_to_api_lang(lang)
episode_cache_pattern = '_e' + str(episode) if episode != None else ''
cache_path = searchinc.get_plugin_data_directory(
constant.PLUGINID) + "/tv/" + str(item_id) + "/" + convert_lang + '_s' + str(season) + episode_cache_pattern + ".json"
# example: https://api.themoviedb.org/3/tv/1403/season/1/episode/3?api_key=xxxxx&language=en&append_to_response=credits
episode_url_pattern = '/episode/' + str(episode) if episode != None else ''
url = constant.THEMOVIEDB_URL + "tv/" + \
str(item_id) + '/season/' + str(season) + episode_url_pattern + '?api_key=' + \
api_key + '&language=' + convert_lang + '&append_to_response=credits'
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_EXPIRED_TIME)
def _get_tv_translation_data(item_id):
api_key = constant.APIKEY
cache_path = searchinc.get_plugin_data_directory(constant.PLUGINID) + "/tv/" + str(item_id) + "/translation.json"
# example: https://api.themoviedb.org/3/tv/1403/translations?api_key=xxxxx
url = constant.THEMOVIEDB_URL + "tv/" + str(item_id) + "/translations?api_key=" + api_key
return _get_data_from_cache_or_download(url, cache_path, constant.DEFAULT_EXPIRED_TIME)
def _get_data_from_cache_or_download(url, cache_path, expired_time):
result = None
if os.path.exists(cache_path):
last_modify_time = os.path.getmtime(cache_path)
if expired_time > (time.time()-last_modify_time):
result = searchinc.load_local_cache(cache_path)
if result != None:
return result
os.remove(cache_path)
else:
directory_path = os.path.dirname(cache_path)
if not os.path.exists(directory_path):
oldmask = os.umask(0)
os.makedirs(directory_path, 0o755)
os.umask(oldmask)
download_success = searchinc.http_get_download(url, cache_path)
if download_success:
result = searchinc.load_local_cache(cache_path)
return result
def _is_translation_available(item_id, lang, mediaType):
translationData = None
if mediaType == 'movie':
translationData = _get_movie_translation_data(item_id)
elif mediaType == 'tvshow' or mediaType == 'tvshow_episode':
translationData = _get_tv_translation_data(item_id)
else:
return False
if not translationData:
return False
translation_array = _parse_translation(translationData)
converted_lang = _convert_to_api_lang(lang)
if converted_lang not in translation_array:
return False
return True
def _parse_translation(translationData):
langList = []
for item in translationData['translations']:
iso639 = item['iso_639_1']
iso3166 = item['iso_3166_1']
langList.append(iso639 + '-' + iso3166)
return langList
def _convert_to_api_lang(lang):
langDict = {
'chs': 'zh-CN', 'cht': 'zh-TW', 'csy': 'cs-CZ', 'dan': 'da-DK',
'enu': 'en-US', 'fre': 'fr-FR', 'ger': 'de-DE', 'hun': 'hu-HU',
'ita': 'it-IT', 'jpn': 'ja-JP', 'krn': 'ko-KR', 'nld': 'nl-NL',
'nor': 'no-NO', 'plk': 'pl-PL', 'ptb': 'pt-BR', 'ptg': 'pt-PT',
'rus': 'ru-RU', 'spn': 'es-ES', 'sve': 'sv-SE', 'trk': 'tr-TR',
'tha': 'th-TH'
}
if lang in langDict.keys():
return langDict[lang]
if lang in langDict.values():
return lang
return None