Clones NewPct1: soporte Fail-over

Adaptción de los clones de NewPct1 para saltar de una web caída a otra activa

EliteTorrent y MejorTorrent: soporte de librería de código reutilizable
This commit is contained in:
Kingbox
2018-06-27 20:59:17 +02:00
parent f15c0d622b
commit ab0c17c77c
11 changed files with 1489 additions and 1034 deletions

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

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

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"

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

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

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

View File

@@ -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",

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

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

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

View File

@@ -63,6 +63,8 @@ def update_title(item):
if item.from_title:
item.title = item.from_title
del item.from_title
else:
item.add_videolibrary = True #Estamos Añadiendo a la Videoteca. Indicador para control de uso de los Canales
#Sólo ejecutamos este código si no se ha hecho antes en el Canal. Por ejemplo, si se ha llamado desde Episodios,
#ya no se ejecutará al Añadia a Videoteca, aunque desde el canal se podrá llamar tantas veces como se quiera,
@@ -125,16 +127,21 @@ def update_title(item):
item.title = item.title.replace("[" + str(rating_old) + "]", "[" + str(rating_new) + "]")
if item.wanted: #Actualizamos Wanted, si existe
item.wanted = item.contentTitle
if new_item.contentSeason: #Restauramos el núm. de Temporada después de TMDB
item.contentSeason = new_item.contentSeason
#Para evitar el "efecto memoria" de TMDB, se le llama con un título ficticio para que resetee los buffers
if item.contentSerieName:
new_item.infoLabels['tmdb_id'] = '289' #una peli no ambigua
new_item.infoLabels['tmdb_id'] = '289' #una serie no ambigua
else:
new_item.infoLabels['tmdb_id'] = '111' #una serie no ambigua
new_item.infoLabels['tmdb_id'] = '111' #una peli no ambigua
new_item.infoLabels['year'] = '-'
if new_item.contentSeason:
del new_item.infoLabels['season'] #Funciona mal con num. de Temporada
scraper_return = scraper.find_and_set_infoLabels(new_item)
#logger.debug(item)
return item
@@ -158,25 +165,40 @@ def post_tmdb_listado(item, itemlist):
"""
for item_local in itemlist: #Recorremos el Itenlist generado por el canal
title = item_local.title
#Borramos valores si ha habido fail-over
channel_alt = ''
if item.channel_alt:
channel_alt = item.channel
del item.channel_alt
if item.url_alt:
del item.url_alt
for item_local in itemlist: #Recorremos el Itenlist generado por el canal
title = item_local.title
if item_local.contentSeason_save: #Restauramos el num. de Temporada
item_local.contentSeason = item_local.contentSeason_save
#Borramos valores para cada Contenido si ha habido fail-over
if item_local.channel_alt:
del item_local.channel_alt
if item_local.url_alt:
del item_local.url_alt
#Restauramos la info adicional guarda en la lista title_subs, y la borramos de Item
if item_local.title_subs and len(item_local.title_subs) > 0:
title += " "
title_add = ' '
if item_local.title_subs:
for title_subs in item_local.title_subs:
if "audio" in title_subs.lower(): #se restaura info de Audio
title = '%s [%s]' % (title, scrapertools.find_single_match(title_subs, r'[a|A]udio (.*?)'))
title_add += scrapertools.find_single_match(title_subs, r'[a|A]udio (.*?)')
continue
if scrapertools.find_single_match(title_subs, r'(\d{4})'): #Se restaura el año, s no lo ha dado TMDB
if not item_local.infoLabels['year'] or item_local.infoLabels['year'] == "-":
item_local.infoLabels['year'] = scrapertools.find_single_match(title_subs, r'(\d{4})')
continue
if not config.get_setting("unify"): #Si Titulos Inteligentes NO seleccionados:
title = '%s %s' % (title, title_subs) #se agregan el resto de etiquetas salvadas
else:
title = '%s -%s-' % (title, title_subs) #se agregan el resto de etiquetas salvadas
title_add = title_add.rstrip()
title_add += '%s -%s-' % (title_add, title_subs) #se agregan el resto de etiquetas salvadas
del item_local.title_subs
#Preparamos el Rating del vídeo
@@ -195,20 +217,49 @@ def post_tmdb_listado(item, itemlist):
# Para Episodios, tomo el año de exposición y no el de inicio de la serie
elif item_local.infoLabels['aired']:
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
# 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":
if item.infoLabels['title']: del item.infoLabels['title']
if item_local.contentType == "season":
if scrapertools.find_single_match(item_local.url, '-(\d+)x'):
title = '%s -Temporada %s' % (title, scrapertools.find_single_match(item_local.url, '-(\d+)x'))
if scrapertools.find_single_match(item_local.url, '-temporadas?-(\d+)'):
title = '%s -Temporada %s' % (title, scrapertools.find_single_match(item_local.url, '-temporadas?-(\d+)'))
if item_local.contentType in ['season', 'tvshow', 'episode']:
if item_local.infoLabels['title']: del item_local.infoLabels['title']
if item_local.contentType == "episode":
if "Temporada" in title: #Compatibilizamos "Temporada" con Unify
title = '%sx%s al 99 -' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber))
if " al " in title: #Si son episodios múltiples, ponemos nombre de serie
if " al 99" in title.lower(): #Temporada completa. Buscamos num total de episodios
title = title.replace("99", str(item_local.infoLabels['temporada_num_episodios']))
title = '%s %s' % (title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s - %s [%s] [%s]' % (scrapertools.find_single_match(title, r'(al \d+)'), item_local.contentSerieName, item_local.infoLabels['year'], rating)
elif item_local.infoLabels['episodio_titulo']:
title = '%s %s, %s' % (title, item_local.infoLabels['episodio_titulo'], item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s, %s [%s] [%s]' % (item_local.infoLabels['episodio_titulo'], item_local.contentSerieName, item_local.infoLabels['year'], rating)
else: #Si no hay título de episodio, ponermos el nombre de la serie
title = '%s %s' % (title, item_local.contentSerieName)
item_local.infoLabels['episodio_titulo'] = '%s [%s] [%s]' % (item_local.contentSerieName, item_local.infoLabels['year'], rating)
elif item_local.contentType == "season":
if not item_local.contentSeason:
item_local.contentSeason = scrapertools.find_single_match(item_local.url, '-(\d+)x')
if not item_local.contentSeason:
item_local.contentSeason = scrapertools.find_single_match(item_local.url, '-temporadas?-(\d+)')
if item_local.contentSeason:
title = '%s -Temporada %s' % (title, str(item_local.contentSeason))
if not item_local.contentSeason_save: #Restauramos el num. de Temporada
item_local.contentSeason_save = item_local.contentSeason #Y lo volvemos a salvar
del item_local.infoLabels['season'] #Funciona mal con num. de Temporada. Luego lo restauramos
else:
title = '%s -Temporada !!!' % (title)
elif item.action == "search":
title += " -Serie-"
elif item_local.extra == "varios" and item.action == "search":
title += " -Varios-"
item_local.contentTitle += " -Varios-"
title += title_add #Se añaden etiquetas adicionales, si las hay
#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:
@@ -218,6 +269,8 @@ def post_tmdb_listado(item, itemlist):
title = title.replace("[", "-").replace("]", "-")
#Limpiamos las etiquetas vacías
if item_local.infoLabels['episodio_titulo']:
item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].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()
@@ -226,11 +279,17 @@ def post_tmdb_listado(item, itemlist):
title += ' -%s-' % item_local.channel.capitalize()
if item_local.contentType == "movie":
item_local.contentTitle += ' -%s-' % item_local.channel.capitalize()
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 + "[" + str(item_local.language) + "]" + " / year: " + str(item_local.infoLabels['year']))
#logger.debug(item_local)
#Si ha habido fail-over, lo comento
if channel_alt:
itemlist.append(item.clone(action='', title="[COLOR yellow]" + channel_alt.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] caído'))
return (item, itemlist)
@@ -261,7 +320,7 @@ def post_tmdb_episodios(item, itemlist):
modo_ultima_temp = ''
if config.get_setting('seleccionar_ult_temporadda_activa', item.channel) is True or config.get_setting('seleccionar_ult_temporadda_activa', item.channel) is False:
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
#Inicia variables para el control del núm de episodios por temporada
num_episodios = 1
num_episodios_lista = []
@@ -270,8 +329,39 @@ def post_tmdb_episodios(item, itemlist):
num_temporada_max = 99
num_episodios_flag = True
for item_local in itemlist: #Recorremos el Itenlist generado por el canal
#Restauramos el num de Temporada para hacer más flexible la elección de Videoteca
contentSeason = item.contentSeason
if item.contentSeason_save:
contentSeason = item.contentSeason_save
item.contentSeason = item.contentSeason_save
del item.contentSeason_save
#Restauramos valores si ha habido fail-over
channel_alt = ''
if item.channel_alt:
channel_alt = item.channel
item.channel = item.channel_alt
del item.channel_alt
if item.url_alt:
item.url = item.url_alt
del item.url_alt
for item_local in itemlist: #Recorremos el Itenlist generado por el canal
if item_local.add_videolibrary:
del item_local.add_videolibrary
if item_local.add_menu:
del item_local.add_menu
#Restauramos valores para cada Episodio si ha habido fail-over
if item_local.channel_alt:
item_local.channel = item_local.channel_alt
del item_local.channel_alt
if item_local.url_alt:
host_act = scrapertools.find_single_match(item_local.url, ':\/\/(.*?)\/')
host_org = scrapertools.find_single_match(item_local.url_alt, ':\/\/(.*?)\/')
item_local.url = item_local.url.replace(host_act, host_org)
del item_local.url_alt
#Si el título de la serie está verificado en TMDB, se intenta descubrir los eisodios fuera de rango,
#que son probables errores de la Web
if item.tmdb_stat:
@@ -316,9 +406,7 @@ def post_tmdb_episodios(item, itemlist):
elif item_local.infoLabels['aired']:
item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})')
#Preparamos el título para que sea compatible con Añadir Serie a Videoteca
if item.infoLabels['title']: del item.infoLabels['title']
#Preparamos el título para que sea compatible con Añadir Serie a Videoteca
if "Temporada" in item_local.title: #Compatibilizamos "Temporada" con Unify
item_local.title = '%sx%s al 99 -' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber))
if " al " in item_local.title: #Si son episodios múltiples, ponemos nombre de serie
@@ -334,13 +422,14 @@ def post_tmdb_episodios(item, itemlist):
else: #Si no hay título de episodio, ponermos el nombre de la serie
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']
#Componemos el título final, aunque con Unify usará infoLabels['episodio_titulo']
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
item_local.title = '%s [%s] [%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(" []", "").strip()
item_local.infoLabels['title'] = item_local.infoLabels['title'].replace(" []", "").strip()
item_local.title = item_local.title.replace(" []", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title).strip()
@@ -348,10 +437,13 @@ def post_tmdb_episodios(item, itemlist):
#Si la información de num. total de episodios de TMDB no es correcta, tratamos de calcularla
if num_episodios < item_local.contentEpisodeNumber:
num_episodios = item_local.contentEpisodeNumber
if num_episodios > item_local.contentEpisodeNumber:
item_local.infoLabels['temporada_num_episodios'] = num_episodios
num_episodios_flag = False
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]
num_episodios_lista[item_local.contentSeason] = num_episodios
#logger.debug("title: " + item_local.title + " / url: " + item_local.url + " / calidad: " + item_local.quality + " / Season: " + str(item_local.contentSeason) + " / EpisodeNumber: " + str(item_local.contentEpisodeNumber) + " / num_episodios_lista: " + str(num_episodios_lista) + str(num_episodios_flag))
#logger.debug(item_local)
@@ -361,23 +453,22 @@ def post_tmdb_episodios(item, itemlist):
try:
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]
item_local.infoLabels['temporada_num_episodios'] = int(num_episodios_lista[item_local.contentSeason])
except:
logger.error("ERROR 07: EPISODIOS: Num de Temporada fuera de rango " + " / TEMPORADA: " + str(item_local.contentSeason) + " / " + str(item_local.contentEpisodeNumber) + " / MAX_TEMPORADAS: " + str(num_temporada_max) + " / LISTA_TEMPORADAS: " + str(num_episodios_lista))
#Permitimos la actualización de los títulos, bien para uso inmediato, o para añadir a la videoteca
item.from_action = item.action #Salvamos la acción...
item.from_title = item.title #... y el título
#item.tmdb_stat=False #Fuerza la actualización de TMDB hasta desambiguar
itemlist.append(item.clone(title="** [COLOR yelow]Actualizar Títulos - vista previa videoteca[/COLOR] **", action="actualizar_titulos", extra="episodios", tmdb_stat=False))
contentSeason = item.contentSeason
if item.contentSeason_save:
contentSeason = item.contentSeason_save
del item.contentSeason_save
itemlist.append(item.clone(title="** [COLOR yelow]Actualizar Títulos - vista previa videoteca[/COLOR] **", action="actualizar_titulos", extra="episodios", tmdb_stat=False, from_action=item.action, from_title=item.title))
#Borro num. Temporada si no viene de menú de Añadir a Videoteca y no está actualizando la Videoteca
if not item.library_playcounts: #si no está actualizando la Videoteca
if modo_serie_temp != '': #y puede cambiara a serie-temporada
if item.contentSeason and not item.add_menu:
del item.infoLabels['season'] #La decisión de ponerlo o no se toma en la zona de menús
#Ponemos el título de Añadir a la Videoteca, con el núm. de episodios de la última temporada y el estado de la Serie
if config.get_videolibrary_support() and len(itemlist) > 0:
if config.get_videolibrary_support() and len(itemlist) > 1:
item_local = itemlist[-2]
title = ''
if item_local.infoLabels['temporada_num_episodios']:
@@ -406,16 +497,29 @@ def post_tmdb_episodios(item, itemlist):
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a la Videoteca[/COLOR]" + title, action="add_serie_to_library"))
elif modo_serie_temp == 1: #si es Serie damos la opción de guardar la última temporada o la serie completa
itemlist.append(item.clone(title="[COLOR yellow]Añadir última Temp. a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="season", contentSeason=contentSeason, url=item_local.url))
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="tvshow"))
itemlist.append(item.clone(title="[COLOR yellow]Añadir última Temp. a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="season", contentSeason=contentSeason, url=item_local.url, add_menu=True))
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="tvshow", add_menu=True))
else: #si no, damos la opción de guardar la temporada actual o la serie completa
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="tvshow"))
item.contentSeason = contentSeason
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Temp. a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="season", contentSeason=contentSeason))
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Serie a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="tvshow", add_menu=True))
if item.add_videolibrary and not item.add_menu:
item.contentSeason = contentSeason
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta Temp. a Videoteca[/COLOR]" + title, action="add_serie_to_library", contentType="season", contentSeason=contentSeason, add_menu=True))
else: #Es un canal estándar, sólo una linea de Añadir a Videoteca
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta serie a la videoteca[/COLOR]" + title, action="add_serie_to_library", extra="episodios"))
itemlist.append(item.clone(title="[COLOR yellow]Añadir esta serie a la videoteca[/COLOR]" + title, action="add_serie_to_library", extra="episodios", add_menu=True))
#Si ha habido fail-over, lo comento
if channel_alt:
itemlist.append(item.clone(action='', title="[COLOR yellow]" + channel_alt.capitalize() + '[/COLOR] [ALT ] en uso'))
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] caído'))
if item.add_videolibrary: #Estamos Añadiendo a la Videoteca.
del item.add_videolibrary #Borramos ya el indicador
if item.add_menu: #Opción que avisa si se ha añadido a la Videoteca
del item.add_menu #desde la página de Episodios o desde Menú Contextual
#logger.debug(item)
return (item, itemlist)
@@ -452,10 +556,9 @@ def post_tmdb_findvideos(item, itemlist):
item.unify = config.get_setting("unify")
#Salvamos la información de max num. de episodios por temporada para despues de TMDB
num_episodios = item.contentEpisodeNumber
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. Siempre cuando viene de Videoteca
if not item.infoLabels['tmdb_id'] or (not item.infoLabels['episodio_titulo'] and item.contentType == 'episode'):
@@ -464,7 +567,10 @@ def post_tmdb_findvideos(item, itemlist):
tmdb.set_infoLabels(item, True)
#Restauramos la información de max num. de episodios por temporada despues de TMDB
try:
if item.infoLabels['temporada_num_episodios'] and int(num_episodios) > int(item.infoLabels['temporada_num_episodios']):
if item.infoLabels['temporada_num_episodios']:
if int(num_episodios) > int(item.infoLabels['temporada_num_episodios']):
item.infoLabels['temporada_num_episodios'] = num_episodios
else:
item.infoLabels['temporada_num_episodios'] = num_episodios
except:
pass
@@ -485,6 +591,9 @@ def post_tmdb_findvideos(item, itemlist):
except:
pass
if item.quality.lower() in ['gb', 'mb']:
item.quality = item.quality.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
#Formateamos de forma especial el título para un episodio
if item.contentType == "episode": #Series
title = '%sx%s' % (str(item.contentSeason), str(item.contentEpisodeNumber).zfill(2)) #Temporada y Episodio
@@ -509,7 +618,9 @@ def post_tmdb_findvideos(item, itemlist):
else: #Si Titulos Inteligentes SÍ seleccionados:
title_gen = '[COLOR gold]Enlaces Ver: [/COLOR]%s' % (title_gen)
if config.get_setting("quit_channel_name", "videolibrary") == 1 and item.contentChannel == "videolibrary":
if item.channel_alt:
title_gen = '[COLOR yellow]%s [/COLOR][ALT]: %s' % (item.channel.capitalize(), title_gen)
elif config.get_setting("quit_channel_name", "videolibrary") == 1 and item.contentChannel == "videolibrary":
title_gen = '%s: %s' % (item.channel.capitalize(), title_gen)
#Pintamos el pseudo-título con toda la información disponible del vídeo
@@ -519,4 +630,118 @@ def post_tmdb_findvideos(item, itemlist):
#logger.debug(item)
return (item, itemlist)
return (item, itemlist)
def fail_over_newpct1(item, patron, patron2=None):
logger.info()
import ast
"""
Llamada para encontrar una web alternativa a un canal caído, clone de NewPct1
Creamos una liat de tuplas con los datos de los canales alternativos. Los datos de la tupla son:
- active = 0,1 Indica si el canal no está activo o sí lo está
- channel nombre del canal alternativo
- channel_host host del canal alternativo, utilizado para el reemplazo de parte de la url
- contentType indica que tipo de contenido que soporta el nuevo canal en fail-overs
- info reservado para uso futuro
La llamada al método desde el principio de Submenu, Episodios y Findvideos, es:
from lib import generictools
item, data = generictools.fail_over_newpct1(item, patron)
- Entrada: patron: con este patron permite verificar si los datos de la nueva web son buenos
- Entrada (opcional): patron2: segundo patron opcional
- Saida: data: devuelve los datos del la nueva web. Si vuelve vacía es que no se ha encontrado alternativa
"""
data = ''
#lista de tuplas con los datos de los canales alternativos
fail_over_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid")
fail_over_list = ast.literal_eval(fail_over_list)
#Recorremos la tupla identificando el canala que falla
for active, channel, channel_host, contentType, info in fail_over_list:
if channel != item.channel: #es el canal que falla?
continue
channel_failed = channel #salvamos el nombre del canal
channel_host_failed = channel_host #salvamos el nombre del host
channel_url_failed = item.url #salvamos la url
if item.action != 'submenu' and item.action != 'search' and item.contentType not in contentType: #soporta el fail_over de este contenido?
data = ''
return (item, data) #no soporta el fail_over de este contenido, no podemos hacer nada
#Recorremos la tupla identificando canales activos que funcionen, distintos del caído, que soporten el contenido
for active, channel, channel_host, contentType, info in fail_over_list:
data_alt = ''
if channel == channel_failed or active == '0': #está activo el nuevo canal?
continue
if item.action != 'submenu' and item.action != 'search' and item.contentType not in contentType: #soporta el contenido?
continue
#Hacemos el cambio de nombre de canal y url, conservando las anteriores como ALT
item.channel_alt = channel_failed
item.channel = channel
item.url_alt = channel_url_failed
item.url = channel_url_failed
item.url = item.url.replace(channel_host_failed, channel_host)
#quitamos el código de series, porque puede variar entre webs
if item.action == "episodios" or item.action == "get_seasons":
item.url = re.sub(r'\/\d+$', '', item.url) #parece que con el título solo ecuentra la serie, normalmente...
#Leemos la nueva url
try:
if item.post:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, post=item.post, timeout=2).data)
else:
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, timeout=2).data)
except:
data = ''
if not data: #no ha habido suerte, probamos con el siguiente canal válido
logger.error("ERROR 01: " + item.action + ": La Web no responde o la URL es erronea: " + item.url)
continue
#Hemos logrado leer la web, validamos si encontramos un línk válido en esta estructura
#Evitar páginas engañosas que puede meter al canal en un loop infinito
if (not ".com/images/no_imagen.jpg" in data and not ".com/images/imagen-no-disponible.jpg" in data) or item.action != "episodios":
if item.action == 'submenu': #Para submenú hacemos un cambio total de canal
patron = patron.replace(item.channel_alt, item.channel) #el patron lleva el nombre de host
if patron:
data_alt = scrapertools.find_single_match(data, patron)
if patron2 != None:
data_alt = scrapertools.find_single_match(data_alt, patron2)
if not data_alt: #no ha habido suerte, probamos con el siguiente canal
logger.error("ERROR 02: " + item.action + ": Ha cambiado la estructura de la Web: " + item.url + " / Patron: " + patron)
data = ''
if item.action == 'submenu': #restauramos el patrón para el siguiente canal
patron = patron.replace(item.channel, item.channel_alt)
continue
else:
#if item.action == "episodios" or item.action == "get_seasons": #guardamos la url real de esta web
#item.url += str(scrapertools.find_single_match(data, '<ul class="buscar-list">.*?<img src=".*?\/pictures\/.*?(\/\d+)_'))
#para Submenu y Search cambiamos también la Categoria
if item.action == 'submenu' or item.action == 'search':
item.category = item.channel.capitalize()
break #por fin !!! Este canal parece que funciona
else:
logger.error("ERROR 02: " + item.action + ": Ha cambiado la estructura de la Web: " + item.url + " / Patron: " + patron)
data = ''
continue
#logger.debug(item)
if not data: #Si no ha logrado encontrar nada, salimos limpiando variables
if item.channel_alt:
item.channel = item.channel_alt
del item.channel_alt
if item.url_alt:
item.url = item.url_alt
del item.url_alt
return (item, data)