Videoteca DB

This commit is contained in:
Alhaziel01
2021-05-11 18:56:11 +02:00
parent 9b70993ad6
commit c942f9b4ec
18 changed files with 1514 additions and 1563 deletions

View File

@@ -384,7 +384,7 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
args=item.args,
contentSerieName= title if 'movie' not in [contentType] and function != 'episodios' else item.contentSerieName,
contentTitle= title if 'movie' in [contentType] and function == 'peliculas' else item.contentTitle,
contentLanguage = lang1,
contentLanguage = lang1 if lang1 else item.contentLanguage,
contentSeason= infolabels.get('season', ''),
contentEpisodeNumber=infolabels.get('episode', ''),
news= item.news if item.news else '',
@@ -529,14 +529,14 @@ def scrape(func):
nextArgs['groupExplode'] = False
nextArgs['item'] = item
itemlist = newFunc()
itemlist = [i for i in itemlist if i.action not in ['add_pelicula_to_library', 'add_serie_to_library']]
itemlist = [i for i in itemlist if i.action not in ['add_movie_to_library', 'add_serie_to_library']]
if anime and inspect.stack()[1][3] not in ['find_episodes']:
from platformcode import autorenumber
if function == 'episodios': autorenumber.start(itemlist, item)
else: autorenumber.start(itemlist)
if action != 'play' and 'patronMenu' not in args and not disabletmdb: # and function != 'episodios' and item.contentType in ['movie', 'tvshow', 'episode', 'undefined']
if action != 'play' and 'patronMenu' not in args and not disabletmdb and inspect.stack()[1][3] not in ['add_tvshow'] or (function in ['episodios'] and config.get_setting('episode_info')): # and function != 'episodios' and item.contentType in ['movie', 'tvshow', 'episode', 'undefined']
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
if not group and not args.get('groupExplode') and ((pagination and len(matches) <= pag * pagination) or not pagination): # next page with pagination
@@ -568,7 +568,7 @@ def scrape(func):
prevthumb=item.prevthumb if item.prevthumb else item.thumbnail))
if inspect.stack()[1][3] not in ['find_episodes']:
if inspect.stack()[1][3] not in ['find_episodes', 'add_tvshow']:
if addVideolibrary and (item.infoLabels["title"] or item.fulltitle):
# item.fulltitle = item.infoLabels["title"]
videolibrary(itemlist, item, function=function)
@@ -1078,7 +1078,7 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
logger.debug()
if item.contentType == 'movie':
action = 'add_pelicula_to_library'
action = 'add_movie_to_library'
extra = 'findvideos'
contentType = 'movie'
else:
@@ -1203,9 +1203,11 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
srv_param = servertools.get_server_parameters(videoitem.server.lower())
logger.debug(videoitem)
if videoitem.video_urls or srv_param.get('active', False):
item.title = typo(item.contentTitle.strip(), 'bold') if item.contentType == 'movie' or (config.get_localized_string(30161) in item.title) else item.title
# dbg()
item.title = typo(item.contentTitle.strip(), 'bold') if item.contentType == 'movie' and item.contentTitle or (config.get_localized_string(30161) in item.title) else item.title
quality = videoitem.quality if videoitem.quality else item.quality if item.quality else ''
videoitem.contentLanguage = videoitem.contentLanguage if videoitem.contentLanguage else item.contentLanguage
videoitem.title = (item.title if item.channel not in ['url'] else '')\
+ (typo(videoitem.title, '_ color kod [] bold') if videoitem.title else "")\
+ (typo(videoitem.quality, '_ color kod []') if videoitem.quality else "")\

View File

