Files
addon/core/videolibrarytools.py
2021-08-24 17:38:44 +02:00

1194 lines
55 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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()