added translation with italian support

This commit is contained in:
angedam
2018-07-03 17:21:45 +02:00
57 changed files with 3907 additions and 2124 deletions
+145 -44
View File
@@ -5,6 +5,7 @@ import sys
import urllib
import urlparse
import datetime
import ast
from channelselector import get_thumb
from core import httptools
@@ -17,15 +18,34 @@ from lib import generictools
host = 'http://descargas2020.com/'
#Código para permitir usar un único canal para todas las webs clones de NewPct1
clone_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid") #Carga lista de clones
clone_list = ast.literal_eval(clone_list) #la convierte a lista de tuplas
host_index = 0
host_index = config.get_setting('clonenewpct1_channel_default', "torrentrapid") #Clone por defecto
i = 0
for active_clone, channel_clone, host_clone, contentType_clone, info_clone in clone_list:
if i == host_index:
#channel_clone_name = channel_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
#host = 'http://%s/' % host_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
i += 1
#Carga de opciones del canal
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
channel_clone_name = scrapertools.find_single_match(host, r'(\w+)\.com\/') #QUITAR CUANDO SE PASE A NEWPCT1
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
thumb_pelis = get_thumb("channels_movie.png")
@@ -64,20 +84,40 @@ def settingCanal(item):
def submenu(item):
logger.info()
itemlist = []
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
pass
host_alt = host
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] caído'))
host_alt = host.replace(item.channel_alt, item.channel)
del item.channel_alt
if item.url_alt: del item.url_alt
#data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
#data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
host_dom = host_alt.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host_alt and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host_alt + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
else:
if data:
data = scrapertools.get_match(data, patron)
@@ -104,10 +144,10 @@ def submenu(item):
Item(channel=item.channel, action="alfabeto", title=title + " [A-Z]", url=url, extra=item.extra))
if item.extra == "peliculas":
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
return itemlist
@@ -203,7 +243,8 @@ def listado(item):
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
total_pag = scrapertools.find_single_match(data,'<a href=".*?(\d+)?">Last<\/a><\/li>')
patron_last_page = '<a href="[^"]+(\d+)">Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
@@ -419,6 +460,9 @@ def listado(item):
def listado_busqueda(item):
logger.info()
host = 'http://%s/' % scrapertools.find_single_match(item.url, '(\w+\.com)\/')
itemlist = []
cnt_tot = 40 # Poner el num. máximo de items por página. Dejamos que la web lo controle
cnt_title = 0 # Contador de líneas insertadas en Itemlist
@@ -449,17 +493,24 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
pass
cnt_next += 1
if not data or not scrapertools.find_single_match(data, pattern):
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, pattern)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -824,6 +875,11 @@ def listado_busqueda(item):
def findvideos(item):
from core import channeltools
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Cualquiera de las tres opciones son válidas
@@ -934,9 +990,20 @@ def findvideos(item):
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
pass
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -948,6 +1015,8 @@ def findvideos(item):
else:
item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
if size:
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
@@ -957,7 +1026,6 @@ def findvideos(item):
item_local = item.clone()
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
@@ -969,17 +1037,17 @@ def findvideos(item):
#Ahora pintamos el link del Torrent, si lo hay
if item_local.url: # Hay Torrent ?
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Servidor
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
itemlist.append(item_local.clone(quality=quality)) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
@@ -1163,9 +1231,20 @@ def findvideos(item):
def episodios(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
max_temp = 1
if item.infoLabels['number_of_seasons']:
max_temp = item.infoLabels['number_of_seasons']
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
@@ -1173,16 +1252,30 @@ def episodios(item):
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
patron = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data_alt = ''
if data: data_alt = scrapertools.get_match(data, patron)
except: #Algún error de proceso
pass
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data_alt or not scrapertools.find_single_match(data_alt, pattern):
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron, pattern)
if not data: #No se ha encontrado ningún canal activo para este vídeo
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
@@ -1209,7 +1302,8 @@ def episodios(item):
list_pages = [item.url]
season = max_temp
if item.library_playcounts or item.tmdb_stat: #Comprobamos si realmente sabemos el num. máximo de temporadas
#Comprobamos si realmente sabemos el num. máximo de temporadas
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
num_temporadas_flag = True
else:
num_temporadas_flag = False
@@ -1226,11 +1320,11 @@ def episodios(item):
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + str(data))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
@@ -1245,7 +1339,7 @@ def episodios(item):
#Empezamos a generar cada episodio
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
if "pelisyseries.com" in item.url: #En esta web están en diferente orden
interm = url
url = thumb
thumb = interm
@@ -1273,6 +1367,10 @@ def episodios(item):
if scrapertools.find_single_match(info, '\[\d{3}\]'):
info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info)
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'
elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'):
@@ -1312,11 +1410,9 @@ def episodios(item):
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
#logger.error("TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / " + str(match['episode2']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
@@ -1331,11 +1427,11 @@ def episodios(item):
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
item_local.quality = item_local.quality.replace("ALTA DEFINICION", "HDTV")
if match['lang'] and estado == False:
match['lang'] = match['lang'].replace("- ", "")
if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()):
match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "")
item_local.infoLabels['episodio_titulo'] = match['lang']
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.contentEpisodeNumber = match['episode']
if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca
@@ -1381,6 +1477,8 @@ def episodios(item):
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
#logger.debug(item)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
@@ -1395,7 +1493,7 @@ def actualizar_titulos(item):
from platformcode import launcher
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return launcher.run(item)
@@ -1403,6 +1501,9 @@ def actualizar_titulos(item):
def search(item, texto):
logger.info("search:" + texto)
# texto = texto.replace(" ", "+")
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
try:
item.post = "q=%s" % texto
+1 -1
View File
@@ -474,7 +474,7 @@ def download_from_url(url, item):
block_size=2 ** (17 + int(config.get_setting("block_size", "downloads"))),
part_size=2 ** (20 + int(config.get_setting("part_size", "downloads"))),
max_buffer=2 * int(config.get_setting("max_buffer", "downloads")))
d.start_dialog("Descargas")
d.start_dialog(config.get_localized_string(60332))
# Descarga detenida. Obtenemos el estado:
# Se ha producido un error en la descarga
+83 -331
View File
@@ -12,6 +12,7 @@ from core import servertools
from core.item import Item
from platformcode import config, logger
from core import tmdb
from lib import generictools
host = 'http://www.elitetorrent.biz'
@@ -39,7 +40,12 @@ def submenu(item):
logger.info()
itemlist = []
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
patron = '<div class="cab_menu">.*?<\/div>' #Menú principal
data1 = scrapertools.get_match(data, patron)
@@ -48,6 +54,10 @@ def submenu(item):
patron = '<a href="(.*?)".*?title="(.*?)"' #Encontrar todos los apartados
matches = re.compile(patron, re.DOTALL).findall(data1)
if not matches:
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data1)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
for scrapedurl, scrapedtitle in matches:
scrapedtitle = re.sub('\r\n', '', scrapedtitle).decode('utf8').strip()
@@ -76,8 +86,17 @@ def listado(item):
itemlist = []
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
patron = '<div id="principal">.*?<\/nav><\/div><\/div>'
data = scrapertools.find_single_match(data, patron)
@@ -90,6 +109,11 @@ def listado(item):
patron += '="dig2">(.*?)<\/span><\/div>' #tipo tamaño
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches and not '<title>503 Backend fetch failed</title>' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("PATRON: " + patron)
#logger.debug(matches)
#logger.debug(data)
@@ -102,7 +126,7 @@ def listado(item):
item_local.url = urlparse.urljoin(host, scrapedurl)
item_local.thumbnail = urlparse.urljoin(host, scrapedthumbnail)
if "---" in scrapedcalidad: #Scrapeamos y limpiamos calidades
if "---" in scrapedcalidad: #limpiamos calidades
scrapedcalidad = ''
if "microhd" in title.lower():
item_local.quality = "microHD"
@@ -137,13 +161,18 @@ def listado(item):
if item_local.extra == "peliculas": #preparamos Item para películas
if "/serie" in scrapedurl or "/serie" in item.url:
continue
if not "/serie" in scrapedurl and not "/serie" in item.url:
item_local.contentType = "movie"
item_local.contentTitle = title.strip()
else: #preparamos Item para series
item_local.contentTitle = title
item_local.extra = "peliculas"
if item_local.extra == "series": #preparamos Item para series
if not "/serie" in scrapedurl and not "/serie" in item.url:
continue
if "/serie" in scrapedurl or "/serie" in item.url:
item_local.contentType = "episode"
epi_mult = scrapertools.find_single_match(item_local.url, r'cap.*?-\d+-(al-\d+)')
item_local.extra = "series"
epi_mult = scrapertools.find_single_match(item_local.url, r'cap.*?-\d+-al-(\d+)')
item_local.contentSeason = scrapertools.find_single_match(item_local.url, r'temp.*?-(\d+)')
item_local.contentEpisodeNumber = scrapertools.find_single_match(item_local.url, r'cap.*?-(\d+)')
if not item_local.contentSeason:
@@ -154,87 +183,35 @@ def listado(item):
item_local.contentSeason = 1
if item_local.contentEpisodeNumber < 1:
item_local.contentEpisodeNumber = 1
item_local.contentSerieName = title.strip()
item_local.contentSerieName = title
if epi_mult:
title = '%s, %s' % (epi_mult.replace("-", " "), title)
title = "%sx%s al %s -" % (item_local.contentSeason, str(item_local.contentEpisodeNumber).zfill(2), str(epi_mult).zfill(2)) #Creamos un título con el rango de episodios
else:
title = '%sx%s ' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))
item_local.action = "findvideos"
item_local.title = title.strip()
item_local.infoLabels['year'] = "-"
#Pasamos a TMDB cada Item, para evitar el efecto memoria de tmdb
if item.category: #Si este campo no existe es que viene de la primera pasada de una búsqueda global, pasamos
tmdb.set_infoLabels(item_local, True)
itemlist.append(item_local.clone()) #Pintar pantalla
#if not item.category: #Si este campo no existe es que viene de la primera pasada de una búsqueda global
# return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
#tmdb.set_infoLabels(itemlist, True)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
title = item_local.title
# Si TMDB no ha encontrado el vídeo limpiamos el año
if item_local.infoLabels['year'] == "-":
item_local.infoLabels['year'] = ''
item_local.infoLabels['aired'] = ''
# Preparamos el título para series, con los núm. de temporadas, si las hay
if item_local.contentType == "season" or item_local.contentType == "tvshow":
item_local.contentTitle= ''
if item_local.contentType == "episode":
if scrapertools.find_single_match(title, r'(al\s\d+)'):
item_local.infoLabels['episodio_titulo'] = scrapertools.find_single_match(title, r'(al\s\d+)')
if scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'):
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
rating = ''
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
#Ahora maquillamos un poco los titulos dependiendo de si se han seleccionado títulos inteleigentes o no
if not config.get_setting("unify"): #Si Titulos Inteligentes NO seleccionados:
if item_local.contentType == "episode":
if item_local.infoLabels['episodio_titulo']:
title = '%sx%s %s, %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), item_local.infoLabels['episodio_titulo'], item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
else:
title = '%sx%s %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
item_local.infoLabels['title'] = item_local.contentSerieName
elif item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series":
title = '%s - Temporada %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, item_local.contentSeason, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
else:
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
elif item_local.contentType == "movie":
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (title, str(item_local.infoLabels['year']), rating, item_local.quality, str(item_local.language))
if config.get_setting("unify"): #Si Titulos Inteligentes SÍ seleccionados:
if item_local.contentType == "episode":
if item_local.infoLabels['episodio_titulo']:
item_local.infoLabels['episodio_titulo'] = '%s, %s [%s] [%s]' % (item_local.infoLabels['episodio_titulo'], item_local.contentSerieName, item_local.infoLabels['year'], rating)
else:
item_local.infoLabels['episodio_titulo'] = '%s [%s] [%s]' % (item_local.contentSerieName, item_local.infoLabels['year'], rating)
item_local.infoLabels['title'] = item_local.contentSerieName
elif item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series":
title = '%s - Temporada %s [%s] [%s]' % (item_local.contentSerieName, item_local.contentSeason, item_local.infoLabels['year'], rating)
else:
title = '%s' % (item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
title = title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title).strip()
title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title).strip()
item_local.title = title
logger.debug("url: " + item_local.url + " / title: " + item_local.title + " / content title: " + item_local.contentTitle + "/" + item_local.contentSerieName + " / calidad: " + item_local.quality + " / year: " + str(item_local.infoLabels['year']))
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_listado(item, itemlist)
# Extrae el paginador
patron = '<div class="paginacion">.*?<span class="pagina pag_actual".*?'
patron += "<a href='([^']+)'.*?" #url siguiente página
patron += 'class="pagina">(\d+)<.*?' #próxima página
patron += 'class="pagina">(\d+)<' #próxima página
matches = scrapertools.find_single_match(data, patron)
patron = 'class="pagina pag_sig">Siguiente.*?'
@@ -257,278 +234,50 @@ def listado(item):
return itemlist
def listado_busqueda(item):
logger.info()
itemlist = []
# Descarga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
patron = '<div id="principal">.*?<\/nav><\/div><\/div>'
data = scrapertools.find_single_match(data, patron)
patron = '<li>.*?<a href="(.*?)".*?' #url
patron += 'title="(.*?)".*?' #título
patron += 'src="(.*?)".*?' #thumb
patron += "title='(.*?)'.*?" #categoría, idioma
patron += '"><i>(.*?)<\/i><\/span.*?' #calidad
patron += '="dig1">(.*?)<.*?' #tamaño
patron += '="dig2">(.*?)<\/span><\/div>' #tipo tamaño
matches = re.compile(patron, re.DOTALL).findall(data)
#logger.debug("PATRON: " + patron)
#logger.debug(matches)
#logger.debug(data)
for scrapedurl, scrapedtitle, scrapedthumbnail, scrapedcategory, scrapedcalidad, scrapedsize, scrapedsizet in matches:
item_local = item.clone()
title = re.sub('\r\n', '', scrapedtitle).decode('utf8').strip()
title = title.replace(" torrent", "").replace(" Torrent", "").replace("Series y ", "")
item_local.url = urlparse.urljoin(host, scrapedurl)
item_local.thumbnail = urlparse.urljoin(host, scrapedthumbnail)
if "---" in scrapedcalidad:
scrapedcalidad = ''
if "microhd" in title.lower():
item_local.quality = "microHD"
if not "/series-vose/" in item.url and not item_local.quality:
item_local.quality = scrapedcalidad
if scrapertools.find_single_match(item_local.quality, r'\d+\.\d+'):
item_local.quality = ''
if not item_local.quality and ("DVDRip" in title or "HDRip" in title or "BR-LINE" in title or "HDTS-SCREENER" in title or "BDRip" in title or "BR-Screener" in title or "DVDScreener" in title or "TS-Screener" in title):
item_local.quality = scrapertools.find_single_match(title, r'\((.*?)\)')
item_local.quality = item_local.quality.replace("Latino", "")
if not scrapedsizet:
scrapedsize = ''
else:
item_local.quality += ' [%s %s]' % (scrapedsize.replace(".", ","), scrapedsizet)
item_local.language = []
if "latino" in scrapedcategory.lower() or "latino" in item.url or "latino" in title.lower():
item_local.language += ["LAT"]
if "ingles" in scrapedcategory.lower() or "ingles" in item.url or "vose" in scrapedurl or "vose" in item.url:
if "VOSE" in scrapedcategory.lower() or "sub" in title.lower() or "vose" in scrapedurl or "vose" in item.url:
item_local.language += ["VOS"]
else:
item_local.language += ["VO"]
if "dual" in scrapedcategory.lower() or "dual" in title.lower():
item_local.language[0:0] = ["DUAL"]
title = title.replace("Dual", "").replace("dual", "").replace("Subtitulada", "").replace("subtitulada", "").replace("Subt", "").replace("subt", "").replace("Sub", "").replace("sub", "").replace("(Proper)", "").replace("(proper)", "").replace("Proper", "").replace("proper", "").replace("#", "").replace("(Latino)", "").replace("Latino", "")
title = title.replace("- HDRip", "").replace("(HDRip)", "").replace("- Hdrip", "").replace("(microHD)", "").replace("(DVDRip)", "").replace("(HDRip)", "").replace("(BR-LINE)", "").replace("(HDTS-SCREENER)", "").replace("(BDRip)", "").replace("(BR-Screener)", "").replace("(DVDScreener)", "").replace("TS-Screener", "").replace(" TS", "").replace(" Ts", "")
title = re.sub(r'\??\s?\d*?\&.*', '', title).title().strip()
if not "/serie" in scrapedurl:
item_local.contentType = "movie"
item_local.extra = "peliculas"
item_local.contentTitle = title
else:
item_local.contentType = "episode"
item_local.extra = "series"
epi_mult = scrapertools.find_single_match(item_local.url, r'cap.*?-\d+-(al-\d+)')
item_local.contentSeason = scrapertools.find_single_match(item_local.url, r'temp.*?-(\d+)')
item_local.contentEpisodeNumber = scrapertools.find_single_match(item_local.url, r'cap.*?-(\d+)')
if not item_local.contentSeason:
item_local.contentSeason = scrapertools.find_single_match(item_local.url, r'-(\d+)[x|X]\d+')
if not item_local.contentEpisodeNumber:
item_local.contentEpisodeNumber = scrapertools.find_single_match(item_local.url, r'-\d+[x|X](\d+)')
if item_local.contentSeason < 1:
item_local.contentSeason = 1
if item_local.contentEpisodeNumber < 1:
item_local.contentEpisodeNumber = 1
item_local.contentSerieName = title
if epi_mult:
title = '%s, %s' % (epi_mult.replace("-", " "), title)
item_local.action = "findvideos"
item_local.title = title
item_local.infoLabels['year'] = "-"
itemlist.append(item_local.clone()) #Pintar pantalla
if not item.category: #Si este campo no existe es que viene de la primera pasada de una búsqueda global
return itemlist #Retornamos sin pasar por la fase de maquillaje para ahorra tiempo
#Pasamos a TMDB la lista completa Itemlist
tmdb.set_infoLabels(itemlist, True)
# Pasada para maquillaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
title = item_local.title
# Si TMDB no ha encontrado el vídeo limpiamos el año
if item_local.infoLabels['year'] == "-":
item_local.infoLabels['year'] = ''
item_local.infoLabels['aired'] = ''
# Preparamos el título para series, con los núm. de temporadas, si las hay
if item_local.contentType == "season" or item_local.contentType == "tvshow":
item_local.contentTitle= ''
if item_local.contentType == "episode":
if scrapertools.find_single_match(title, r'(al\s\d+)'):
item_local.infoLabels['episodio_titulo'] = scrapertools.find_single_match(title, r'(al\s\d+)')
if scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'):
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
rating = ''
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
#Ahora maquillamos un poco los titulos dependiendo de si se han seleccionado títulos inteleigentes o no
if not config.get_setting("unify"): #Si Titulos Inteligentes NO seleccionados:
if item_local.contentType == "episode":
if item_local.infoLabels['episodio_titulo']:
title = '%sx%s %s, %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), item_local.infoLabels['episodio_titulo'], item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
else:
title = '%sx%s %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
item_local.infoLabels['title'] = item_local.contentSerieName
elif item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series":
title = '%s - Temporada %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, item_local.contentSeason, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
else:
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
elif item_local.contentType == "movie":
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (title, str(item_local.infoLabels['year']), rating, item_local.quality, str(item_local.language))
if config.get_setting("unify"): #Si Titulos Inteligentes SÍ seleccionados:
if item_local.contentType == "episode":
if item_local.infoLabels['episodio_titulo']:
item_local.infoLabels['episodio_titulo'] = '%s, %s [%s] [%s]' % (item_local.infoLabels['episodio_titulo'], item_local.contentSerieName, item_local.infoLabels['year'], rating)
else:
item_local.infoLabels['episodio_titulo'] = '%s [%s] [%s]' % (item_local.contentSerieName, item_local.infoLabels['year'], rating)
item_local.infoLabels['title'] = item_local.contentSerieName
elif item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series":
title = '%s - Temporada %s [%s] [%s]' % (item_local.contentSerieName, item_local.contentSeason, item_local.infoLabels['year'], rating)
else:
title = '%s' % (item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
title = title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title).strip()
title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title).strip()
item_local.title = title
logger.debug("url: " + item_local.url + " / title: " + item_local.title + " / content title: " + item_local.contentTitle + "/" + item_local.contentSerieName + " / calidad: " + item_local.quality + " / year: " + str(item_local.infoLabels['year']))
# Extrae el paginador
patron = '<div class="paginacion">.*?<span class="pagina pag_actual".*?'
patron += "<a href='([^']+)'.*?" #url siguiente página
patron += 'class="pagina">(\d+)<' #próxima página
matches = scrapertools.find_single_match(data, patron)
patron = 'class="pagina pag_sig">Siguiente.*?'
patron += "<a href='.*?\/page\/(\d+)\/" #total de páginas
last_page = scrapertools.find_single_match(data, patron)
if not last_page:
patron = '<div class="paginacion">.*?'
patron += 'class="pagina">(\d+)<\/a><\/div><\/nav><\/div><\/div>' #total de páginas
last_page = scrapertools.find_single_match(data, patron)
if matches:
scrapedurl = urlparse.urljoin(item.url, matches[0])
if last_page:
title = '[COLOR gold]Página siguiente >>[/COLOR] %s de %s' % (int(matches[1]) - 1, last_page)
else:
title = '[COLOR gold]Página siguiente >>[/COLOR] %s' % (int(matches[1]) - 1)
itemlist.append(Item(channel=item.channel, action="listado_busqueda", title=title, url=scrapedurl, extra=item.extra))
return itemlist
def findvideos(item):
logger.info()
itemlist = []
# Saber si estamos en una ventana emergente lanzada desde una viñeta del menú principal,
# con la función "play_from_library"
unify_status = False
try:
import xbmc
if xbmc.getCondVisibility('Window.IsMedia') == 1:
unify_status = config.get_setting("unify")
except:
unify_status = config.get_setting("unify")
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] and item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, True)
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
#Bajamos los datos de la página
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#data = unicode(data, "utf-8", errors="replace")
#Añadimos el tamaño para todos
size = scrapertools.find_single_match(item.quality, '\s\[(\d+,?\d*?\s\w[b|B]s)\]')
item.quality = re.sub('\s\[\d+,?\d*?\s\w[b|B]s\]', '', item.quality) #Quitamos size de calidad, si lo traía
if size:
item.title = re.sub('\s\[\d+,?\d*?\s\w[b|B]s\]', '', item.title) #Quitamos size de título, si lo traía
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
item.quality = re.sub('\s\[\d+,?\d*?\s\w[b|B]s\]', '', item.quality) #Quitamos size de calidad, si lo traía
item.quality = '%s [%s]' % (item.quality, size) #Agregamos size al final de calidad
item.quality = item.quality.replace("G", "G ").replace("M", "M ") #Se evita la palabra reservada en Unify
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
if item.infoLabels['episodio_titulo'] == item.contentSerieName:
item.infoLabels['episodio_titulo'] = ''
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
patron = '<div class="enlace_descarga".*?<a href="(.*?\.torrent)"'
link_torrent = scrapertools.find_single_match(data, patron)
link_torrent = urlparse.urljoin(item_local.url, link_torrent)
patron_t = '<div class="enlace_descarga".*?<a href="(.*?\.torrent)"'
link_torrent = scrapertools.find_single_match(data, patron_t)
link_torrent = urlparse.urljoin(item.url, link_torrent)
link_torrent = link_torrent.replace(" ", "%20") #sustituimos espacios por %20, por si acaso
#logger.info("link Torrent: " + link_torrent)
patron = '<div class="enlace_descarga".*?<a href="(magnet:?.*?)"'
link_magnet = scrapertools.find_single_match(data, patron)
link_magnet = urlparse.urljoin(item_local.url, link_magnet)
patron_m = '<div class="enlace_descarga".*?<a href="(magnet:?.*?)"'
link_magnet = scrapertools.find_single_match(data, patron_m)
link_magnet = urlparse.urljoin(item.url, link_magnet)
#logger.info("link Magnet: " + link_magnet)
#Pintamos el pseudo-título con toda la información disponible del vídeo
item_local.action = ""
item_local.server = "torrent"
rating = '' #Ponemos el rating
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
if item_local.contentType == "episode":
title = '%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))
if item_local.infoLabels['temporada_num_episodios']:
title = '%s (de %s)' % (title, str(item_local.infoLabels['temporada_num_episodios']))
title = '%s %s' % (title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['episodio_titulo']: #Ya viene con el nombre de Serie
title_gen = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] [%s]' % (title, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language), size)
else:
title_gen = '%s, %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] [%s]' % (title, item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language), size)
else:
title = item_local.title
title_gen = title
title_gen = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title_gen) #Quitamos etiquetas vacías
title_gen = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title_gen) #Quitamos colores vacíos
title_gen = title_gen.replace(" []", "") #Quitamos etiquetas vacías
if not link_torrent and not link_magnet: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron_t + " / " + patron_m + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web. Verificar en la Web y reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if not unify_status: #Si Titulos Inteligentes NO seleccionados:
title_gen = '**- [COLOR gold]Enlaces Ver: [/COLOR]%s[COLOR gold] -**[/COLOR]' % (title_gen)
else:
title_gen = '[COLOR gold]Enlaces Ver: [/COLOR]%s' % (title_gen)
if config.get_setting("quit_channel_name", "videolibrary") == 1 and item_local.contentChannel == "videolibrary":
title_gen = '%s: %s' % (item_local.channel.capitalize(), title_gen)
itemlist.append(item_local.clone(title=title_gen)) #Título con todos los datos del vídeo
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
item, itemlist = generictools.post_tmdb_findvideos(item, itemlist)
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
#Ahora pintamos el link del Torrent, si lo hay
if link_torrent: # Hay Torrent ?
if item_local.quality:
@@ -540,6 +289,7 @@ def findvideos(item):
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title) #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Seridor Torrent
itemlist.append(item_local.clone()) #Pintar pantalla
@@ -554,10 +304,11 @@ def findvideos(item):
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title) #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Seridor Torrent
itemlist.append(item_local.clone()) #Pintar pantalla
logger.debug("TORRENT: " + link_torrent + "MAGNET: " + link_magnet + " / title gen/torr: " + title_gen + " / " + title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
#logger.debug("TORRENT: " + link_torrent + "MAGNET: " + link_magnet + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
#logger.debug(item_local)
return itemlist
@@ -569,7 +320,7 @@ def search(item, texto):
try:
item.url = host + "?s=%s&x=0&y=0" % texto
itemlist = listado_busqueda(item)
itemlist = listado(item)
return itemlist
@@ -587,9 +338,10 @@ def newest(categoria):
item = Item()
try:
if categoria == 'torrent':
item.url = 'http://www.elitetorrent.wesconference.net/categoria/2/peliculas/modo:mini'
item.url = host
item.extra = "peliculas"
itemlist = peliculas(item)
itemlist = listado(item)
if itemlist[-1].title == "Página siguiente >>":
itemlist.pop()
+12 -17
View File
@@ -286,20 +286,20 @@ def listado(item):
title = title.replace("Dual", "").replace("dual", "").replace("Subtitulada", "").replace("subtitulada", "").replace("Subt", "").replace("subt", "").replace("Sub", "").replace("sub", "").replace("(Reparado)", "").replace("(Proper)", "").replace("(proper)", "").replace("Proper", "").replace("proper", "").replace("(Latino)", "").replace("Latino", "")
title = title.replace("- HDRip", "").replace("(HDRip)", "").replace("- Hdrip", "").replace("(microHD)", "").replace("(DVDRip)", "").replace("(HDRip)", "").replace("(BR-LINE)", "").replace("(HDTS-SCREENER)", "").replace("(BDRip)", "").replace("(BR-Screener)", "").replace("(DVDScreener)", "").replace("TS-Screener", "").replace(" TS", "").replace(" Ts", "")
if item_local.extra == "peliculas": #preparamos Item para películas
if item_local.extra == "peliculas": #preparamos Item para películas
if "/serie" in scrapedurl or "/serie" in item.url:
continue
item_local.contentType = "movie"
item_local.action = "findvideos"
title = scrapertools.htmlclean(title) #Quitamos html restante
title = scrapertools.htmlclean(title) #Quitamos html restante
item_local.contentTitle = title.strip()
else: #preparamos Item para series
else: #preparamos Item para series
if not "/serie" in scrapedurl and not "/serie" in item.url:
continue
if modo_serie_temp == 1: #si está en modo Serie
if modo_serie_temp == 1: #si está en modo Serie
item_local.contentType = "tvshow"
item_local.extra = "tvshow"
else: #si no, en modo temporada
else: #si no, en modo temporada
item_local.contentType = "season"
item_local.extra = "season"
item_local.action = "episodios"
@@ -378,6 +378,7 @@ def findvideos(item):
if item.contentType == "episode": #En Series los campos están en otro orden. No hay size, en su lugar sxe
temp_epi = quality
quality = size
size = ''
contentSeason = ''
contentEpisodeNumber = ''
try: #obtenemos la temporada y episodio de la página y la comparamos con Item
@@ -423,17 +424,11 @@ def findvideos(item):
item_local.quality = quality
if "temporada" in temp_epi.lower():
item_local.quality = '%s [Temporada]' % item_local.quality
if size and item_local.contentType != "episode":
#if size and item_local.contentType != "episode":
if size:
size = size.replace(".", ",").replace("B,", " B").replace("b,", " b")
item_local.quality = '%s [%s]' % (item_local.quality, size)
#Limpiamos de año y rating de episodios
if item.infoLabels['episodio_titulo']:
item.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item.infoLabels['episodio_titulo'])
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(item.wanted, '')
if item.infoLabels['aired'] and item.contentType == "episode":
item.infoLabels['year'] = scrapertools.find_single_match(str(item.infoLabels['aired']), r'\/(\d{4})')
#Salvamos la url del .torrent
if scrapedurl:
item_local.url = scrapedurl
@@ -446,7 +441,7 @@ def findvideos(item):
itemlist.append(item_local.clone()) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality)
#logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality)
#logger.debug(item_local)
return itemlist
@@ -495,14 +490,14 @@ def episodios(item):
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
max_temp = int(max(matches))
if not item.library_playcounts: #no viene de Videoteca, se ponen valores de configuración o de la pasada anterior
if not item.library_playcounts: #no viene de Videoteca, se ponen valores de configuración o de la pasada anterior
if not item.contentType:
if modo_serie_temp == 0:
item.contentType = "season"
else:
item.contentType = "tvshow"
if item.contentSeason:
item.contentSeason = 0
del item.infoLabels['season']
elif max_temp < item.infoLabels["number_of_seasons"]: #Si tenemos en .nfo menos temporadas, Temp.
item.contentType = "season"
-3
View File
@@ -413,9 +413,6 @@ def episodios(item):
patron = "<li><a href='([^']+)'>[^<]+</a></li>"
matches = re.compile(patron, re.DOTALL).findall(data)
for scrapedurl in matches:
if "temporada-0" in scrapedurl:
continue
## Episodios
data = agrupa_datos(httptools.downloadpage(scrapedurl).data)
sid = scrapertools.get_match(data, "<script>var sid = '(\d+)'")
ssid = scrapertools.get_match(scrapedurl, "temporada-(\d+)")
+37 -37
View File
@@ -54,8 +54,8 @@ def start(item, recomendaciones=[], from_window=False):
global SearchWindows
SearchWindows = list()
dialog = platformtools.dialog_progress("Cargando nuevos datos",
"Buscandoen Tmdb.......")
dialog = platformtools.dialog_progress(config.get_localized_string(60469),
config.get_localized_string(60470))
principal_window = main(item=item, recomendaciones=recomendaciones, dialog=dialog, from_window=from_window)
try:
@@ -101,7 +101,7 @@ class main(xbmcgui.WindowDialog):
self.item.infoLabels.pop("episode", None)
if not self.item.infoLabels["year"]:
self.dialog.close()
platformtools.dialog_notification("Sin resultados. Falta información del año del video", "No hay info de la %s solicitada" % tipo)
platformtools.dialog_notification(config.get_localized_string(60471), config.get_localized_string(60472) % tipo)
global mainWindow
self.close()
del mainWindow
@@ -113,7 +113,7 @@ class main(xbmcgui.WindowDialog):
if not self.infoLabels["tmdb_id"]:
self.dialog.close()
platformtools.dialog_notification("Sin resultados", "No hay info de la %s solicitada" % tipo)
platformtools.dialog_notification(config.get_localized_string(60473), config.get_localized_string(60474) % tipo)
global mainWindow
self.close()
del mainWindow
@@ -133,30 +133,30 @@ class main(xbmcgui.WindowDialog):
rating = "[COLOR crimson][B]%s[/B][/COLOR]" % self.infoLabels["rating"]
self.dialog.update(40,
'Registrando filmaffinity.......')
config.get_localized_string(60475))
rating_fa, plot_fa = get_filmaf(self.item, self.infoLabels)
if not self.infoLabels.get("plot") and plot_fa:
self.infoLabels["plot"] = "[COLOR moccasin][B]%s[/B][/COLOR]" % plot_fa
elif not self.infoLabels["plot"]:
self.infoLabels["plot"] = "[COLOR yellow][B]Esta pelicula no tiene informacion...[/B][/COLOR]"
self.infoLabels["plot"] = config.get_localized_string(60476)
else:
self.infoLabels["plot"] = "[COLOR moccasin][B]%s[/B][/COLOR]" % self.infoLabels.get("plot")
self.dialog.update(60, 'Indagando recomendaciones.......')
self.dialog.update(60, config.get_localized_string(60477))
thread1 = Thread(target=get_recomendations, args=[self.item, self.infoLabels, self.recomendaciones])
thread1.setDaemon(True)
thread1.start()
if self.infoLabels.get("status") == "Ended" and tipo == "serie":
status = "[COLOR aquamarine][B]Finalizada %s[/B][/COLOR]"
status = config.get_localized_string(60478)
elif self.infoLabels.get("status") and tipo == "serie":
status = "[COLOR aquamarine][B]En emisión %s[/B][/COLOR]"
status = config.get_localized_string(60479)
else:
status = "[COLOR aquamarine][B]%s[/B][/COLOR]"
if self.infoLabels.get("tagline") and tipo == "serie":
self.infoLabels["tagline"] = status % "(" + self.infoLabels["tagline"] + ")"
elif not self.infoLabels.get("tagline") and tipo == "serie":
self.infoLabels["tagline"] = status % "(Temporadas: %s)" % self.infoLabels.get("number_of_seasons",
self.infoLabels["tagline"] = status % config.get_localized_string(60480) % self.infoLabels.get("number_of_seasons",
"---")
else:
self.infoLabels["tagline"] = status % self.infoLabels.get("tagline", "")
@@ -184,7 +184,7 @@ class main(xbmcgui.WindowDialog):
if self.item.contentType != "movie":
self.dialog.update(60,
'Recopilando imágenes en FANART.TV')
config.get_localized_string(60481))
try:
###Busca música serie
titulo = re.sub('\[.*?\]', '', titulo)
@@ -210,9 +210,9 @@ class main(xbmcgui.WindowDialog):
logger.error(traceback.format_exc())
if xbmc.Player().isPlaying():
self.dialog.update(80, 'Afinado instrumentos en Vtunes')
self.dialog.update(80, config.get_localized_string(60482))
else:
self.dialog.update(80, 'Recopilando imágenes en FANART.TV')
self.dialog.update(80, config.get_localized_string(60483))
while thread2.isAlive():
xbmc.sleep(100)
@@ -337,7 +337,7 @@ class main(xbmcgui.WindowDialog):
[('conditional', 'effect=fade start=0% end=100% delay=2000 time=1500 condition=true',),
('WindowClose', 'effect=fade start=100% end=0% time=800 condition=true',)])
self.duration.setText(
"[COLOR mediumturquoise][B]Duración: %s minutos[/B][/COLOR]" % self.infoLabels["duration"])
config.get_localized_string(70252) % self.infoLabels["duration"])
self.addControl(self.rating)
if set_animation:
self.rating.setAnimations(
@@ -741,8 +741,8 @@ class main(xbmcgui.WindowDialog):
else:
for boton, peli, id, poster2 in self.idps:
if control == boton:
dialog = platformtools.dialog_progress("Cargando nueva info",
"Buscando en Tmdb.......")
dialog = platformtools.dialog_progress(config.get_localized_string(60486),
config.get_localized_string(60487))
tipo = self.item.contentType
if tipo != "movie":
tipo = "tv"
@@ -834,7 +834,7 @@ class related(xbmcgui.WindowDialog):
[('conditional', 'effect=slide delay=6000 start=2000 time=800 condition=true',),
('WindowClose', 'effect=slide end=0,-700% time=1000 condition=true',)])
self.info = "[COLOR lemonchiffon]%s[/COLOR]" % self.infoLabels.get("plot", "Sin información...")
self.info = "[COLOR lemonchiffon]%s[/COLOR]" % self.infoLabels.get("plot", config.get_localized_string(60488))
self.info_peli = xbmcgui.ControlTextBox(455, 120, 750, 234)
self.addControl(self.info_peli)
@@ -923,7 +923,7 @@ class related(xbmcgui.WindowDialog):
self.paist_peli = xbmcgui.ControlTextBox(210, 435, 400, 60, self.fonts["12"])
self.addControl(self.paist_peli)
self.paist_peli.setText("[COLOR limegreen][B]País: [/B][/COLOR]")
self.paist_peli.setText(config.get_localized_string(60490))
if set_animation:
self.paist_peli.setAnimations(
[('conditional', 'effect=slide start=0,-700 delay=5650 time=700 condition=true tween=circle easing=in',),
@@ -939,7 +939,7 @@ class related(xbmcgui.WindowDialog):
self.ft_peli = xbmcgui.ControlTextBox(210, 460, 1100, 60, self.fonts["12"])
self.addControl(self.ft_peli)
self.ft_peli.setText("[COLOR limegreen][B]Estreno: [/B][/COLOR]")
self.ft_peli.setText(config.get_localized_string(60491))
if set_animation:
self.ft_peli.setAnimations(
[('conditional', 'effect=slide start=0,-700 delay=5600 time=700 condition=true tween=circle easing=in',),
@@ -959,7 +959,7 @@ class related(xbmcgui.WindowDialog):
if self.infoLabels.get("number_of_seasons"):
self.seasons_txt = xbmcgui.ControlTextBox(210, 485, 200, 60, self.fonts["12"])
self.addControl(self.seasons_txt)
self.seasons_txt.setText("[COLOR limegreen][B]Temporadas/Episodios: [/B][/COLOR]")
self.seasons_txt.setText(config.get_localized_string(60492))
if set_animation:
self.seasons_txt.setAnimations([('conditional',
'effect=slide start=0,-700 delay=5600 time=700 condition=true tween=circle easing=in',),
@@ -1234,9 +1234,9 @@ class Busqueda(xbmcgui.WindowXMLDialog):
except:
pass
if self.item.contentType != "movie":
self.getControl(1).setLabel("[COLOR orange][B]¿Está la serie que buscas?[/B][/COLOR]")
self.getControl(1).setLabel(config.get_localized_string(60493))
else:
self.getControl(1).setLabel("[COLOR orange][B]¿Está la película que buscas?[/B][/COLOR]")
self.getControl(1).setLabel(config.get_localized_string(60494))
self.getControl(5).setLabel("[COLOR tomato][B]Cerrar[/B][/COLOR]")
self.control_list.reset()
@@ -1256,7 +1256,7 @@ class Busqueda(xbmcgui.WindowXMLDialog):
def onAction(self, action):
global BusquedaWindow
if (action == ACTION_SELECT_ITEM or action == 100) and self.getFocusId() == 6:
dialog = platformtools.dialog_progress_bg("Cargando resultados", "Espere........")
dialog = platformtools.dialog_progress_bg(config.get_localized_string(60496), config.get_localized_string(60497))
selectitem = self.getControl(6).getSelectedItem()
item = Item().fromurl(selectitem.getProperty("item_copy"))
exec "import channels." + item.channel + " as channel"
@@ -1289,8 +1289,8 @@ class GlobalSearch(xbmcgui.WindowXMLDialog):
except:
pass
self.getControl(1).setLabel("[COLOR orange][B]Selecciona...[/B][/COLOR]")
self.getControl(5).setLabel("[COLOR tomato][B]Cerrar[/B][/COLOR]")
self.getControl(1).setLabel(config.get_localized_string(60498))
self.getControl(5).setLabel(config.get_localized_string(60495))
self.control_list.reset()
if not self.lista:
global SearchWindows
@@ -1327,7 +1327,7 @@ class GlobalSearch(xbmcgui.WindowXMLDialog):
item = itemlist[0]
else:
ventana_error = xbmcgui.Dialog()
ok = ventana_error.ok("plugin", "No hay nada para reproducir")
ok = ventana_error.ok("plugin", config.get_localized_string(60500))
return
global BusquedaWindow, exit_loop, mainWindow, ActorInfoWindow, relatedWindow, ActoresWindow
@@ -1375,7 +1375,7 @@ class GlobalSearch(xbmcgui.WindowXMLDialog):
else:
try:
dialog = platformtools.dialog_progress_bg("Cargando resultados", "Espere........")
dialog = platformtools.dialog_progress_bg(config.get_localized_string(60496), config.get_localized_string(60497))
itemlist = getattr(channel, item.action)(item)
window = GlobalSearch('DialogSelect.xml', config.get_runtime_path(), itemlist=itemlist,
dialog=dialog)
@@ -1416,8 +1416,8 @@ class Actores(xbmcgui.WindowXMLDialog):
self.getControl(3).setVisible(0)
except:
pass
self.getControl(1).setLabel("[COLOR orange][B]Reparto[/B][/COLOR]")
self.getControl(5).setLabel("[COLOR red][B]Cerrar[/B][/COLOR]")
self.getControl(1).setLabel(config.get_localized_string(60501))
self.getControl(5).setLabel(config.get_localized_string(60495))
self.control_list.reset()
items = []
@@ -1470,8 +1470,8 @@ class Actores(xbmcgui.WindowXMLDialog):
name_info = selectitem.getProperty("name_info")
thumbnail = selectitem.getProperty("thumbnail")
job = selectitem.getProperty("job")
dialog = platformtools.dialog_progress("Cargando nuevos datos",
"Obteniendo datos del %s..." % job.lower())
dialog = platformtools.dialog_progress(config.get_localized_string(60502),
config.get_localized_string(60503) % job.lower())
global ActorInfoWindow
ActorInfoWindow = ActorInfo(id=id_actor, name=name_info, thumbnail=thumbnail, item=self.item,
@@ -1542,7 +1542,7 @@ class ActorInfo(xbmcgui.WindowDialog):
bio = dhe(scrapertools.htmlclean(info.strip()))
actor_tmdb.result["biography"] = bio
else:
actor_tmdb.result["biography"] = "Sin información"
actor_tmdb.result["biography"] = config.get_localized_string(60504)
elif not actor_tmdb.result.get("biography"):
actor_tmdb.result["biography"] = "Sin información"
@@ -1579,7 +1579,7 @@ class ActorInfo(xbmcgui.WindowDialog):
xbmc.executebuiltin(
'Notification([COLOR red][B]Actualiza Kodi a su última versión[/B][/COLOR], [COLOR skyblue]para mejor info[/COLOR],8000, "http://i.imgur.com/mHgwcn3.png")')
self.info_actor.setText(
"[COLOR coral][B]%s[/B][/COLOR]" % actor_tmdb.result.get("biography", "Sin información"))
"[COLOR coral][B]%s[/B][/COLOR]" % actor_tmdb.result.get("biography", config.get_localized_string(60504)))
self.titulos = []
tipo_busqueda = "cast"
@@ -1914,8 +1914,8 @@ class ActorInfo(xbmcgui.WindowDialog):
for boton, peli, id, poster2 in self.idps:
if control == boton:
dialog = platformtools.dialog_progress("Cargando nueva info",
"Buscando en Tmdb.......")
dialog = platformtools.dialog_progress(config.get_localized_string(60486),
config.get_localized_string(60487))
tipo = self.item.contentType
if tipo != "movie":
tipo = "tv"
@@ -2177,8 +2177,8 @@ class Trailer(xbmcgui.WindowXMLDialog):
def onInit(self):
self.setCoordinateResolution(0)
if not self.video_url:
platformtools.dialog_notification("[COLOR crimson][B]Error[/B][/COLOR]",
"[COLOR tomato]Vídeo no disponible[/COLOR]", 2)
platformtools.dialog_notification(config.get_localized_string(60507),
config.get_localized_string(60508), 2)
self.close()
elif self.video_url == "no_video":
self.close()
+226 -373
View File
@@ -12,6 +12,7 @@ from core import servertools
from core.item import Item
from platformcode import config, logger
from core import tmdb
from lib import generictools
host = "http://www.mejortorrent.com"
@@ -84,20 +85,29 @@ def alfabeto(item):
def listado(item):
logger.info()
itemlist = []
url_next_page ='' # Controlde paginación
cnt_tot = 30 # Poner el num. máximo de items por página
url_next_page ='' # Control de paginación
cnt_tot = 30 # Poner el num. máximo de items por página
if item.category:
del item.category
if item.totalItems:
del item.totalItems
try:
# La url de Películas por orden Alfabético tiene un formato distinto
if item.extra == "peliculas" and item.tipo:
url = item.url.split("?")
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(url[0], post=url[1]).data)
else:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
if item.extra == "peliculas" and item.tipo:
url = item.url.split("?")
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(url[0], post=url[1]).data)
else:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
# En este canal las url's y los títulos tienen diferente formato dependiendo del contenido
if item.extra == "peliculas" and item.tipo: #Desde Lista Alfabética
@@ -115,6 +125,7 @@ def listado(item):
item.action = "findvideos"
item.contentType = "movie"
pag = True #Sí hay paginación
cnt_tot = 25 # Poner el num. máximo de items por página. Parece que hay 50
elif item.extra == "series" and item.tipo:
patron = "<a href='(/serie-descargar-torrent[^']+)'>()"
patron_enlace = "\/serie-descargar-torrent*.-\d+-?\d+-(.*?)\.html"
@@ -163,10 +174,35 @@ def listado(item):
else:
cnt_pag = item.cnt_pag
del item.cnt_pag
if not item.cnt_pag_num:
cnt_pag_num = 0 # Número de página actual
else:
cnt_pag_num = item.cnt_pag_num
del item.cnt_pag_num
matches = re.compile(patron, re.DOTALL).findall(data)
matches_cnt = len(matches)
if not matches and not 'Se han encontrado <b>0</b> resultados.' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#Capturamos el num. de la última página para informala a pié de página. Opción para páginas sin paginación
if pag == False:
item.last_page = (len(matches) / cnt_tot) + 1
if not item.last_page and pag: #Capturamos el num. de la última página para informala a pié de página
item.last_page = -1
patron_next_page = "<a href='([^']+)' class='paginar'> Siguiente >> <\/a>"
url_next_page = urlparse.urljoin(item.url, scrapertools.find_single_match(data, patron_next_page))
url_last_page = re.sub(r"\d+$", "9999", url_next_page)
data_last = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(url_last_page).data)
patron_last_page = "<span class='nopaginar'>(\d+)<\/span>"
if item.extra == "documentales":
item.last_page = int(scrapertools.find_single_match(data_last, patron_last_page))
else:
item.last_page = int(scrapertools.find_single_match(data_last, patron_last_page)) * (len(matches) / cnt_tot)
if matches_cnt > cnt_tot and item.extra == "documentales" and pag:
item.next_page = ''
if item.next_page != 'b':
@@ -189,10 +225,10 @@ def listado(item):
modo = 'next'
if item.next_page:
del item.next_page
#logger.debug(data)
#logger.debug("PATRON1: " + patron + " / ")
#logger.debug(matches)
logger.debug("PATRON1: " + patron + " / ")
logger.debug(matches)
# Primera pasada
# En la primera pasada se obtiene una información básica del título a partir de la url
@@ -212,6 +248,10 @@ def listado(item):
del item_local.pag
if item_local.text_color:
del item_local.text_color
if item_local.last_page:
del item_local.last_page
if item_local.cnt_pag_num:
del item_local.cnt_pag_num
item_local.title = ''
item_local.context = "['buscar_trailer']"
@@ -257,13 +297,16 @@ def listado(item):
real_title = scrapertools.find_single_match(scrapedurl, patron_title_se)
real_title = real_title.replace("-", " ")
item_local.contentSeason = scrapertools.find_single_match(scrapedurl, '.*?-(\d{1,2})-Temp.*?\.html')
item_local.contentSerieName = real_title
if not item_local.contentSeason:
item_local.contentSeason = 1
else:
item_local.contentTitle = item_local.title
if item_local.contentType == "episode":
item_local.title = '%sx%s ' % (item_local.contentSeason, item_local.contentEpisodeNumber)
itemlist.append(item_local.clone())
#logger.debug(item_local)
@@ -277,9 +320,10 @@ def listado(item):
cnt_pag = 0
else:
cnt_pag += cnt_tot
cnt_pag_num += 1
#logger.debug("PATRON2: " + patron_title)
#logger.debug(matches)
logger.debug("PATRON2: " + patron_title)
logger.debug(matches)
cnt = 0
for scrapedtitle, notused, scrapedinfo in matches:
item_local = itemlist[cnt] #Vinculamos item_local con la entrada de la lista itemlist (más fácil de leer)
@@ -287,8 +331,11 @@ def listado(item):
# Limpiamos títulos, Sacamos datos de calidad, audio y lenguaje
scrapedtitle = re.sub('\r\n', '', scrapedtitle).decode('iso-8859-1').encode('utf8').strip()
title = scrapedtitle
title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ")
title_subs = ""
title_subs = []
#Determinamos y marcamos idiomas distintos del castellano
item_local.language = []
if "[subs" in title.lower() or "[vos" in title.lower() or "v.o.s" in title.lower():
item_local.language += ["VOS"]
@@ -299,25 +346,25 @@ def listado(item):
title = title.replace("Castellano", "").replace("castellano", "").replace("inglés", "").replace("ingles", "").replace("Inglés", "").replace("Ingles", "")
if "3d" in title.lower(): #Reservamos info para después de TMDB
title_subs = " 3D"
item_local.quality += " 3D"
title = title.replace(" [3d]", "").replace(" 3d", "").replace(" [3D]", "").replace(" 3D", "")
if "temp" in title.lower(): #Reservamos info de Temporada para después de TMDB
title_subs = "[Temp.]"
#if "temp" in title.lower(): #Reservamos info de Temporada para después de TMDB
# title_subs += ["Temporada"]
if "audio" in title.lower(): #Reservamos info de audio para después de TMDB
title_subs = '[%s]' % scrapertools.find_single_match(title, r'(\[[a|A]udio.*?\])')
title_subs += ['[%s]' % scrapertools.find_single_match(title, r'(\[[a|A]udio.*?\])')]
title = re.sub(r'\[[a|A]udio.*?\]', '', title)
if "[dual" in title.lower():
title_subs = "[Dual]"
item_local.language[0:0] = ["DUAL"]
title = title = re.sub(r'\[D|dual.*?\]', '', title)
if scrapertools.find_single_match(title, r'-\s[m|M].*?serie'):
title = re.sub(r'-\s[m|M].*?serie', '', title)
title_subs += "[Miniserie]"
title_subs += ["Miniserie"]
if title.endswith('.'):
title = title[:-1]
title = title.replace("á", "a", 1).replace("é", "e", 1).replace("í", "i", 1).replace("ó", "o", 1).replace("ú", "u", 1).replace("ü", "u", 1)
if not title:
title = "dummy"
title = "SIN TÍTULO"
title = scrapertools.remove_htmltags(title)
info = scrapedinfo.decode('iso-8859-1').encode('utf8')
@@ -330,13 +377,13 @@ def listado(item):
if item_local.quality:
title = re.sub(r'[\[|\(]\d+.*?[\)|\]]', '', title) # Quitar la calidad del título
info = ""
item_local.contentSerieName = scrapertools.find_single_match(title, '(.*?) - \d.*?')
item_local.contentSerieName = scrapertools.find_single_match(title, '(.*?) - \d.*?').strip()
if not item_local.contentSerieName:
item_local.contentSerieName = title
item_local.infoLabels['tvshowtitle'] = item_local.contentSerieName
item_local.infoLabels['title'] = ''
item_local.contentSerieName = title.strip()
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
if not item_local.contentSerieName:
item_local.contentSerieName = "dummy"
item_local.contentSerieName = "SIN TITULO"
if info != "" and not item_local.quality:
item_local.quality = info
@@ -355,30 +402,28 @@ def listado(item):
item_local.quality = "4K"
title = title.replace("4k-hdr", "").replace("4K-HDR", "").replace("hdr", "").replace("HDR", "").replace("4k", "").replace("4K", "")
title = title.replace("(", "").replace(")", "").replace("[", "").replace("]", "").strip()
item_local.title = title
if item_local.extra == "peliculas":
if item_local.extra == "peliculas":
item_local.title = title
item_local.contentTitle = title
elif item_local.contentType != "episode":
item_local.title = title
item_local.title = '%s ' % item_local.contentSerieName
if "saga" in item_local.contentTitle.lower() or "saga" in item_local.contentSerieName.lower():
item_local.contentTitle = item_local.contentTitle.replace("Saga ", "").replace("Saga", "")
item_local.contentSerieName = item_local.contentSerieName.replace("Saga ", "").replace("Saga", "")
title_subs = "[Saga]"
title_subs += ["Saga"]
if "colecc" in item_local.contentTitle.lower() or "colecc" in item_local.contentSerieName.lower():
item_local.contentTitle = item_local.contentTitle.replace("Coleccion ", "").replace("Coleccion", "")
item_local.contentSerieName = item_local.contentSerieName.replace("Coleccion ", "").replace("Coleccion", "")
title_subs = "[Coleccion]"
if "3D" in title_subs: #Si es 3D lo añadimos a calidad
item_local.quality = item_local.quality + title_subs
title_subs = ''
title_subs += ["Coleccion"]
# Guardamos temporalmente info extra, si lo hay
item_local.extra = item_local.extra + title_subs
#Guarda la variable temporal que almacena la info adicional del título a ser restaurada después de TMDB
item_local.title_subs = title_subs
#Salvamos y borramos el número de temporadas porque TMDB a veces hace tonterias. Lo pasamos como serie completa
if item_local.contentSeason and (item_local.contentType == "season" or item_local.contentType == "tvshow"):
item_local.SeasonBackup = item_local.contentSeason
item_local.contentSeason_save = item_local.contentSeason
del item_local.infoLabels['season']
#logger.debug(item_local)
@@ -386,91 +431,22 @@ def listado(item):
cnt += 1
if cnt == len(itemlist):
break
#Llamamos a TMDB para que complete InfoLabels
#Llamamos a TMDB para que complete InfoLabels desde itemlist. Mejor desde itemlist porque envía las queries en paralelo
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
title = item_local.title
title_subs = ""
temporada = ""
title_subs = scrapertools.find_single_match(item_local.extra, r'(\[.*?\])')
if "[Temp.]" in item_local.extra:
temporada = "[Temp.]"
title_subs = ""
if "Audio" in item_local.extra or "audio" in item_local.extra:
title_subs = '[%s]' % scrapertools.find_single_match(item_local.extra, r'\[[a|A]udio (.*?)\]')
item_local.extra = re.sub(r'\[.*?\]', '', item_local.extra)
# Si TMDB no ha encontrado el vídeo limpiamos el año
if item_local.infoLabels['year'] == "-":
item_local.infoLabels['year'] = ''
item_local.infoLabels['aired'] = ''
# Preparamos el título para series, con los núm. de temporadas, si las hay
if item_local.contentType == "season" or item_local.contentType == "tvshow":
item_local.contentTitle= ''
rating = ''
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
#Cambiamos el título si son capítulos múltiples
if scrapertools.find_single_match(item_local.url, r'\d+x\d+.*?(\w+.*?\d+x\d+)'):
item_local.infoLabels['episodio_titulo'] = scrapertools.find_single_match(item_local.url, r'\d+x\d+.*?(\w+.*?\d+x\d+)').replace("-", " ")
#Ahora maquillamos un poco los titulos dependiendo de si se han seleccionado títulos inteleigentes o no
if not config.get_setting("unify"): #Si Titulos Inteligentes NO seleccionados:
if item_local.contentType == "episode":
if item_local.infoLabels['episodio_titulo']:
title = '%sx%s %s, %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (str(item_local.SeasonBackup), str(item_local.contentEpisodeNumber).zfill(2), item_local.infoLabels['episodio_titulo'], item_local.contentSerieName, scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'), rating, item_local.quality, str(item_local.language))
else:
title = '%sx%s %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (str(item_local.SeasonBackup), str(item_local.contentEpisodeNumber).zfill(2), item_local.contentSerieName, scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'), rating, item_local.quality, str(item_local.language))
item_local.infoLabels['title'] = item_local.contentSerieName
elif item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series" or temporada == "[Temp.]":
title = '%s - Temporada %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, str(item_local.SeasonBackup), scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'), rating, item_local.quality, str(item_local.language))
else:
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'), rating, item_local.quality, str(item_local.language))
elif item_local.contentType == "movie":
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (title, str(item_local.infoLabels['year']), rating, item_local.quality, str(item_local.language))
if config.get_setting("unify"): #Si Titulos Inteligentes SÍ seleccionados:
if item_local.contentType == "episode":
if item_local.infoLabels['episodio_titulo']:
item_local.infoLabels['episodio_titulo'] = '%s, %s [%s]' % (item_local.infoLabels['episodio_titulo'], item_local.contentSerieName, scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'))
else:
item_local.infoLabels['episodio_titulo'] = '%s [%s]' % (item_local.contentSerieName, scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'))
item_local.infoLabels['title'] = item_local.contentSerieName
elif item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series" or temporada == "[Temp.]":
title = '%s - Temporada %s' % (item_local.contentSerieName, item_local.SeasonBackup)
else:
title = '%s' % (item_local.contentSerieName)
title_subs = title_subs.replace("[", "-").replace("]", "-")
if item_local.SeasonBackup:
del item_local.SeasonBackup
item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace("--", "").replace(" []", "").replace("()", "").replace("(/)", "").replace("[/]", "")
title = title.replace("--", "").replace(" []", "").replace("()", "").replace("(/)", "").replace("[/]", "")
title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title)
title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title)
item_local.title = title + title_subs
item_local.contentTitle += title_subs #añadimos info adicional para display
#logger.debug(item_local)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_listado(item, itemlist)
if len(itemlist) == 0:
itemlist.append(Item(channel=item.channel, action="mainlist", title="No se ha podido cargar el listado"))
else:
if url_next_page:
title_foot = str(cnt_pag_num)
if item.last_page > 0:
title_foot += ' de %s' % str(item.last_page)
itemlist.append(
Item(channel=item.channel, action="listado", title="[COLOR gold][B]Pagina siguiente >>[/B][/COLOR]", url=url_next_page, next_page=next_page, cnt_pag=cnt_pag, pag=pag, modo=modo, extra=item.extra, tipo=item.tipo))
Item(channel=item.channel, action="listado", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + title_foot, url=url_next_page, next_page=next_page, cnt_pag=cnt_pag, pag=pag, modo=modo, extra=item.extra, tipo=item.tipo, last_page=item.last_page, cnt_pag_num=cnt_pag_num))
#logger.debug(url_next_page + " / " + next_page + " / " + str(matches_cnt) + " / " + str(cnt_pag) + " / " + str(pag) + " / " + modo + " / " + item.extra + " / " + str(item.tipo))
@@ -484,9 +460,17 @@ def listado_busqueda(item):
cnt_tot = 30 # Poner el num. máximo de items por página
pag = False # No hay paginación en la web
category = "" # Guarda la categoria que viene desde una busqueda global
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
#logger.debug(data)
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
# busca series y Novedades
patron = "<a href='(\/serie-descargar-torrent[^']+)'[^>]+>(.*?)<\/a>"
@@ -509,6 +493,12 @@ def listado_busqueda(item):
patron += "<td align='right' width='20%'>(.*?)<\/td>"
patron_enlace = "\/doc-descargar-torrent-\d+-\d+-(.*?)\.html"
matches += re.compile(patron, re.DOTALL).findall(data)
matches_cnt = len(matches)
if not matches and not 'Se han encontrado <b>0</b> resultados.' in data: #error
logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("MATCHES: ")
#logger.debug(matches)
@@ -519,8 +509,15 @@ def listado_busqueda(item):
else:
cnt_pag = item.cnt_pag
del item.cnt_pag
if not item.cnt_pag_num:
cnt_pag_num = 0 # Número de página actual
else:
cnt_pag_num = item.cnt_pag_num
del item.cnt_pag_num
matches_cnt = len(matches)
#Capturamos el num. de la última página para informala a pié de página
last_page = (len(matches) / cnt_tot) + 1
if item.next_page != 'b':
if matches_cnt > cnt_pag + cnt_tot:
url_next_page = item.url
@@ -546,6 +543,7 @@ def listado_busqueda(item):
cnt_pag += cnt_tot
else:
cnt_pag += matches_cnt
cnt_pag_num += 1
for scrapedurl, scrapedtitle, scrapedinfo in matches:
# Creamos "item_local" y lo limpiamos un poco de algunos restos de item
@@ -559,8 +557,11 @@ def listado_busqueda(item):
del item_local.totalItems
if item_local.text_color:
del item_local.text_color
if item_local.cnt_pag_num:
del item_local.cnt_pag_num
item_local.contentThumbnail = ''
item_local.thumbnail = ''
item_local.title = ''
item_local.context = "['buscar_trailer']"
item_local.infoLabels['year'] = '-' # Al no saber el año, le ponemos "-" y TmDB lo calcula automáticamente
@@ -569,11 +570,11 @@ def listado_busqueda(item):
title = scrapedtitle
title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ")
title_subs = ""
title_subs = []
#Determinamos y marcamos idiomas distintos del castellano
item_local.language = []
if "[vos" in title.lower() or "v.o.s" in title.lower() or "vo" in title.lower():
if "[subs" in title.lower() or "[vos" in title.lower() or "v.o.s" in title.lower() or "vo" in title.lower():
item_local.language += ["VOS"]
title = title.replace(" [Subs. integrados]", "").replace(" [subs. Integrados]", "").replace(" [VOSE", "").replace(" [VOS", "").replace(" (V.O.S.E)", "").replace(" VO", "")
if "latino" in title.lower() or "argentina" in title.lower():
@@ -581,28 +582,29 @@ def listado_busqueda(item):
title = title.replace(" Latino", "").replace(" latino", "").replace(" Argentina", "").replace(" argentina", "")
title = title.replace("Castellano", "").replace("castellano", "").replace("inglés", "").replace("ingles", "").replace("Inglés", "").replace("Ingles", "")
if "3d" in title or "3D" in title: #Reservamos info de subtítulos para después de TMDB
title_subs = "[3D]"
if "3d" in title or "3D" in title: #Reservamos info para después de TMDB
item_local.quality += " 3D"
title = title.replace(" [3d]", "").replace(" 3d", "").replace(" [3D]", "").replace(" 3D", "")
if "Temp" in title or "temp" in title: #Reservamos info de Temporada para después de TMDB
title_subs = "[Temp.]"
if "Audio" in title or "audio" in title: #Reservamos info de subtítulos para después de TMDB
title_subs = '[%s]' % scrapertools.find_single_match(title, r'(\[[a|A]udio.*?\])')
#if "temp" in title.lower(): #Reservamos info de Temporada para después de TMDB
# title_subs += ["Temporada"]
if "audio" in title.lower(): #Reservamos info de audio para después de TMDB
title_subs += ['[%s]' % scrapertools.find_single_match(title, r'(\[[a|A]udio.*?\])')]
title = re.sub(r'\[[a|A]udio.*?\]', '', title)
if "[Dual" in title or "[dual" in title:
title_subs = "[Dual]"
title = title = re.sub(r'\[[D|d]ual.*?\]', '', title)
if "[dual" in title.lower():
item_local.language[0:0] = ["DUAL"]
title = title = re.sub(r'\[D|dual.*?\]', '', title)
if scrapertools.find_single_match(title, r'-\s[m|M].*?serie'):
title = re.sub(r'-\s[m|M].*?serie', '', title)
title_subs += "[Miniserie]"
title_subs += ["Miniserie"]
if title.endswith('.'):
title = title[:-1]
if not title:
title = "dummy"
title = "SIN TÍTULO"
title = scrapertools.remove_htmltags(title)
# Ahora preparamos el título y la calidad tanto para series como para documentales y películas
if item.extra == "novedades" and ("/serie-" in scrapedurl or "/doc-" in scrapedurl):
item_local.quality = scrapertools.find_single_match(scrapedtitle, r'.*?\[(.*?)\]')
else:
@@ -621,22 +623,20 @@ def listado_busqueda(item):
item_local.contentType = "season"
title = re.sub(r'\[\d+.*?\]', '', title) # Quitar la calidad del título
item_local.contentSerieName = scrapertools.find_single_match(title, '(.*?) - \d.*?')
item_local.contentSerieName = scrapertools.find_single_match(title, '(.*?) - \d.*?').strip()
if not item_local.contentSerieName:
item_local.contentSerieName = title
if item_local.contentSerieName.endswith(' '):
item_local.contentSerieName = item_local.contentSerieName[:-1]
item_local.contentSerieName = title.strip()
if item_local.infoLabels['title']:
del item_local.infoLabels['title']
title = item_local.contentSerieName
item_local.title = title
item_local.infoLabels['tvshowtitle'] = item_local.contentSerieName
item_local.infoLabels['title'] = ''
if not item_local.contentSerieName:
item_local.contentSerieName = "dummy"
item_local.contentSerieName = "SIN TITULO"
item_local.contentSeason = scrapertools.find_single_match(scrapedurl, '.*?-(\d{1,2})-Temp.*?\.html')
if not item_local.contentSeason:
item_local.contentSeason = 1
if "(HDRip" in title or "(BR" in title or "(HDRip" in title or "(VHSRip" in title or "(DVDRip" in title or "(FullB" in title or "(fullb" in title or "(Blu" in title or "(4K" in title or "(4k" in title or "(HEVC" in title or "(IMAX" in title or "Extendida" in title or "[720p]" in title or "[1080p]" in title:
if "(hdrip" in title.lower() or "(br" in title.lower() or "(vhsrip" in title.lower() or "(dvdrip" in title.lower() or "(fullb" in title.lower() or "(blu" in title.lower() or "(4k" in title.lower() or "(hevc" in title.lower() or "(imax" in title.lower() or "extendida" in title.lower() or "[720p]" in title.lower() or "[1080p]" in title.lower():
if not item_local.quality:
item_local.quality = scrapertools.find_single_match(title, r'\(.*?\)?\(.*?\)')
if not item_local.quality:
@@ -644,10 +644,10 @@ def listado_busqueda(item):
title = re.sub(r'\(.*?\)?\(.*?\)', '', title)
title = re.sub(r'[\[|\(].*?[\)|\]]', '', title)
if not item_local.quality:
if "FullBluRay" in title or "fullbluray" in title:
if "fullbluray" in title.lower():
item_local.quality = "FullBluRay"
title = title.replace("FullBluRay", "").replace("fullbluray", "")
if "4K" in title or "4k" in title or "HDR" in title or "hdr" in title:
if "4k" in title.lower() or "hdr" in title.lower():
item_local.quality = "4K"
title = title.replace("4k-hdr", "").replace("4K-HDR", "").replace("hdr", "").replace("HDR", "").replace("4k", "").replace("4K", "")
title = title.replace("(", "").replace(")", "").replace("[", "").replace("]", "").strip()
@@ -659,21 +659,21 @@ def listado_busqueda(item):
item_local.contentType = "movie"
item_local.contentTitle = title
if "Saga" in item_local.contentTitle or "Saga" in item_local.contentSerieName:
item_local.contentTitle = item_local.contentTitle.replace("Saga ", "").replace("Saga", "")
item_local.contentSerieName = item_local.contentSerieName.replace("Saga ", "").replace("Saga", "")
title_subs = "[Saga]"
if "Colecc" in item_local.contentTitle or "Colecc" in item_local.contentSerieName:
item_local.contentTitle = item_local.contentTitle.replace("Coleccion ", "").replace("Coleccion", "")
item_local.contentSerieName = item_local.contentSerieName.replace("Coleccion ", "").replace("Coleccion", "")
title_subs = "[Coleccion]"
if "saga" in item_local.contentTitle.lower() or "saga" in item_local.contentSerieName.lower():
item_local.contentTitle = item_local.contentTitle.replace("Saga ", "").replace("Saga", "")
item_local.contentSerieName = item_local.contentSerieName.replace("Saga ", "").replace("Saga", "")
title_subs += ["Saga"]
if "colecc" in item_local.contentTitle.lower() or "colecc" in item_local.contentSerieName.lower():
item_local.contentTitle = item_local.contentTitle.replace("Coleccion ", "").replace("Coleccion", "")
item_local.contentSerieName = item_local.contentSerieName.replace("Coleccion ", "").replace("Coleccion", "")
title_subs += ["Coleccion"]
# Guardamos temporalmente info de subtítulos, si lo hay
item_local.extra = item_local.extra + title_subs
#Guarda la variable temporal que almacena la info adicional del título a ser restaurada después de TMDB
item_local.title_subs = title_subs
#Salvamos y borramos el número de temporadas porque TMDB a veces hace tonterias. Lo pasamos como serie completa
if item_local.contentSeason and (item_local.contentType == "season" or item_local.contentType == "tvshow"):
item_local.SeasonBackup = item_local.contentSeason
item_local.contentSeason_save = item_local.contentSeason
del item_local.infoLabels['season']
itemlist.append(item_local.clone())
@@ -686,67 +686,15 @@ def listado_busqueda(item):
#Llamamos a TMDB para que complete InfoLabels desde itemlist. Mejor desde itemlist porque envía las queries en paralelo
tmdb.set_infoLabels(itemlist, __modo_grafico__)
# Pasada para maqullaje de los títulos obtenidos desde TMDB
for item_local in itemlist:
title = item_local.title
title_subs = ""
temporada = ""
title_subs = scrapertools.find_single_match(item_local.extra, r'(\[.*?\])')
if "[Temp.]" in item_local.extra:
temporada = "[Temp.]"
title_subs = ""
if "Audio" in item_local.extra or "audio" in item_local.extra:
title_subs = '[%s]' % scrapertools.find_single_match(item_local.extra, r'\[[a|A]udio (.*?)\]')
item_local.extra = re.sub(r'\[.*?\]', '', item_local.extra)
# Si TMDB no ha encontrado el vídeo limpiamos el año
if item_local.infoLabels['year'] == "-":
item_local.infoLabels['year'] = ''
item_local.infoLabels['aired'] = ''
# Preparamos el título para series, con los núm. de temporadas, si las hay
if item_local.contentType == "season" or item_local.contentType == "tvshow":
item_local.contentTitle= ''
rating = ''
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
# Ahora maquillamos un poco los titulos dependiendo de si se han seleccionado títulos inteleigentes o no
if not config.get_setting("unify"): #Si Titulos Inteligentes NO seleccionados:
if item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series" or temporada == "[Temp.]":
title = '%s - Temporada %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, str(item_local.SeasonBackup), scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'), rating, item_local.quality, str(item_local.language))
else:
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.contentSerieName, scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})'), rating, item_local.quality, str(item_local.language))
elif item_local.contentType == "movie":
title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (title, str(item_local.infoLabels['year']), rating, item_local.quality, str(item_local.language))
if config.get_setting("unify"): #Si Titulos Inteligentes SÍ seleccionados:
if item_local.contentType == "season" or item_local.contentType == "tvshow":
if item_local.extra == "series" or temporada == "[Temp.]":
title = '%s - Temporada %s' % (item_local.contentSerieName, item_local.SeasonBackup)
else:
title = '%s' % (item_local.contentSerieName)
title_subs = title_subs.replace("[", "-").replace("]", "-")
if item_local.SeasonBackup:
del item_local.SeasonBackup
item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace("--", "").replace(" []", "").replace("()", "").replace("(/)", "").replace("[/]", "")
title = title.replace("--", "").replace(" []", "").replace("()", "").replace("(/)", "").replace("[/]", "")
title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title)
title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title)
item_local.title = title + title_subs
item_local.contentTitle += title_subs #añadimos info adicional para display
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], calidad=[" + item_local.quality + "]")
#logger.debug(item_local)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_listado(item, itemlist)
if url_next_page:
title_foot = str(cnt_pag_num)
if last_page > 0:
title_foot += ' de %s' % str(last_page)
itemlist.append(
Item(channel=item.channel, action="listado_busqueda", title="[COLOR gold][B]Pagina siguiente >>[/B][/COLOR]", url=url_next_page, next_page=next_page, cnt_pag=cnt_pag, pag=pag, modo=modo, extra=item.extra))
Item(channel=item.channel, action="listado_busqueda", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + title_foot, url=url_next_page, next_page=next_page, cnt_pag=cnt_pag, pag=pag, modo=modo, extra=item.extra, cnt_pag_num=cnt_pag_num))
#logger.debug(url_next_page + " / " + next_page + " / " + str(matches_cnt) + " / " + str(cnt_pag) + " / " + str(pag) + " / " + modo + " / " + item.extra ))
@@ -757,44 +705,28 @@ def findvideos(item):
logger.info()
itemlist = []
# Saber si estamos en una ventana emergente lanzada desde una viñeta del menú principal,
# con la función "play_from_library"
unify_status = False
#Bajamos los datos de la página
try:
import xbmc
if xbmc.getCondVisibility('Window.IsMedia') == 1:
unify_status = config.get_setting("unify")
if item.post: #Puede traer datos para una llamada "post". De momento usado para documentales, pero podrían ser series
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, post=item.post).data)
data = data.replace('"', "'")
patron = ">Pincha.*?<a href='(.*?\/uploads\/torrents\/\w+\/.*?\.torrent)'"
else:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
patron = "<a href='(secciones.php\?sec\=descargas&ap=contar&tabla=[^']+)'"
except:
unify_status = config.get_setting("unify")
#Salvamos la información de max num. de episodios por temporada para despues de TMDB
if item.infoLabels['temporada_num_episodios']:
num_episodios = item.infoLabels['temporada_num_episodios']
else:
num_episodios = 1
# Obtener la información actualizada del Episodio, si no la hay
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
tmdb.set_infoLabels(item, __modo_grafico__)
elif (not item.infoLabels['tvdb_id'] and item.contentType == 'episode') or item.contentChannel == "videolibrary":
tmdb.set_infoLabels(item, __modo_grafico__)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
if item.infoLabels['temporada_num_episodios'] and num_episodios > item.infoLabels['temporada_num_episodios']:
item.infoLabels['temporada_num_episodios'] = num_episodios
if item.post: #Puede traer datos para una llamada "post". De momento usado para documentales, pero podrían ser series
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, post=item.post).data)
data = data.replace('"', "'")
patron = ">Pincha.*?<a href='(.*?\/uploads\/torrents\/\w+\/.*?\.torrent)'"
else:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
patron = "<a href='(secciones.php\?sec\=descargas&ap=contar&tabla=[^']+)'"
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
matches = re.compile(patron, re.DOTALL).findall(data)
#logger.debug(data)
#logger.debug("PATRON: " + patron)
#logger.debug(matches)
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
item, itemlist = generictools.post_tmdb_findvideos(item, itemlist)
for scrapedurl in matches:
#Generamos una copia de Item para trabajar sobre ella
item_local = item.clone()
@@ -802,79 +734,46 @@ def findvideos(item):
# Localiza el .torrent en el siguiente link
if not item.post: # Si no es llamada con Post, hay que bajar un nivel más
torrent_data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(url).data)
try:
torrent_data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(url).data)
except: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / URL: " + url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web. Verificar en la Web y reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug(torrent_data)
item_local.url = scrapertools.get_match(torrent_data, ">Pincha.*?<a href='(.*?\/uploads\/torrents\/\w+\/.*?\.torrent)'")
item_local.url = urlparse.urljoin(url, item_local.url)
else:
item_local.url = url # Ya teníamos el link desde el primer nivel (documentales)
item_local.url = item_local.url.replace(" ", "%20")
#Pintamos el pseudo-título con toda la información disponible del vídeo
item_local.action = ""
item_local.server = "torrent"
#Limpiamos de año y rating de episodios, usamos el año del episodio en vez del de la serie
if item_local.infoLabels['episodio_titulo']:
item_local.infoLabels['episodio_titulo'] = re.sub(r'\s?\[.*?\]', '', item_local.infoLabels['episodio_titulo'])
item.infoLabels['episodio_titulo'] = item.infoLabels['episodio_titulo'].replace(' - ' + item.contentSerieName, '')
if item_local.infoLabels['aired'] and item_local.contentType == "episode":
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
rating = '' #Ponemos el rating
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
# Extrae la dimensión del vídeo
size = scrapertools.find_single_match(item_local.url, '(\d{1,3},\d{1,2}?\w+)\.torrent')
size = size.upper().replace(".", ",").replace("G", " G").replace("M", " M") #sustituimos . por , porque Unify lo borra
item_local.quality = re.sub('\s\[\d+,?\d*?\s\w[b|B]\]', '', item_local.quality) #Quitamos size de calidad, si lo traía
if size:
item_local.title = re.sub('\s\[\d+,?\d*?\s\w[b|B]\]', '', item_local.title) #Quitamos size de título, si lo traía
item_local.title = '%s [%s]' % (item_local.title, size) #Agregamos size al final del título
# Poner la calidad, si es necesario
if not item_local.quality:
if "HDTV" in item_local.url or "720p" in item_local.url or "1080p" in item_local.url or "4K" in item_local.url:
if "hdtv" in item_local.url.lower() or "720p" in item_local.url.lower() or "1080p" in item_local.url.lower() or "4k" in item_local.url.lower():
item_local.quality = scrapertools.find_single_match(item_local.url, '.*?_([H|7|1|4].*?)\.torrent')
item_local.quality = item_local.quality.replace("_", " ")
if item_local.contentType == "episode":
title = '%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))
if item_local.infoLabels['temporada_num_episodios']:
title = '%s (de %s)' % (title, str(item_local.infoLabels['temporada_num_episodios']))
title = '%s %s' % (title, item_local.infoLabels['episodio_titulo'])
title_gen = '%s, %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] [%s]' % (title, item_local.contentSerieName, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language), size)
else:
title = item_local.title
title_gen = title
title_gen = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title_gen) #Quitamos etiquetas vacías
title_gen = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title_gen) #Quitamos colores vacíos
title_gen = title_gen.replace(" []", "") #Quitamos etiquetas vacías
if not unify_status: #Si Titulos Inteligentes NO seleccionados:
title_gen = '**- [COLOR gold]Enlaces Ver: [/COLOR]%s[COLOR gold] -**[/COLOR]' % (title_gen)
else:
title_gen = '[COLOR gold]Enlaces Ver: [/COLOR]%s' % (title_gen)
if config.get_setting("quit_channel_name", "videolibrary") == 1 and item_local.contentChannel == "videolibrary":
title_gen = '%s: %s' % (item_local.channel.capitalize(), title_gen)
itemlist.append(item_local.clone(title=title_gen)) #Título con todos los datos del vídeo
# Extrae la dimensión del vídeo
size = scrapertools.find_single_match(item_local.url, '(\d{1,3},\d{1,2}?\w+)\.torrent')
size = size.upper().replace(".", ",").replace("G", " G ").replace("M", " M ") #sustituimos . por , porque Unify lo borra
if size:
item_local.title = re.sub('\s\[\d+,?\d*?\s\w[b|B]\]', '', item_local.title) #Quitamos size de título, si lo traía
item_local.title = '%s [%s]' % (item_local.title, size) #Agregamos size al final del título
item_local.quality = re.sub('\s\[\d+,?\d*?\s\w[b|B]\]', '', item_local.quality) #Quitamos size de calidad, si lo traía
item_local.quality = '%s [%s]' % (item.quality, size) #Agregamos size al final de calidad
#Ahora pintamos el link del Torrent, si lo hay
if item_local.url: # Hay Torrent ?
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title) #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title) #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title) #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Seridor Torrent
itemlist.append(item_local.clone()) #Pintar pantalla
#logger.debug("title=[" + title + "], torrent=[ " + item_local.url + " ], url=[ " + url + " ], post=[" + item.post + "], thumbnail=[ " + item.thumbnail + " ]")
#logger.debug("title=[" + item.title + "], torrent=[ " + item_local.url + " ], url=[ " + url + " ], post=[" + item.post + "], thumbnail=[ " + item.thumbnail + " ]" + " size: " + size)
return itemlist
@@ -888,7 +787,12 @@ def episodios(item):
tmdb.set_infoLabels(item, True)
# Carga la página
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
#Datos para crear el Post. Usado para documentales
total_capis = scrapertools.find_single_match(data, "<input type='hidden' name='total_capis' value='(\d+)'>")
@@ -909,6 +813,10 @@ def episodios(item):
patron += "<input type='checkbox' name='([^']+)' value='([^']+)'"
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches: #error
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
#logger.debug("PATRON: " + patron)
#logger.debug(matches)
@@ -923,7 +831,6 @@ def episodios(item):
item_local.url = urlparse.urljoin(host, scrapedurl)
scrapedtitle = scrapedtitle.strip()
scrapedtitle = re.sub('\r\n', '', scrapedtitle).decode('iso-8859-1').encode('utf8').strip()
if scrapedtitle.endswith('.'):
scrapedtitle = scrapedtitle[:-1]
@@ -931,6 +838,7 @@ def episodios(item):
scrapedtitle = "SIN TITULO"
if '/serie' in item.url:
scrapedtitle = re.sub(r'[a|A]l \d+[x|X]', 'al ', scrapedtitle) #Quitamos Temporada del segundo rango
title = scrapedtitle.lower()
epi = title.split("x")
if len(epi) > 1:
@@ -958,86 +866,30 @@ def episodios(item):
itemlist.append(item_local.clone())
# Llamamos a TMDB para que complete el episodio en InfoLabels
tmdb.set_infoLabels(itemlist, True)
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
# Pasada para maqullaje de los títulos obtenidos desde TMDB
num_episodios = 1
num_episodios_lista = [0]
num_temporada = 1
num_episodios_flag = True
for item_local in itemlist:
# Si no hay datos de TMDB, pongo los datos locales que conozco
if item_local.infoLabels['aired']:
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
# Si son episodios múltiples, se toman los datos locales para nombre de episodio
if scrapertools.find_single_match(item_local.title, r'\d+x\d+.*?(\w+.*?\d+x\d+)'):
item_local.infoLabels['episodio_titulo'] = scrapertools.find_single_match(item_local.title, r'\d+x\d+.*?(\w+.*?\d+x\d+)')
item_local.title = '%sx%s - %s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), item_local.infoLabels['episodio_titulo'])
else:
item_local.title = '%sx%s -' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))
rating = ''
if item_local.infoLabels['rating'] and item_local.infoLabels['rating'] != '0.0':
rating = float(item_local.infoLabels['rating'])
rating = round(rating, 1)
#Salvamos en número de episodios de la temporada
if num_temporada != item_local.contentSeason:
num_temporada = item_local.contentSeason
num_episodios = 0
if item_local.infoLabels['temporada_num_episodios']:
num_episodios = item_local.infoLabels['temporada_num_episodios']
#Preparamos el título para que sea compatible con Añadir Serie a Videoteca
if item_local.infoLabels['episodio_titulo']:
if "al" in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
item_local.title = '%s - %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s %s' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName)
else:
item_local.title = '%s %s' % (item_local.title, item_local.infoLabels['episodio_titulo'])
if item_local.infoLabels['year']:
item_local.infoLabels['episodio_titulo'] = '%s [%s]' % (item_local.infoLabels['episodio_titulo'], item_local.infoLabels['year'])
if rating:
item_local.infoLabels['episodio_titulo'] = '%s [%s]' % (item_local.infoLabels['episodio_titulo'], rating)
else:
item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s [%s] [%s]' % (item_local.contentSerieName, item_local.infoLabels['year'], rating)
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.title = '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.title, item_local.infoLabels['year'], rating, item_local.quality, str(item_local.language))
#Quitamos campos vacíos
item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace(" []", "")
item_local.title = item_local.title.replace(" []", "")
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title)
item_local.title = re.sub(r'\s\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title)
if num_episodios < item_local.contentEpisodeNumber:
num_episodios = item_local.contentEpisodeNumber
if num_episodios and not item_local.infoLabels['temporada_num_episodios']:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
num_episodios_lista[item_local.contentSeason:] = [num_episodios]
#logger.debug("title=[" + item_local.title + "], url=[" + item_local.url + "], item=[" + str(item_local) + "]")
if not num_episodios_flag: #Si el num de episodios no está informado, acualizamos episodios de toda la serie
for item_local in itemlist:
item_local.infoLabels['temporada_num_episodios'] = num_episodios_lista[item_local.contentSeason]
if config.get_videolibrary_support() and len(itemlist) > 0:
title = ''
if item_local.infoLabels['temporada_num_episodios']:
title = ' [Temp. de %s ep.]' % item_local.infoLabels['temporada_num_episodios']
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta serie a la videoteca[/COLOR]" + title, action="add_serie_to_library", extra="episodios"))
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
return itemlist
def actualizar_titulos(item):
logger.info()
itemlist = []
from platformcode import launcher
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return launcher.run(item)
def search(item, texto):
itemlist = []
logger.info("search:" + texto)
@@ -1054,6 +906,7 @@ def search(item, texto):
for line in sys.exc_info():
logger.error("%s" % line)
return []
def newest(categoria):
logger.info()
+145 -44
View File
@@ -5,6 +5,7 @@ import sys
import urllib
import urlparse
import datetime
import ast
from channelselector import get_thumb
from core import httptools
@@ -17,15 +18,34 @@ from lib import generictools
host = 'http://mispelisyseries.com/'
#Código para permitir usar un único canal para todas las webs clones de NewPct1
clone_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid") #Carga lista de clones
clone_list = ast.literal_eval(clone_list) #la convierte a lista de tuplas
host_index = 0
host_index = config.get_setting('clonenewpct1_channel_default', "torrentrapid") #Clone por defecto
i = 0
for active_clone, channel_clone, host_clone, contentType_clone, info_clone in clone_list:
if i == host_index:
#channel_clone_name = channel_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
#host = 'http://%s/' % host_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
i += 1
#Carga de opciones del canal
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
channel_clone_name = scrapertools.find_single_match(host, r'(\w+)\.com\/') #QUITAR CUANDO SE PASE A NEWPCT1
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
thumb_pelis = get_thumb("channels_movie.png")
@@ -64,20 +84,40 @@ def settingCanal(item):
def submenu(item):
logger.info()
itemlist = []
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
pass
host_alt = host
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] caído'))
host_alt = host.replace(item.channel_alt, item.channel)
del item.channel_alt
if item.url_alt: del item.url_alt
#data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
#data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
host_dom = host_alt.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host_alt and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host_alt + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
else:
if data:
data = scrapertools.get_match(data, patron)
@@ -104,10 +144,10 @@ def submenu(item):
Item(channel=item.channel, action="alfabeto", title=title + " [A-Z]", url=url, extra=item.extra))
if item.extra == "peliculas":
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
return itemlist
@@ -203,7 +243,8 @@ def listado(item):
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
total_pag = scrapertools.find_single_match(data,'<a href=".*?(\d+)?">Last<\/a><\/li>')
patron_last_page = '<a href="[^"]+(\d+)">Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
@@ -419,6 +460,9 @@ def listado(item):
def listado_busqueda(item):
logger.info()
host = 'http://%s/' % scrapertools.find_single_match(item.url, '(\w+\.com)\/')
itemlist = []
cnt_tot = 40 # Poner el num. máximo de items por página. Dejamos que la web lo controle
cnt_title = 0 # Contador de líneas insertadas en Itemlist
@@ -449,17 +493,24 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
pass
cnt_next += 1
if not data or not scrapertools.find_single_match(data, pattern):
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, pattern)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -824,6 +875,11 @@ def listado_busqueda(item):
def findvideos(item):
from core import channeltools
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Cualquiera de las tres opciones son válidas
@@ -934,9 +990,20 @@ def findvideos(item):
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
pass
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -948,6 +1015,8 @@ def findvideos(item):
else:
item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
if size:
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
@@ -957,7 +1026,6 @@ def findvideos(item):
item_local = item.clone()
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
@@ -969,17 +1037,17 @@ def findvideos(item):
#Ahora pintamos el link del Torrent, si lo hay
if item_local.url: # Hay Torrent ?
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Servidor
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
itemlist.append(item_local.clone(quality=quality)) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
@@ -1163,9 +1231,20 @@ def findvideos(item):
def episodios(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
max_temp = 1
if item.infoLabels['number_of_seasons']:
max_temp = item.infoLabels['number_of_seasons']
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
@@ -1173,16 +1252,30 @@ def episodios(item):
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
patron = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data_alt = ''
if data: data_alt = scrapertools.get_match(data, patron)
except: #Algún error de proceso
pass
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data_alt or not scrapertools.find_single_match(data_alt, pattern):
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron, pattern)
if not data: #No se ha encontrado ningún canal activo para este vídeo
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
@@ -1209,7 +1302,8 @@ def episodios(item):
list_pages = [item.url]
season = max_temp
if item.library_playcounts or item.tmdb_stat: #Comprobamos si realmente sabemos el num. máximo de temporadas
#Comprobamos si realmente sabemos el num. máximo de temporadas
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
num_temporadas_flag = True
else:
num_temporadas_flag = False
@@ -1226,11 +1320,11 @@ def episodios(item):
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + str(data))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
@@ -1245,7 +1339,7 @@ def episodios(item):
#Empezamos a generar cada episodio
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
if "pelisyseries.com" in item.url: #En esta web están en diferente orden
interm = url
url = thumb
thumb = interm
@@ -1273,6 +1367,10 @@ def episodios(item):
if scrapertools.find_single_match(info, '\[\d{3}\]'):
info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info)
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'
elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'):
@@ -1312,11 +1410,9 @@ def episodios(item):
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
#logger.error("TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / " + str(match['episode2']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
@@ -1331,11 +1427,11 @@ def episodios(item):
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
item_local.quality = item_local.quality.replace("ALTA DEFINICION", "HDTV")
if match['lang'] and estado == False:
match['lang'] = match['lang'].replace("- ", "")
if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()):
match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "")
item_local.infoLabels['episodio_titulo'] = match['lang']
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.contentEpisodeNumber = match['episode']
if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca
@@ -1381,6 +1477,8 @@ def episodios(item):
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
#logger.debug(item)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
@@ -1395,7 +1493,7 @@ def actualizar_titulos(item):
from platformcode import launcher
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return launcher.run(item)
@@ -1403,6 +1501,9 @@ def actualizar_titulos(item):
def search(item, texto):
logger.info("search:" + texto)
# texto = texto.replace(" ", "+")
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
try:
item.post = "q=%s" % texto
+10 -8
View File
@@ -16,7 +16,7 @@ from core.item import Item
from platformcode import config, logger
from platformcode import platformtools
from core import jsontools
from channels import side_menu
THUMBNAILS = {'0': 'posters', '1': 'banners', '2': 'squares'}
@@ -245,13 +245,15 @@ def novedades(item):
list_canales, any_active = get_channels_list()
if mode=='silent' and any_active and len(list_canales[item.extra]) > 0:
side_menu.set_menu_settings(item)
aux_list=[]
for canal in list_canales[item.extra]:
if len(aux_list)<2:
aux_list.append(canal)
list_canales[item.extra]=aux_list
if config.is_xbmc():
from channels import side_menu
if mode=='silent' and any_active and len(list_canales[item.extra]) > 0:
side_menu.set_menu_settings(item)
aux_list=[]
for canal in list_canales[item.extra]:
if len(aux_list)<2:
aux_list.append(canal)
list_canales[item.extra]=aux_list
if mode == 'set_cache':
list_canales[item.extra] = list_canales[item.extra][2:]
+65
View File
@@ -0,0 +1,65 @@
{
"id": "playview",
"name": "Playview",
"active": true,
"adult": false,
"language": [
"lat", "cast"
],
"thumbnail": "https://s15.postimg.cc/pkcz7kda3/playview.png",
"banner": "",
"version": 1,
"categories": [
"movie",
"tvshow",
"anime"
],
"settings": [
{
"id": "include_in_global_search",
"type": "bool",
"label": "Incluir en busqueda global",
"default": false,
"enabled": false,
"visible": false
},
{
"id": "filter_languages",
"type": "list",
"label": "Mostrar enlaces en idioma...",
"default": 0,
"enabled": true,
"visible": true,
"lvalues": [
"No filtrar",
"Cast",
"Lat",
"VOSE"
]
},
{
"id": "include_in_newest_peliculas",
"type": "bool",
"label": "Incluir en Novedades - Peliculas",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "include_in_newest_infantiles",
"type": "bool",
"label": "Incluir en Novedades - Infantiles",
"default": true,
"enabled": true,
"visible": true
},
{
"id": "include_in_newest_terror",
"type": "bool",
"label": "Incluir en Novedades - terror",
"default": true,
"enabled": true,
"visible": true
}
]
}
+317
View File
@@ -0,0 +1,317 @@
# -*- coding: utf-8 -*-
# -*- Channel Playview -*-
# -*- Created for Alfa-addon -*-
# -*- By the Alfa Develop Group -*-
import re
import urllib
from channels import autoplay
from channels import filtertools
from core import httptools
from core import scrapertools
from core import servertools
from core import tmdb
from core.item import Item
from platformcode import config, logger
from channelselector import get_thumb
IDIOMAS = {'Latino':'Lat', 'Español':'Cast', 'Subtitulado':'VOSE'}
list_language = IDIOMAS.values()
list_quality = ['HD 1080p', 'HD 720p', 'DVDRIP', 'CAM']
list_servers = ['openload', 'vidoza', 'clipwatching', 'fastplay', 'flashx', 'gamovideo', 'powvideo', 'streamango',
'streamcherry', 'rapidvideo']
host = 'https://playview.io/'
def mainlist(item):
logger.info()
autoplay.init(item.channel, list_servers, list_quality)
itemlist = []
itemlist.append(Item(channel=item.channel, title='Películas', action='submenu', type='movie',
thumbnail=get_thumb('movies', auto=True)))
itemlist.append(Item(channel=item.channel, title='Series', action='submenu', type='tvshow',
thumbnail=get_thumb('tvshows', auto=True)))
itemlist.append(Item(channel=item.channel, title='Anime', action='list_all', url=host+'anime-online',
type='tvshow', first=0, thumbnail=get_thumb('anime', auto=True)))
itemlist.append(Item(channel=item.channel, title='Buscar', action='search', url=host+'search/',
thumbnail=get_thumb('search', auto=True)))
autoplay.show_option(item.channel, itemlist)
return itemlist
def submenu(item):
logger.info()
itemlist = []
if item.type == 'movie':
itemlist.append(
Item(channel=item.channel, title='Todas', action='list_all', url=host + 'peliculas-online', type='movie',
first=0, thumbnail=get_thumb('all', auto=True)))
itemlist.append(
Item(channel=item.channel, title='Generos', action='genres', thumbnail=get_thumb('genres', auto=True)))
else:
itemlist.append(
Item(channel=item.channel, title='Todas', action='list_all', url=host + 'series-online', type='tvshow',
first=0, thumbnail=get_thumb('all', auto=True)))
itemlist.append(
Item(channel=item.channel, title='Series Animadas', action='list_all', url=host + 'series-animadas-online',
type='tvshow', first=0, thumbnail=get_thumb('animacion', auto=True)))
return itemlist
def get_source(url):
logger.info()
data = httptools.downloadpage(url).data
data = re.sub(r'"|\n|\r|\t|&nbsp;|<br>|\s{2,}', "", data)
return data
def genres(item):
logger.info()
itemlist = []
data = get_source(host)
patron = '<li value=(\d+)><a href=(.*?)>(.*?)</a></li>'
matches = re.compile(patron, re.DOTALL).findall(data)
for value, url, title in matches:
if value not in ['1', '4', '22', '23', '24']:
if value == '20':
title = 'Familiar'
itemlist.append(Item(channel=item.channel, title=title, action='list_all', url=url, type='Movie', first=0))
return sorted(itemlist, key=lambda i: i.title)
def list_all(item):
logger.info()
itemlist = []
next = False
data = get_source(item.url)
patron = 'spotlight_container>.*?image lazy data-original=(.*?)>.*?<div class=spotlight_title>(.*?)<'
patron += '(.*?) sres>(\d{4})<.*?playLink href=(.*?)>'
matches = re.compile(patron, re.DOTALL).findall(data)
first = item.first
last = first+19
if last > len(matches):
last = len(matches)
next = True
for scrapedthumbnail, scrapedtitle, type_data, year, scrapedurl in matches[first:last]:
url = scrapedurl
title = scrapedtitle
season = scrapertools.find_single_match(type_data, 'class=title-season>Temporada<.*?> (\d+) <')
episode = scrapertools.find_single_match(type_data, 'class=title-season>Episodio<.*?> (\d+) <')
if season != '' or episode != '':
item.type = 'tvshow'
else:
item.type = 'movie'
new_item = Item(channel=item.channel, title=title, url=url, thumbnail=scrapedthumbnail, type=item.type,
infoLabels={'year': year})
if item.type == 'tvshow':
new_item.action = 'episodios'
new_item.contentSerieName = scrapedtitle
season = season.strip()
episode = episode.strip()
if season == '':
if 'Anime' in item.title:
season = 1
else:
season = scrapertools.find_single_match(url, '.*?temp-(\d+)')
new_item.contentSeasonNumber = season
else:
new_item.contentSeasonNumber = season
if episode != '':
new_item.contentEpisodeNumber = episode
if season != '' and episode != '':
new_item.title = '%s %sx%s' % (new_item.title, season, episode)
elif episode == '':
new_item.title = '%s Temporada %s' % (new_item.title, season)
else:
new_item.action = 'findvideos'
new_item.contentTitle = scrapedtitle
itemlist.append(new_item)
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
# Paginación
if not next:
url_next_page = item.url
first = last
else:
url_next_page = scrapertools.find_single_match(data, "<a href=([^ ]+) class=page-link aria-label=Next>")
first = 0
if url_next_page:
itemlist.append(item.clone(title="Siguiente >>", url=url_next_page, action='list_all', first=first))
return itemlist
def get_data(post):
logger.info()
post = urllib.urlencode(post)
data = httptools.downloadpage(host + 'playview', post=post).data
return data
def episodios(item):
logger.info()
itemlist = []
data = get_source(item.url)
try:
id, type = scrapertools.find_single_match(data, 'data-id=(\d+) data-type=(.*?) ')
post = {'set': 'LoadOptionsEpisode', 'action': 'EpisodeList', 'id': id, 'type': '1'}
data = get_data(post)
patron = 'data-episode="(\d+)".*?title="(.*?)"'
matches = re.compile(patron, re.DOTALL).findall(data)
infoLabels = item.infoLabels
for episode, title in matches:
post = {'set': 'LoadOptionsEpisode', 'action': 'Step1', 'id': id, 'type': '1',
'episode': episode}
season = scrapertools.find_single_match(item.url, '.*?temp-(\d+)')
if season == '':
season = 1
infoLabels['season'] = season
infoLabels['episode'] = episode
if title[0].isdigit():
title = '%sx%s' % (season, title)
else:
title = '%sx%s - %s' % (season, episode, title)
itemlist.append(Item(channel=item.channel, title=title, contentSeasonNumber=season,
contentEpisodeNumber=episode, action='findvideos', post=post, type=item.type,
infoLabels=infoLabels))
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
if config.get_videolibrary_support() and len(itemlist) > 0:
itemlist.append(
Item(channel=item.channel, title='[COLOR yellow]Añadir esta serie a la videoteca[/COLOR]', url=item.url,
action="add_serie_to_library", extra="episodios", contentSerieName=item.contentSerieName, ))
except:
pass
return itemlist
def findvideos(item):
logger.info()
itemlist = []
set_mode = 'LoadOptions'
episode = ''
if item.type == 'tvshow':
post = item.post
id= post['id']
episode = post['episode']
type = post['type']
set_mode = 'LoadOptionsEpisode'
else:
data=get_source(item.url)
try:
id, type = scrapertools.find_single_match(data, 'data-id=(\d+) data-type=(.*?) ')
post = {'set': set_mode, 'action': 'Step1', 'id': id, 'type': type}
except:
pass
try:
data = get_data(post)
patron = 'data-quality="(.*?)"'
matches = re.compile(patron, re.DOTALL).findall(data)
for quality in matches:
post = {'set': set_mode, 'action': 'Step2', 'id': id, 'type': type, 'quality': quality, 'episode':episode}
data = get_data(post)
patron = 'getplayer" data-id="(\d+)"> <h4>(.*?)</h4>.*?title="(.*?)"'
matches = re.compile(patron, re.DOTALL).findall(data)
for video_id, language, server in matches:
post = {'set': set_mode, 'action': 'Step3', 'id': video_id, 'type': type}
data = get_data(post)
url = scrapertools.find_single_match(data, '<iframe class="embed.*?src="(.*?)"')
if 'clipwatching' in url:
url = url.replace('https://clipwatching.com/embed-', '')
title = '%s [%s] [%s]'
quality = quality.replace('(','').replace(')', '')
if url != '':
itemlist.append(Item(channel=item.channel, title=title, language=IDIOMAS[language], url=url,
action='play', quality=quality, infoLabels=item.infoLabels))
itemlist = servertools.get_servers_itemlist(itemlist, lambda i: i.title % (i.server.capitalize(), i.quality,
i.language))
itemlist=sorted(itemlist, key=lambda i: i.language)
# Requerido para FilterTools
itemlist = filtertools.get_links(itemlist, item, list_language)
# Requerido para AutoPlay
autoplay.start(itemlist, item)
if config.get_videolibrary_support() and len(itemlist) > 0 and item.extra != 'findvideos' and type == 'Movie':
itemlist.append(
Item(channel=item.channel, title='[COLOR yellow]Añadir esta pelicula a la videoteca[/COLOR]',
url=item.url, action="add_pelicula_to_library", extra="findvideos",
contentTitle=item.contentTitle))
return itemlist
except:
return itemlist
def search(item, texto):
logger.info()
texto = texto.replace(" ", "+")
item.url = item.url + texto
item.first = 0
if texto != '':
return list_all(item)
def newest(categoria):
logger.info()
itemlist = []
item = Item()
item.type = 'movie'
item.first = 0
try:
if categoria == 'peliculas':
item.url = host + 'peliculas-online'
elif categoria == 'infantiles':
item.url = host + 'peliculas-online/animacion'
elif categoria == 'terror':
item.url = host + 'peliculas-online/terror'
itemlist = list_all(item)
if itemlist[-1].title == 'Siguiente >>':
itemlist.pop()
except:
import sys
for line in sys.exc_info():
logger.error("{0}".format(line))
return []
return itemlist
+1 -1
View File
@@ -490,7 +490,7 @@ def episodios(item):
# Sin valoración:
# show = re.sub(r"\s\(\d+\.\d+\)", "", item.show)
itemlist.append(
Item(channel='plusdede', title="Añadir esta serie a la biblioteca de XBMC", url=item.url, token=token,
Item(channel='plusdede', title="Añadir esta serie a la videoteca", url=item.url, token=token,
action="add_serie_to_library", extra="episodios###", show=show))
itemlist.append(
Item(channel='plusdede', title="Descargar todos los episodios de la serie", url=item.url, token=token,
+28 -28
View File
@@ -18,39 +18,39 @@ def mainlist(item):
item.channel = "search"
itemlist = list()
context = [{"title": "Elegir canales incluidos",
context = [{"title": config.get_localized_string(70273),
"action": "setting_channel",
"channel": item.channel}]
itemlist.append(Item(channel=item.channel, action="search",
title="Buscar por titulo", context=context,
title=config.get_localized_string(70276), context=context,
thumbnail=get_thumb("search.png")))
thumbnail = get_thumb("search_star.png")
itemlist.append(Item(channel='tvmoviedb', title="Buscar actor/actriz", action="search_",
itemlist.append(Item(channel='tvmoviedb', title=config.get_localized_string(59999), action="search_",
search={'url': 'search/person', 'language': 'es', 'page': 1}, star=True,
thumbnail=thumbnail))
itemlist.append(Item(channel=item.channel, action="search",
title="Buscar por categorias (búsqueda avanzada)", extra="categorias",
title=config.get_localized_string(59998), extra="categorias",
context=context,
thumbnail=get_thumb("search.png")))
itemlist.append(Item(channel=item.channel, action="opciones", title="Opciones",
itemlist.append(Item(channel=item.channel, action="opciones", title=config.get_localized_string(59997),
thumbnail=get_thumb("search.png")))
itemlist.append(Item(channel="tvmoviedb", action="mainlist", title="Búsqueda alternativa",
itemlist.append(Item(channel="tvmoviedb", action="mainlist", title=config.get_localized_string(70274),
thumbnail=get_thumb("search.png")))
saved_searches_list = get_saved_searches()
context2 = context[:]
context2.append({"title": "Borrar búsquedas guardadas",
context2.append({"title": config.get_localized_string(59996),
"action": "clear_saved_searches",
"channel": item.channel})
logger.info("saved_searches_list=%s" % saved_searches_list)
if saved_searches_list:
itemlist.append(Item(channel=item.channel, action="",
title="Búsquedas guardadas:", context=context2,
title=config.get_localized_string(59995), context=context2,
thumbnail=get_thumb("search.png")))
for saved_search_text in saved_searches_list:
itemlist.append(Item(channel=item.channel, action="do_search",
@@ -65,17 +65,17 @@ def mainlist(item):
def opciones(item):
itemlist = list()
itemlist.append(Item(channel=item.channel, action="setting_channel",
title="Elegir canales incluidos en la búsqueda", folder=False,
title=config.get_localized_string(59994), folder=False,
thumbnail=get_thumb("search.png")))
itemlist.append(Item(channel=item.channel, action="clear_saved_searches", title="Borrar búsquedas guardadas",
itemlist.append(Item(channel=item.channel, action="clear_saved_searches", title=config.get_localized_string(59996),
folder=False, thumbnail=get_thumb("search.png")))
itemlist.append(Item(channel=item.channel, action="settings", title="Otros ajustes", folder=False,
itemlist.append(Item(channel=item.channel, action="settings", title=config.get_localized_string(60531), folder=False,
thumbnail=get_thumb("search.png")))
return itemlist
def settings(item):
return platformtools.show_channel_settings(caption="configuración -- Buscador")
return platformtools.show_channel_settings(caption=config.get_localized_string(59993))
def setting_channel(item):
@@ -119,12 +119,12 @@ def setting_channel(item):
list_controls.append(control)
if config.get_setting("custom_button_value", item.channel):
custom_button_label = "Ninguno"
custom_button_label = config.get_localized_string(59992)
else:
custom_button_label = "Todos"
custom_button_label = config.get_localized_string(59991)
return platformtools.show_channel_settings(list_controls=list_controls,
caption="Canales incluidos en la búsqueda",
caption=config.get_localized_string(59990),
callback="save_settings", item=item,
custom_button={'visible': True,
'function': "cb_custom_button",
@@ -133,10 +133,10 @@ def setting_channel(item):
def save_settings(item, dict_values):
progreso = platformtools.dialog_progress("Guardando configuración...", "Espere un momento por favor.")
progreso = platformtools.dialog_progress(config.get_localized_string(59988), config.get_localized_string(59989))
n = len(dict_values)
for i, v in enumerate(dict_values):
progreso.update((i * 100) / n, "Guardando configuración...")
progreso.update((i * 100) / n, config.get_localized_string(59988))
config.set_setting("include_in_global_search", dict_values[v], v)
progreso.close()
@@ -151,9 +151,9 @@ def cb_custom_button(item, dict_values):
dict_values[v] = not value
if config.set_setting("custom_button_value", not value, item.channel) == True:
return {"label": "Ninguno"}
return {"label": config.get_localized_string(59992)}
else:
return {"label": "Todos"}
return {"label": config.get_localized_string(59991)}
def searchbycat(item):
@@ -181,13 +181,13 @@ def searchbycat(item):
list_controls.append(control)
control = {'id': "torrent",
'type': "bool",
'label': 'Incluir en la búsqueda canales Torrent',
'label': config.get_localized_string(70275),
'default': True,
'enabled': True,
'visible': True}
list_controls.append(control)
return platformtools.show_channel_settings(list_controls=list_controls, caption="Elegir categorías",
return platformtools.show_channel_settings(list_controls=list_controls, caption=config.get_localized_string(59974),
callback="search_cb", item=item)
@@ -229,7 +229,7 @@ def show_result(item):
tecleado = None
if item.adult and config.get_setting("adult_request_password"):
# Solicitar contraseña
tecleado = platformtools.dialog_input("", "Contraseña para canales de adultos", True)
tecleado = platformtools.dialog_input("", config.get_localized_string(60334), True)
if tecleado is None or tecleado != config.get_setting("adult_password"):
return []
@@ -288,7 +288,7 @@ def do_search(item, categories=None):
if item.contextual==True:
categories = ["Películas"]
setting_item = Item(channel=item.channel, title="Elegir canales incluidos en la búsqueda", folder=False,
setting_item = Item(channel=item.channel, title=config.get_localized_string(59994), folder=False,
thumbnail=get_thumb("search.png"))
setting_channel(setting_item)
@@ -315,7 +315,7 @@ def do_search(item, categories=None):
# Para Kodi es necesario esperar antes de cargar el progreso, de lo contrario
# el cuadro de progreso queda "detras" del cuadro "cargando..." y no se le puede dar a cancelar
time.sleep(0.5)
progreso = platformtools.dialog_progress("Buscando '%s'..." % tecleado, "")
progreso = platformtools.dialog_progress(config.get_localized_string(30993) % tecleado, "")
channel_files = sorted(glob.glob(channels_path), key=lambda x: os.path.basename(x))
import math
@@ -396,7 +396,7 @@ def do_search(item, categories=None):
logger.info("%s incluido en la búsqueda" % basename_without_extension)
progreso.update(percentage,
"Buscando en %s..." % channel_parameters["title"])
config.get_localized_string(60520) % channel_parameters["title"])
except:
logger.error("No se puede buscar en: %s" % channel_parameters["title"])
@@ -417,7 +417,7 @@ def do_search(item, categories=None):
list_pendent_names = [a.getName() for a in pendent]
mensaje = "Buscando en %s" % (", ".join(list_pendent_names))
progreso.update(percentage, "Finalizado en %d/%d canales..." % (len(threads) - len(pendent), len(threads)),
progreso.update(percentage, config.get_localized_string(60521) % (len(threads) - len(pendent), len(threads)),
mensaje)
logger.debug(mensaje)
@@ -460,7 +460,7 @@ def do_search(item, categories=None):
itemlist.append(i.clone(title=title, from_action=i.action, from_channel=i.channel,
channel="search", action="show_result", adult=element["adult"]))
title = "Buscando: '%s' | Encontrado: %d vídeos | Tiempo: %2.f segundos" % (
title = config.get_localized_string(59972) % (
tecleado, total, time.time() - start_time)
itemlist.insert(0, Item(title=title, text_color='yellow'))
@@ -506,7 +506,7 @@ def save_search(text):
def clear_saved_searches(item):
config.set_setting("saved_searches_list", list(), "search")
platformtools.dialog_ok("Buscador", "Búsquedas borradas correctamente")
platformtools.dialog_ok(config.get_localized_string(60329), config.get_localized_string(60424))
def get_saved_searches():
File diff suppressed because it is too large Load Diff
+145 -44
View File
@@ -5,6 +5,7 @@ import sys
import urllib
import urlparse
import datetime
import ast
from channelselector import get_thumb
from core import httptools
@@ -17,15 +18,34 @@ from lib import generictools
host = 'http://torrentlocura.com/'
#Código para permitir usar un único canal para todas las webs clones de NewPct1
clone_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid") #Carga lista de clones
clone_list = ast.literal_eval(clone_list) #la convierte a lista de tuplas
host_index = 0
host_index = config.get_setting('clonenewpct1_channel_default', "torrentrapid") #Clone por defecto
i = 0
for active_clone, channel_clone, host_clone, contentType_clone, info_clone in clone_list:
if i == host_index:
#channel_clone_name = channel_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
#host = 'http://%s/' % host_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
i += 1
#Carga de opciones del canal
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
channel_clone_name = scrapertools.find_single_match(host, r'(\w+)\.com\/') #QUITAR CUANDO SE PASE A NEWPCT1
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
thumb_pelis = get_thumb("channels_movie.png")
@@ -64,20 +84,40 @@ def settingCanal(item):
def submenu(item):
logger.info()
itemlist = []
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
pass
host_alt = host
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] caído'))
host_alt = host.replace(item.channel_alt, item.channel)
del item.channel_alt
if item.url_alt: del item.url_alt
#data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
#data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
host_dom = host_alt.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host_alt and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host_alt + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
else:
if data:
data = scrapertools.get_match(data, patron)
@@ -104,10 +144,10 @@ def submenu(item):
Item(channel=item.channel, action="alfabeto", title=title + " [A-Z]", url=url, extra=item.extra))
if item.extra == "peliculas":
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
return itemlist
@@ -203,7 +243,8 @@ def listado(item):
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
total_pag = scrapertools.find_single_match(data,'<a href=".*?(\d+)?">Last<\/a><\/li>')
patron_last_page = '<a href="[^"]+(\d+)">Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
@@ -419,6 +460,9 @@ def listado(item):
def listado_busqueda(item):
logger.info()
host = 'http://%s/' % scrapertools.find_single_match(item.url, '(\w+\.com)\/')
itemlist = []
cnt_tot = 40 # Poner el num. máximo de items por página. Dejamos que la web lo controle
cnt_title = 0 # Contador de líneas insertadas en Itemlist
@@ -449,17 +493,24 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
pass
cnt_next += 1
if not data or not scrapertools.find_single_match(data, pattern):
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, pattern)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -824,6 +875,11 @@ def listado_busqueda(item):
def findvideos(item):
from core import channeltools
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Cualquiera de las tres opciones son válidas
@@ -934,9 +990,20 @@ def findvideos(item):
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
pass
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -948,6 +1015,8 @@ def findvideos(item):
else:
item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
if size:
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
@@ -957,7 +1026,6 @@ def findvideos(item):
item_local = item.clone()
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
@@ -969,17 +1037,17 @@ def findvideos(item):
#Ahora pintamos el link del Torrent, si lo hay
if item_local.url: # Hay Torrent ?
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Servidor
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
itemlist.append(item_local.clone(quality=quality)) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
@@ -1163,9 +1231,20 @@ def findvideos(item):
def episodios(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
max_temp = 1
if item.infoLabels['number_of_seasons']:
max_temp = item.infoLabels['number_of_seasons']
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
@@ -1173,16 +1252,30 @@ def episodios(item):
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
patron = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data_alt = ''
if data: data_alt = scrapertools.get_match(data, patron)
except: #Algún error de proceso
pass
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data_alt or not scrapertools.find_single_match(data_alt, pattern):
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron, pattern)
if not data: #No se ha encontrado ningún canal activo para este vídeo
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
@@ -1209,7 +1302,8 @@ def episodios(item):
list_pages = [item.url]
season = max_temp
if item.library_playcounts or item.tmdb_stat: #Comprobamos si realmente sabemos el num. máximo de temporadas
#Comprobamos si realmente sabemos el num. máximo de temporadas
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
num_temporadas_flag = True
else:
num_temporadas_flag = False
@@ -1226,11 +1320,11 @@ def episodios(item):
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + str(data))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
@@ -1245,7 +1339,7 @@ def episodios(item):
#Empezamos a generar cada episodio
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
if "pelisyseries.com" in item.url: #En esta web están en diferente orden
interm = url
url = thumb
thumb = interm
@@ -1273,6 +1367,10 @@ def episodios(item):
if scrapertools.find_single_match(info, '\[\d{3}\]'):
info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info)
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'
elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'):
@@ -1312,11 +1410,9 @@ def episodios(item):
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
#logger.error("TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / " + str(match['episode2']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
@@ -1331,11 +1427,11 @@ def episodios(item):
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
item_local.quality = item_local.quality.replace("ALTA DEFINICION", "HDTV")
if match['lang'] and estado == False:
match['lang'] = match['lang'].replace("- ", "")
if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()):
match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "")
item_local.infoLabels['episodio_titulo'] = match['lang']
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.contentEpisodeNumber = match['episode']
if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca
@@ -1381,6 +1477,8 @@ def episodios(item):
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
#logger.debug(item)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
@@ -1395,7 +1493,7 @@ def actualizar_titulos(item):
from platformcode import launcher
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return launcher.run(item)
@@ -1403,6 +1501,9 @@ def actualizar_titulos(item):
def search(item, texto):
logger.info("search:" + texto)
# texto = texto.replace(" ", "+")
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
try:
item.post = "q=%s" % texto
@@ -33,6 +33,30 @@
"enabled": true,
"visible": true
},
{
"id": "clonenewpct1_channel_default",
"type": "list",
"label": "Clone de NewPct1 por defecto",
"default": 0,
"enabled": true,
"visible": true,
"lvalues": [
"Torrentrapid",
"Torrentlocura",
"Tumejortorrent",
"Tvsinpagar",
"Descargas2020",
"Mispelisyseries"
]
},
{
"id": "clonenewpct1_channels_list",
"type": "text",
"label": "Lista de clones de NewPct1 y orden de uso",
"default": "('1', 'torrentrapid', 'torrentrapid.com', 'movie, tvshow, season, episode', ''), ('1', 'torrentlocura', 'torrentlocura.com', 'movie, tvshow, season, episode', ''), ('1', 'tumejortorrent', 'tumejortorrent.com', 'movie, tvshow, season, episode', ''), ('1', 'tvsinpagar', 'www.tvsinpagar.com', 'tvshow, season, episode', ''), ('1', 'descargas2020', 'descargas2020.com', 'movie, tvshow, season, episode', ''), ('1', 'mispelisyseries', 'mispelisyseries.com', 'movie, tvshow, season, episode', '')",
"enabled": true,
"visible": false
},
{
"id": "seleccionar_ult_temporadda_activa",
"type": "bool",
+145 -44
View File
@@ -5,6 +5,7 @@ import sys
import urllib
import urlparse
import datetime
import ast
from channelselector import get_thumb
from core import httptools
@@ -17,15 +18,34 @@ from lib import generictools
host = 'http://torrentrapid.com/'
#Código para permitir usar un único canal para todas las webs clones de NewPct1
clone_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid") #Carga lista de clones
clone_list = ast.literal_eval(clone_list) #la convierte a lista de tuplas
host_index = 0
host_index = config.get_setting('clonenewpct1_channel_default', "torrentrapid") #Clone por defecto
i = 0
for active_clone, channel_clone, host_clone, contentType_clone, info_clone in clone_list:
if i == host_index:
#channel_clone_name = channel_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
#host = 'http://%s/' % host_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
i += 1
#Carga de opciones del canal
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
channel_clone_name = scrapertools.find_single_match(host, r'(\w+)\.com\/') #QUITAR CUANDO SE PASE A NEWPCT1
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
thumb_pelis = get_thumb("channels_movie.png")
@@ -64,20 +84,40 @@ def settingCanal(item):
def submenu(item):
logger.info()
itemlist = []
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
pass
host_alt = host
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] caído'))
host_alt = host.replace(item.channel_alt, item.channel)
del item.channel_alt
if item.url_alt: del item.url_alt
#data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
#data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
host_dom = host_alt.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host_alt and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host_alt + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
else:
if data:
data = scrapertools.get_match(data, patron)
@@ -104,10 +144,10 @@ def submenu(item):
Item(channel=item.channel, action="alfabeto", title=title + " [A-Z]", url=url, extra=item.extra))
if item.extra == "peliculas":
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
return itemlist
@@ -203,7 +243,8 @@ def listado(item):
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
total_pag = scrapertools.find_single_match(data,'<a href=".*?(\d+)?">Last<\/a><\/li>')
patron_last_page = '<a href="[^"]+(\d+)">Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
@@ -419,6 +460,9 @@ def listado(item):
def listado_busqueda(item):
logger.info()
host = 'http://%s/' % scrapertools.find_single_match(item.url, '(\w+\.com)\/')
itemlist = []
cnt_tot = 40 # Poner el num. máximo de items por página. Dejamos que la web lo controle
cnt_title = 0 # Contador de líneas insertadas en Itemlist
@@ -449,17 +493,24 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
pass
cnt_next += 1
if not data or not scrapertools.find_single_match(data, pattern):
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, pattern)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -824,6 +875,11 @@ def listado_busqueda(item):
def findvideos(item):
from core import channeltools
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Cualquiera de las tres opciones son válidas
@@ -934,9 +990,20 @@ def findvideos(item):
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
pass
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -948,6 +1015,8 @@ def findvideos(item):
else:
item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
if size:
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
@@ -957,7 +1026,6 @@ def findvideos(item):
item_local = item.clone()
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
@@ -969,17 +1037,17 @@ def findvideos(item):
#Ahora pintamos el link del Torrent, si lo hay
if item_local.url: # Hay Torrent ?
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Servidor
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
itemlist.append(item_local.clone(quality=quality)) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
@@ -1163,9 +1231,20 @@ def findvideos(item):
def episodios(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
max_temp = 1
if item.infoLabels['number_of_seasons']:
max_temp = item.infoLabels['number_of_seasons']
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
@@ -1173,16 +1252,30 @@ def episodios(item):
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
patron = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data_alt = ''
if data: data_alt = scrapertools.get_match(data, patron)
except: #Algún error de proceso
pass
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data_alt or not scrapertools.find_single_match(data_alt, pattern):
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron, pattern)
if not data: #No se ha encontrado ningún canal activo para este vídeo
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
@@ -1209,7 +1302,8 @@ def episodios(item):
list_pages = [item.url]
season = max_temp
if item.library_playcounts or item.tmdb_stat: #Comprobamos si realmente sabemos el num. máximo de temporadas
#Comprobamos si realmente sabemos el num. máximo de temporadas
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
num_temporadas_flag = True
else:
num_temporadas_flag = False
@@ -1226,11 +1320,11 @@ def episodios(item):
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + str(data))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
@@ -1245,7 +1339,7 @@ def episodios(item):
#Empezamos a generar cada episodio
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
if "pelisyseries.com" in item.url: #En esta web están en diferente orden
interm = url
url = thumb
thumb = interm
@@ -1273,6 +1367,10 @@ def episodios(item):
if scrapertools.find_single_match(info, '\[\d{3}\]'):
info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info)
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'
elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'):
@@ -1312,11 +1410,9 @@ def episodios(item):
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
#logger.error("TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / " + str(match['episode2']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
@@ -1331,11 +1427,11 @@ def episodios(item):
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
item_local.quality = item_local.quality.replace("ALTA DEFINICION", "HDTV")
if match['lang'] and estado == False:
match['lang'] = match['lang'].replace("- ", "")
if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()):
match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "")
item_local.infoLabels['episodio_titulo'] = match['lang']
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.contentEpisodeNumber = match['episode']
if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca
@@ -1381,6 +1477,8 @@ def episodios(item):
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
#logger.debug(item)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
@@ -1395,7 +1493,7 @@ def actualizar_titulos(item):
from platformcode import launcher
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return launcher.run(item)
@@ -1403,6 +1501,9 @@ def actualizar_titulos(item):
def search(item, texto):
logger.info("search:" + texto)
# texto = texto.replace(" ", "+")
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
try:
item.post = "q=%s" % texto
+145 -44
View File
@@ -5,6 +5,7 @@ import sys
import urllib
import urlparse
import datetime
import ast
from channelselector import get_thumb
from core import httptools
@@ -17,15 +18,34 @@ from lib import generictools
host = 'http://tumejortorrent.com/'
#Código para permitir usar un único canal para todas las webs clones de NewPct1
clone_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid") #Carga lista de clones
clone_list = ast.literal_eval(clone_list) #la convierte a lista de tuplas
host_index = 0
host_index = config.get_setting('clonenewpct1_channel_default', "torrentrapid") #Clone por defecto
i = 0
for active_clone, channel_clone, host_clone, contentType_clone, info_clone in clone_list:
if i == host_index:
#channel_clone_name = channel_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
#host = 'http://%s/' % host_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
i += 1
#Carga de opciones del canal
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
channel_clone_name = scrapertools.find_single_match(host, r'(\w+)\.com\/') #QUITAR CUANDO SE PASE A NEWPCT1
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
thumb_pelis = get_thumb("channels_movie.png")
@@ -64,20 +84,40 @@ def settingCanal(item):
def submenu(item):
logger.info()
itemlist = []
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
pass
host_alt = host
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] caído'))
host_alt = host.replace(item.channel_alt, item.channel)
del item.channel_alt
if item.url_alt: del item.url_alt
#data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
#data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
host_dom = host_alt.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host_alt and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host_alt + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
else:
if data:
data = scrapertools.get_match(data, patron)
@@ -104,10 +144,10 @@ def submenu(item):
Item(channel=item.channel, action="alfabeto", title=title + " [A-Z]", url=url, extra=item.extra))
if item.extra == "peliculas":
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
return itemlist
@@ -203,7 +243,8 @@ def listado(item):
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
total_pag = scrapertools.find_single_match(data,'<a href=".*?(\d+)?">Last<\/a><\/li>')
patron_last_page = '<a href="[^"]+(\d+)">Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
@@ -419,6 +460,9 @@ def listado(item):
def listado_busqueda(item):
logger.info()
host = 'http://%s/' % scrapertools.find_single_match(item.url, '(\w+\.com)\/')
itemlist = []
cnt_tot = 40 # Poner el num. máximo de items por página. Dejamos que la web lo controle
cnt_title = 0 # Contador de líneas insertadas en Itemlist
@@ -449,17 +493,24 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
pass
cnt_next += 1
if not data or not scrapertools.find_single_match(data, pattern):
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, pattern)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -824,6 +875,11 @@ def listado_busqueda(item):
def findvideos(item):
from core import channeltools
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Cualquiera de las tres opciones son válidas
@@ -934,9 +990,20 @@ def findvideos(item):
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
pass
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -948,6 +1015,8 @@ def findvideos(item):
else:
item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
if size:
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
@@ -957,7 +1026,6 @@ def findvideos(item):
item_local = item.clone()
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
@@ -969,17 +1037,17 @@ def findvideos(item):
#Ahora pintamos el link del Torrent, si lo hay
if item_local.url: # Hay Torrent ?
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Servidor
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
itemlist.append(item_local.clone(quality=quality)) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
@@ -1163,9 +1231,20 @@ def findvideos(item):
def episodios(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
max_temp = 1
if item.infoLabels['number_of_seasons']:
max_temp = item.infoLabels['number_of_seasons']
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
@@ -1173,16 +1252,30 @@ def episodios(item):
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
patron = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data_alt = ''
if data: data_alt = scrapertools.get_match(data, patron)
except: #Algún error de proceso
pass
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data_alt or not scrapertools.find_single_match(data_alt, pattern):
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron, pattern)
if not data: #No se ha encontrado ningún canal activo para este vídeo
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
@@ -1209,7 +1302,8 @@ def episodios(item):
list_pages = [item.url]
season = max_temp
if item.library_playcounts or item.tmdb_stat: #Comprobamos si realmente sabemos el num. máximo de temporadas
#Comprobamos si realmente sabemos el num. máximo de temporadas
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
num_temporadas_flag = True
else:
num_temporadas_flag = False
@@ -1226,11 +1320,11 @@ def episodios(item):
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + str(data))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
@@ -1245,7 +1339,7 @@ def episodios(item):
#Empezamos a generar cada episodio
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
if "pelisyseries.com" in item.url: #En esta web están en diferente orden
interm = url
url = thumb
thumb = interm
@@ -1273,6 +1367,10 @@ def episodios(item):
if scrapertools.find_single_match(info, '\[\d{3}\]'):
info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info)
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'
elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'):
@@ -1312,11 +1410,9 @@ def episodios(item):
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
#logger.error("TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / " + str(match['episode2']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
@@ -1331,11 +1427,11 @@ def episodios(item):
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
item_local.quality = item_local.quality.replace("ALTA DEFINICION", "HDTV")
if match['lang'] and estado == False:
match['lang'] = match['lang'].replace("- ", "")
if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()):
match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "")
item_local.infoLabels['episodio_titulo'] = match['lang']
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.contentEpisodeNumber = match['episode']
if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca
@@ -1381,6 +1477,8 @@ def episodios(item):
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
#logger.debug(item)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
@@ -1395,7 +1493,7 @@ def actualizar_titulos(item):
from platformcode import launcher
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return launcher.run(item)
@@ -1403,6 +1501,9 @@ def actualizar_titulos(item):
def search(item, texto):
logger.info("search:" + texto)
# texto = texto.replace(" ", "+")
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
try:
item.post = "q=%s" % texto
+145 -44
View File
@@ -5,6 +5,7 @@ import sys
import urllib
import urlparse
import datetime
import ast
from channelselector import get_thumb
from core import httptools
@@ -17,15 +18,34 @@ from lib import generictools
host = 'http://www.tvsinpagar.com/'
#Código para permitir usar un único canal para todas las webs clones de NewPct1
clone_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid") #Carga lista de clones
clone_list = ast.literal_eval(clone_list) #la convierte a lista de tuplas
host_index = 0
host_index = config.get_setting('clonenewpct1_channel_default', "torrentrapid") #Clone por defecto
i = 0
for active_clone, channel_clone, host_clone, contentType_clone, info_clone in clone_list:
if i == host_index:
#channel_clone_name = channel_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
#host = 'http://%s/' % host_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
i += 1
#Carga de opciones del canal
item = Item()
if not item.channel:
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
channel_clone_name = scrapertools.find_single_match(host, r'(\w+)\.com\/') #QUITAR CUANDO SE PASE A NEWPCT1
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
def mainlist(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
thumb_pelis = get_thumb("channels_movie.png")
@@ -64,20 +84,40 @@ def settingCanal(item):
def submenu(item):
logger.info()
itemlist = []
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #Algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
pass
host_alt = host
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] caído'))
host_alt = host.replace(item.channel_alt, item.channel)
del item.channel_alt
if item.url_alt: del item.url_alt
#data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
#data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
host_dom = host_alt.replace("https://", "").replace("http://", "").replace("www.", "")
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
if "pelisyseries.com" in host_alt and item.extra == "varios": #compatibilidad con mispelisy.series.com
data = '<a href="' + host_alt + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
else:
if data:
data = scrapertools.get_match(data, patron)
@@ -104,10 +144,10 @@ def submenu(item):
Item(channel=item.channel, action="alfabeto", title=title + " [A-Z]", url=url, extra=item.extra))
if item.extra == "peliculas":
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
itemlist.append(
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
return itemlist
@@ -203,7 +243,8 @@ def listado(item):
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
total_pag = scrapertools.find_single_match(data,'<a href=".*?(\d+)?">Last<\/a><\/li>')
patron_last_page = '<a href="[^"]+(\d+)">Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
@@ -419,6 +460,9 @@ def listado(item):
def listado_busqueda(item):
logger.info()
host = 'http://%s/' % scrapertools.find_single_match(item.url, '(\w+\.com)\/')
itemlist = []
cnt_tot = 40 # Poner el num. máximo de items por página. Dejamos que la web lo controle
cnt_title = 0 # Contador de líneas insertadas en Itemlist
@@ -449,17 +493,24 @@ def listado_busqueda(item):
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
while cnt_title <= cnt_tot and cnt_next < 5:
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
except:
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
cnt_next += 1
if not data: #Si la web está caída salimos sin dar error
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
pass
cnt_next += 1
if not data or not scrapertools.find_single_match(data, pattern):
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
item, data = generictools.fail_over_newpct1(item, pattern)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
@@ -824,6 +875,11 @@ def listado_busqueda(item):
def findvideos(item):
from core import channeltools
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Cualquiera de las tres opciones son válidas
@@ -934,9 +990,20 @@ def findvideos(item):
try:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
except:
pass
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data or not scrapertools.find_single_match(data, patron):
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron)
if not data: #Si no ha logrado encontrar nada, salimos
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
@@ -948,6 +1015,8 @@ def findvideos(item):
else:
item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
if size:
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
@@ -957,7 +1026,6 @@ def findvideos(item):
item_local = item.clone()
# obtenemos la url torrent
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
item_local.url = scrapertools.find_single_match(data, patron)
if not item_local.url: #error
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
@@ -969,17 +1037,17 @@ def findvideos(item):
#Ahora pintamos el link del Torrent, si lo hay
if item_local.url: # Hay Torrent ?
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
item_local.alive = "??" #Calidad del link sin verificar
item_local.action = "play" #Visualizar vídeo
item_local.server = "torrent" #Servidor
if size:
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
else:
quality = item_local.quality
itemlist.append(item_local.clone(quality=quality)) #Pintar pantalla
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
@@ -1163,9 +1231,20 @@ def findvideos(item):
def episodios(item):
logger.info()
#Renombramos el canal al nombre de clone elegido
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
itemlist = []
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
max_temp = 1
if item.infoLabels['number_of_seasons']:
max_temp = item.infoLabels['number_of_seasons']
y = []
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
patron = 'season (\d+)'
@@ -1173,16 +1252,30 @@ def episodios(item):
for x in matches:
y += [int(x)]
max_temp = max(y)
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
if not item.infoLabels['tmdb_id']:
tmdb.set_infoLabels(item, True)
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
except: #Algún error de proceso, salimos
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
patron = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
data_alt = ''
if data: data_alt = scrapertools.get_match(data, patron)
except: #Algún error de proceso
pass
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
if not data_alt or not scrapertools.find_single_match(data_alt, pattern):
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url)
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
item, data = generictools.fail_over_newpct1(item, patron, pattern)
if not data: #No se ha encontrado ningún canal activo para este vídeo
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
return itemlist
@@ -1209,7 +1302,8 @@ def episodios(item):
list_pages = [item.url]
season = max_temp
if item.library_playcounts or item.tmdb_stat: #Comprobamos si realmente sabemos el num. máximo de temporadas
#Comprobamos si realmente sabemos el num. máximo de temporadas
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
num_temporadas_flag = True
else:
num_temporadas_flag = False
@@ -1226,11 +1320,11 @@ def episodios(item):
if not data:
raise
except:
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + str(data))
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
if "pelisyseries.com" in host:
if "pelisyseries.com" in item.url:
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
else:
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
@@ -1245,7 +1339,7 @@ def episodios(item):
#Empezamos a generar cada episodio
for url, thumb, info in matches:
if "pelisyseries.com" in host: #En esta web están en diferente orden
if "pelisyseries.com" in item.url: #En esta web están en diferente orden
interm = url
url = thumb
thumb = interm
@@ -1273,6 +1367,10 @@ def episodios(item):
if scrapertools.find_single_match(info, '\[\d{3}\]'):
info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info)
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'):
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'
elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'):
@@ -1312,11 +1410,9 @@ def episodios(item):
except:
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
#logger.error("TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / " + str(match['episode2']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
match['season'] = season
item_local.contentSeason = season
else:
@@ -1331,11 +1427,11 @@ def episodios(item):
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
item_local.quality = item_local.quality.replace("ALTA DEFINICION", "HDTV")
if match['lang'] and estado == False:
match['lang'] = match['lang'].replace("- ", "")
if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()):
match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "")
item_local.infoLabels['episodio_titulo'] = match['lang']
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.contentEpisodeNumber = match['episode']
if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca
@@ -1381,6 +1477,8 @@ def episodios(item):
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
#logger.debug(item)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
@@ -1395,7 +1493,7 @@ def actualizar_titulos(item):
from platformcode import launcher
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return launcher.run(item)
@@ -1403,6 +1501,9 @@ def actualizar_titulos(item):
def search(item, texto):
logger.info("search:" + texto)
# texto = texto.replace(" ", "+")
item.channel = channel_clone_name
if item.category: item.category = channel_clone_name.capitalize()
try:
item.post = "q=%s" % texto
+62 -5
View File
@@ -494,9 +494,62 @@ def update_tvshow(item):
p_dialog.close()
def mark_content_as_watched2(item):
logger.info()
# logger.debug("item:\n" + item.tostring('\n'))
if filetools.exists(item.nfo):
head_nfo, it = videolibrarytools.read_nfo(item.nfo)
#logger.debug(it)
if item.contentType == 'movie':
name_file = os.path.splitext(os.path.basename(item.nfo))[0]
if name_file != 'tvshow' :
it.library_playcounts.update({name_file: item.playcount})
if item.contentType == 'episode' or item.contentType == 'list' or name_file == 'tvshow':
# elif item.contentType == 'episode':
name_file = os.path.splitext(os.path.basename(item.strm_path))[0]
num_season = name_file [0]
item.__setattr__('contentType', 'episode')
item.__setattr__('contentSeason', num_season)
#logger.debug(name_file)
else:
name_file = item.contentTitle
# logger.debug(name_file)
if not hasattr(it, 'library_playcounts'):
it.library_playcounts = {}
it.library_playcounts.update({name_file: item.playcount})
# se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada
if item.contentType != 'movie':
it = check_season_playcount(it, item.contentSeason)
#logger.debug(it)
# Guardamos los cambios en item.nfo
if filetools.write(item.nfo, head_nfo + it.tojson()):
item.infoLabels['playcount'] = item.playcount
logger.debug(item.playcount)
# if item.contentType == 'episodesss':
# Actualizar toda la serie
#new_item = item.clone(contentSeason=-1)
#mark_season_as_watched(new_item)
if config.is_xbmc():
from platformcode import xbmc_videolibrary
xbmc_videolibrary.mark_content_as_watched_on_kodi(item , item.playcount)
# logger.debug(item)
platformtools.itemlist_refresh()
def mark_content_as_watched(item):
logger.info()
# logger.debug("item:\n" + item.tostring('\n'))
logger.debug("item:\n" + item.tostring('\n'))
if filetools.exists(item.nfo):
head_nfo, it = videolibrarytools.read_nfo(item.nfo)
@@ -520,10 +573,11 @@ def mark_content_as_watched(item):
if filetools.write(item.nfo, head_nfo + it.tojson()):
item.infoLabels['playcount'] = item.playcount
if item.contentType == 'tvshow':
if item.contentType == 'tvshow' and item.type != 'episode' :
# Actualizar toda la serie
new_item = item.clone(contentSeason=-1)
mark_season_as_watched(new_item)
if config.is_xbmc(): #and item.contentType == 'episode':
from platformcode import xbmc_videolibrary
xbmc_videolibrary.mark_content_as_watched_on_kodi(item, item.playcount)
@@ -555,7 +609,7 @@ def mark_season_as_watched(item):
season, episode = season_episode.split("x")
if int(item.contentSeason) == -1 or int(season) == int(item.contentSeason):
name_file = os.path.splitext(os.path.basename(f))[0]
name_file = os.path.splitext(os.path.basename(i))[0]
it.library_playcounts[name_file] = item.playcount
episodios_marcados += 1
@@ -685,16 +739,19 @@ def check_season_playcount(item, season):
def check_tvshow_playcount(item, season):
logger.info()
# logger.debug(item)
if season:
temporadas_serie = 0
temporadas_vistas_serie = 0
for key, value in item.library_playcounts.iteritems():
if key == ("season %s" % season):
#if key.startswith("season %s" % season):
if key.startswith("season" ):
temporadas_serie += 1
if value > 0:
temporadas_vistas_serie += 1
#logger.debug(temporadas_serie)
if temporadas_serie == temporadas_vistas_serie:
if temporadas_serie == temporadas_vistas_serie:
item.library_playcounts.update({item.title: 1})
else:
item.library_playcounts.update({item.title: 0})