KoD 0.9
- 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:
@@ -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
@@ -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
@@ -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
@@ -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")
|
||||
|
||||
@@ -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
@@ -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
@@ -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, l’audio è 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. L’audio è 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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user