- Nuova sezione Musica
- Download in Background
- Download dalla Videoteca e supporto file locali
- Backup e cancellazione della Videoteca
- Spostamento della Videoteca
- Migliorata integrazione con libreria di Kodi
- Gestione delle Viste Preferite
- Nuovo layout impostazioni
This commit is contained in:
marco
2020-04-15 22:58:06 +02:00
parent ecafd1b0df
commit 6de0f4fec4
213 changed files with 5294 additions and 2482 deletions
+1 -2
View File
@@ -44,8 +44,7 @@ def get_channel_parameters(channel_name):
channel_parameters["adult"] = channel_parameters.get("adult", False)
logger.info(channel_parameters["adult"])
if channel_parameters["adult"]:
channel_parameters["update_url"] = channel_parameters.get("update_url",
DEFAULT_UPDATE_URL + 'porn/')
channel_parameters["update_url"] = channel_parameters.get("update_url", DEFAULT_UPDATE_URL + 'porn/')
else:
channel_parameters["update_url"] = channel_parameters.get("update_url", DEFAULT_UPDATE_URL)
channel_parameters["language"] = channel_parameters.get("language", ["all"])
+40 -15
View File
@@ -19,6 +19,9 @@ metodos:
"""
from __future__ import division
from future import standard_library
from core.item import Item
standard_library.install_aliases()
from builtins import range
from builtins import object
@@ -102,22 +105,24 @@ class Downloader(object):
# Funciones
def start_dialog(self, title=config.get_localized_string(60200)):
from platformcode import platformtools
progreso = platformtools.dialog_progress(title, config.get_localized_string(60201))
self.start()
while self.state == self.states.downloading and not progreso.iscanceled():
time.sleep(0.1)
line1 = "%s" % (self.filename)
line2 = config.get_localized_string(59983) % (
self.progress, self.downloaded[1], self.downloaded[2], self.size[1], self.size[2],
self.speed[1], self.speed[2], self.connections[0], self.connections[1])
line3 = config.get_localized_string(60202) % (self.remaining_time)
progreso = platformtools.dialog_progress_bg(title, config.get_localized_string(60201))
try:
self.start()
while self.state == self.states.downloading:
time.sleep(0.2)
line1 = "%s" % (self.filename)
line2 = config.get_localized_string(59983) % (
self.downloaded[1], self.downloaded[2], self.size[1], self.size[2],
self.speed[1], self.speed[2], self.connections[0], self.connections[1])
line3 = config.get_localized_string(60202) % (self.remaining_time)
progreso.update(int(self.progress), line1, line2, line3)
if self.state == self.states.downloading:
self.stop()
progreso.close()
progreso.update(int(self.progress), line1, line2 + " " + line3)
self.__update_json()
finally:
progreso.close()
def start(self):
self.__update_json(started=False)
if self._state == self.states.error: return
conns = []
for x in range(self._max_connections):
@@ -190,7 +195,7 @@ class Downloader(object):
# Funciones internas
def __init__(self, url, path, filename=None, headers=[], resume=True, max_connections=10, block_size=2 ** 17,
part_size=2 ** 24, max_buffer=10):
part_size=2 ** 24, max_buffer=10, json_path=None):
# Parametros
self._resume = resume
self._path = path
@@ -199,6 +204,9 @@ class Downloader(object):
self._block_size = block_size
self._part_size = part_size
self._max_buffer = max_buffer
self._json_path = json_path
self._json_text = ''
self._json_item = Item()
try:
import xbmc
@@ -258,7 +266,7 @@ class Downloader(object):
self.__get_download_info__()
try:
logger.info("Descarga inicializada: Partes: %s | Ruta: %s | Archivo: %s | Tamaño: %s" % \
logger.info("Download started: Parts: %s | Path: %s | File: %s | Size: %s" % \
(str(len(self._download_info["parts"])), self._pathencode('utf-8'), \
self._filenameencode('utf-8'), str(self._download_info["size"])))
except:
@@ -579,3 +587,20 @@ class Downloader(object):
self.__set_part_stopped__(id)
logger.info("Thread stopped: %s" % threading.current_thread().name)
def __update_json(self, started=True):
text = filetools.read(self._json_path)
# load item only if changed
if self._json_text != text:
self._json_text = text
self._json_item = Item().fromjson(text)
logger.info('item loaded')
progress = int(self.progress)
if started and self._json_item.downloadStatus == 0: # stopped
logger.info('Download paused')
self.stop()
elif self._json_item.downloadProgress != progress or not started:
params = {"downloadStatus": 4, "downloadComplete": 0, "downloadProgress": progress}
self._json_item.__dict__.update(params)
self._json_text = self._json_item.tojson()
filetools.write(self._json_path, self._json_text)
+1 -3
View File
@@ -123,6 +123,7 @@ def load_cookies(alfa_s=False):
os.remove(cookies_file)
cookies_lock.release()
load_cookies()
def save_cookies(alfa_s=False):
cookies_lock.acquire()
@@ -131,8 +132,6 @@ def save_cookies(alfa_s=False):
cookies_lock.release()
load_cookies()
def random_useragent():
"""
Based on code from https://github.com/theriley106/RandomHeaders
@@ -257,7 +256,6 @@ def downloadpage(url, **opt):
"""
url = scrapertools.unescape(url)
load_cookies()
domain = urlparse.urlparse(url).netloc
global domainCF
CF = False
+2 -3
View File
@@ -13,10 +13,9 @@ if PY3:
#from future import standard_library
#standard_library.install_aliases()
import urllib.parse as urllib # Es muy lento en PY2. En PY3 es nativo
from html.parser import HTMLParser
else:
import urllib # Usamos el nativo de PY2 que es más rápido
from HTMLParser import HTMLParser
from core.scrapertools import unescape
import base64
import copy
@@ -454,7 +453,7 @@ class Item(object):
"""
try:
unicode_title = unicode(value, "utf8", "ignore")
return HTMLParser().unescape(unicode_title).encode("utf8")
return unescape(unicode_title).encode("utf8")
except:
if PY3 and isinstance(value, bytes):
value = value.decode("utf8")
+4 -4
View File
@@ -120,7 +120,7 @@ def unescape(text):
pass
return text # leave as is
return re.sub("&#?\w+;", fixup, text)
return re.sub("&#?\w+;", str(fixup), str(text))
# Convierte los codigos html "ñ" y lo reemplaza por "ñ" caracter unicode utf-8
@@ -418,14 +418,14 @@ def get_season_and_episode(title):
"""
filename = ""
patrons = ["(\d+)x(\d+)", "(?:s|t)(\d+)e(\d+)",
"(?:season|temp\w*)\s*(\d+)\s*(?:capitulo|epi\w*)\s*(\d+)"]
patrons = ["(\d+)\s*[x-]\s*(\d+)", "(\d+)\s*×\s*(\d+)", "(?:[Ss]|[Tt])(\d+)(?:[Ee]|Ep\.)(\d+)",
"(?:[Ss]tag|[Ss]eason|[Ss]tagione\w*)\s*(\d+)\s*(?:[Ee]pi|[Ee]pisode|[Ee]pisodio\w*)\s*(\d+)"]
for patron in patrons:
try:
matches = re.compile(patron, re.I).search(title)
if matches:
filename = matches.group(1) + "x" + matches.group(2).zfill(2)
filename = str(int(matches.group(1))) + "x" + str(int(matches.group(2))).zfill(2)
break
except:
pass
+8 -2
View File
@@ -220,7 +220,7 @@ def get_server_from_url(url):
return devuelve
def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialogo=False):
def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialogo=False, background_dialog=False):
"""
Función para obtener la url real del vídeo
@param server: Servidor donde está alojado el vídeo
@@ -231,6 +231,8 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
@type video_password: str
@param muestra_dialogo: Muestra el diálogo de progreso
@type muestra_dialogo: bool
@type background_dialog: bool
@param background_dialog: if progress dialog should be in background
@return: devuelve la url del video
@rtype: list
@@ -261,7 +263,7 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
if server_parameters:
# Muestra un diágo de progreso
if muestra_dialogo:
progreso = platformtools.dialog_progress(config.get_localized_string(20000),
progreso = (platformtools.dialog_progress_bg if background_dialog else platformtools.dialog_progress)(config.get_localized_string(20000),
config.get_localized_string(70180) % server_parameters["name"])
# Cuenta las opciones disponibles, para calcular el porcentaje
@@ -292,6 +294,8 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
logger.info("Servidor importado: %s" % server_module)
except:
server_module = None
if muestra_dialogo:
progreso.close()
logger.error("No se ha podido importar el servidor: %s" % server)
import traceback
logger.error(traceback.format_exc())
@@ -305,6 +309,8 @@ def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialo
if not video_exists:
error_messages.append(message)
logger.info("test_video_exists dice que el video no existe")
if muestra_dialogo:
progreso.close()
else:
logger.info("test_video_exists dice que el video SI existe")
except:
+88 -60
View File
@@ -26,9 +26,7 @@ from core import httptools, scrapertools, servertools, tmdb, channeltools
from core.item import Item
from lib import unshortenit
from platformcode import logger, config
from specials import autoplay, shortcuts
CONTEXT =shortcuts.context()
from specials import autoplay
def hdpass_get_servers(item):
def get_hosts(url, quality):
@@ -40,15 +38,15 @@ def hdpass_get_servers(item):
for mir_url, srv in scrapertools.find_multiple_matches(mir, patron_option):
mir_url = scrapertools.decodeHtmlentities(mir_url)
ret.append(Item(channel=item.channel,
action="play",
fulltitle=item.fulltitle,
quality=quality,
show=item.show,
thumbnail=item.thumbnail,
contentType=item.contentType,
title=srv,
server=srv,
url= mir_url))
action="play",
fulltitle=item.fulltitle,
quality=quality,
show=item.show,
thumbnail=item.thumbnail,
contentType=item.contentType,
title=srv,
server=srv,
url= mir_url))
return ret
# Carica la pagina
itemlist = []
@@ -176,11 +174,10 @@ def cleantitle(title):
def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, typeContentDict, typeActionDict, blacklist, search, pag, function, lang):
itemlist = []
log("scrapeBlock qui")
matches = scrapertools.find_multiple_matches_groups(block, patron)
log('MATCHES =', matches)
if debug:
regexDbg(item, patron, headers, block)
matches = scrapertools.find_multiple_matches_groups(block, patron)
log('MATCHES =', matches)
known_keys = ['url', 'title', 'title2', 'season', 'episode', 'thumb', 'quality', 'year', 'plot', 'duration', 'genere', 'rating', 'type', 'lang', 'other']
# Legenda known_keys per i groups nei patron
@@ -264,7 +261,7 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
infolabels['plot'] = plot
if scraped['duration']:
matches = scrapertools.find_multiple_matches(scraped['duration'],
r'([0-9])\s*?(?:[hH]|:|\.|,|\\|\/|\||\s)\s*?([0-9]+)')
r'([0-9])\s*?(?:[hH]|:|\.|,|\\|\/|\||\s)\s*?([0-9]+)')
for h, m in matches:
scraped['duration'] = int(h) * 60 + int(m)
if not matches:
@@ -308,8 +305,7 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
contentLanguage = lang1,
contentEpisodeNumber=episode if episode else '',
news= item.news if item.news else '',
other = scraped['other'] if scraped['other'] else '',
context = CONTEXT
other = scraped['other'] if scraped['other'] else ''
)
# for lg in list(set(listGroups).difference(known_keys)):
@@ -389,7 +385,8 @@ def scrape(func):
if not data:
page = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True)
# if url may be changed and channel has findhost to update
if (not page.data or scrapertools.get_domain_from_url(page.url) != scrapertools.get_domain_from_url(item.url)) and 'findhost' in func.__globals__:
if 'findhost' in func.__globals__ and (not page.data or scrapertools.get_domain_from_url(page.url).lower() != scrapertools.get_domain_from_url(item.url).lower()):
logger.info('running findhost ' + func.__module__)
host = func.__globals__['findhost']()
parse = list(urlparse.urlparse(item.url))
from core import jsontools
@@ -633,8 +630,7 @@ def menuItem(itemlist, filename, title='', action='', url='', contentType='movie
url = url,
extra = extra,
args = args,
contentType = contentType,
context = CONTEXT
contentType = contentType
))
# Apply auto Thumbnails at the menus
@@ -697,7 +693,7 @@ def menu(func):
if dictUrl[name] is not None and type(dictUrl[name]) is not str:
for sub, var in dictUrl[name]:
menuItem(itemlist, filename,
title = sub + ' submenu' + typo(title,'_ {}'),
title = sub + ' submenu {' + title + '}',
url = host + var[0] if len(var) > 0 else '',
action = var[1] if len(var) > 1 else 'peliculas',
args=var[2] if len(var) > 2 else '',
@@ -745,15 +741,27 @@ def typo(string, typography=''):
# If there are no attributes, it applies the default ones
attribute = ['[]','()','submenu','color','bold','italic','_','--','[B]','[I]','[COLOR]']
if int(config.get_setting('view_mode_channel').split(',')[-1]) in [0, 50, 55]:
VLT = True
else:
VLT = False
# Otherwise it uses the typographical attributes of the string
# else:
if 'capitalize' in string.lower():
string = re.sub(r'\s*capitalize','',string).capitalize()
if 'uppercase' in string.lower():
string = re.sub(r'\s*uppercase','',string).upper()
if 'lowercase' in string.lower():
string = re.sub(r'\s*lowercase','',string).lower()
if '[]' in string:
string = '[' + re.sub(r'\s*\[\]','',string) + ']'
if '()' in string:
string = '(' + re.sub(r'\s*\(\)','',string) + ')'
if 'submenu' in string:
string = "•• " + re.sub(r'\s*submenu','',string)
if VLT:
string = "•• " + re.sub(r'\s*submenu','',string)
else:
string = re.sub(r'\s*submenu','',string)
if 'color' in string:
color = scrapertools.find_single_match(string, 'color ([a-z]+)')
if color == 'kod' or '': color = kod_color
@@ -767,13 +775,10 @@ def typo(string, typography=''):
if '--' in string:
string = ' - ' + re.sub(r'\s*--','',string)
if 'bullet' in string:
string = '[B]' + "" + '[/B] ' + re.sub(r'\s*bullet','',string)
if 'capitalize' in string.lower():
string = re.sub(r'\s*capitalize','',string).capitalize()
if 'uppercase' in string.lower():
string = re.sub(r'\s*uppercase','',string).upper()
if 'lowercase' in string.lower():
string = re.sub(r'\s*lowercase','',string).lower()
if VLT:
string = '[B]' + "" + '[/B] ' + re.sub(r'\s*bullet','',string)
else:
string = re.sub(r'\s*bullet','',string)
if '{}' in string:
string = re.sub(r'\s*\{\}','',string)
@@ -915,23 +920,34 @@ def download(itemlist, item, typography='', function_level=1, function=''):
contentSerieName=item.contentSerieName if item.contentSerieName else ''
contentTitle=item.contentTitle if item.contentTitle else ''
downloadItemlist = [i.tourl() for i in itemlist]
if itemlist and item.contentChannel != 'videolibrary':
itemlist.append(
Item(channel='downloads',
from_channel=item.channel,
title=title,
fulltitle=item.fulltitle,
show=item.fulltitle,
contentType=item.contentType,
contentSerieName=contentSerieName,
url=item.url,
action='save_download',
from_action=from_action,
contentTitle=contentTitle,
path=item.path,
thumbnail=thumb(thumb='downloads.png')
))
show = True
# do not show if we are on findvideos and there are no valid servers
if from_action == 'findvideos':
for i in itemlist:
if i.action == 'play':
break
else:
show = False
if show:
itemlist.append(
Item(channel='downloads',
from_channel=item.channel,
title=title,
fulltitle=item.fulltitle,
show=item.fulltitle,
contentType=item.contentType,
contentSerieName=contentSerieName,
url=item.url,
action='save_download',
from_action=from_action,
contentTitle=contentTitle,
path=item.path,
thumbnail=thumb(thumb='downloads.png'),
downloadItemlist=downloadItemlist
))
if from_action == 'episodios':
itemlist.append(
Item(channel='downloads',
@@ -946,8 +962,9 @@ def download(itemlist, item, typography='', function_level=1, function=''):
from_action=from_action,
contentTitle=contentTitle,
download='season',
thumbnail=thumb(thumb='downloads.png')
))
thumbnail=thumb(thumb='downloads.png'),
downloadItemlist=downloadItemlist
))
return itemlist
@@ -985,18 +1002,20 @@ def videolibrary(itemlist, item, typography='', function_level=1, function=''):
if (function == 'findvideos' and contentType == 'movie') \
or (function == 'episodios' and contentType != 'movie'):
if config.get_videolibrary_support() and len(itemlist) > 0:
from channelselector import get_thumb
itemlist.append(
Item(channel=item.channel,
title=title,
fulltitle=item.fulltitle,
show=item.fulltitle,
contentType=contentType,
contentTitle=contentTitle,
contentSerieName=contentSerieName,
url=item.url,
action=action,
extra=extra,
contentTitle=contentTitle,
path=item.path
path=item.path,
thumbnail=get_thumb('add_to_videolibrary.png')
))
return itemlist
@@ -1038,7 +1057,7 @@ def pagination(itemlist, item, page, perpage, function_level=1):
thumbnail=thumb()))
return itemlist
def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=True, down_load=True, patronTag=None):
def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=True, down_load=True, patronTag=None, video_library=True):
if not data and not itemlist:
data = httptools.downloadpage(item.url, headers=headers, ignore_response_code=True).data
@@ -1068,7 +1087,7 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
item.title = typo(item.contentTitle.strip(),'bold') if item.contentType == 'movie' or (config.get_localized_string(30161) in item.title) else item.title
videoitem.plot= typo(videoitem.title, 'bold') + typo(videoitem.quality, '_ [] bold')
videoitem.title = item.title + (typo(videoitem.title, '_ color kod [] bold') if videoitem.title else "") + (typo(videoitem.quality, '_ color kod []') if videoitem.quality else "")
videoitem.title = (item.title if item.channel not in ['url'] else '') + (typo(videoitem.title, '_ color kod [] bold') if videoitem.title else "") + (typo(videoitem.quality, '_ color kod []') if videoitem.quality else "")
videoitem.fulltitle = item.fulltitle
videoitem.show = item.show
videoitem.thumbnail = item.thumbnail
@@ -1078,9 +1097,9 @@ def server(item, data='', itemlist=[], headers='', AutoPlay=True, CheckLinks=Tru
if patronTag:
addQualityTag(item, verifiedItemlist, data, patronTag)
return controls(verifiedItemlist, item, AutoPlay, CheckLinks, down_load)
return controls(verifiedItemlist, item, AutoPlay, CheckLinks, down_load, video_library)
def controls(itemlist, item, AutoPlay=True, CheckLinks=True, down_load=True):
def controls(itemlist, item, AutoPlay=True, CheckLinks=True, down_load=True, video_library=True):
from core import jsontools
from platformcode.config import get_setting
@@ -1088,13 +1107,17 @@ def controls(itemlist, item, AutoPlay=True, CheckLinks=True, down_load=True):
autoplay_node = jsontools.get_node_from_file('autoplay', 'AUTOPLAY')
channel_node = autoplay_node.get(item.channel, {})
if not channel_node: # non ha mai aperto il menu del canale quindi in autoplay_data.json non c'e la key
channelFile = __import__('channels.' + item.channel, fromlist=["channels.%s" % item.channel])
autoplay.init(item.channel, channelFile.list_servers, channelFile.list_quality)
try:
channelFile = __import__('channels.' + item.channel, fromlist=["channels.%s" % item.channel])
except:
channelFile = __import__('specials.' + item.channel, fromlist=["specials.%s" % item.channel])
if hasattr(channelFile, 'list_servers') and hasattr(channelFile, 'list_quality'):
autoplay.init(item.channel, channelFile.list_servers, channelFile.list_quality)
autoplay_node = jsontools.get_node_from_file('autoplay', 'AUTOPLAY')
channel_node = autoplay_node.get(item.channel, {})
settings_node = channel_node.get('settings', {})
AP = get_setting('autoplay') or settings_node['active']
AP = get_setting('autoplay') or (settings_node['active'] if 'active' in settings_node else False)
HS = config.get_setting('hide_servers') or (settings_node['hide_servers'] if 'hide_server' in settings_node else False)
if CL and not AP:
@@ -1109,7 +1132,7 @@ def controls(itemlist, item, AutoPlay=True, CheckLinks=True, down_load=True):
if AutoPlay == True and not 'downloads' in inspect.stack()[3][1] + inspect.stack()[4][1]:
autoplay.start(itemlist, item)
if item.contentChannel != 'videolibrary': videolibrary(itemlist, item, function_level=3)
if item.contentChannel != 'videolibrary' and video_library: videolibrary(itemlist, item, function_level=3)
if get_setting('downloadenabled') and down_load == True: download(itemlist, item, function_level=3)
VL = False
@@ -1156,7 +1179,7 @@ def channel_config(item, itemlist):
itemlist.append(
Item(channel='setting',
action="channel_config",
title=typo("Configurazione Canale color kod bold"),
title=typo(config.get_localized_string(60587), 'color kod bold'),
config=item.channel,
folder=False,
thumbnail=get_thumb('setting_0.png'))
@@ -1197,6 +1220,8 @@ def addQualityTag(item, itemlist, data, patron):
"DLMux": "si tratta di un 720p o 1080p reperiti dalla versione americana di iTunes americano. La qualità è paragonabile a quella di un BluRayRip e permette di fruire di episodi televisivi, senza il fastidioso bollo distintivo della rete che trasmette.",
"DVD5": "il film è in formato DVD Single Layer, nel quale vengono mantenute tutte le caratteristiche del DVD originale: tra queste il menu multilingue, i sottotitoli e i contenuti speciali, se presenti. Il video è codificato nel formato DVD originale MPEG-2.",
"DVD9": "ha le stesse caratteristiche del DVD5, ma le dimensioni del file sono di un DVD Dual Layer (8,5 GB).",
"HDTS": "viene utilizzata una videocamera professionale ad alta definizione posizionata in modo fisso. La qualità audio video è buona.",
"DVDMUX": "indica una buona qualità video, laudio è stato aggiunto da una sorgente diversa per una migliore qualità.",
}
defQualAudio = {
@@ -1206,6 +1231,7 @@ def addQualityTag(item, itemlist, data, patron):
"DD": "audio ricavato dai dischi DTS cinema. Laudio è di buona qualità, ma potreste riscontrare il fatto che non potrebbe essere più riproducibile.",
"AC3": "audio in Dolby Digital puo' variare da 2.0 a 5.1 canali in alta qualità.",
"MP3": "codec per compressione audio utilizzato MP3.",
"RESYNC": "il film è stato lavorato e re sincronizzato con una traccia audio. A volte potresti riscontrare una mancata sincronizzazione tra audio e video.",
}
qualityStr = scrapertools.find_single_match(data, patron).strip()
if PY3:
@@ -1215,7 +1241,9 @@ def addQualityTag(item, itemlist, data, patron):
if qualityStr:
try:
audio, video = qualityStr.split('.')
splitted = qualityStr.split('.')
video = splitted[-1]
audio = splitted[-2]
descr = typo(video + ': ', 'color kod') + defQualVideo.get(video.upper(), '') + '\n' +\
typo(audio + ': ', 'color kod') + defQualAudio.get(audio.upper(), '')
except:
+2 -2
View File
@@ -32,8 +32,8 @@ from core.item import InfoLabels
from platformcode import config
from platformcode import logger
addon = xbmcaddon.Addon('metadata.themoviedb.org')
def_lang = addon.getSetting('language')
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
# -----------------------------------------------------------------------------------------------------------
# Conjunto de funciones relacionadas con las infoLabels.
+2 -4
View File
@@ -25,11 +25,9 @@ from platformcode import platformtools
HOST = "https://api.thetvdb.com"
HOST_IMAGE = "http://thetvdb.com/banners/"
import xbmcaddon
addon = xbmcaddon.Addon('metadata.tvdb.com')
TOKEN = config.get_setting("tvdb_token", default="")
DEFAULT_LANG = addon.getSetting('language')
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
DEFAULT_LANG = info_language[config.get_setting("info_language", "videolibrary")]
DEFAULT_HEADERS = {
'Content-Type': 'application/json',
'Accept': 'application/json, application/vnd.thetvdb.v2.1.1',
+68 -25
View File
@@ -130,7 +130,7 @@ def save_movie(item):
# progress dialog
p_dialog = platformtools.dialog_progress(config.get_localized_string(20000), config.get_localized_string(60062))
if config.get_setting("original_title_folder", "videolibrary") == 1 and item.infoLabels['originaltitle']:
if config.get_setting("original_title_folder", "videolibrary") and item.infoLabels['originaltitle']:
base_name = item.infoLabels['originaltitle']
else:
base_name = item.contentTitle
@@ -140,7 +140,7 @@ def save_movie(item):
else:
base_name = filetools.validate_path(base_name.replace('/', '-'))
if config.get_setting("lowerize_title", "videolibrary") == 0:
if config.get_setting("lowerize_title", "videolibrary"):
base_name = base_name.lower()
for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH):
@@ -221,7 +221,7 @@ def save_movie(item):
if filetools.write(nfo_path, head_nfo + item_nfo.tojson()):
#logger.info("FOLDER_MOVIES : %s" % FOLDER_MOVIES)
# actualizamos la videoteca de Kodi con la pelicula
if config.is_xbmc():
if config.is_xbmc() and config.get_setting("videolibrary_kodi"):
from platformcode import xbmc_videolibrary
xbmc_videolibrary.update()
@@ -234,12 +234,55 @@ def save_movie(item):
p_dialog.close()
return 0, 0, -1
def update_renumber_options(item, head_nfo, path):
from core import jsontools
# from core.support import dbg;dbg()
tvshow_path = filetools.join(path, 'tvshow.nfo')
if filetools.isfile(tvshow_path) and item.channel_prefs:
for channel in item.channel_prefs:
filename = filetools.join(config.get_data_path(), "settings_channels", channel + '_data.json')
json_file = jsontools.load(filetools.read(filename))
if 'TVSHOW_AUTORENUMBER' in json_file:
json = json_file['TVSHOW_AUTORENUMBER']
if item.fulltitle in json:
item.channel_prefs[channel]['TVSHOW_AUTORENUMBER'] = json[item.fulltitle]
logger.info('UPDATED=\n' + str(item.channel_prefs))
filetools.write(tvshow_path, head_nfo + item.tojson())
def add_renumber_options(item, head_nfo, path):
from core import jsontools
# from core.support import dbg;dbg()
ret = None
filename = filetools.join(config.get_data_path(), "settings_channels", item.channel + '_data.json')
json_file = jsontools.load(filetools.read(filename))
if 'TVSHOW_AUTORENUMBER' in json_file:
json = json_file['TVSHOW_AUTORENUMBER']
if item.fulltitle in json:
ret = json[item.fulltitle]
return ret
def check_renumber_options(item):
from specials.autorenumber import load, write
for key in item.channel_prefs:
if 'TVSHOW_AUTORENUMBER' in item.channel_prefs[key]:
item.channel = key
json = load(item)
if not json or item.fulltitle not in json:
json[item.fulltitle] = item.channel_prefs[key]['TVSHOW_AUTORENUMBER']
write(item, json)
# head_nfo, tvshow_item = read_nfo(filetools.join(item.context[0]['nfo']))
# if tvshow_item['channel_prefs'][item.fullti]
def filter_list(episodelist, action=None, path=None):
# if path: path = path.decode('utf8')
# import xbmc
# if xbmc.getCondVisibility('system.platform.windows') > 0: path = path.replace('smb:','').replace('/','\\')
channel_prefs = {}
lang_sel = quality_sel = show_title = channel =''
# from core.support import dbg;dbg()
if action:
tvshow_path = filetools.join(path, "tvshow.nfo")
head_nfo, tvshow_item = read_nfo(tvshow_path)
@@ -253,8 +296,13 @@ def filter_list(episodelist, action=None, path=None):
filetools.remove(filetools.join(path, File))
if channel not in tvshow_item.channel_prefs:
tvshow_item.channel_prefs[channel] = {}
channel_prefs = tvshow_item.channel_prefs[channel]
renumber = add_renumber_options(episodelist[0], head_nfo, tvshow_path)
if renumber:
channel_prefs['TVSHOW_AUTORENUMBER'] = renumber
if action == 'get_seasons':
if 'favourite_language' not in channel_prefs:
channel_prefs['favourite_language'] = ''
@@ -418,7 +466,7 @@ def save_tvshow(item, episodelist):
+ ' / ' + item.infoLabels['code'])
return 0, 0, -1, path
if config.get_setting("original_title_folder", "videolibrary") == 1 and item.infoLabels['originaltitle']:
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']
@@ -432,7 +480,7 @@ def save_tvshow(item, episodelist):
else:
base_name = filetools.validate_path(base_name.replace('/', '-'))
if config.get_setting("lowerize_title", "videolibrary") == 0:
if config.get_setting("lowerize_title", "videolibrary"):
base_name = base_name.lower()
for raiz, subcarpetas, ficheros in filetools.walk(TVSHOWS_PATH):
@@ -490,7 +538,7 @@ def save_tvshow(item, episodelist):
item_tvshow.library_filter_show = {item.channel: item.show}
if item.channel != "downloads":
item_tvshow.active = 1 # para que se actualice a diario cuando se llame a videolibrary_service
item_tvshow.active = 1 # para que se actualice a diario cuando se llame a service
filetools.write(tvshow_path, head_nfo + item_tvshow.tojson())
@@ -554,7 +602,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
nostrm_episodelist.append(season_episode)
nostrm_episodelist = sorted(set(nostrm_episodelist))
# Silent es para no mostrar progreso (para videolibrary_service)
# Silent es para no mostrar progreso (para service)
if not silent:
# progress dialog
p_dialog = platformtools.dialog_progress(config.get_localized_string(20000), config.get_localized_string(60064))
@@ -571,16 +619,11 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
new_episodelist = []
# Obtenemos el numero de temporada y episodio y descartamos los q no lo sean
tags = []
if config.get_setting("enable_filter", "videolibrary"):
tags = [x.strip() for x in config.get_setting("filters", "videolibrary").lower().split(",")]
for e in episodelist:
headers = {}
if e.headers:
headers = e.headers
if tags != [] and tags != None and any(tag in e.title.lower() for tag in tags):
continue
try:
season_episode = scrapertools.get_season_and_episode(e.title)
@@ -659,7 +702,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower())
if season_episode in nostrm_episodelist:
logger.error('Error in the structure of the Video Library: Seriese ' + serie.contentSerieName + ' ' + season_episode)
logger.info('Skipped: Serie ' + serie.contentSerieName + ' ' + season_episode + ' available as local content')
continue
strm_exists = strm_path in ficheros
nfo_exists = nfo_path in ficheros
@@ -789,7 +832,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
fallidos = -1
else:
# ... si ha sido correcto actualizamos la videoteca de Kodi
if config.is_xbmc() and not silent:
if config.is_xbmc() and config.get_setting("videolibrary_kodi") and not silent:
from platformcode import xbmc_videolibrary
xbmc_videolibrary.update()
@@ -834,11 +877,11 @@ def add_movie(item):
insertados, sobreescritos, fallidos = save_movie(new_item)
if fallidos == 0:
platformtools.dialog_ok(config.get_localized_string(30131), new_item.contentTitle,
config.get_localized_string(30135)) # 'se ha añadido a la videoteca'
platformtools.dialog_ok(config.get_localized_string(30131),
config.get_localized_string(30135) % new_item.contentTitle) # 'se ha añadido a la videoteca'
else:
platformtools.dialog_ok(config.get_localized_string(30131),
config.get_localized_string(60066)) #"ERROR, la pelicula NO se ha añadido a la videoteca")
config.get_localized_string(60066) % new_item.contentTitle) #"ERROR, la pelicula NO se ha añadido a la videoteca")
def add_tvshow(item, channel=None):
@@ -906,20 +949,20 @@ def add_tvshow(item, channel=None):
insertados, sobreescritos, fallidos, path = save_tvshow(item, itemlist)
if not insertados and not sobreescritos and not fallidos:
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60067))
logger.error("The %s series could not be added to the video library. Could not get any episode" % item.show)
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60067) % item.show)
logger.error("La serie %s no se ha podido añadir a la videoteca. No se ha podido obtener ningun episodio" % item.show)
elif fallidos == -1:
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60068))
logger.error("The %s series could not be added to the video library" % item.show)
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60068) % item.show)
logger.error("La serie %s no se ha podido añadir a la videoteca" % item.show)
elif fallidos > 0:
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60069))
logger.error("Could not add %s episodes of the %s series to the video library" % (fallidos, item.show))
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60069) % item.show)
logger.error("No se han podido añadir %s episodios de la serie %s a la videoteca" % (fallidos, item.show))
else:
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60070))
logger.info("%s episodes of the %s series have been added to the video library" % (insertados, item.show))
platformtools.dialog_ok(config.get_localized_string(30131), config.get_localized_string(60070) % item.show)
logger.info("Se han añadido %s episodios de la serie %s a la videoteca" % (insertados, item.show))
if config.is_xbmc():
if config.get_setting("sync_trakt_new_tvshow", "videolibrary"):
import xbmc
+11
View File
@@ -104,3 +104,14 @@ class ziptools(object):
dirs.sort()
return dirs
def zip(self, dir, file):
import os
zf = zipfile.ZipFile(file, "w", zipfile.ZIP_DEFLATED)
abs_src = os.path.abspath(dir)
for dirname, subdirs, files in os.walk(dir):
for filename in files:
absname = os.path.abspath(os.path.join(dirname, filename))
arcname = absname[len(abs_src) + 1:]
zf.write(absname, arcname)
zf.close()