1194 lines
55 KiB
Python
1194 lines
55 KiB
Python
# -*- coding: utf-8 -*-
|
||
# ------------------------------------------------------------
|
||
# Common Library Tools
|
||
# ------------------------------------------------------------
|
||
|
||
import sys
|
||
PY3 = False
|
||
if sys.version_info[0] >= 3: PY3 = True; unicode = str; unichr = chr; long = int
|
||
|
||
if PY3: from concurrent import futures
|
||
else: from concurrent_py2 import futures
|
||
|
||
import math, traceback, re, os
|
||
|
||
from core import filetools, scraper, scrapertools, support, httptools, tmdb
|
||
from core.item import Item
|
||
from lib import generictools
|
||
from platformcode import config, dbconverter, logger, platformtools
|
||
from platformcode.autorenumber import RENUMBER
|
||
from core.videolibrarydb import videolibrarydb
|
||
|
||
FOLDER_MOVIES = config.get_setting("folder_movies")
|
||
FOLDER_TVSHOWS = config.get_setting("folder_tvshows")
|
||
VIDEOLIBRARY_PATH = config.get_videolibrary_path()
|
||
MOVIES_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_MOVIES)
|
||
TVSHOWS_PATH = filetools.join(VIDEOLIBRARY_PATH, FOLDER_TVSHOWS)
|
||
|
||
if not FOLDER_MOVIES or not FOLDER_TVSHOWS or not VIDEOLIBRARY_PATH or not filetools.exists(MOVIES_PATH) or not filetools.exists(TVSHOWS_PATH):
|
||
config.verify_directories_created()
|
||
|
||
addon_name = "plugin://plugin.video.%s/" % config.PLUGIN_NAME
|
||
|
||
quality_order = ['4k', '2160p', '2160', '4k2160p', '4k2160', '4k 2160p', '4k 2160', '2k',
|
||
'fullhd', 'fullhd 1080', 'fullhd 1080p', 'full hd', 'full hd 1080', 'full hd 1080p', 'hd1080', 'hd1080p', 'hd 1080', 'hd 1080p', '1080', '1080p',
|
||
'hd', 'hd720', 'hd720p', 'hd 720', 'hd 720p', '720', '720p', 'hdtv',
|
||
'sd', '480p', '480', '360p', '360', '240p', '240']
|
||
|
||
video_extensions = ['3g2', '3gp', '3gp2', 'asf', 'avi', 'divx', 'flv', 'iso', 'm4v', 'mk2', 'mk3d', 'mka', 'mkv', 'mov', 'mp4', 'mp4a', 'mpeg', 'mpg', 'ogg', 'ogm', 'ogv', 'qt', 'ra', 'ram', 'rm', 'ts', 'vob', 'wav', 'webm', 'wma', 'wmv']
|
||
subtitle_extensions = ['srt', 'idx', 'sub', 'ssa', 'ass']
|
||
image_extensions = ['.jpg', '.jpeg', '.png']
|
||
library_extension = ['.nfo', '.strm', '.json']
|
||
|
||
|
||
def save_movie(item, silent=False):
|
||
"""
|
||
saves the item element in the movie library, with the values it contains.
|
||
@type item: item
|
||
@param item: item to be saved.
|
||
@rtype inserted: int
|
||
@return: the number of elements inserted
|
||
@rtype overwritten: int
|
||
@return: the number of overwritten elements
|
||
@rtype failed: int
|
||
@return: the number of failed items or -1 if all failed
|
||
"""
|
||
|
||
logger.debug()
|
||
# logger.debug(item.tostring('\n'))
|
||
inserted = 0
|
||
overwritten = 0
|
||
failed = 0
|
||
path = ""
|
||
|
||
# Put the correct title on your site so that scraper can locate it
|
||
if not item.contentTitle:
|
||
if item.fulltitle: item.contentTitle = item.fulltitle
|
||
else: item.contentTitle = re.sub(r'\[\s*[^\]]+\]', '', item.title).strip()
|
||
|
||
# If at this point we do not have a title, we leave
|
||
if not item.contentTitle or not item.channel:
|
||
logger.debug("contentTitle NOT FOUND")
|
||
return 0, 0, -1, path # Salimos sin guardar
|
||
|
||
# At this point we can have:
|
||
# scraper_return = True: An item with infoLabels with the updated information of the movie
|
||
# scraper_return = False: An item without movie information (it has been canceled in the window)
|
||
# item.infoLabels['code'] == "" : The required IMDB identifier was not found to continue, we quit
|
||
if not item.infoLabels['code']:
|
||
logger.debug("NOT FOUND IN SCRAPER OR DO NOT HAVE code")
|
||
return 0, 0, -1, path
|
||
|
||
# Get ID from infoLabels
|
||
_id = get_id(item)
|
||
if not _id:
|
||
logger.debug("NOT FOUND IN SCRAPER OR DO NOT HAVE code")
|
||
return 0, 0, -1, path
|
||
|
||
# get parameters from db
|
||
try:
|
||
moviedb = videolibrarydb['movie'].get(_id, {})
|
||
movie_item = moviedb.get('item', Item())
|
||
head_nfo = movie_item.head_nfo
|
||
channels = moviedb.get('channels',{})
|
||
except:
|
||
logger.debug("The film cannot be added to the database")
|
||
videolibrarydb.close()
|
||
return 0, 0, -1, path
|
||
|
||
# progress dialog
|
||
if not silent: p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), config.get_localized_string(60062))
|
||
|
||
base_name = set_base_name(item, _id)
|
||
path = filetools.join(MOVIES_PATH, base_name)
|
||
|
||
it, local_files = get_local_files(path, item)
|
||
|
||
# check if path already exist
|
||
if not filetools.exists(path):
|
||
logger.debug("Creating movie directory:" + path)
|
||
if not filetools.mkdir(path):
|
||
logger.debug("Could not create directory")
|
||
videolibrarydb.close()
|
||
return 0, 0, -1, path
|
||
try:
|
||
# set nfo and strm paths
|
||
nfo_path = filetools.join(base_name, "{}.nfo".format(base_name))
|
||
strm_path = filetools.join(base_name, "{}.strm".format(base_name))
|
||
|
||
# check if nfo and strm file exist
|
||
nfo_exists = filetools.exists(filetools.join(MOVIES_PATH, nfo_path))
|
||
strm_exists = filetools.exists(filetools.join(MOVIES_PATH, strm_path))
|
||
|
||
if not head_nfo:
|
||
head_nfo = scraper.get_nfo(item)
|
||
|
||
|
||
# get extra info from fanart tv
|
||
# support.dbg()
|
||
extra_info = get_fanart_tv(item)
|
||
if not item.infoLabels.get('posters', []): item.infoLabels['posters'] = []
|
||
item.infoLabels['posters'] += extra_info['poster']
|
||
if not item.infoLabels.get('fanarts', []): item.infoLabels['fanarts'] = []
|
||
item.infoLabels['fanarts'] += extra_info['fanart']
|
||
if not item.infoLabels.get('clearlogos', []): item.infoLabels['clearlogos'] = []
|
||
item.infoLabels['clearlogos'] += extra_info['clearlogo']
|
||
if not item.infoLabels.get('cleararts', []): item.infoLabels['cleararts'] = []
|
||
item.infoLabels['cleararts'] += extra_info['clearart']
|
||
if not item.infoLabels.get('landscapes', []): item.infoLabels['landscapes'] = []
|
||
item.infoLabels['landscapes'] += extra_info['landscape']
|
||
if not item.infoLabels.get('banners', []): item.infoLabels['banners'] = []
|
||
item.infoLabels['banners'] += extra_info['banner']
|
||
if not item.infoLabels.get('discs', []): item.infoLabels['discs'] = []
|
||
item.infoLabels['discs'] += extra_info['disc']
|
||
|
||
if 'setid' in item.infoLabels:
|
||
c_playcount = 0
|
||
collection = videolibrarydb['collection'].get(item.infoLabels['setid'], None)
|
||
if item.infoLabels.get('playcount', 0) > 0:
|
||
collections = [c for c in dict(videolibrarydb['collection']).values() if c.infoLabels.get('setid') == item.infoLabels['setid']]
|
||
viewed = [c for c in collections if c.infoLabels.get('playcount') > 0]
|
||
if len(collections) == len(viewed):
|
||
c_playcount = 1
|
||
if not collection:
|
||
collection = Item(title=item.infoLabels['set'],
|
||
plot=item.infoLabels['setoverview'],
|
||
infoLabels={'playcount':c_playcount},
|
||
thumbnail=item.infoLabels.get('setposters')[0] if item.infoLabels.get('setposters') else item.thumbnail,
|
||
fanart=item.infoLabels.get('setfanarts')[0] if item.infoLabels.get('setfanarts') else item.fanart,
|
||
videolibrary_id = item.infoLabels['setid'],
|
||
set = item.infoLabels['setid'],
|
||
channel = "videolibrary",
|
||
action='list_movies')
|
||
|
||
if not collection.infoLabels.get('posters') and item.infoLabels.get('setposters'):
|
||
collection.infoLabels['posters'] = item.infoLabels['setposters']
|
||
if not collection.infoLabels.get('fanarts') and item.infoLabels.get('fanarts'):
|
||
collection.infoLabels['fanarts'] = item.infoLabels['setfanarts']
|
||
if not collection.infoLabels.get('clearlogos') and extra_info.get('setclearlogo'):
|
||
collection.infoLabels['clearlogos'] = extra_info['setclearlogo']
|
||
collection.infoLabels['clearlogo'] = extra_info['setclearlogo'][0]
|
||
if not collection.infoLabels.get('cleararts') and extra_info.get('setclearart'):
|
||
collection.infoLabels['cleararts'] = extra_info['setclearart']
|
||
collection.infoLabels['clearart'] = extra_info['setclearart'][0]
|
||
if not collection.infoLabels.get('landscapes') and extra_info.get('setlandscape'):
|
||
collection.infoLabels['landscapes'] = extra_info['setlandscape']
|
||
collection.infoLabels['landscape'] = extra_info['setlandscape'][0]
|
||
if not collection.infoLabels.get('banners') and extra_info.get('setbanner'):
|
||
collection.infoLabels['banners'] = extra_info['setbanner']
|
||
collection.infoLabels['banner'] = extra_info['setbanner'][0]
|
||
if not collection.infoLabels.get('discs') and extra_info.get('setdisc'):
|
||
collection.infoLabels['discs'] = extra_info['setdisc']
|
||
collection.infoLabels['disc'] = extra_info['setdisc'][0]
|
||
videolibrarydb['collection'][item.infoLabels['setid']] = collection
|
||
|
||
|
||
# Make or update Videolibrary Movie Item
|
||
movie_item.channel = "videolibrary"
|
||
movie_item.action = 'findvideos'
|
||
movie_item.infoLabels = item.infoLabels
|
||
movie_item.infoLabels['playcount'] = item.infoLabels.get('playcount',0)
|
||
if not movie_item.head_nfo: movie_item.head_nfo = head_nfo
|
||
if not movie_item.title: movie_item.title = item.contentTitle
|
||
if not movie_item.videolibrary_id: movie_item.videolibrary_id = _id
|
||
if not movie_item.strm_path: movie_item.strm_path = strm_path
|
||
if not movie_item.nfo_path: movie_item.nfo_path = nfo_path
|
||
if not movie_item.base_name: movie_item.base_name = base_name
|
||
if not movie_item.thumbnail: movie_item.thumbnail = item.infoLabels['thumbnail']
|
||
if not movie_item.fanart: movie_item.fanart = item.infoLabels['fanart']
|
||
if not movie_item.infoLabels['landscape'] and item.infoLabels['landscapes']: movie_item.infoLabels['landscape'] = item.infoLabels['landscapes'][0]
|
||
if not movie_item.infoLabels['banner'] and item.infoLabels['banners']: movie_item.infoLabels['banner']= item.infoLabels['banners'][0]
|
||
if not movie_item.infoLabels['clearart'] and item.infoLabels['cleararts']: movie_item.infoLabels['clearart'] = item.infoLabels['cleararts'][0]
|
||
if not movie_item.infoLabels['clearlogo'] and item.infoLabels['clearlogos']: movie_item.infoLabels['clearlogo'] = item.infoLabels['clearlogos'][0]
|
||
if not movie_item.infoLabels['disc'] and item.infoLabels['discs']: movie_item.infoLabels['disc'] = item.infoLabels['discs'][0]
|
||
if not movie_item.prefered_lang: movie_item.prefered_lang = ''
|
||
if not movie_item.lang_list: movie_item.lang_list = []
|
||
movie_item.no_reload = item.no_reload
|
||
|
||
if not item.contentLanguage: item.contentLanguage = 'ITA'
|
||
if not item.contentLanguage in movie_item.lang_list: movie_item.lang_list.append(item.contentLanguage)
|
||
|
||
if len(movie_item.lang_list) > 1:
|
||
movie_item.prefered_lang = movie_item.lang_list[platformtools.dialog_select(config.get_localized_string(70246), movie_item.lang_list)]
|
||
else:
|
||
movie_item.prefered_lang = movie_item.lang_list[0]
|
||
|
||
# create nfo file if it does not exist
|
||
|
||
if not nfo_exists:
|
||
filetools.write(filetools.join(MOVIES_PATH, movie_item.nfo_path), head_nfo)
|
||
|
||
# create strm file if it does not exist
|
||
if not strm_exists and not local_files:
|
||
logger.debug("Creating .strm: " + strm_path)
|
||
item_strm = Item(channel='videolibrary', action='play_from_library', strm_path=movie_item.strm_path, contentType='movie', contentTitle=item.contentTitle, videolibrary_id=movie_item.videolibrary_id)
|
||
strm_exists = filetools.write(filetools.join(MOVIES_PATH, movie_item.strm_path), '{}?{}'.format(addon_name, item_strm.tourl()))
|
||
|
||
# checks if the content already exists
|
||
if videolibrarydb['movie'].get(_id, {}):
|
||
logger.debug("The file exists. Is overwritten")
|
||
overwritten += 1
|
||
else:
|
||
logger.debug("Creating .nfo: " + nfo_path)
|
||
inserted += 1
|
||
|
||
remove_host(item)
|
||
# write on db
|
||
if item.channel in channels and item.channel != 'download':
|
||
channels_url = [u.url for u in channels[item.channel]]
|
||
if item.url not in channels_url:
|
||
channels[item.channel].append(item)
|
||
else:
|
||
del channels[item.channel][channels_url.index(item.url)]
|
||
channels[item.channel].append(item)
|
||
else:
|
||
channels[item.channel] = [item]
|
||
|
||
if local_files.get('db') or local_files.get('internal'):
|
||
if local_files.get('db'):
|
||
channels['local']['db'] = local_files['db'][0]
|
||
elif local_files.get('internal'):
|
||
channels['local']['db'] = local_files['internal'][0]
|
||
|
||
moviedb['item'] = movie_item
|
||
moviedb['channels'] = channels
|
||
|
||
videolibrarydb['movie'][_id] = moviedb
|
||
except:
|
||
failed += 1
|
||
|
||
videolibrarydb.close()
|
||
|
||
|
||
# Only if movie_item and .strm exist we continue
|
||
if failed == 0:
|
||
if not silent:
|
||
p_dialog.update(100, item.contentTitle)
|
||
p_dialog.close()
|
||
if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not item.not_add:
|
||
# Update Kodi Library
|
||
from platformcode.dbconverter import add_video
|
||
add_video(movie_item)
|
||
# if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not silent and inserted:
|
||
# from platformcode.xbmc_videolibrary import update
|
||
# update(MOVIES_PATH)
|
||
return inserted, overwritten, failed, path
|
||
|
||
# If we get to this point it is because something has gone wrong
|
||
logger.error("Could not save %s in the video library" % item.contentTitle)
|
||
if not silent:
|
||
p_dialog.update(100, item.contentTitle)
|
||
p_dialog.close()
|
||
return 0, 0, -1, path
|
||
|
||
|
||
def save_tvshow(item, episodelist, silent=False):
|
||
"""
|
||
stores in the series library the series with all the chapters included in the episodelist
|
||
@type item: item
|
||
@param item: item that represents the series to save
|
||
@type episodelist: list
|
||
@param episodelist: list of items that represent the episodes to be saved.
|
||
@rtype inserted: int
|
||
@return: the number of episodes inserted
|
||
@rtype overwritten: int
|
||
@return: the number of overwritten episodes
|
||
@rtype failed: int
|
||
@return: the number of failed episodes or -1 if the entire series has failed
|
||
@rtype path: str
|
||
@return: serial directory
|
||
"""
|
||
|
||
inserted = 0
|
||
overwritten = 0
|
||
failed = 0
|
||
path = ""
|
||
|
||
# If at this point we do not have a title or code, we leave
|
||
if not (item.contentSerieName or item.infoLabels['code']) or not item.channel:
|
||
logger.debug("NOT FOUND contentSerieName or code")
|
||
return 0, 0, -1, path # Salimos sin guardar
|
||
|
||
# contentTypeBackup = item.contentType # Fix errors in some channels
|
||
# item.contentType = contentTypeBackup # Fix errors in some channels
|
||
# item.contentType = 'tvshow'
|
||
|
||
# At this point we can have:
|
||
# scraper_return = True: An item with infoLabels with the updated information of the series
|
||
# scraper_return = False: An item without movie information (it has been canceled in the window)
|
||
# item.infoLabels['code'] == "" :T he required IMDB identifier was not found to continue, we quit
|
||
if not item.infoLabels['code']:
|
||
logger.debug("NOT FOUND IN SCRAPER OR DO NOT HAVE code")
|
||
return 0, 0, -1, path
|
||
|
||
# Get ID from infoLabels
|
||
_id = get_id(item)
|
||
if not _id:
|
||
logger.debug("NOT FOUND IN SCRAPER OR DO NOT HAVE code")
|
||
return 0, 0, -1, path
|
||
|
||
# get parameters from db
|
||
try:
|
||
tvshowdb = videolibrarydb['tvshow'].get(_id, {})
|
||
tvshow_item = tvshowdb.get('item', Item())
|
||
head_nfo = tvshow_item.head_nfo
|
||
channels = tvshowdb.get('channels',{})
|
||
|
||
except:
|
||
logger.debug("The tv show cannot be added to the database")
|
||
videolibrarydb.close()
|
||
return 0, 0, -1, path
|
||
|
||
# set base name
|
||
base_name = set_base_name(item, _id)
|
||
path = filetools.join(TVSHOWS_PATH, base_name)
|
||
|
||
item.local_episodes_path = tvshow_item.local_episodes_path
|
||
item, local_files = get_local_files(path, item)
|
||
tvshow_item.local_episodes_path = item.local_episodes_path
|
||
|
||
# check if path already exist
|
||
if not filetools.exists(path):
|
||
logger.debug("Creating tv show directory:" + path)
|
||
if not filetools.mkdir(path):
|
||
logger.debug("Could not create directory")
|
||
return 0, 0, -1, path
|
||
|
||
nfo_path = filetools.join(base_name, "tvshow.nfo")
|
||
nfo_exists = filetools.exists(filetools.join(TVSHOWS_PATH, nfo_path))
|
||
|
||
# get parameters
|
||
if not item.head_nfo:
|
||
head_nfo = scraper.get_nfo(item)
|
||
if not head_nfo: return 0, 0, -1, ''
|
||
|
||
extra_info = get_fanart_tv(item)
|
||
if not item.infoLabels.get('posters'):item.infoLabels['posters'] = []
|
||
item.infoLabels['posters'] += extra_info['poster'].get('all',[])
|
||
if not item.infoLabels.get('fanarts'): item.infoLabels['fanarts'] = []
|
||
item.infoLabels['fanarts'] += extra_info['fanart']
|
||
if not item.infoLabels.get('clearlogos'): item.infoLabels['clearlogos'] = []
|
||
item.infoLabels['clearlogos'] += extra_info['clearlogo']
|
||
if not item.infoLabels.get('cleararts'): item.infoLabels['cleararts'] = []
|
||
item.infoLabels['cleararts'] += extra_info['clearart']
|
||
if not item.infoLabels.get('landscapes'): item.infoLabels['landscapes'] = []
|
||
item.infoLabels['landscapes'] += extra_info['landscape'].get('all',[])
|
||
if not item.infoLabels.get('banners'):item.infoLabels['banners'] = []
|
||
item.infoLabels['banners'] += extra_info['banner'].get('all',[])
|
||
|
||
|
||
item.infoLabels['mediatype'] = 'tvshow'
|
||
item.contentType = 'tvshow'
|
||
if item.contentSerieName: item.infoLabels['title'] = item.contentSerieName
|
||
tvshow_item.infoLabels = item.infoLabels
|
||
if not tvshow_item.infoLabels.get('playcount'): tvshow_item.infoLabels['playcount'] = 0
|
||
tvshow_item.channel = 'videolibrary'
|
||
tvshow_item.action = 'get_seasons'
|
||
tvshow_item.nfo_path = nfo_path
|
||
if not tvshow_item.head_nfo: tvshow_item.head_nfo = head_nfo
|
||
if not tvshow_item.title: tvshow_item.title = item.infoLabels['title']
|
||
if not tvshow_item.videolibrary_id: tvshow_item.videolibrary_id = _id
|
||
if not tvshow_item.thumbnail: tvshow_item.thumbnail = item.infoLabels['thumbnail']
|
||
if not tvshow_item.fanart: tvshow_item.fanart = item.infoLabels['fanart']
|
||
if not tvshow_item.infoLabels.get('landscape'): tvshow_item.infoLabels['landscape'] = item.infoLabels['landscapes'][0] if item.infoLabels['landscapes'] else item.infoLabels['fanart']
|
||
if not tvshow_item.infoLabels.get('banner') and item.infoLabels['banners']: tvshow_item.infoLabels['banner'] = item.infoLabels['banners'][0]
|
||
if not tvshow_item.infoLabels.get('clearart') and item.infoLabels['cleararts']: tvshow_item.infoLabels['clearart'] = item.infoLabels['cleararts'][0]
|
||
if not tvshow_item.infoLabels.get('clearlogo') and item.infoLabels['clearlogos']: tvshow_item.infoLabels['clearlogo'] = item.infoLabels['clearlogos'][0]
|
||
if not tvshow_item.base_name: tvshow_item.base_name = base_name
|
||
if tvshow_item.active == '': tvshow_item.active = True
|
||
if not tvshow_item.prefered_lang: tvshow_item.prefered_lang = ''
|
||
if not tvshow_item.lang_list: tvshow_item.lang_list = []
|
||
|
||
tvshow_item.no_reload = item.no_reload
|
||
|
||
remove_host(item)
|
||
|
||
item.renumber = add_renumber_options(item)
|
||
|
||
# write on db
|
||
if item.channel in channels and item.channel != 'download':
|
||
channels_url = [u.url for u in channels[item.channel]]
|
||
if item.url not in channels_url:
|
||
channels[item.channel].append(item)
|
||
else:
|
||
del channels[item.channel][channels_url.index(item.url)]
|
||
channels[item.channel].append(item)
|
||
else:
|
||
channels[item.channel] = [item]
|
||
tvshowdb['item'] = tvshow_item
|
||
tvshowdb['channels'] = channels
|
||
videolibrarydb['tvshow'][_id] = tvshowdb
|
||
|
||
if not nfo_exists:
|
||
filetools.write(filetools.join(TVSHOWS_PATH, tvshow_item.nfo_path), head_nfo)
|
||
|
||
if not episodelist:
|
||
# The episode list is empty
|
||
return 0, 0, -1, path
|
||
|
||
# Save the episodes
|
||
logger.debug()
|
||
inserted, overwritten, failed = save_episodes(tvshow_item, episodelist, extra_info, item.host, local_files, silent=silent)
|
||
videolibrarydb.close()
|
||
if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not item.not_add:
|
||
from platformcode.dbconverter import add_video
|
||
add_video(tvshow_item)
|
||
|
||
|
||
return inserted, overwritten, failed, path
|
||
|
||
|
||
def save_episodes(item, episodelist, extra_info, host, local_files, silent=False):
|
||
logger.debug()
|
||
|
||
def save_episode(item, episodes, e):
|
||
inserted = 0
|
||
overwritten = 0
|
||
failed = 0
|
||
episode = None
|
||
season_episode = None
|
||
|
||
|
||
if e.contentSeason and e.contentEpisodeNumber:
|
||
season_episode = '{}x{:02d}'.format(e.contentSeason, e.contentEpisodeNumber)
|
||
strm_path = filetools.join(item.base_name, "{}.strm".format(season_episode))
|
||
|
||
if item.infoLabels.get('imdb_id'): e.infoLabels['imdb_id'] = item.infoLabels['imdb_id']
|
||
if item.infoLabels.get('tmdb_id'): e.infoLabels['tmdb_id'] = item.infoLabels['tmdb_id']
|
||
if item.infoLabels.get('tvdb_id'): e.infoLabels['tvdb_id'] = item.infoLabels['tvdb_id']
|
||
|
||
tmdb.set_infoLabels_item(e)
|
||
if not e.infoLabels.get('playcount'): e.infoLabels['playcount'] = 0
|
||
head_nfo = scraper.get_nfo(e)
|
||
|
||
episode_item = Item(action='findvideos',
|
||
channel='videolibrary',
|
||
strm_path=strm_path,
|
||
contentSeason = e.contentSeason,
|
||
contentEpisodeNumber = e.contentEpisodeNumber,
|
||
contentType = e.contentType,
|
||
infoLabels = e.infoLabels,
|
||
head_nfo = head_nfo,
|
||
videolibrary_id = item.videolibrary_id,
|
||
thumbnail = e.infoLabels.get('poster_path') if e.infoLabels.get('poster_path') else item.thumbnail,
|
||
fanart = e.infoLabels.get('poster_path') if e.infoLabels.get('poster_path') else item.fanart,
|
||
title = e.infoLabels['title'])
|
||
|
||
episode = episodes.get(season_episode, {})
|
||
|
||
try:
|
||
if not episode:
|
||
inserted += 1
|
||
episode['item'] = episode_item
|
||
|
||
# else:
|
||
epchannels = episode.get('channels',{})
|
||
|
||
if e.url.startswith(host):
|
||
remove_host(e)
|
||
|
||
e.contentTitle = e.infoLabels['title']
|
||
contentType = e.contentType
|
||
e.infoLabels = {}
|
||
e.contentType = contentType
|
||
|
||
if e.channel in epchannels and e.channel != 'download':
|
||
channels_url = [u.url for u in epchannels[e.channel]]
|
||
if e.url not in channels_url:
|
||
epchannels[e.channel].append(e)
|
||
overwritten += 1
|
||
else:
|
||
del epchannels[e.channel][channels_url.index(e.url)]
|
||
epchannels[e.channel].append(e)
|
||
overwritten += 1
|
||
else:
|
||
epchannels[e.channel] = [e]
|
||
overwritten += 1
|
||
|
||
# add local files
|
||
if list(local_files.values()):
|
||
epchannels['local'] = {}
|
||
if season_episode in list(local_files.get('db',{}).keys()):
|
||
epchannels['local']['db'] = local_files['db'][season_episode]
|
||
if season_episode in list(local_files.get('internal',{}).keys()):
|
||
epchannels['local']['internal'] = local_files['db'][season_episode]
|
||
if season_episode in list(local_files.get('connected',{}).keys()):
|
||
epchannels['local']['connected'] = local_files['connected'][season_episode]
|
||
logger.debug('LOCALS', epchannels)
|
||
# if season_episode in list(local_files.get('external',{}).keys()):
|
||
# epchannels['external'] = local_files['db'][season_episode]
|
||
|
||
# Delete the local key if local files no longer exist
|
||
elif 'local' in epchannels:
|
||
del epchannels['local']
|
||
|
||
episode['channels'] = epchannels
|
||
|
||
except:
|
||
logger.error(traceback.format_exc())
|
||
failed += 1
|
||
|
||
# add strm_file if episode is not present in db or inside videolibrary path
|
||
# if not filetools.exists(filetools.join(TVSHOWS_PATH, strm_path)):
|
||
if season_episode not in local_files.get('db',{}).keys():
|
||
logger.debug("Creating .strm: " + strm_path)
|
||
item_strm = Item(channel='videolibrary', action='play_from_library', strm_path=strm_path, contentType='episode', videolibrary_id=episode_item.videolibrary_id, contentSeason = episode_item.contentSeason, contentEpisodeNumber = episode_item.contentEpisodeNumber,)
|
||
filetools.write(filetools.join(TVSHOWS_PATH, strm_path), '{}?{}'.format(addon_name, item_strm.tourl()))
|
||
|
||
# update db if episode added
|
||
# if failed == 0 and config.get_setting('kod_scraper'):
|
||
# add_video(episode_item)
|
||
|
||
return item, episode, season_episode, e.contentLanguage, inserted, overwritten, failed
|
||
|
||
def save_season(item, s, w):
|
||
tmdb_info = tmdb.Tmdb(id_Tmdb = item.infoLabels['tmdb_id'], search_type='tv')
|
||
seasoninfo = tmdb.get_season_dic(tmdb_info.get_season(s))
|
||
infoLabels = {}
|
||
|
||
if seasoninfo.get('season_posters'): infoLabels['posters'] = seasoninfo.get('season_posters') + extra_info['poster'].get(str(s), [])
|
||
if seasoninfo.get('season_fanarts'): infoLabels['fanarts'] = seasoninfo.get('season_fanarts') + extra_info['fanart'].get(str(s), [])
|
||
if seasoninfo.get('season_trailer'): infoLabels['trailer'] = seasoninfo.get('season_trailer')
|
||
infoLabels['landscapes'] = extra_info['landscape'].get(str(s), [])
|
||
infoLabels['banners'] = extra_info['banner'].get(str(s), [])
|
||
infoLabels['clearlogos'] = item.infoLabels.get('clearlogos', [])
|
||
infoLabels['cleararts'] = item.infoLabels.get('cleararts', [])
|
||
infoLabels['playcount'] = w
|
||
|
||
season_item = Item(action="get_episodes",
|
||
channel='videolibrary',
|
||
title=seasoninfo.get('season_title'),
|
||
thumbnail = seasoninfo.get('season_poster') if seasoninfo.get('season_poster') else item.thumbnail,
|
||
fanart = item.fanart,
|
||
plot = seasoninfo.get('season_plot') if seasoninfo.get('season_plot') else item.infoLabels.get('plot'),
|
||
contentType = 'season',
|
||
infoLabels = infoLabels,
|
||
contentSeason = s,
|
||
videolibrary_id = item.videolibrary_id)
|
||
|
||
if infoLabels['clearlogos']: season_item.clearlogo = infoLabels['clearlogos'][0]
|
||
if infoLabels['cleararts']: season_item.clearart = infoLabels['cleararts'][0]
|
||
if infoLabels['landscapes']: season_item.landscape = infoLabels['landscapes'][0]
|
||
if infoLabels['banners']: season_item.banner = infoLabels['banners'][0]
|
||
|
||
return s, season_item
|
||
|
||
def watched_season(s):
|
||
w = 0
|
||
s_ep = [e['item'] for e in episodes.values() if e['item'].contentSeason == s]
|
||
w_ep = [e for e in s_ep if e.infoLabels.get('playcount') > 0]
|
||
if len(s_ep) == len(w_ep): w = 1
|
||
return s, w
|
||
|
||
|
||
# No episode list, nothing to save
|
||
if not len(episodelist):
|
||
logger.debug("There is no episode list, we go out without creating strm")
|
||
return 0, 0, 0
|
||
|
||
# Silent is to show no progress (for service)
|
||
if not silent:
|
||
# progress dialog
|
||
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(60064) ,'')
|
||
|
||
inserted = 0
|
||
overwritten = 0
|
||
failed = 0
|
||
current_seasons = []
|
||
seasons = videolibrarydb['season'].get(item.videolibrary_id, {})
|
||
episodes = videolibrarydb['episode'].get(item.videolibrary_id, {})
|
||
videolibrarydb.close()
|
||
|
||
try: t = float(100) / len(episodelist)
|
||
except: t = 0
|
||
|
||
i = 0
|
||
# save episodes Thread
|
||
with futures.ThreadPoolExecutor() as executor:
|
||
itlist = [executor.submit(save_episode, item, episodes, e) for e in episodelist]
|
||
for res in futures.as_completed(itlist):
|
||
if res.result():
|
||
item, episode, season_episode, lang, I, O, F = res.result()
|
||
inserted += I
|
||
overwritten += O
|
||
failed += F
|
||
if episode:
|
||
episodes[season_episode] = episode
|
||
e = episode['item']
|
||
if not e.contentSeason in current_seasons: current_seasons.append(e.contentSeason)
|
||
if not lang: lang = item.contentLanguage if item.contentLanguage else 'ITA'
|
||
if not lang in item.lang_list: item.lang_list.append(lang)
|
||
if not silent:
|
||
i += 1
|
||
p_dialog.update(int(math.ceil(i * t)), message=e.title)
|
||
|
||
# support.dbg()
|
||
# for e in episodelist:
|
||
# item, episode, season_episode, lang, I, O, F = save_episode(item, episodes, e)
|
||
# inserted += I
|
||
# overwritten += O
|
||
# failed += F
|
||
# if episode:
|
||
# episodes[season_episode] = episode
|
||
# e = episode['item']
|
||
# if not e.contentSeason in current_seasons: current_seasons.append(e.contentSeason)
|
||
# if not lang: lang = item.contentLanguage if item.contentLanguage else 'ITA'
|
||
# if not lang in item.lang_list: item.lang_list.append(lang)
|
||
# if not silent:
|
||
# i += 1
|
||
# p_dialog.update(int(math.ceil(i * t)), message=e.title)
|
||
|
||
# set seasons as watched
|
||
add_seasons = {}
|
||
with futures.ThreadPoolExecutor() as executor:
|
||
itlist = [executor.submit(watched_season, s) for s in current_seasons]
|
||
for res in futures.as_completed(itlist):
|
||
add_seasons[res.result()[0]] = res.result()[1]
|
||
|
||
# save seasons
|
||
with futures.ThreadPoolExecutor() as executor:
|
||
itlist = [executor.submit(save_season, item, s, w) for s, w in add_seasons.items()]
|
||
for res in futures.as_completed(itlist):
|
||
if res.result():
|
||
s, season_item = res.result()
|
||
seasons[s] = season_item
|
||
|
||
# Add to Kodi DB if Kod is set to add information
|
||
# if config.get_setting('kod_scraper'):
|
||
# add_video(season_item)
|
||
|
||
|
||
if not silent:
|
||
# update tvshow info if forced
|
||
if len(item.lang_list) > 1:
|
||
item.prefered_lang = item.lang_list[platformtools.dialog_select(config.get_localized_string(70246), item.lang_list)]
|
||
else:
|
||
item.prefered_lang = item.lang_list[0]
|
||
|
||
tvshowdb = videolibrarydb['tvshow'][item.videolibrary_id]
|
||
tvshowdb['item'] = item
|
||
videolibrarydb['tvshow'][item.videolibrary_id] = tvshowdb
|
||
videolibrarydb.close()
|
||
|
||
videolibrarydb['episode'][item.videolibrary_id] = episodes
|
||
videolibrarydb['season'][item.videolibrary_id] = seasons
|
||
|
||
videolibrarydb.close()
|
||
if not silent:
|
||
p_dialog.close()
|
||
|
||
return inserted, overwritten, failed
|
||
|
||
|
||
def add_to_videolibrary(item, channel):
|
||
itemlist = getattr(channel, item.from_action)(item)
|
||
if itemlist and itemlist[0].contentType == 'episode':
|
||
return add_tvshow(item, itemlist=itemlist)
|
||
elif itemlist and itemlist[0].server:
|
||
return add_movie(item)
|
||
else:
|
||
videolibrarydb.close()
|
||
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(70838) % item.contentTitle)
|
||
|
||
|
||
def add_movie(item):
|
||
"""
|
||
Keep a movie at the movie library. The movie can be a link within a channel or a previously downloaded video.
|
||
|
||
To add locally downloaded episodes, the item must have exclusively:
|
||
- contentTitle: title of the movie
|
||
- title: title to show next to the list of links -findvideos- ("Play local HD video")
|
||
- infoLabels ["tmdb_id"] o infoLabels ["imdb_id"]
|
||
- contentType == "movie"
|
||
- channel = "downloads"
|
||
- url: local path to the video
|
||
|
||
@type item: item
|
||
@param item: item to be saved.
|
||
"""
|
||
logger.debug()
|
||
item.contentType = 'movie'
|
||
# from platformcode.launcher import set_search_temp; set_search_temp(item)
|
||
|
||
# To disambiguate titles, TMDB is caused to ask for the really desired title
|
||
# The user can select the title among those offered on the first screen
|
||
# or you can cancel and enter a new title on the second screen
|
||
# If you do it in "Enter another name", TMDB will automatically search for the new title
|
||
# If you do it in "Complete Information", it partially changes to the new title, but does not search TMDB. We have to do it
|
||
# If the second screen is canceled, the variable "scraper_return" will be False. The user does not want to continue
|
||
|
||
item = generictools.update_title(item) # We call the method that updates the title with tmdb.find_and_set_infoLabels
|
||
|
||
if item:
|
||
new_item = item.clone(action="findvideos")
|
||
inserted, overwritten, failed, path = save_movie(new_item)
|
||
|
||
if failed == 0:
|
||
platformtools.dialog_notification(config.get_localized_string(30131), config.get_localized_string(30135) % new_item.contentTitle) # 'has been added to the video library'
|
||
else:
|
||
filetools.rmdirtree(path)
|
||
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60066) % new_item.contentTitle) # "ERROR, the movie has NOT been added to the video library")
|
||
movies = videolibrarydb['movie']
|
||
_id = get_id(item)
|
||
if _id in list(movies.keys()):
|
||
del movies[_id]
|
||
videolibrarydb['movie'] = movies
|
||
videolibrarydb.close()
|
||
|
||
|
||
def add_tvshow(item, channel=None, itemlist=[]):
|
||
"""
|
||
Save content in the series library. This content can be one of these two:
|
||
- The series with all the chapters included in the episodelist.
|
||
- A single chapter previously downloaded locally.
|
||
|
||
To add locally downloaded episodes, the item must have exclusively:
|
||
- contentSerieName (or show): Title of the series
|
||
- contentTitle: title of the episode to extract season_and_episode ("1x01 Pilot")
|
||
- title: title to show next to the list of links -findvideos- ("Play local video")
|
||
- infoLabels ["tmdb_id"] o infoLabels ["imdb_id"]
|
||
- contentType != "movie"
|
||
- channel = "downloads"
|
||
- url: local path to the video
|
||
|
||
@type item: item
|
||
@param item: item that represents the series to save
|
||
@type channel: modulo
|
||
@param channel: channel from which the series will be saved. By default, item.from_channel or item.channel will be imported.
|
||
|
||
"""
|
||
logger.debug("show=#" + item.show + "#")
|
||
item.contentType = 'tvshow'
|
||
# from platformcode.launcher import set_search_temp; set_search_temp(item)
|
||
|
||
if item.channel == "downloads":
|
||
itemlist = [item.clone()]
|
||
|
||
else:
|
||
# This mark is because the item has something else apart in the "extra" attribute
|
||
# item.action = item.extra if item.extra else item.action
|
||
if isinstance(item.extra, str) and "###" in item.extra:
|
||
item.action = item.extra.split("###")[0]
|
||
item.extra = item.extra.split("###")[1]
|
||
|
||
if item.from_action:
|
||
item.__dict__["action"] = item.__dict__.pop("from_action")
|
||
if item.from_channel:
|
||
item.__dict__["channel"] = item.__dict__.pop("from_channel")
|
||
|
||
if not channel:
|
||
try:
|
||
channel = __import__('channels.%s' % item.channel, fromlist=["channels.%s" % item.channel])
|
||
# channel = __import__('specials.%s' % item.channel, fromlist=["specials.%s" % item.channel])
|
||
except ImportError:
|
||
exec("import channels." + item.channel + " as channel")
|
||
|
||
# To disambiguate titles, TMDB is caused to ask for the really desired title
|
||
# The user can select the title among those offered on the first screen
|
||
# or you can cancel and enter a new title on the second screen
|
||
# If you do it in "Enter another name", TMDB will automatically search for the new title
|
||
# If you do it in "Complete Information", it partially changes to the new title, but does not search TMDB. We have to do it
|
||
# If the second screen is canceled, the variable "scraper_return" will be False. The user does not want to continue
|
||
|
||
item = generictools.update_title(item) # We call the method that updates the title with tmdb.find_and_set_infoLabels
|
||
|
||
if not item: return
|
||
#if item.tmdb_stat:
|
||
# del item.tmdb_stat # We clean the status so that it is not recorded in the Video Library
|
||
|
||
# Get the episode list
|
||
it = item.clone()
|
||
if not itemlist:
|
||
itemlist = getattr(channel, it.action)(it)
|
||
item.host = channel.host
|
||
if itemlist:
|
||
# support.dbg()
|
||
from platformcode.autorenumber import start, check
|
||
if not check(item, itemlist):
|
||
action = item.action
|
||
item.setrenumber = True
|
||
start(item)
|
||
item.setrenumber = False
|
||
item.action = action
|
||
if not item.exit:
|
||
return add_tvshow(item, channel)
|
||
itemlist = getattr(channel, item.action)(item)
|
||
else:
|
||
itemlist = getattr(channel, item.action)(item)
|
||
|
||
global magnet_caching
|
||
magnet_caching = False
|
||
|
||
inserted, overwritten, failed, path = save_tvshow(item, itemlist)
|
||
|
||
if not path:
|
||
pass
|
||
|
||
elif not inserted and not overwritten and not failed:
|
||
filetools.rmdirtree(path)
|
||
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60067) % item.contentTitle)
|
||
logger.error("The string %s could not be added to the video library. Could not get any episode" % item.contentTitle)
|
||
|
||
elif failed == -1:
|
||
filetools.rmdirtree(path)
|
||
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60068) % item.contentTitle)
|
||
logger.error("The string %s could not be added to the video library" % item.contentTitle)
|
||
|
||
elif failed == -2:
|
||
filetools.rmdirtree(path)
|
||
|
||
elif failed > 0:
|
||
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60069) % item.contentTitle)
|
||
logger.error("Could not add %s episodes of series %s to the video library" % (failed, item.contentTitle))
|
||
|
||
else:
|
||
platformtools.dialog_notification(config.get_localized_string(30131), config.get_localized_string(60070) % item.contentTitle)
|
||
logger.debug("%s episodes of series %s have been added to the video library" % (inserted, item.contentTitle))
|
||
if config.is_xbmc():
|
||
if config.get_setting("sync_trakt_new_tvshow", "videolibrary"):
|
||
import xbmc
|
||
from platformcode import xbmc_videolibrary
|
||
if config.get_setting("sync_trakt_new_tvshow_wait", "videolibrary"):
|
||
# Check that you are not looking for content in the Kodi video library
|
||
while xbmc.getCondVisibility('Library.IsScanningVideo()'):
|
||
xbmc.sleep(1000)
|
||
# Synchronization for Kodi video library launched
|
||
xbmc_videolibrary.sync_trakt_kodi()
|
||
# Synchronization for the addon video library is launched
|
||
xbmc_videolibrary.sync_trakt_addon(path)
|
||
|
||
|
||
def remove_host(item):
|
||
if PY3: import urllib.parse as urlparse # It is very slow in PY2. In PY3 it is native
|
||
else: import urlparse # We use the native of PY2 which is faster
|
||
parsed_url = urlparse.urlparse(item.url)
|
||
item.url = urlparse.urlunparse(('', '', parsed_url.path, parsed_url.params, parsed_url.query, parsed_url.fragment))
|
||
|
||
|
||
def get_id(item):
|
||
return item.infoLabels.get('tmdb_id')
|
||
|
||
|
||
def get_fanart_tv(item, set='', ret={}):
|
||
def set_dict(l):
|
||
d = {}
|
||
for k in l:
|
||
o = d.get(k['season'], [])
|
||
o.append(k['url'])
|
||
d[k['season']] = o
|
||
return d
|
||
|
||
_id = item.infoLabels.get('tmdb_id')
|
||
# support.dbg()
|
||
|
||
if _id:
|
||
_type = item.contentType.replace('show','').replace('movie','movies')
|
||
host = 'http://webservice.fanart.tv/v3/{}/{}?api_key=cab16e262d72fea6a6843d679aa10300'
|
||
url = host.format(_type, _id)
|
||
res = httptools.downloadpage(url).json
|
||
if _type == 'tv':
|
||
ret['clearlogo'] = [k.get('url') for k in res.get('hdtvlogo', [])] + [k.get('url') for k in res.get('tvlogo', [])]
|
||
ret['clearart'] = [k.get('url') for k in res.get('hdclearart', [])] + [k.get('url') for k in res.get('hdclearart', [])]
|
||
ret['fanart'] = set_dict(res.get('showbackground', []))
|
||
ret['poster'] = set_dict(res.get('seasonposter', []))
|
||
ret['poster']['all'] = [k.get('url') for k in res.get('tvposter', [])]
|
||
ret['landscape'] = set_dict(res.get('seasonthumb', []))
|
||
ret['landscape']['all'] = [k.get('url') for k in res.get('tvthumb', [])]
|
||
ret['banner'] = set_dict(res.get('seasonbanner', []))
|
||
ret['banner']['all'] = [k.get('url') for k in res.get('tvbanner', [])]
|
||
|
||
elif _type == 'movies':
|
||
ret[set + 'clearlogo'] = [k.get('url') for k in res.get('hdmovielogo', [])] + [k.get('url') for k in res.get('movielogo', [])]
|
||
ret[set + 'poster'] = [k.get('url') for k in res.get('movieposter', [])]
|
||
ret[set + 'fanart'] = [k.get('url') for k in res.get('moviebackground', [])]
|
||
ret[set + 'clearart'] = [k.get('url') for k in res.get('hdmovieclearart', [])] + [k.get('url') for k in res.get('movieclearart', [])]
|
||
ret[set + 'landscape'] = [k.get('url') for k in res.get('moviethumb', [])]
|
||
ret[set + 'banner'] = [k.get('url') for k in res.get('moviebanner', [])]
|
||
ret[set + 'disc'] = [k.get('url') for k in res.get('moviedisc', [])]
|
||
if item.infoLabels.get('setid'):
|
||
it = item.clone(infoLabels = {'tmdb_id':item.infoLabels['setid']})
|
||
get_fanart_tv(it, 'set', ret)
|
||
|
||
return ret
|
||
|
||
|
||
def get_local_files(path, item):
|
||
from platformcode.xbmc_videolibrary import execute_sql_kodi
|
||
# check if movie or season already exist in path or db
|
||
excluded_extensions = subtitle_extensions + image_extensions + library_extension
|
||
|
||
local_files = {}
|
||
if item.contentType == 'movie':
|
||
# search on path:
|
||
internal = [f for f in filetools.listdir(path) if not (f.endswith('nfo') or f.endswith('strm') or f.endswith('json'))]
|
||
if internal:
|
||
local_files['internal'] = internal
|
||
|
||
# search on db:
|
||
sql = 'SELECT c22, uniqueid_value FROM movie_view WHERE uniqueid_type != "kod"'
|
||
n, records = execute_sql_kodi(sql)
|
||
if records:
|
||
local_files['db']= [r[0] for r in records if r[1] in item.infoLabels['code'] and not r[0].endswith('strm')]
|
||
|
||
else:
|
||
# search on path:
|
||
internal = {scrapertools.get_season_and_episode(f):f for f in filetools.listdir(path) if os.path.splitext(f)[1] not in excluded_extensions}
|
||
if internal:
|
||
local_files['internal'] = internal
|
||
|
||
# search on db:
|
||
sql = 'SELECT idShow, uniqueid_value FROM tvshow_view WHERE uniqueid_type != "kod"'
|
||
n, records = execute_sql_kodi(sql)
|
||
if records:
|
||
for r in records:
|
||
if r[1] in item.infoLabels['code']:
|
||
sql = 'SELECT strPath, strFilename From episode_view WHERE idShow = {}'.format(r[0])
|
||
n, ep_records = execute_sql_kodi(sql)
|
||
if ep_records:
|
||
local_files['db'] = {scrapertools.get_season_and_episode(e[1]):e[0]+e[1] for e in ep_records if not e[1].endswith('strm')}
|
||
break
|
||
|
||
# search on custom path
|
||
item = select_local_path(item)
|
||
if item.local_episodes_path:
|
||
connected = {scrapertools.get_season_and_episode(f):filetools.join(item.local_episodes_path, f) for f in filetools.listdir(item.local_episodes_path) if os.path.splitext(f)[1] not in excluded_extensions}
|
||
if connected:
|
||
local_files['connected'] = connected
|
||
|
||
return item, local_files
|
||
|
||
|
||
def select_local_path(item):
|
||
if not item.local_episodes_path and config.get_setting('local_episodes'):
|
||
if platformtools.dialog_yesno(config.get_localized_string(30131), config.get_localized_string(80044) % item.title):
|
||
local_episodes_path = platformtools.dialog_browse(0, config.get_localized_string(80046))
|
||
if local_episodes_path:
|
||
item.local_episodes_path = local_episodes_path
|
||
return item
|
||
|
||
|
||
def update_renumber_options(item):
|
||
from core import jsontools
|
||
|
||
filename = filetools.join(config.get_data_path(), "settings_channels", item.channel + '_data.json')
|
||
if filetools.isfile(filename):
|
||
json_file = jsontools.load(filetools.read(filename))
|
||
json = json_file.get(RENUMBER,{}).get(item.fulltitle,{})
|
||
if json:
|
||
logger.debug('UPDATED=\n' + item.fulltitle)
|
||
item.renumber = json
|
||
return item
|
||
|
||
|
||
def add_renumber_options(item):
|
||
from core import jsontools
|
||
ret = None
|
||
filename = filetools.join(config.get_data_path(), "settings_channels", item.channel + '_data.json')
|
||
json_file = jsontools.load(filetools.read(filename))
|
||
if item.renumber and not json_file.get(RENUMBER,{}).get(item.fulltitle):
|
||
check_renumber_options(item)
|
||
if RENUMBER in json_file:
|
||
json = json_file[RENUMBER]
|
||
if item.fulltitle in json:
|
||
ret = json[item.fulltitle]
|
||
return ret
|
||
|
||
|
||
def check_renumber_options(item):
|
||
from platformcode.autorenumber import load, write
|
||
if item.renumber:
|
||
json = load(item)
|
||
if not json or item.fulltitle not in json:
|
||
json[item.fulltitle] = item.renumber
|
||
write(item, json)
|
||
|
||
|
||
def read_nfo(path_nfo, item=None):
|
||
"""
|
||
Method to read nfo files.
|
||
Nfo files have the following structure: url_scraper | xml + item_json [url_scraper] and [xml] are optional, but only one of them must always exist.
|
||
@param path_nfo: absolute path to nfo file
|
||
@type path_nfo: str
|
||
@param item: If this parameter is passed the returned item will be a copy of it with the values of 'infoLabels', 'library_playcounts' and 'path' read from the nfo
|
||
@type: Item
|
||
@return: A tuple consisting of the header (head_nfo = 'url_scraper' | 'xml') and the object 'item_json'
|
||
@rtype: tuple (str, Item)
|
||
"""
|
||
head_nfo = ""
|
||
it = None
|
||
|
||
data = filetools.read(path_nfo)
|
||
|
||
if data:
|
||
head_nfo = data.splitlines()[0] + "\n"
|
||
data = "\n".join(data.splitlines()[1:])
|
||
|
||
it_nfo = Item().fromjson(data)
|
||
if not it_nfo.library_playcounts: # may be corrupted
|
||
it_nfo.library_playcounts = {}
|
||
|
||
if item:
|
||
it = item.clone()
|
||
it.infoLabels = it_nfo.infoLabels
|
||
if 'library_playcounts' in it_nfo:
|
||
it.library_playcounts = it_nfo.library_playcounts
|
||
if it_nfo.path:
|
||
it.path = it_nfo.path
|
||
else:
|
||
it = it_nfo
|
||
|
||
if 'fanart' in it.infoLabels:
|
||
it.fanart = it.infoLabels['fanart']
|
||
|
||
return head_nfo, it
|
||
|
||
|
||
def set_base_name(item, _id):
|
||
# set base_name for videolibrary
|
||
logger.debug()
|
||
if item.contentType == 'movie':
|
||
if config.get_setting("original_title_folder", "videolibrary") and item.infoLabels['originaltitle']:
|
||
base_name = item.infoLabels['originaltitle']
|
||
else:
|
||
base_name = item.contentTitle
|
||
else:
|
||
if config.get_setting("original_title_folder", "videolibrary") and item.infoLabels['originaltitle']:
|
||
base_name = item.infoLabels['originaltitle']
|
||
elif item.infoLabels['tvshowtitle']:
|
||
base_name = item.infoLabels['tvshowtitle']
|
||
elif item.infoLabels['title']:
|
||
base_name = item.infoLabels['title']
|
||
else:
|
||
base_name = item.contentSerieName
|
||
|
||
if not PY3:
|
||
base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8")
|
||
else:
|
||
base_name = filetools.validate_path(base_name.replace('/', '-'))
|
||
|
||
if config.get_setting("lowerize_title", "videolibrary"):
|
||
base_name = base_name.lower()
|
||
|
||
return '{} [{}]'.format(base_name, _id)
|
||
|
||
|
||
def restore_videolibrary():
|
||
movies = [x['item'] for x in dict(videolibrarydb['movie']).values()]
|
||
tvshows = [x['item'] for x in dict(videolibrarydb['tvshow']).values()]
|
||
total = len(movies) + len(tvshows)
|
||
progress = 0
|
||
dialog = platformtools.dialog_progress(config.get_localized_string(20000), 'Ripristino videoteca in corso')
|
||
try: os.mkdir(MOVIES_PATH)
|
||
except: pass
|
||
try: os.mkdir(TVSHOWS_PATH)
|
||
except: pass
|
||
|
||
for item in movies:
|
||
base_name = set_base_name(item, item.videolibrary_id)
|
||
path = filetools.join(MOVIES_PATH, base_name)
|
||
try: os.mkdir(path)
|
||
except: pass
|
||
nfo_path = filetools.join(base_name, "{}.nfo".format(base_name))
|
||
strm_path = filetools.join(base_name, "{}.strm".format(base_name))
|
||
nfo_exists = filetools.exists(filetools.join(MOVIES_PATH, nfo_path))
|
||
strm_exists = filetools.exists(filetools.join(MOVIES_PATH, strm_path))
|
||
local = True if 'local' in videolibrarydb['movie'][item.videolibrary_id]['channels'] else False
|
||
if not nfo_exists:
|
||
if not item.head_nfo: item.head_nfo = scraper.get_nfo(item)
|
||
filetools.write(filetools.join(MOVIES_PATH, item.nfo_path), item.head_nfo)
|
||
if not strm_exists and not local:
|
||
item_strm = Item(channel='videolibrary', action='play_from_library', strm_path=item.strm_path, contentType='movie', contentTitle=item.contentTitle, videolibrary_id=item.videolibrary_id)
|
||
filetools.write(filetools.join(MOVIES_PATH, item.strm_path), '{}?{}'.format(addon_name, item_strm.tourl()))
|
||
progress += 1
|
||
dialog.update(int(progress / total * 100))
|
||
|
||
for item in tvshows:
|
||
base_name = set_base_name(item, item.videolibrary_id)
|
||
path = filetools.join(TVSHOWS_PATH, base_name)
|
||
try: os.mkdir(path)
|
||
except: pass
|
||
nfo_path = filetools.join(base_name, "tvshow.nfo")
|
||
nfo_exists = filetools.exists(filetools.join(TVSHOWS_PATH, nfo_path))
|
||
if not nfo_exists:
|
||
if not item.head_nfo: item.head_nfo = scraper.get_nfo(item)
|
||
filetools.write(filetools.join(TVSHOWS_PATH, item.nfo_path), item.head_nfo)
|
||
|
||
episodes = [x['item'] for x in dict(videolibrarydb['episode'][item.videolibrary_id]).values()]
|
||
for e in episodes:
|
||
season_episode = '{}x{:02d}'.format(e.contentSeason, e.contentEpisodeNumber)
|
||
strm_path = filetools.join(item.base_name, "{}.strm".format(season_episode))
|
||
strm_exists = filetools.exists(filetools.join(MOVIES_PATH, strm_path))
|
||
local = True if 'local' in videolibrarydb['episode'][item.videolibrary_id][season_episode]['channels'] else False
|
||
if not strm_exists and not local:
|
||
logger.debug("Creating .strm: " + strm_path)
|
||
item_strm = Item(channel='videolibrary', action='play_from_library', strm_path=strm_path, contentType='episode', videolibrary_id=e.videolibrary_id, contentSeason = e.contentSeason, contentEpisodeNumber = e.contentEpisodeNumber,)
|
||
filetools.write(filetools.join(TVSHOWS_PATH, strm_path), '{}?{}'.format(addon_name, item_strm.tourl()))
|
||
progress += 1
|
||
dialog.update(int(progress / total * 100))
|
||
videolibrarydb.close()
|
||
|
||
dbconverter.save_all()
|
||
|
||
def convert_videolibrary():
|
||
import glob, xbmc
|
||
from platformcode import xbmc_videolibrary
|
||
from core import jsontools
|
||
|
||
dialog = platformtools.dialog_progress(config.get_localized_string(20000), 'Conversione videoteca in corso')
|
||
path_to_delete = []
|
||
film_lst = glob.glob(filetools.join(MOVIES_PATH, '*/*.json'))
|
||
tvshow_lst = glob.glob((filetools.join(TVSHOWS_PATH, '*/tvshow.nfo')))
|
||
total = len(film_lst) + len(tvshow_lst)
|
||
progress = 0
|
||
|
||
tvPath = filetools.join(config.get_setting('videolibrarypath'), config.get_setting('folder_tvshows'))
|
||
moviePath = filetools.join(config.get_setting('videolibrarypath'), config.get_setting('folder_movies'))
|
||
|
||
# set local info only
|
||
xbmc_videolibrary.execute_sql_kodi('update path set strScraper="metadata.local", strSettings="" where strPath = "{}{}"'.format(tvPath, '/' if '/' in tvPath else '\\'))
|
||
xbmc_videolibrary.execute_sql_kodi('update path set strScraper="metadata.local", strSettings="" where strPath = "{}{}"'.format(moviePath, '/' if '/' in moviePath else '\\'))
|
||
|
||
for film in film_lst:
|
||
path_to_delete.append(filetools.dirname(film))
|
||
it = Item().fromjson(filetools.read(film))
|
||
it.infoLabels = {'tmdb_id': it.infoLabels['tmdb_id'], 'mediatype':'movie'}
|
||
tmdb.find_and_set_infoLabels(it)
|
||
it.no_reload = True
|
||
save_movie(it)
|
||
progress += 1
|
||
dialog.update(int(progress / total * 100))
|
||
|
||
for tvshow in tvshow_lst:
|
||
if not dialog:
|
||
dialog = platformtools.dialog_progress(config.get_localized_string(20000), 'Conversione videoteca in corso')
|
||
js = jsontools.load('\n'.join(filetools.read(tvshow).splitlines()[1:]))
|
||
channels_dict = js.get('library_urls')
|
||
if channels_dict:
|
||
for ch, url in channels_dict.items():
|
||
dir = filetools.listdir(xbmc.translatePath(filetools.join(config.get_setting('videolibrarypath'), config.get_setting('folder_tvshows'), js['path'])))
|
||
json_files = [f for f in dir if f.endswith('.json')]
|
||
if json_files:
|
||
path_to_delete.append(filetools.dirname(tvshow))
|
||
nfo, it = read_nfo(tvshow)
|
||
it.infoLabels = {'tmdb_id': it.infoLabels['tmdb_id'], 'mediatype':'tvshow'}
|
||
it.contentType = 'tvshow'
|
||
it.channel = ch
|
||
it.url = channels_dict[ch]
|
||
remove_host(it)
|
||
tmdb.find_and_set_infoLabels(it)
|
||
try: channel = __import__('channels.%s' % ch, fromlist=['channels.%s' % ch])
|
||
except: channel = __import__('specials.%s' % ch, fromlist=['specials.%s' % ch])
|
||
it.host = channel.host
|
||
it.url = channel.host + it.url
|
||
episodes = getattr(channel, 'episodios')(it)
|
||
for ep in episodes:
|
||
logger.debug('EPISODE URL', ep.url)
|
||
it.no_reload = True
|
||
save_tvshow(it, episodes, True)
|
||
progress += 1
|
||
dialog.update(int(progress / total * 100))
|
||
for path in path_to_delete:
|
||
filetools.rmdirtree(path, True)
|
||
dialog.close()
|
||
if path_to_delete:
|
||
dbconverter.save_all() |