@@ -7,22 +7,23 @@ if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
if PY3:
import urllib.parse as urllib # It is very slow in PY2. In PY3 it is native
from concurrent import futures
else:
import urllib # We use the native of PY2 which is faster
from concurrent_py2 import futures
from future.builtins import range
from future.builtins import object
import ast, copy, re, time
from core import filetools, httptools, jsontools, scrapertools
from core import filetools, httptools, jsontools, scrapertools, support
from core.item import InfoLabels
from platformcode import config, logger, platformtools
import threading
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
lock = threading.Lock()
host = 'https://api.themoviedb.org/3'
api = 'a1ab8b8669da03637a4b98fa39c39228'
@@ -201,45 +202,35 @@ def set_infoLabels_itemlist(item_list, seekTmdb=False, search_language=def_lang,
if not config.get_setting('tmdb_active') and not forced:
return
# threads_num = config.get_setting("tmdb_threads", default=20)
# semaphore = threading.Semaphore(threads_num)
r_list = list()
i = 0
l_thread = list()
def sub_thread(_item, _i, _seekTmdb):
# semaphore.acquire()
ret = 0
try:
ret = set_infoLabels_item(_item, _seekTmdb, search_language, lock)
ret = set_infoLabels_item(_item, _seekTmdb, search_language)
except:
import traceback
logger.error(traceback.format_exc(1))
if lock and lock.locked():
lock.release()
# logger.debug(str(ret) + "item: " + _item.tostring())
# semaphore.release()
r_list.append((_i, _item, ret))
for item in item_list:
sub_thread(item, i, seekTmdb)
# t = threading.Thread(target=sub_thread, args=(item, i, seekTmdb))
# t.start()
# i += 1
# l_thread.append(t)
return (_i, _item, ret)
# for i, item in enumerate(item_list):
# r_list.append(sub_thread(item, i, seekTmdb))
with futures.ThreadPoolExecutor() as executor:
searchList = [executor.submit(sub_thread, item, i, seekTmdb) for i, item in enumerate(item_list)]
for res in futures.as_completed(searchList):
r_list.append(res.result())
# wait for all the threads to end
for x in l_thread:
x.join()
# Sort results list by call order to keep the same order q item_list
r_list.sort(key=lambda i: i[0])
# Rebuild and return list only with results of individual calls
return [ii[2] for ii in r_list]
return [it[2] for it in r_list]
def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None):
def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang):
"""
Gets and sets (item.infoLabels) the extra data of a series, chapter or movie.
@@ -249,7 +240,6 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
@type seekTmdb: bool
@param search_language: Language code according to ISO 639-1, in case of search at www.themoviedb.org.
@type search_language: str
@param lock: For use of threads when calling the 'set_infoLabels_itemlist' method
@return: A number whose absolute value represents the number of elements included in the item.infoLabels attribute. This number will be positive if the data has been obtained from www.themoviedb.org and negative otherwise.
@rtype: int
"""
@@ -257,7 +247,7 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
def read_data(otmdb_aux):
infoLabels = otmdb_aux.get_infoLabels(item.infoLabels)
if not infoLabels['plot']: infoLabels['plot'] = otmdb_aux.get_plot('en-US')
if not infoLabels['plot']: infoLabels['plot'] = otmdb_aux.get_plot('en')
item.infoLabels = infoLabels
if item.infoLabels.get('thumbnail'):
item.thumbnail = item.infoLabels['thumbnail']
@@ -273,9 +263,6 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
logger.debug("The season number is not valid.")
return -1 * len(item.infoLabels)
if lock:
lock.acquire()
if not otmdb_global or (item.infoLabels['tmdb_id'] and str(otmdb_global.result.get("id")) != item.infoLabels['tmdb_id']) \
or (otmdb_global.searched_text and otmdb_global.searched_text != item.infoLabels['tvshowtitle']):
if item.infoLabels['tmdb_id']:
@@ -287,10 +274,6 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
read_data(otmdb_global)
# 4l3x87 - fix for overlap infoLabels if there is episode or season
# if lock and lock.locked():
# lock.release()
if item.infoLabels['episode']:
try:
ep = int(item.infoLabels['episode'])
@@ -319,10 +302,12 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
item.infoLabels['rating'] = episode['episode_vote_average']
if episode.get('episode_vote_count'):
item.infoLabels['votes'] = episode['episode_vote_count']
# 4l3x87 - fix for overlap infoLabels if there is episode or season
if lock and lock.locked():
lock.release()
if episode.get('episode_id'):
item.infoLabels['episode_id'] = episode['episode_id']
if episode.get('episode_imdb_id'):
item.infoLabels['episode_imdb_id'] = episode['episode_imdb_id']
if episode.get('episode_tvdb_id'):
item.infoLabels['episode_tvdb_id'] = episode['episode_tvdb_id']
return len(item.infoLabels)
@@ -331,11 +316,11 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
# ... search season data
item.infoLabels['mediatype'] = 'season'
season = otmdb_global.get_season(seasonNumber)
enseason = otmdb_global.get_season(seasonNumber, language='en-US')
# enseason = otmdb_global.get_season(seasonNumber, language='en')
if not isinstance(season, dict):
season = ast.literal_eval(season.decode('utf-8'))
if not isinstance(enseason, dict):
enseason = ast.literal_eval(enseason.decode('utf-8'))
# if not isinstance(enseason, dict):
# enseason = ast.literal_eval(enseason.decode('utf-8'))
if season:
# Update data
@@ -344,33 +329,26 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
seasonPlot = season.get("overview" , '')
seasonDate = season.get("air_date", '')
seasonPoster = season.get('poster_path', '')
seasonPosters = []
for image in season['images']['posters']:
seasonPosters.append('https://image.tmdb.org/t/p/original' + image['file_path'])
seasonTitleEN = enseason.get("name", '')
seasonPlotEN = enseason.get("overview" , '')
seasonDateEN = enseason.get("air_date", '')
seasonPosterEN = enseason.get('poster_path', '')
item.infoLabels['title'] = seasonTitle if seasonTitle else seasonTitleEN if seasonTitleEN else config.get_localized_string(60027) % seasonNumber
item.infoLabels['plot'] = seasonPlot if seasonPlot else seasonPlotEN if seasonPlotEN else ''
date = seasonDate if seasonDate else seasonDateEN if seasonDateEN else ''
item.infoLabels['title'] = seasonTitle
item.infoLabels['plot'] = seasonPlot
date = seasonDate
if date:
date.split('-')
item.infoLabels['aired'] = date[2] + "/" + date[1] + "/" + date[0]
poster = seasonPoster if seasonPoster else seasonPosterEN if seasonPosterEN else ''
if poster:
item.infoLabels['poster_path'] = 'https://image.tmdb.org/t/p/original' + poster
item.thumbnail = item.infoLabels['poster_path']
# 4l3x87 - fix for overlap infoLabels if there is episode or season
if lock and lock.locked():
lock.release()
if seasonPoster:
item.infoLabels['poster_path'] = 'https://image.tmdb.org/t/p/original' + seasonPoster
item.thumbnail = item.infoLabels['poster_path']
if seasonPosters:
if seasonPoster: seasonPosters.insert(0, seasonPoster)
item.infoLabels['posters'] = seasonPosters
return len(item.infoLabels)
# 4l3x87 - fix for overlap infoLabels if there is episode or season
if lock and lock.locked():
lock.release()
# Search...
else:
otmdb = copy.copy(otmdb_global)
@@ -427,9 +405,6 @@ def set_infoLabels_item(item, seekTmdb=True, search_language=def_lang, lock=None
otmdb = Tmdb(id_Tmdb=otmdb.result.get("id"), search_type=search_type,
search_language=search_language)
if lock and lock.locked():
lock.release()
if otmdb is not None and otmdb.get_id():
# The search has found a valid result
read_data(otmdb)
@@ -524,7 +499,6 @@ def get_nfo(item, search_groups=False):
@rtype: str
@return:
"""
# from core.support import dbg;dbg()
if search_groups:
from platformcode.autorenumber import RENUMBER, GROUP
@@ -859,7 +833,7 @@ class Tmdb(object):
self.search_text = re.sub('\[\\\?(B|I|COLOR)\s?[^\]]*\]', '', self.searched_text).strip()
self.search_type = kwargs.get('search_type', '')
self.search_language = kwargs.get('search_language', def_lang)
self.fallback_language = kwargs.get('search_language', 'en-US')
self.fallback_language = kwargs.get('search_language', 'en')
# self.search_include_adult = kwargs.get('include_adult', False)
self.search_year = kwargs.get('year', '')
self.search_filter = kwargs.get('filtro', {})
@@ -958,14 +932,9 @@ class Tmdb(object):
if self.search_id:
if source == "tmdb":
# http://api.themoviedb.org/3/movie/1924?api_key=a1ab8b8669da03637a4b98fa39c39228&language=es
# &append_to_response=images,videos,external_ids,credits&include_image_language=es,null
# http://api.themoviedb.org/3/tv/1407?api_key=a1ab8b8669da03637a4b98fa39c39228&language=es
# &append_to_response=images,videos,external_ids,credits&include_image_language=es,null
url = ('{}/{}/{}?api_key={}&language={}&append_to_response=images,videos,external_ids,credits&include_image_language={},null'.format(host, self.search_type, self.search_id, api, self.search_language, self.search_language))
url = ('{}/{}/{}?api_key={}&language={}&append_to_response=images,videos,external_ids,credits&include_image_language={},en,null'.format(host, self.search_type, self.search_id, api, self.search_language, self.search_language))
searching = "id_Tmdb: " + self.search_id
else:
# http://api.themoviedb.org/3/find/%s?external_source=imdb_id&api_key=a1ab8b8669da03637a4b98fa39c39228
url = ('{}/find/{}?external_source={}&api_key={}8&language={}'.format(host, self.search_id, source, api, self.search_language))
searching = "{}: {}".format(source.capitalize(), self.search_id)
@@ -1005,8 +974,6 @@ class Tmdb(object):
searching = ""
if self.search_text:
# http://api.themoviedb.org/3/search/movie?api_key=a1ab8b8669da03637a4b98fa39c39228&query=superman&language=es
# &include_adult=false&page=1
url = ('{}/search/{}?api_key={}&query={}&language={}&include_adult={}&page={}'.format(host, self.search_type, api, text_quote, self.search_language, True, page))
if self.search_year:
@@ -1023,8 +990,6 @@ class Tmdb(object):
if total_results > 0:
results = [r for r in result["results"] if r.get('first_air_date', r.get('release_date', ''))]
# results = result["results"]
# logger.debug('RISULTATI', results)
if self.search_filter and total_results > 1:
for key, value in list(dict(self.search_filter).items()):
@@ -1067,7 +1032,7 @@ class Tmdb(object):
total_results = 0
total_pages = 0
# Ejemplo self.discover: {'url': 'discover/movie', 'with_cast': '1'}
# Exampleself.discover: {'url': 'discover/movie', 'with_cast': '1'}
# url: API method to run
# rest of keys: Search parameters concatenated to the url
type_search = self.discover.get('url', '')
@@ -1076,7 +1041,7 @@ class Tmdb(object):
for key, value in list(self.discover.items()):
if key != "url":
params.append(key + "=" + str(value))
# http://api.themoviedb.org/3/discover/movie?api_key=a1ab8b8669da03637a4b98fa39c39228&query=superman&language=es
url = ('{}/{}?api_key={}&{}'.format(host, type_search, api, "&".join(params)))
logger.debug("[Tmdb.py] Searching %s:\n%s" % (type_search, url))
@@ -1247,11 +1212,11 @@ class Tmdb(object):
return ret
def get_poster(self, tipo_respuesta="str", size="original"):
def get_poster(self, response_type="str", size="original"):
"""
@param tipo_respuesta: Data type returned by this method. Default "str"
@type tipo_respuesta: list, str
@param response_type: Data type returned by this method. Default "str"
@type response_type: list, str
@param size: ("w45", "w92", "w154", "w185", "w300", "w342", "w500", "w600", "h632", "w780", "w1280", "original")
Indicates the width (w) or height (h) of the image to download. Default "original"
@return: If the response_type is "list" it returns a list with all the urls of the poster images of the specified size.
@@ -1268,7 +1233,7 @@ class Tmdb(object):
else:
poster_path = 'https://image.tmdb.org/t/p/' + size + self.result["poster_path"]
if tipo_respuesta == 'str':
if response_type == 'str':
return poster_path
elif not self.result["id"]:
return []
@@ -1293,11 +1258,11 @@ class Tmdb(object):
return ret
def get_backdrop(self, tipo_respuesta="str", size="original"):
def get_backdrop(self, response_type="str", size="original"):
"""
Returns the images of type backdrop
@param tipo_respuesta: Data type returned by this method. Default "str"
@type tipo_respuesta: list, str
@param response_type: Data type returned by this method. Default "str"
@type response_type: list, str
@param size: ("w45", "w92", "w154", "w185", "w300", "w342", "w500", "w600", "h632", "w780", "w1280", "original")
Indicates the width (w) or height (h) of the image to download. Default "original"
@type size: str
@@ -1313,9 +1278,9 @@ class Tmdb(object):
if self.result["backdrop_path"] is None or self.result["backdrop_path"] == "":
backdrop_path = ""
else:
backdrop_path = 'https://image.tmdb.org/t/p/' + size + self.result["backdrop_path"]
backdrop_path = 'get_posterget_poster' + size + self.result["backdrop_path"]
if tipo_respuesta == 'str':
if response_type == 'str':
return backdrop_path
elif self.result["id"] == "":
return []
@@ -1363,14 +1328,20 @@ class Tmdb(object):
# http://api.themoviedb.org/3/tv/1407/season/1?api_key=a1ab8b8669da03637a4b98fa39c39228&language=es&
# append_to_response=credits
url = "{}/tv/{}/season/{}?api_key={}&language={}&append_to_response=credits".format(host, self.result["id"], seasonNumber, api, search_language)
url = "{}/tv/{}/season/{}?api_key={}&language={}&append_to_response=videos,images,credits,external_ids&include_image_language={},en,null".format(host, self.result["id"], seasonNumber, api, search_language, search_language)
fallbackUrl = "{}/tv/{}/season/{}?api_key={}&language=en&append_to_response=videos,images,credits&include_image_language={},en,null".format(host, self.result["id"], seasonNumber, api, search_language)
logger.debug('TMDB URL', url)
searching = "id_Tmdb: " + str(self.result["id"]) + " season: " + str(seasonNumber) + "\nURL: " + url
logger.debug("[Tmdb.py] Searching " + searching)
# from core.support import dbg;dbg()
try:
self.season[seasonNumber] = self.get_json(url)
info = self.get_json(url)
if not language:
fallbackInfo = self.get_json(fallbackUrl)
self.season[seasonNumber] = parse_fallback_info(info, fallbackInfo)
else:
self.season[seasonNumber] = self.get_json(url)
if not isinstance(self.season[seasonNumber], dict):
self.season[seasonNumber] = ast.literal_eval(self.season[seasonNumber].decode('utf-8'))
@@ -1389,6 +1360,29 @@ class Tmdb(object):
return self.season[seasonNumber]
def get_collection(self, _id=''):
ret = {}
if not _id:
collection = self.result.get('belongs_to_collection', {})
if collection:
_id = collection.get('id')
if _id:
url = '{}/collection/{}?api_key={}&language={}&append_to_response=images'.format(host, _id, api, self.search_language)
fallbackUrl = '{}/collection/{}?api_key={}&language=en&append_to_response=images'.format(host, _id, api)
info = self.get_json(url)
fallbackInfo = self.get_json(fallbackUrl)
ret['set'] = info.get('name') if info.get('name') else fallbackInfo.get('name')
ret['setoverview'] = info.get('overview') if info.get('overview') else fallbackInfo.get('overview')
posters = ['https://image.tmdb.org/t/p/original' + (info.get('poster_path') if info.get('poster_path') else fallbackInfo.get('poster_path'))]
fanarts = ['https://image.tmdb.org/t/p/original' + (info.get('backdrop_path') if info.get('backdrop_path') else fallbackInfo.get('backdrop_path'))]
for image in info['images']['posters'] + fallbackInfo['images']['posters']:
posters.append('https://image.tmdb.org/t/p/original' + image['file_path'])
for image in info['images']['backdrops'] + fallbackInfo['images']['backdrops']:
fanarts.append('https://image.tmdb.org/t/p/original' + image['file_path'])
ret['setposters'] = posters
ret['setfanarts'] = fanarts
return ret
def get_episode(self, seasonNumber=1, chapter=1):
# --------------------------------------------------------------------------------------------------------------------------------------------
# Parameters:
@@ -1408,92 +1402,62 @@ class Tmdb(object):
try:
chapter = int(chapter)
seasonNumber = int(seasonNumber)
season = int(seasonNumber)
except ValueError:
logger.debug("The episode or season number is not valid")
return {}
season = self.get_season(seasonNumber)
enseason = self.get_season(seasonNumber, language='en-US')
if not isinstance(season, dict):
season = ast.literal_eval(season.decode('utf-8'))
if not isinstance(enseason, dict):
enseason = ast.literal_eval(enseason.decode('utf-8'))
if not season and not enseason:
# An error has occurred
return {}
# season = self.get_season(seasonNumber)
# # enseason = self.get_season(seasonNumber, language='en')
# # if not isinstance(season, dict):
# # season = ast.literal_eval(season.decode('utf-8'))
# # if not isinstance(enseason, dict):
# # enseason = ast.literal_eval(enseason.decode('utf-8'))
# if not season:
# # An error has occurred
# return {}
if len(season["episodes"]) == 0 and len(enseason["episodes"]) == 0:
# An error has occurred
logger.error("Episode %d of the season %d not found." % (chapter, seasonNumber))
return {}
# if len(season["episodes"]) == 0:
# # An error has occurred
# logger.error("Episode %d of the season %d not found." % (chapter, seasonNumber))
# return {}
elif len(season["episodes"]) < chapter and season["episodes"][-1]['episode_number'] >= chapter:
n = None
for i, chapters in enumerate(season["episodes"]):
if chapters['episode_number'] == chapter:
n = i + 1
break
if n != None:
chapter = n
else:
logger.error("Episode %d of the season %d not found." % (chapter, seasonNumber))
return {}
# elif len(season["episodes"]) < chapter and season["episodes"][-1]['episode_number'] >= chapter:
# n = None
# for i, chapters in enumerate(season["episodes"]):
# if chapters['episode_number'] == chapter:
# n = i + 1
# break
# if n != None:
# chapter = n
# else:
# logger.error("Episode %d of the season %d not found." % (chapter, seasonNumber))
# return {}
elif len(season["episodes"]) < chapter:
logger.error("Episode %d of the season %d not found." % (chapter, seasonNumber))
return {}
# elif len(season["episodes"]) < chapter:
# logger.error("Episode %d of the season %d not found." % (chapter, seasonNumber))
# return {}
ret_dic = dict()
# Get data for this season
seasonTitle = season.get("name", '')
seasonPlot = season.get("overview" , '')
seasonId = season.get("id", '')
seasonEpisodes = len(season.get("episodes",[]))
seasonDate = season.get("air_date", '')
seasonPoster = season.get('poster_path', '')
seasonCredits = season.get('credits', {})
# ret_dic = get_season_dic(season)
seasonTitleEN = enseason.get("name", '')
seasonPlotEN = enseason.get("overview" , '')
seasonIdEN = enseason.get("id", '')
seasonEpisodesEN = len(enseason.get("episodes",[]))
seasonDateEN = enseason.get("air_date", '')
seasonPosterEN = enseason.get('poster_path', '')
seasonCreditsEN = enseason.get('credits', {})
# if chapter == 0:
# # If we only look for season data, include the technical team that has intervened in any chapter
# dic_aux = dict((i['id'], i) for i in ret_dic["season_crew"])
# for e in season["episodes"]:
# for crew in e['crew']:
# if crew['id'] not in list(dic_aux.keys()):
# dic_aux[crew['id']] = crew
# ret_dic["season_crew"] = list(dic_aux.values())
ret_dic["season_title"] = seasonTitle if seasonTitle else seasonTitleEN if seasonTitleEN else config.get_localized_string(60027) % seasonNumber
ret_dic["season_plot"] = seasonPlot if seasonPlot else seasonPlotEN if seasonPlotEN else ''
ret_dic["season_id"] = seasonId if seasonId else seasonIdEN if seasonIdEN else ''
ret_dic["season_episodes_number"] = seasonEpisodes if seasonEpisodes else seasonEpisodesEN if seasonEpisodesEN else 0
date = seasonDate if seasonDate else seasonDateEN if seasonDateEN else ''
if date:
date = date.split("-")
ret_dic["season_air_date"] = date[2] + "/" + date[1] + "/" + date[0]
else:
ret_dic["season_air_date"] = ''
poster = seasonPoster if seasonPoster else seasonPosterEN if seasonPosterEN else ''
if poster:
ret_dic["season_poster"] = 'https://image.tmdb.org/t/p/original' + poster
else:
ret_dic["season_poster"] = ''
dic_aux = seasonCredits if seasonCredits else seasonCreditsEN if seasonCreditsEN else {}
ret_dic["season_cast"] = dic_aux.get('cast', [])
ret_dic["season_crew"] = dic_aux.get('crew', [])
if chapter == 0:
# If we only look for season data, include the technical team that has intervened in any chapter
dic_aux = dict((i['id'], i) for i in ret_dic["season_crew"])
for e in season["episodes"]:
for crew in e['crew']:
if crew['id'] not in list(dic_aux.keys()):
dic_aux[crew['id']] = crew
ret_dic["season_crew"] = list(dic_aux.values())
# Obtain chapter data if applicable
# from core.support import dbg;dbg()
ret_dic = {}
if chapter > 0:
episode = season["episodes"][chapter - 1]
enepisode = enseason["episodes"][chapter - 1]
# episode = season["episodes"][chapter - 1]
url = "{}/tv/{}/season/{}/episode/{}?api_key={}&language={}&append_to_response=videos,images,credits,external_ids&include_image_language={},en,null".format(host, self.result["id"], seasonNumber, chapter, api, self.search_language, self.search_language)
episode = self.get_json(url)
# logger.debug('EPISODE', jsontools.dump(episode))
episodeTitle = episode.get("name", '')
episodeId = episode.get('id', '')
@@ -1504,40 +1468,37 @@ class Tmdb(object):
episodeStars = episode.get('guest_stars', [])
episodeVoteCount = episode.get('vote_count', 0)
episodeVoteAverage = episode.get('vote_average', 0)
externalIds = episode.get('external_ids', {})
imdb_id = externalIds.get('imdb_id')
tvdb_id = externalIds.get('tvdb_id')
episodeTitleEN = enepisode.get("name", '')
episodeIdEN = enepisode.get('id', '')
episodePlotEN = enepisode.get('overview', '')
episodeDateEN = enepisode.get('air_date', '')
episodeImageEN = enepisode.get('still_path', '')
episodeCrewEN = enepisode.get('crew', [])
episodeStarsEN = enepisode.get('guest_stars', [])
episodeVoteCountEN = enepisode.get('vote_count', 0)
episodeVoteAverageEN = enepisode.get('vote_average', 0)
ret_dic["episode_title"] = episodeTitle
ret_dic["episode_plot"] = episodePlot
ret_dic["episode_title"] = episodeTitle if episodeTitle and not episodeTitle.startswith(config.get_localized_string(70677)) else episodeTitleEN if episodeTitleEN and not episodeTitleEN.startswith('Episode') else episodeTitle if episodeTitle else ''
ret_dic["episode_plot"] = episodePlot if episodePlot else episodePlotEN if episodePlotEN else ''
date = episodeDate if episodeDate else episodeDateEN if episodeDateEN else ''
image = episodeImage if episodeImage else episodeImageEN if episodeImageEN else ''
if image:
ret_dic["episode_image"] = 'https://image.tmdb.org/t/p/original' + image
if episodeImage:
ret_dic["episode_image"] = 'https://image.tmdb.org/t/p/original' + episodeImage
else:
ret_dic["episode_image"] = ""
if date:
date = date.split("-")
if episodeDate:
date = episodeDate.split("-")
ret_dic["episode_air_date"] = date[2] + "/" + date[1] + "/" + date[0]
else:
ret_dic["episode_air_date"] = ""
ret_dic["episode_crew"] = episodeCrew if episodeCrew else episodeCrewEN if episodeCrewEN else []
ret_dic["episode_guest_stars"] = episodeStars if episodeStars else episodeStarsEN if episodeStarsEN else []
ret_dic["episode_vote_count"] = episodeVoteCount if episodeVoteCount else episodeVoteCountEN if episodeVoteCountEN else 0
ret_dic["episode_vote_average"] = episodeVoteAverage if episodeVoteAverage else episodeVoteAverageEN if episodeVoteAverageEN else 0
ret_dic["episode_id"] = episodeId if episodeId else episodeIdEN if episodeIdEN else ''
ret_dic["episode_crew"] = episodeCrew
if episodeStars:
ret_dic["episode_actors"] = [[k['name'], k['character'], 'https://image.tmdb.org/t/p/original/' + k['profile_path'] if k['profile_path'] else '', k['order']] for k in episodeStars]
ret_dic["episode_vote_count"] = episodeVoteCount
ret_dic["episode_vote_average"] = episodeVoteAverage
ret_dic["episode_id"] = episodeId
ret_dic["episode_imdb_id"] = imdb_id
ret_dic["episode_tvdb_id"] = tvdb_id
return ret_dic
def get_list_episodes(self):
url = '{}/tv/{}?api_key={}&language={}'.format(host=host, id=self.search_id, api=api, lang=self.search_language)
url = '{}/tv/{}?api_key={}&language={}'.format(host, self.search_id, api, self.search_language)
results = requests.get(url).json().get('seasons', [])
seasons = []
if results and 'Error' not in results:
@@ -1622,18 +1583,24 @@ class Tmdb(object):
origen['credits_crew'] = dic_origen_credits.get('crew', [])
del origen['credits']
if 'images' in list(origen.keys()):
dic_origen_credits = origen['images']
origen['posters'] = dic_origen_credits.get('posters', [])
origen['fanarts'] = dic_origen_credits.get('backdrops', [])
del origen['images']
items = list(origen.items())
# Season / episode information
if ret_infoLabels['season'] and self.season.get(ret_infoLabels['season']):
# If there is data loaded for the indicated season
episodio = -1
if ret_infoLabels['episode']:
episodio = ret_infoLabels['episode']
items.extend(list(self.get_episode(ret_infoLabels['season'], episodio).items()))
# logger.debug("ret_infoLabels" % ret_infoLabels)
for k, v in items:
if not v:
@@ -1662,7 +1629,7 @@ class Tmdb(object):
elif k == 'release_date':
ret_infoLabels['year'] = int(v[:4])
ret_infoLabels['release_date'] = v.split("-")[2] + "/" + v.split("-")[1] + "/" + v.split("-")[0]
ret_infoLabels['premiered'] = v.split("-")[2] + "/" + v.split("-")[1] + "/" + v.split("-")[0]
elif k == 'first_air_date':
ret_infoLabels['year'] = int(v[:4])
@@ -1702,22 +1669,36 @@ class Tmdb(object):
elif k == 'name' or k == 'title':
ret_infoLabels['title'] = v
elif k == 'tagline':
ret_infoLabels['tagline'] = v
elif k == 'production_companies':
ret_infoLabels['studio'] = ", ".join(i['name'] for i in v)
elif k == 'credits_cast' or k == 'season_cast' or k == 'episode_guest_stars':
dic_aux = dict((name, character) for (name, character) in l_castandrole)
l_castandrole.extend([(p['name'], p.get('character', '') or p.get('character_name', '')) \
dic_aux = dict((name, [character, thumb, order]) for (name, character, thumb, order) in l_castandrole)
l_castandrole.extend([(p['name'], p.get('character', '') or p.get('character_name', ''), 'https://image.tmdb.org/t/p/original' + p.get('profile_path', '') if p.get('profile_path', '') else '', p.get('order')) \
for p in v if 'name' in p and p['name'] not in list(dic_aux.keys())])
elif k == 'videos':
if not isinstance(v, list):
v = v.get('result', [])
v = v.get('results', [])
for i in v:
if i.get("site", "") == "YouTube":
ret_infoLabels['trailer'] = "https://www.youtube.com/watch?v=" + v[0]["key"]
ret_infoLabels['trailer'] = "plugin://plugin.video.youtube/play/?video_id=" + v[0]["key"]
break
elif k == 'posters':
ret_infoLabels['posters'] = ['https://image.tmdb.org/t/p/original' + p["file_path"] for p in v]
elif k == 'fanarts':
ret_infoLabels['fanarts'] = ['https://image.tmdb.org/t/p/original' + p["file_path"] for p in v]
elif k == 'belongs_to_collection':
c = Tmdb.get_collection(self, v.get('id',''))
for k, v in c.items():
ret_infoLabels[k] = v
elif k == 'production_countries' or k == 'origin_country':
if isinstance(v, str):
l_country = list(set(l_country + v.split(',')))
@@ -1744,6 +1725,7 @@ class Tmdb(object):
for crew in v:
l_writer = list(set(l_writer + [crew['name']]))
elif isinstance(v, str) or isinstance(v, int) or isinstance(v, float):
ret_infoLabels[k] = v
@@ -1751,6 +1733,13 @@ class Tmdb(object):
# logger.debug("Atributos no añadidos: " + k +'= '+ str(v))
pass
Mpaaurl = '{}/{}/{}/content_ratings?api_key={}'.format(host, self.search_type, ret_infoLabels['tmdb_id'], api)
Mpaas = self.get_json(Mpaaurl).get('results',[])
for m in Mpaas:
if m.get('iso_3166_1','').lower() == 'us':
ret_infoLabels['Mpaa'] = m['rating']
break
# Sort the lists and convert them to str if necessary
if l_castandrole:
ret_infoLabels['castandrole'] = sorted(l_castandrole, key=lambda tup: tup[0])
@@ -1762,3 +1751,71 @@ class Tmdb(object):
ret_infoLabels['writer'] = ', '.join(sorted(l_writer))
return ret_infoLabels
def get_season_dic(season):
ret_dic = dict()
# logger.debug(jsontools.dump(season))
# Get data for this season
seasonTitle = season.get("name", '')
seasonPlot = season.get("overview" , '')
seasonId = season.get("id", '')
seasonEpisodes = len(season.get("episodes",[]))
seasonDate = season.get("air_date", '')
seasonPoster = season.get('poster_path', '')
seasonCredits = season.get('credits', {})
seasonPosters = season.get('images',{}).get('posters',{})
seasonFanarts = season.get('images',{}).get('backdrops',{})
seasonTrailers = season.get('videos',[]).get('results',[])
ret_dic["season_title"] = seasonTitle
ret_dic["season_plot"] = seasonPlot
ret_dic["season_id"] = seasonId
ret_dic["season_episodes_number"] = seasonEpisodes
if seasonDate:
date = seasonDate.split("-")
ret_dic["season_air_date"] = date[2] + "/" + date[1] + "/" + date[0]
else:
ret_dic["season_air_date"] = ''
if seasonPoster:
ret_dic["season_poster"] = 'https://image.tmdb.org/t/p/original' + seasonPoster
else:
ret_dic["season_poster"] = ''
if seasonPosters:
ret_dic['season_posters'] = ['https://image.tmdb.org/t/p/original' + p["file_path"] for p in seasonPosters]
if seasonFanarts:
ret_dic['season_fanarts'] = ['https://image.tmdb.org/t/p/original' + p["file_path"] for p in seasonFanarts]
if seasonTrailers:
ret_dic['season_trailer'] = []
for i in seasonTrailers:
if i.get("site", "") == "YouTube":
ret_dic['season_trailer'] = "plugin://plugin.video.youtube/play/?video_id=" + seasonTrailers[0]["key"]
break
dic_aux = seasonCredits if seasonCredits else {}
ret_dic["season_cast"] = dic_aux.get('cast', [])
ret_dic["season_crew"] = dic_aux.get('crew', [])
return ret_dic
def parse_fallback_info(info, fallbackInfo):
info_dict = {}
for key, value in info.items():
if not value:
value = fallbackInfo[key]
info_dict[key] = value
episodes = info_dict['episodes']
episodes_list = []
for i, episode in enumerate(episodes):
episode_dict = {}
for key, value in episode.items():
if not value:
value = fallbackInfo['episodes'][i][key]
episode_dict[key] = value
episodes_list.append(episode_dict)
info_dict['episodes'] = episodes_list
return info_dict

20
core/videolibrarydb.py Normal file
View File

@@ -0,0 +1,20 @@
from collections import defaultdict
from lib.sqlitedict import SqliteDict
from core import filetools
from platformcode import config
class nested_dict_sqlite(defaultdict):
'like defaultdict but default_factory receives the key'
def __missing__(self, key):
self[key] = value = self.default_factory(key)
return value
def close(self):
for key in self.keys():
self[key].close()
self.clear()
db_name = filetools.join(config.get_videolibrary_path(), "videolibrary.sqlite")
videolibrarydb = nested_dict_sqlite(lambda table: SqliteDict(db_name, table, 'c', True))

File diff suppressed because it is too large Load Diff

View File

@@ -1204,7 +1204,7 @@ def post_tmdb_findvideos(item, itemlist):
itemlist.append(item.clone(title="** [COLOR yelow]Actualizar Títulos - vista previa videoteca[/COLOR] **", action="actualizar_titulos", extra="peliculas", tmdb_stat=False, from_action=item.action, from_title_tmdb=item.title, from_update=True))
if item.contentType == 'movie' and item.contentChannel != "videolibrary":
itemlist.append(item.clone(title="**-[COLOR yellow] Añadir a la videoteca [/COLOR]-**", action="add_pelicula_to_library", extra="peliculas", from_action=item.action, from_title_tmdb=item.title))
itemlist.append(item.clone(title="**-[COLOR yellow] Añadir a la videoteca [/COLOR]-**", action="add_movie_to_library", extra="peliculas", from_action=item.action, from_title_tmdb=item.title))
# We added the option to watch trailers
if item.contentChannel != "videolibrary":

36
libraryscraper.py Normal file
View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# scraper for Kodi Library based on db
import xbmc, xbmcplugin, sys, os
from platformcode import logger, config
try:
import xbmcvfs
xbmc.translatePath = xbmcvfs.translatePath
xbmc.validatePath = xbmcvfs.validatePath
xbmc.makeLegalFilename = xbmcvfs.makeLegalFilename
except:
pass
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
sys.path.insert(0, librerias)
from core.videolibrarytools import MOVIES_PATH, TVSHOWS_PATH, videolibrarydb
try:
from urlparse import parse_qsl
except ImportError: # py2 / py3
from urllib.parse import parse_qsl
def get_params(argv):
result = {'handle': int(argv[0])}
if len(argv) < 2 or not argv[1]:
return result
result.update(parse_qsl(argv[1].lstrip('?')))
return result
if __name__ == '__main__':
# params = get_params(sys.argv[1:])
logger.debug('PARAMS')
# run()

View File

@@ -11,6 +11,10 @@ from core.item import Item
from core.support import typo, match, dbg, Item
from platformcode import config, platformtools, logger
PY3 = True if sys.version_info[0] >= 3 else False
if PY3:
from concurrent import futures
else:
from concurrent_py2 import futures
# Json Var
RENUMBER = 'TVSHOW_AUTORENUMBER'
@@ -171,15 +175,18 @@ class autorenumber():
def renumber(self):
def sub_thread(item):
if not match(item.title, patron=r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)').match:
number = match(item.title, patron=r'(\d+)').match.lstrip('0')
if number:
if not number in self.episodes: self.makelist()
item.title = '{} - {}'.format(typo(self.episodes[number], 'bold'), item.title)
item.contentSeason = int(self.episodes[number].split('x')[0])
item.contentEpisodeNumber = int(self.episodes[number].split('x')[1])
if not self.item.renumber and self.itemlist:
for item in self.itemlist:
if not match(item.title, patron=r'[Ss]?(\d+)(?:x|_|\s+)[Ee]?[Pp]?(\d+)').match:
number = match(item.title, patron=r'(\d+)').match.lstrip('0')
if number:
if not number in self.episodes: self.makelist()
item.title = '{} - {}'.format(typo(self.episodes[number], 'bold'), item.title)
item.contentSeason = int(self.episodes[number].split('x')[0])
item.contentEpisodeNumber = int(self.episodes[number].split('x')[1])
with futures.ThreadPoolExecutor() as executor:
renumber_list = [executor.submit(sub_thread, item,) for item in self.itemlist]
else:
self.makelist()

View File

@@ -185,7 +185,7 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
self.close()
modal()
for item in itemlist:
if item.action not in ['save_download', 'add_pelicula_to_library', 'add_serie_to_library', ''] and item.infoLabels['title']:
if item.action not in ['save_download', 'add_movie_to_library', 'add_serie_to_library', ''] and item.infoLabels['title']:
if item.action == 'findvideos' and item.contentType in ['episode', 'tvshow']:
it = xbmcgui.ListItem(re.sub(r'\[[^\]]+\]', '', item.title))
self.getControl(NUMBER).setText(support.typo(config.get_localized_string(70362),'uppercase bold'))
@@ -204,7 +204,7 @@ class SearchWindow(xbmcgui.WindowXMLDialog):
self.itemlist.append(item)
if itemlist[0].contentType == 'movie':
if not itemlist[0].server:
self.commands.append(itemlist[0].clone(action='add_pelicula_to_library', thumbnail=support.thumb('add_to_videolibrary')))
self.commands.append(itemlist[0].clone(action='add_movie_to_library', thumbnail=support.thumb('add_to_videolibrary')))
self.commands.append(itemlist[0].clone(channel='downloads', action='save_download', from_channel=itemlist[0].channel, from_action=itemlist[0].action, thumbnail=support.thumb('downloads')))
else:
self.commands.append(Info.clone(channel='downloads', action='save_download', from_channel=Info.channel, from_action=Info.action, thumbnail=support.thumb('downloads')))

View File

@@ -231,7 +231,7 @@ def run(item=None):
platformtools.render_items(itemlist, item)
# Special action for adding a movie to the library
elif item.action == "add_pelicula_to_library":
elif item.action == "add_movie_to_library":
from core import videolibrarytools
videolibrarytools.add_movie(item)

View File

@@ -578,7 +578,7 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
if parent_item.channel == 'kodfavorites':
return context_commands
# Options according to criteria, only if the item is not a tag, nor is it "Add to the video library", etc...
if item.action and item.action not in ["add_pelicula_to_library", "add_serie_to_library", "buscartrailer", "actualizar_titulos"]:
if item.action and item.action not in ["add_movie_to_library", "add_serie_to_library", "buscartrailer", "actualizar_titulos"]:
# Show information: if the item has a plot, we assume that it is a series, season, chapter or movie
# if item.infoLabels['plot'] and (num_version_xbmc < 17.0 or item.contentType == 'season'):
# context_commands.append((config.get_localized_string(60348), "Action(Info)"))
@@ -647,7 +647,7 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
context_commands.append((config.get_localized_string(60352), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_serie_to_library&from_action=' + item.action)))
# Add Movie to Video Library
elif item.action in ["detail", "findvideos"] and item.contentType == 'movie' and item.contentTitle:
context_commands.append((config.get_localized_string(60353), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_pelicula_to_library&from_action=' + item.action)))
context_commands.append((config.get_localized_string(60353), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'action=add_movie_to_library&from_action=' + item.action)))
if not item.local and item.channel not in ["downloads", "filmontv", "search"] and item.server != 'torrent' and parent_item.action != 'mainlist' and config.get_setting('downloadenabled'):
# Download movie

View File

@@ -69,6 +69,7 @@ class InfoWindow(xbmcgui.WindowXMLDialog):
self.response = self.results[int(self.getControl(SELECT).getSelectedItem().getProperty('position'))]
self.close()
elif control_id == CLOSE:
self.response = None
self.close()
def onAction(self, action):

View File

@@ -5,6 +5,7 @@
# from future import standard_library
# standard_library.install_aliases()
#from builtins import str
from core.item import Item
import sys, os, threading, time, re, math, xbmc, xbmcgui
PY3 = False
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
@@ -14,7 +15,7 @@ if PY3:
else:
import urllib2 # Usamos el nativo de PY2 que es más rápido
from core import filetools, jsontools
from core import filetools, jsontools, support
from platformcode import config, logger, platformtools
from core import scrapertools
from xml.dom import minidom
@@ -67,8 +68,8 @@ def mark_auto_as_watched(item):
platformtools.set_played_time(item)
if item.options['strm'] : sync = True
show_server = False
from specials import videolibrary
videolibrary.mark_content_as_watched2(item)
# from specials import videolibrary
# videolibrary.mark_content_as_watched(item)
if not next_episode:
break
@@ -98,9 +99,13 @@ def mark_auto_as_watched(item):
if not show_server and item.play_from != 'window' and not item.no_return:
xbmc.sleep(700)
xbmc.executebuiltin('Action(ParentDir)')
xbmc.sleep(500)
# xbmc.sleep(500)
if marked:
from specials import videolibrary
videolibrary.mark_content_as_watched(item)
if next_episode and next_episode.next_ep and config.get_setting('next_ep') < 3:
if next_episode and next_episode.next_ep and config.get_setting('next_ep') == 1:
from platformcode.launcher import play_from_library
play_from_library(next_episode)
@@ -258,8 +263,14 @@ def mark_content_as_watched_on_kodi(item, value=1):
@param value: > 0 for seen, 0 for not seen
"""
logger.debug()
# logger.debug("item:\n" + item.tostring('\n'))
payload_f = ''
pos = item.itemlistPosition
winid = xbmcgui.getCurrentWindowId()
win = xbmcgui.Window(winid)
cid = win.getFocusId()
ctl = win.getControl(cid)
if item.contentType == "movie":
movieid = 0
@@ -300,8 +311,8 @@ def mark_content_as_watched_on_kodi(item, value=1):
filename = filetools.basename(item.strm_path)
head, tail = filetools.split(filetools.split(item.strm_path)[0])
else: # If Item is from the Series
filename = filetools.basename(item.path)
head, tail = filetools.split(filetools.split(item.path)[0])
filename = filetools.basename(item.base_name)
head, tail = filetools.split(filetools.split(item.base_name)[0])
path = filetools.join(tail, filename)
for d in data['result']['episodes']:
@@ -313,6 +324,7 @@ def mark_content_as_watched_on_kodi(item, value=1):
if episodeid != 0:
payload_f = {"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": episodeid, "playcount": value}, "id": 1}
if payload_f:
# Mark as seen
data = get_data(payload_f)
@@ -320,6 +332,9 @@ def mark_content_as_watched_on_kodi(item, value=1):
if data['result'] != 'OK':
logger.error("ERROR putting content as viewed")
xbmc.sleep(700)
ctl.selectItem(pos)
def mark_season_as_watched_on_kodi(item, value=1):
"""
@@ -330,6 +345,7 @@ def mark_season_as_watched_on_kodi(item, value=1):
@param value: > 0 for seen, 0 for not seen
"""
logger.debug()
# support.dbg()
# logger.debug("item:\n" + item.tostring('\n'))
# We can only mark the season as seen in the Kodi database if the database is local, in case of sharing database this functionality will not work
@@ -344,7 +360,7 @@ def mark_season_as_watched_on_kodi(item, value=1):
request_season = ' and c12= %s' % item.contentSeason
tvshows_path = filetools.join(config.get_videolibrary_path(), config.get_setting("folder_tvshows"))
item_path1 = "%" + item.path.replace("\\\\", "\\").replace(tvshows_path, "")
item_path1 = "%" + item.base_name.replace("\\\\", "\\").replace(tvshows_path, "")
if item_path1[:-1] != "\\":
item_path1 += "\\"
item_path2 = item_path1.replace("\\", "/")
@@ -354,37 +370,64 @@ def mark_season_as_watched_on_kodi(item, value=1):
execute_sql_kodi(sql)
def set_watched_on_kod(data):
# support.dbg()
from specials import videolibrary
from core import videolibrarytools
from core.videolibrarytools import videolibrarydb
data = jsontools.load(data)
Type = data.get('item', {}).get('type','')
ID = data.get('item', {}).get('id','')
if not Type or not ID:
return
playcount = data.get('playcount',0)
for Type in ['movie', 'episode']:
sql = 'select strFileName, strPath, uniqueid_value from %s_view where (id%s like "%s")' % (Type, Type.capitalize(), ID)
if Type in ['episode']:
sql = 'select c18 from {}_view where (id{} like "{}")'.format(Type, Type.capitalize(), ID)
n, records = execute_sql_kodi(sql)
if records:
for filename, path, uniqueid_value in records:
if Type in ['movie']:
title = filename.replace('.strm', ' [' + uniqueid_value + ']')
filename = title +'.nfo'
else:
title = filename.replace('.strm', '')
filename = 'tvshow.nfo'
_id = scrapertools.find_single_match(records[0][0], r'\[([^\]]+)')
episode = scrapertools.find_single_match(records[0][0], r'(\d+x\d+)')
season = episode.split('x')[0]
episodes = videolibrarydb['episodes'].get(_id, {})
item = episodes.get(episode, {}).get('item', None)
path = filetools.join(path, filename)
head_nfo, item = videolibrarytools.read_nfo(path)
item.library_playcounts.update({title: playcount})
filetools.write(path, head_nfo + item.tojson())
if Type in ['season']:
sql = 'select season, strPath from {}_view where (id{} like "{}")'.format(Type, Type.capitalize(), ID)
n, records = execute_sql_kodi(sql)
if records:
logger.debug('RECORDS' , records)
_id = scrapertools.find_single_match(records[0][1], r'\[([^\]]+)')
season = records[0][0]
seasons = videolibrarydb['seasons'].get(_id, {})
item = seasons.get(season, None)
item.all_ep
if item.infoLabels['mediatype'] == "tvshow":
for season in item.library_playcounts:
if "season" in season:
season_num = int(scrapertools.find_single_match(season, r'season (\d+)'))
item = videolibrary.check_season_playcount(item, season_num)
filetools.write(path, head_nfo + item.tojson())
else:
# support.dbg()
sql = 'select strPath from {}_view where (id{} like "{}")'.format(Type, Type.replace('tv','').capitalize(), ID)
n, records = execute_sql_kodi(sql)
if records:
logger.debug('RECORDS' , records)
_id = scrapertools.find_single_match(records[0][0], r'\[([^\]]+)')
contents = videolibrarydb[Type].get(_id, {})
item = contents.get('item', None)
if item:
item.playcount = playcount
item.not_update = True
videolibrary.mark_content_as_watched(item)
videolibrarydb.close()
# path = filetools.join(path, filename)
# head_nfo, item = videolibrarytools.read_nfo(path)
# item.library_playcounts.update({title: playcount})
# filetools.write(path, head_nfo + item.tojson())
# if item.infoLabels['mediatype'] == "tvshow":
# for season in item.library_playcounts:
# if "season" in season:
# season_num = int(scrapertools.find_single_match(season, r'season (\d+)'))
# item = videolibrary.check_season_playcount(item, season_num)
# filetools.write(path, head_nfo + item.tojson())
def mark_content_as_watched_on_kod(path):
from specials import videolibrary
@@ -1072,6 +1115,47 @@ def clean(path_list=[]):
progress.close()
def clean_by_id(item):
logger.debug()
# imdb_id = item.infoLabels.get('imdb_id', '')
tmdb_id = item.infoLabels.get('tmdb_id', '')
season_id = item.infoLabels.get('temporada_id', '')
episode_id = item.infoLabels.get('episodio_id', '')
# support.dbg()
# search movie ID
if item.contentType == 'movie':
nun_records, records = execute_sql_kodi('SELECT idMovie FROM movie_view WHERE uniqueid_value LIKE "%s"' % tmdb_id)
# delete movie
if records:
payload = {"jsonrpc": "2.0", "method": "VideoLibrary.RemoveMovie", "id": 1, "params": {"movieid": records[0][0]}}
data = get_data(payload)
return
# search tvshow ID
elif item.contentType == 'tvshow':
nun_records, records = execute_sql_kodi('SELECT idShow FROM tvshow_view WHERE uniqueid_value LIKE "%s"' % tmdb_id)
# delete TV show
if records:
payload = {"jsonrpc": "2.0", "method": "VideoLibrary.RemoveTVShow", "id": 1, "params": {"tvshowid": records[0][0]}}
data = get_data(payload)
elif item.contentType == 'episode':
nun_records, records = execute_sql_kodi('SELECT idEpisode FROM episode_view WHERE uniqueid_value LIKE "%s"' % episode_id)
# delete TV show
if records:
payload = {"jsonrpc": "2.0", "method": "VideoLibrary.RemoveEpisode", "id": 1, "params": {"episodeid": records[0][0]}}
data = get_data(payload)
elif item.contentType == 'season':
nun_records, records = execute_sql_kodi('SELECT idSeason FROM season_view WHERE uniqueid_value LIKE "%s"' % season_id)
# delete TV show
if records:
payload = {"jsonrpc": "2.0", "method": "VideoLibrary.RemoveSeason", "id": 1, "params": {"seasonid": records[0][0]}}
data = get_data(payload)
def check_db(path):
if '\\' in path: sep = '\\'
else: sep = '/'
@@ -1428,3 +1512,4 @@ class NextDialog(xbmcgui.WindowXMLDialog):
self.set_exit(True)
self.set_continue_watching(False)
self.close()

View File

@@ -6139,6 +6139,18 @@ msgctxt "#70834"
msgid "Playlist"
msgstr ""
msgctxt "#70835"
msgid "Episode"
msgstr ""
msgctxt "#70836"
msgid "Season"
msgstr ""
msgctxt "#70837"
msgid "Enable/Disable Channels"
msgstr ""
# DNS start [ settings and declaration ]
msgctxt "#707401"
msgid "Enable DNS check alert"

View File

@@ -6140,6 +6140,18 @@ msgctxt "#70834"
msgid "Playlist"
msgstr "Playlist"
msgctxt "#70835"
msgid "Episode"
msgstr "Episodio"
msgctxt "#70836"
msgid "Season"
msgstr "Stagione"
msgctxt "#70837"
msgid "Enable/Disable Channels"
msgstr "Abilita/Disabilita Canali"
# DNS start [ settings and declaration ]
msgctxt "#707401"
msgid "Enable DNS check alert"

View File

@@ -12,6 +12,7 @@
<setting id="resolver_dns" type="bool" label="707408" default="true" enable="true" visible="true"/>
<setting id="checkdns" type="bool" default="true" visible="false"/>
<setting label="70788" type="lsep"/>
<setting id="episode_info" type="bool" label="Infornmazioni episodio (non consigliato in dispositivi lenti)" default="false"/>
<setting id="debug" type="bool" label="30003" default="false"/>
<setting id="chrome_ua_version" type="text" default="87.0.4280.88" visible="False"/>
</category>

View File

@@ -918,7 +918,7 @@ def get_episodes(item):
info("Omitiendo item no válido:", episode.tostring())
# Any other result is not worth it, we ignore it...
itemlist = videolibrarytools.filter_list(itemlist)
# itemlist = videolibrarytools.filter_list(itemlist)
return itemlist

View File

@@ -642,7 +642,7 @@ class SearchWindow(xbmcgui.WindowXML):
busy(False)
return
if item.action in ['add_pelicula_to_library', 'add_serie_to_library','save_download']: # special items (add to videolibrary, download ecc.)
if item.action in ['add_movie_to_library', 'add_serie_to_library','save_download']: # special items (add to videolibrary, download ecc.)
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item_url + ")")
busy(False)
return

File diff suppressed because it is too large Load Diff