Merge remote-tracking branch 'alfa-addon/master'
This commit is contained in:
24
mediaserver/COMO INSTALAR.txt
Normal file
24
mediaserver/COMO INSTALAR.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
Esta versión de Alfa no necesita de ningún programa para instalar (tampoco kodi), es una versión independiente que solo necesita un navegador web y un equipo (en el cual será instalado) para ver el contenido desde cualquier dispositivo que cuente con un navegador web.
|
||||
|
||||
REQUISITOS:
|
||||
|
||||
Se necesita que esté instalado python 2.x desde aqui: https://www.python.org/
|
||||
|
||||
COMO INSTALAR LA VERSION MEDIASERVER:
|
||||
|
||||
-Descargar Alfa desde el reposotorio de Github: https://github.com/alfa-addon/addon (opcion Clone or download - Download zip
|
||||
-El archivo descargado (addon-master.zip) abrirlo e ingresar a la carpeta: addon-master
|
||||
-Descomprimir la carpeta plugin.video.alfa en alguna carpeta
|
||||
-Luego descomprimir la carpeta mediaserver encima de la carpeta plugi.video.alfa reemplazando los archivos existentes.
|
||||
|
||||
COMO INICIAR LA VERSION MEDIASERVER
|
||||
|
||||
Para iniciar: python alfa.py
|
||||
|
||||
Y mostrará en pantalla la url a la cual se puede conectar desde cualquier dispositivo que contenga un navegador web.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
http://192.168.1.10:8080
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
Debe ejecutar primero el archivo "script.py", si no lo hizo antes.
|
||||
Una vez realizado el proceso podrá ejecutar como siempre "alfa.py" para iniciar el addon.
|
||||
@@ -310,6 +310,23 @@ def verify_directories_created():
|
||||
logger.debug("Creating %s: %s" % (path, saved_path))
|
||||
filetools.mkdir(saved_path)
|
||||
|
||||
config_paths = [["folder_movies", "CINE"],
|
||||
["folder_tvshows", "SERIES"]]
|
||||
|
||||
for path, default in config_paths:
|
||||
saved_path = get_setting(path)
|
||||
|
||||
if not saved_path:
|
||||
saved_path = default
|
||||
set_setting(path, saved_path)
|
||||
|
||||
content_path = filetools.join(get_videolibrary_path(), saved_path)
|
||||
if not filetools.exists(content_path):
|
||||
logger.debug("Creating %s: %s" % (path, content_path))
|
||||
|
||||
# si se crea el directorio
|
||||
filetools.mkdir(content_path)
|
||||
|
||||
|
||||
def get_local_ip():
|
||||
import socket
|
||||
@@ -372,6 +389,7 @@ if not os.path.exists(get_data_path()):
|
||||
TRANSLATION_FILE_PATH = os.path.join(get_runtime_path(), "resources", "language", "Spanish", "strings.po")
|
||||
load_settings()
|
||||
|
||||
|
||||
# modo adulto:
|
||||
# sistema actual 0: Nunca, 1:Siempre, 2:Solo hasta que se reinicie sesión
|
||||
# si es == 2 lo desactivamos.
|
||||
|
||||
@@ -40,6 +40,7 @@ def run(item):
|
||||
platformtools.render_items(None, item)
|
||||
return
|
||||
|
||||
channelmodule = None
|
||||
# Importa el canal para el item, todo item debe tener un canal, sino sale de la función
|
||||
if item.channel:
|
||||
channelmodule = import_channel(item)
|
||||
|
||||
@@ -131,9 +131,12 @@ div.header {
|
||||
}
|
||||
div.header > div.logo {
|
||||
float: left;
|
||||
height: 50px;
|
||||
width: 70px;
|
||||
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2270px%22%20height%3D%2250px%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Crect%20fill%3D%22%2391D9E8%22%20stroke%3D%22%2301455C%22%20stroke-width%3D%221%22%20x%3D%229%22%20y%3D%2215%22%20width%3D%2240.4%22%20height%3D%2226.5%22%2F%3E%0A%3Crect%20fill%3D%22%2303BFEC%22%20stroke%3D%22%2301455C%22%20stroke-width%3D%221%22%20x%3D%226%22%20y%3D%229%22%20width%3D%2210.8%22%20height%3D%229.3%22%20rx%3D%222%22%20ry%3D%222%22%2F%3E%0A%3Crect%20fill%3D%22%2303BFEC%22%20stroke%3D%22%2301455C%22%20stroke-width%3D%221%22%20x%3D%2237%22%20y%3D%2235%22%20width%3D%2215.5%22%20height%3D%2212.4%22%20rx%3D%222%22%20ry%3D%222%22%2F%3E%0A%3Crect%20fill%3D%22%2300ABE3%22%20stroke%3D%22%2301455C%22%20stroke-width%3D%221%22%20x%3D%2233%22%20y%3D%222%22%20width%3D%2234.2%22%20height%3D%2225%22%20rx%3D%222%22%20ry%3D%222%22%2F%3E%0A%3Crect%20fill%3D%22%2303BFEC%22%20stroke%3D%22%2301455C%22%20stroke-width%3D%221%22%20x%3D%223%22%20y%3D%2227%22%20width%3D%2224.8%22%20height%3D%2217%22%20rx%3D%222%22%20ry%3D%222%22%2F%3E%0A%3C%2Fsvg%3E");
|
||||
height: 45px;
|
||||
width: 60px;
|
||||
margin-left: 15px;
|
||||
margin-top: 2px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("https://github.com/alfa-addon/addon/raw/master/mediaserver/platformcode/template/logo-mediaserver.png");
|
||||
}
|
||||
|
||||
div.header > a.settings:after {
|
||||
@@ -1303,4 +1306,4 @@ ul.itemlist > li.item_list > a.item > h3.label {
|
||||
padding-top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
mediaserver/platformcode/template/logo-mediaserver.png
Normal file
BIN
mediaserver/platformcode/template/logo-mediaserver.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
@@ -1,110 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from platformcode import config, logger, platformtools
|
||||
|
||||
|
||||
def conversion():
|
||||
logger.info()
|
||||
data = ""
|
||||
|
||||
try:
|
||||
# do a backup
|
||||
path_settings = os.path.join(config.get_data_path(), "settings.xml")
|
||||
path_settings_backup = os.path.join(config.get_data_path(), "settings.backup.xml")
|
||||
shutil.copy(path_settings, path_settings_backup)
|
||||
|
||||
# open file
|
||||
f = open(path_settings, "r")
|
||||
# copy = open(path_settings2, "w")
|
||||
|
||||
logger.info(" ---")
|
||||
logger.info(" --- 1")
|
||||
logger.info(" --- 2")
|
||||
logger.info(" --- 3")
|
||||
data_aux = ""
|
||||
|
||||
begin_tag = "<settings>\n"
|
||||
end_tag = "</settings>\n"
|
||||
|
||||
adult_data = ' <setting id="adult_aux_intro_password" value="" />\n'
|
||||
adult_data += ' <setting id="adult_aux_new_password1" value="" />\n'
|
||||
adult_data += ' <setting id="adult_aux_new_password2" value="" />\n'
|
||||
adult_data += ' <setting id="adult_mode" value="0" />\n'
|
||||
adult_data += ' <setting id="adult_password" value="0000" />\n'
|
||||
adult_data += ' <setting id="adult_request_password" value="false" />\n'
|
||||
|
||||
for line in f:
|
||||
matches = re.findall('<setting id="([^"]*)" value="([^"]*)', line, re.DOTALL)
|
||||
logger.info("macthes %s" % matches)
|
||||
if not matches:
|
||||
logger.info("no matches")
|
||||
# for <settings></settings> tag
|
||||
# data += line
|
||||
else:
|
||||
logger.info("Matches")
|
||||
for _id, value in matches:
|
||||
logger.info(" dentro del for")
|
||||
logger.info(" _id:%s value:%s" % (_id, value))
|
||||
|
||||
if _id not in ["adult_aux_intro_password", "adult_aux_new_password1", "adult_aux_new_password2",
|
||||
"adult_mode", "adult_password", "adult_request_password", "adult_pin"]:
|
||||
logger.info(" linea %s" % line)
|
||||
logger.info(" value %s" % value)
|
||||
if value:
|
||||
# logger.info(" type value!! %s" % type(value))
|
||||
logger.info(" antes value!! %s" % value)
|
||||
if "(str, " in value:
|
||||
if "(str, '" in value:
|
||||
value = value.replace("(str, '", "")
|
||||
value = value.replace("')", "")
|
||||
elif "(str, '":
|
||||
value = value.replace("(str, '", "")
|
||||
value = value.replace("')", "")
|
||||
elif "(bool, " in value:
|
||||
value = value.replace("(bool, ", "")
|
||||
if value == "True)":
|
||||
value = "true"
|
||||
else:
|
||||
value = "false"
|
||||
value = value.replace('\\\\', '\\')
|
||||
logger.info(" despues value!! %s" % value)
|
||||
|
||||
aux_line = '<setting id="%s" value="%s" />\n' % (_id, value)
|
||||
logger.info(" aux_line %s" % aux_line)
|
||||
data_aux += " " + aux_line
|
||||
f.close()
|
||||
|
||||
data = begin_tag + adult_data + data_aux + end_tag
|
||||
|
||||
copy_file = open(path_settings, "w")
|
||||
copy_file.write(data)
|
||||
copy_file.close()
|
||||
|
||||
while True:
|
||||
import sys
|
||||
logger.info("sys ve %s" % sys.version_info)
|
||||
if sys.version_info > (3, 0):
|
||||
value = input("Alfa\nCorregido un error en la seccion adultos, se ha reseteado la contrasena a por "
|
||||
"defecto, tendra que cambiarla de nuevo si lo desea.\n Escriba 's', si lo ha entendido: ")
|
||||
else:
|
||||
value = raw_input("Alfa\nCorregido un error en la seccion adultos, se ha reseteado la contrasena a por "
|
||||
"defecto, tendra que cambiarla de nuevo si lo desea.\n Escriba 's', si lo ha entendido: ")
|
||||
logger.debug("value %s" % value)
|
||||
if value.lower() == 's':
|
||||
break
|
||||
logger.info("En disclaimer clickó 'No'")
|
||||
|
||||
logger.info("En disclaimer clickó 'Si'")
|
||||
|
||||
except Exception, ex:
|
||||
template = "An exception of type %s occured. Arguments:\n%r"
|
||||
message = template % (type(ex).__name__, ex.args)
|
||||
logger.info(message)
|
||||
print("Alfa", "Error, en conversión")
|
||||
logger.info("Datos a guardar %s" % data)
|
||||
|
||||
if __name__ == "__main__":
|
||||
conversion()
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="plugin.video.alfa" name="Alfa" version="2.5.20" provider-name="Alfa Addon">
|
||||
<addon id="plugin.video.alfa" name="Alfa" version="2.5.21" provider-name="Alfa Addon">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="2.1.0"/>
|
||||
<import addon="script.module.libtorrent" optional="true"/>
|
||||
@@ -22,12 +22,14 @@
|
||||
» grantorrent » descargas2020
|
||||
» torrentlocura » torrentrapid
|
||||
» tumejortorrent » tvsinpagar
|
||||
» mispelisyseries » kbagi
|
||||
» animemovil » pelismagnet
|
||||
» pelisultra » seriesdanko
|
||||
» seriespapaya » seriesverde
|
||||
» ultrapeliculas » wikiseries
|
||||
¤ arreglos internos
|
||||
» mispelisyseries » playview
|
||||
» clipwatching » cloudvideo
|
||||
» filevideo » upvid
|
||||
» vidzella » vivo
|
||||
» watchvideo » vshare
|
||||
¤ arreglos internos y actualizado la versión mediaserver
|
||||
|
||||
¤ Agradecimientos a @alaquepasa y @Pixo506 por colaborar con ésta versión.
|
||||
|
||||
</news>
|
||||
<description lang="es">Navega con Kodi por páginas web para ver sus videos de manera fácil.</description>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -413,9 +413,6 @@ def episodios(item):
|
||||
patron = "<li><a href='([^']+)'>[^<]+</a></li>"
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
for scrapedurl in matches:
|
||||
if "temporada-0" in scrapedurl:
|
||||
continue
|
||||
## Episodios
|
||||
data = agrupa_datos(httptools.downloadpage(scrapedurl).data)
|
||||
sid = scrapertools.get_match(data, "<script>var sid = '(\d+)'")
|
||||
ssid = scrapertools.get_match(scrapedurl, "temporada-(\d+)")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,7 +16,7 @@ from core.item import Item
|
||||
from platformcode import config, logger
|
||||
from platformcode import platformtools
|
||||
from core import jsontools
|
||||
from channels import side_menu
|
||||
|
||||
|
||||
THUMBNAILS = {'0': 'posters', '1': 'banners', '2': 'squares'}
|
||||
|
||||
@@ -245,13 +245,15 @@ def novedades(item):
|
||||
|
||||
list_canales, any_active = get_channels_list()
|
||||
|
||||
if mode=='silent' and any_active and len(list_canales[item.extra]) > 0:
|
||||
side_menu.set_menu_settings(item)
|
||||
aux_list=[]
|
||||
for canal in list_canales[item.extra]:
|
||||
if len(aux_list)<2:
|
||||
aux_list.append(canal)
|
||||
list_canales[item.extra]=aux_list
|
||||
if config.is_xbmc():
|
||||
from channels import side_menu
|
||||
if mode=='silent' and any_active and len(list_canales[item.extra]) > 0:
|
||||
side_menu.set_menu_settings(item)
|
||||
aux_list=[]
|
||||
for canal in list_canales[item.extra]:
|
||||
if len(aux_list)<2:
|
||||
aux_list.append(canal)
|
||||
list_canales[item.extra]=aux_list
|
||||
|
||||
if mode == 'set_cache':
|
||||
list_canales[item.extra] = list_canales[item.extra][2:]
|
||||
|
||||
65
plugin.video.alfa/channels/playview.json
Normal file
65
plugin.video.alfa/channels/playview.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"id": "playview",
|
||||
"name": "Playview",
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"language": [
|
||||
"lat", "cast"
|
||||
],
|
||||
"thumbnail": "https://s15.postimg.cc/pkcz7kda3/playview.png",
|
||||
"banner": "",
|
||||
"version": 1,
|
||||
"categories": [
|
||||
"movie",
|
||||
"tvshow",
|
||||
"anime"
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"id": "include_in_global_search",
|
||||
"type": "bool",
|
||||
"label": "Incluir en busqueda global",
|
||||
"default": false,
|
||||
"enabled": false,
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"id": "filter_languages",
|
||||
"type": "list",
|
||||
"label": "Mostrar enlaces en idioma...",
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"lvalues": [
|
||||
"No filtrar",
|
||||
"Cast",
|
||||
"Lat",
|
||||
"VOSE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_peliculas",
|
||||
"type": "bool",
|
||||
"label": "Incluir en Novedades - Peliculas",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_infantiles",
|
||||
"type": "bool",
|
||||
"label": "Incluir en Novedades - Infantiles",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_terror",
|
||||
"type": "bool",
|
||||
"label": "Incluir en Novedades - terror",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
}
|
||||
]
|
||||
}
|
||||
317
plugin.video.alfa/channels/playview.py
Normal file
317
plugin.video.alfa/channels/playview.py
Normal file
@@ -0,0 +1,317 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- Channel Playview -*-
|
||||
# -*- Created for Alfa-addon -*-
|
||||
# -*- By the Alfa Develop Group -*-
|
||||
|
||||
import re
|
||||
import urllib
|
||||
from channels import autoplay
|
||||
from channels import filtertools
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from core import servertools
|
||||
from core import tmdb
|
||||
from core.item import Item
|
||||
from platformcode import config, logger
|
||||
from channelselector import get_thumb
|
||||
|
||||
|
||||
IDIOMAS = {'Latino':'Lat', 'Español':'Cast', 'Subtitulado':'VOSE'}
|
||||
list_language = IDIOMAS.values()
|
||||
list_quality = ['HD 1080p', 'HD 720p', 'DVDRIP', 'CAM']
|
||||
list_servers = ['openload', 'vidoza', 'clipwatching', 'fastplay', 'flashx', 'gamovideo', 'powvideo', 'streamango',
|
||||
'streamcherry', 'rapidvideo']
|
||||
|
||||
host = 'https://playview.io/'
|
||||
|
||||
|
||||
def mainlist(item):
|
||||
logger.info()
|
||||
|
||||
autoplay.init(item.channel, list_servers, list_quality)
|
||||
|
||||
itemlist = []
|
||||
|
||||
itemlist.append(Item(channel=item.channel, title='Películas', action='submenu', type='movie',
|
||||
thumbnail=get_thumb('movies', auto=True)))
|
||||
itemlist.append(Item(channel=item.channel, title='Series', action='submenu', type='tvshow',
|
||||
thumbnail=get_thumb('tvshows', auto=True)))
|
||||
itemlist.append(Item(channel=item.channel, title='Anime', action='list_all', url=host+'anime-online',
|
||||
type='tvshow', first=0, thumbnail=get_thumb('anime', auto=True)))
|
||||
itemlist.append(Item(channel=item.channel, title='Buscar', action='search', url=host+'search/',
|
||||
thumbnail=get_thumb('search', auto=True)))
|
||||
|
||||
autoplay.show_option(item.channel, itemlist)
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def submenu(item):
|
||||
logger.info()
|
||||
|
||||
itemlist = []
|
||||
if item.type == 'movie':
|
||||
itemlist.append(
|
||||
Item(channel=item.channel, title='Todas', action='list_all', url=host + 'peliculas-online', type='movie',
|
||||
first=0, thumbnail=get_thumb('all', auto=True)))
|
||||
itemlist.append(
|
||||
Item(channel=item.channel, title='Generos', action='genres', thumbnail=get_thumb('genres', auto=True)))
|
||||
else:
|
||||
itemlist.append(
|
||||
Item(channel=item.channel, title='Todas', action='list_all', url=host + 'series-online', type='tvshow',
|
||||
first=0, thumbnail=get_thumb('all', auto=True)))
|
||||
itemlist.append(
|
||||
Item(channel=item.channel, title='Series Animadas', action='list_all', url=host + 'series-animadas-online',
|
||||
type='tvshow', first=0, thumbnail=get_thumb('animacion', auto=True)))
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def get_source(url):
|
||||
logger.info()
|
||||
data = httptools.downloadpage(url).data
|
||||
data = re.sub(r'"|\n|\r|\t| |<br>|\s{2,}', "", data)
|
||||
return data
|
||||
|
||||
def genres(item):
|
||||
logger.info()
|
||||
|
||||
itemlist = []
|
||||
|
||||
data = get_source(host)
|
||||
patron = '<li value=(\d+)><a href=(.*?)>(.*?)</a></li>'
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
|
||||
for value, url, title in matches:
|
||||
if value not in ['1', '4', '22', '23', '24']:
|
||||
if value == '20':
|
||||
title = 'Familiar'
|
||||
itemlist.append(Item(channel=item.channel, title=title, action='list_all', url=url, type='Movie', first=0))
|
||||
|
||||
|
||||
return sorted(itemlist, key=lambda i: i.title)
|
||||
|
||||
def list_all(item):
|
||||
logger.info()
|
||||
|
||||
itemlist = []
|
||||
next = False
|
||||
|
||||
data = get_source(item.url)
|
||||
patron = 'spotlight_container>.*?image lazy data-original=(.*?)>.*?<div class=spotlight_title>(.*?)<'
|
||||
patron += '(.*?) sres>(\d{4})<.*?playLink href=(.*?)>'
|
||||
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
|
||||
first = item.first
|
||||
last = first+19
|
||||
if last > len(matches):
|
||||
last = len(matches)
|
||||
next = True
|
||||
|
||||
for scrapedthumbnail, scrapedtitle, type_data, year, scrapedurl in matches[first:last]:
|
||||
|
||||
url = scrapedurl
|
||||
title = scrapedtitle
|
||||
season = scrapertools.find_single_match(type_data, 'class=title-season>Temporada<.*?> (\d+) <')
|
||||
episode = scrapertools.find_single_match(type_data, 'class=title-season>Episodio<.*?> (\d+) <')
|
||||
if season != '' or episode != '':
|
||||
item.type = 'tvshow'
|
||||
else:
|
||||
item.type = 'movie'
|
||||
|
||||
new_item = Item(channel=item.channel, title=title, url=url, thumbnail=scrapedthumbnail, type=item.type,
|
||||
infoLabels={'year': year})
|
||||
|
||||
if item.type == 'tvshow':
|
||||
new_item.action = 'episodios'
|
||||
new_item.contentSerieName = scrapedtitle
|
||||
season = season.strip()
|
||||
episode = episode.strip()
|
||||
if season == '':
|
||||
if 'Anime' in item.title:
|
||||
season = 1
|
||||
else:
|
||||
season = scrapertools.find_single_match(url, '.*?temp-(\d+)')
|
||||
new_item.contentSeasonNumber = season
|
||||
else:
|
||||
new_item.contentSeasonNumber = season
|
||||
|
||||
if episode != '':
|
||||
new_item.contentEpisodeNumber = episode
|
||||
|
||||
if season != '' and episode != '':
|
||||
new_item.title = '%s %sx%s' % (new_item.title, season, episode)
|
||||
elif episode == '':
|
||||
new_item.title = '%s Temporada %s' % (new_item.title, season)
|
||||
else:
|
||||
new_item.action = 'findvideos'
|
||||
new_item.contentTitle = scrapedtitle
|
||||
itemlist.append(new_item)
|
||||
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
# Paginación
|
||||
|
||||
if not next:
|
||||
url_next_page = item.url
|
||||
first = last
|
||||
else:
|
||||
url_next_page = scrapertools.find_single_match(data, "<a href=([^ ]+) class=page-link aria-label=Next>")
|
||||
first = 0
|
||||
|
||||
if url_next_page:
|
||||
itemlist.append(item.clone(title="Siguiente >>", url=url_next_page, action='list_all', first=first))
|
||||
return itemlist
|
||||
|
||||
|
||||
def get_data(post):
|
||||
logger.info()
|
||||
|
||||
post = urllib.urlencode(post)
|
||||
data = httptools.downloadpage(host + 'playview', post=post).data
|
||||
|
||||
return data
|
||||
|
||||
def episodios(item):
|
||||
logger.info()
|
||||
|
||||
itemlist = []
|
||||
data = get_source(item.url)
|
||||
try:
|
||||
id, type = scrapertools.find_single_match(data, 'data-id=(\d+) data-type=(.*?) ')
|
||||
post = {'set': 'LoadOptionsEpisode', 'action': 'EpisodeList', 'id': id, 'type': '1'}
|
||||
data = get_data(post)
|
||||
patron = 'data-episode="(\d+)".*?title="(.*?)"'
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
infoLabels = item.infoLabels
|
||||
for episode, title in matches:
|
||||
post = {'set': 'LoadOptionsEpisode', 'action': 'Step1', 'id': id, 'type': '1',
|
||||
'episode': episode}
|
||||
season = scrapertools.find_single_match(item.url, '.*?temp-(\d+)')
|
||||
if season == '':
|
||||
season = 1
|
||||
infoLabels['season'] = season
|
||||
infoLabels['episode'] = episode
|
||||
if title[0].isdigit():
|
||||
title = '%sx%s' % (season, title)
|
||||
else:
|
||||
title = '%sx%s - %s' % (season, episode, title)
|
||||
itemlist.append(Item(channel=item.channel, title=title, contentSeasonNumber=season,
|
||||
contentEpisodeNumber=episode, action='findvideos', post=post, type=item.type,
|
||||
infoLabels=infoLabels))
|
||||
|
||||
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
|
||||
|
||||
if config.get_videolibrary_support() and len(itemlist) > 0:
|
||||
itemlist.append(
|
||||
Item(channel=item.channel, title='[COLOR yellow]Añadir esta serie a la videoteca[/COLOR]', url=item.url,
|
||||
action="add_serie_to_library", extra="episodios", contentSerieName=item.contentSerieName, ))
|
||||
except:
|
||||
pass
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
set_mode = 'LoadOptions'
|
||||
episode = ''
|
||||
if item.type == 'tvshow':
|
||||
post = item.post
|
||||
id= post['id']
|
||||
episode = post['episode']
|
||||
type = post['type']
|
||||
set_mode = 'LoadOptionsEpisode'
|
||||
|
||||
else:
|
||||
data=get_source(item.url)
|
||||
try:
|
||||
id, type = scrapertools.find_single_match(data, 'data-id=(\d+) data-type=(.*?) ')
|
||||
post = {'set': set_mode, 'action': 'Step1', 'id': id, 'type': type}
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
data = get_data(post)
|
||||
patron = 'data-quality="(.*?)"'
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
|
||||
for quality in matches:
|
||||
post = {'set': set_mode, 'action': 'Step2', 'id': id, 'type': type, 'quality': quality, 'episode':episode}
|
||||
data = get_data(post)
|
||||
patron = 'getplayer" data-id="(\d+)"> <h4>(.*?)</h4>.*?title="(.*?)"'
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
|
||||
for video_id, language, server in matches:
|
||||
post = {'set': set_mode, 'action': 'Step3', 'id': video_id, 'type': type}
|
||||
data = get_data(post)
|
||||
url = scrapertools.find_single_match(data, '<iframe class="embed.*?src="(.*?)"')
|
||||
if 'clipwatching' in url:
|
||||
url = url.replace('https://clipwatching.com/embed-', '')
|
||||
title = '%s [%s] [%s]'
|
||||
quality = quality.replace('(','').replace(')', '')
|
||||
if url != '':
|
||||
itemlist.append(Item(channel=item.channel, title=title, language=IDIOMAS[language], url=url,
|
||||
action='play', quality=quality, infoLabels=item.infoLabels))
|
||||
itemlist = servertools.get_servers_itemlist(itemlist, lambda i: i.title % (i.server.capitalize(), i.quality,
|
||||
i.language))
|
||||
|
||||
itemlist=sorted(itemlist, key=lambda i: i.language)
|
||||
|
||||
# Requerido para FilterTools
|
||||
|
||||
itemlist = filtertools.get_links(itemlist, item, list_language)
|
||||
|
||||
# Requerido para AutoPlay
|
||||
|
||||
autoplay.start(itemlist, item)
|
||||
|
||||
if config.get_videolibrary_support() and len(itemlist) > 0 and item.extra != 'findvideos' and type == 'Movie':
|
||||
itemlist.append(
|
||||
Item(channel=item.channel, title='[COLOR yellow]Añadir esta pelicula a la videoteca[/COLOR]',
|
||||
url=item.url, action="add_pelicula_to_library", extra="findvideos",
|
||||
contentTitle=item.contentTitle))
|
||||
return itemlist
|
||||
except:
|
||||
return itemlist
|
||||
|
||||
def search(item, texto):
|
||||
logger.info()
|
||||
texto = texto.replace(" ", "+")
|
||||
item.url = item.url + texto
|
||||
item.first = 0
|
||||
|
||||
if texto != '':
|
||||
return list_all(item)
|
||||
|
||||
def newest(categoria):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
item = Item()
|
||||
item.type = 'movie'
|
||||
item.first = 0
|
||||
try:
|
||||
if categoria == 'peliculas':
|
||||
item.url = host + 'peliculas-online'
|
||||
elif categoria == 'infantiles':
|
||||
item.url = host + 'peliculas-online/animacion'
|
||||
elif categoria == 'terror':
|
||||
item.url = host + 'peliculas-online/terror'
|
||||
|
||||
itemlist = list_all(item)
|
||||
if itemlist[-1].title == 'Siguiente >>':
|
||||
itemlist.pop()
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("{0}".format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -490,7 +490,7 @@ def episodios(item):
|
||||
# Sin valoración:
|
||||
# show = re.sub(r"\s\(\d+\.\d+\)", "", item.show)
|
||||
itemlist.append(
|
||||
Item(channel='plusdede', title="Añadir esta serie a la biblioteca de XBMC", url=item.url, token=token,
|
||||
Item(channel='plusdede', title="Añadir esta serie a la videoteca", url=item.url, token=token,
|
||||
action="add_serie_to_library", extra="episodios###", show=show))
|
||||
itemlist.append(
|
||||
Item(channel='plusdede', title="Descargar todos los episodios de la serie", url=item.url, token=token,
|
||||
|
||||
@@ -5,6 +5,7 @@ import sys
|
||||
import urllib
|
||||
import urlparse
|
||||
import datetime
|
||||
import ast
|
||||
|
||||
from channelselector import get_thumb
|
||||
from core import httptools
|
||||
@@ -17,15 +18,34 @@ from lib import generictools
|
||||
|
||||
host = 'http://torrentlocura.com/'
|
||||
|
||||
#Código para permitir usar un único canal para todas las webs clones de NewPct1
|
||||
clone_list = config.get_setting('clonenewpct1_channels_list', "torrentrapid") #Carga lista de clones
|
||||
clone_list = ast.literal_eval(clone_list) #la convierte a lista de tuplas
|
||||
host_index = 0
|
||||
host_index = config.get_setting('clonenewpct1_channel_default', "torrentrapid") #Clone por defecto
|
||||
i = 0
|
||||
for active_clone, channel_clone, host_clone, contentType_clone, info_clone in clone_list:
|
||||
if i == host_index:
|
||||
#channel_clone_name = channel_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
|
||||
#host = 'http://%s/' % host_clone #ACTIVAR CUANDO SE PASE A NEWPCT1
|
||||
i += 1
|
||||
|
||||
#Carga de opciones del canal
|
||||
item = Item()
|
||||
if not item.channel:
|
||||
item.channel = scrapertools.find_single_match(host, r'(\w+)\.com\/')
|
||||
channel_clone_name = scrapertools.find_single_match(host, r'(\w+)\.com\/') #QUITAR CUANDO SE PASE A NEWPCT1
|
||||
__modo_grafico__ = config.get_setting('modo_grafico', item.channel)
|
||||
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', item.channel)
|
||||
|
||||
|
||||
def mainlist(item):
|
||||
logger.info()
|
||||
|
||||
#Renombramos el canal al nombre de clone elegido
|
||||
item.channel = channel_clone_name
|
||||
if item.category: item.category = channel_clone_name.capitalize()
|
||||
|
||||
itemlist = []
|
||||
|
||||
thumb_pelis = get_thumb("channels_movie.png")
|
||||
@@ -64,20 +84,40 @@ def settingCanal(item):
|
||||
def submenu(item):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
|
||||
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
|
||||
except:
|
||||
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
|
||||
return itemlist #Algo no funciona, pintamos lo que tenemos
|
||||
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
|
||||
data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
|
||||
|
||||
pass
|
||||
|
||||
host_alt = host
|
||||
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
|
||||
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
|
||||
if "pelisyseries.com" in host and item.extra == "varios": #compatibilidad con mispelisy.series.com
|
||||
data = '<a href="' + host + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
|
||||
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
|
||||
if not data or not scrapertools.find_single_match(data, patron):
|
||||
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url)
|
||||
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
|
||||
item, data = generictools.fail_over_newpct1(item, patron)
|
||||
|
||||
if not data: #Si no ha logrado encontrar nada, salimos
|
||||
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
|
||||
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
|
||||
elif item.channel_alt: #Si ha habido fail-over, lo comento
|
||||
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR] [ALT ] en uso'))
|
||||
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] caído'))
|
||||
|
||||
host_alt = host.replace(item.channel_alt, item.channel)
|
||||
del item.channel_alt
|
||||
if item.url_alt: del item.url_alt
|
||||
|
||||
#data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
|
||||
#data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com
|
||||
|
||||
host_dom = host_alt.replace("https://", "").replace("http://", "").replace("www.", "")
|
||||
patron = '<li><a href="http://(?:www.)?' + host_dom + item.extra + '/">.*?<ul.*?>(.*?)</ul>'
|
||||
if "pelisyseries.com" in host_alt and item.extra == "varios": #compatibilidad con mispelisy.series.com
|
||||
data = '<a href="' + host_alt + 'varios/" title="Documentales"><i class="icon-rocket"></i> Documentales</a>'
|
||||
else:
|
||||
if data:
|
||||
data = scrapertools.get_match(data, patron)
|
||||
@@ -104,10 +144,10 @@ def submenu(item):
|
||||
Item(channel=item.channel, action="alfabeto", title=title + " [A-Z]", url=url, extra=item.extra))
|
||||
|
||||
if item.extra == "peliculas":
|
||||
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
|
||||
itemlist.append(Item(channel=item.channel, action="listado", title="Películas 4K", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
|
||||
itemlist.append(
|
||||
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host + "peliculas-hd/4kultrahd/", extra=item.extra))
|
||||
|
||||
Item(channel=item.channel, action="alfabeto", title="Películas 4K" + " [A-Z]", url=host_alt + "peliculas-hd/4kultrahd/", extra=item.extra))
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
@@ -203,7 +243,8 @@ def listado(item):
|
||||
#logger.debug("patron: " + patron + " / fichas: " + fichas)
|
||||
|
||||
# Identifico la página actual y el total de páginas para el pie de página
|
||||
total_pag = scrapertools.find_single_match(data,'<a href=".*?(\d+)?">Last<\/a><\/li>')
|
||||
patron_last_page = '<a href="[^"]+(\d+)">Last<\/a><\/li>'
|
||||
total_pag = scrapertools.find_single_match(data, patron_last_page)
|
||||
|
||||
if not item.post_num:
|
||||
post_num = 1
|
||||
@@ -419,6 +460,9 @@ def listado(item):
|
||||
|
||||
def listado_busqueda(item):
|
||||
logger.info()
|
||||
|
||||
host = 'http://%s/' % scrapertools.find_single_match(item.url, '(\w+\.com)\/')
|
||||
|
||||
itemlist = []
|
||||
cnt_tot = 40 # Poner el num. máximo de items por página. Dejamos que la web lo controle
|
||||
cnt_title = 0 # Contador de líneas insertadas en Itemlist
|
||||
@@ -449,17 +493,24 @@ def listado_busqueda(item):
|
||||
#Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento
|
||||
while cnt_title <= cnt_tot and cnt_next < 5:
|
||||
|
||||
pattern = '<ul class="%s">(.*?)</ul>' % item.pattern #seleccionamos el bloque que nos interesa
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post).data)
|
||||
except:
|
||||
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
|
||||
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
|
||||
cnt_next += 1
|
||||
if not data: #Si la web está caída salimos sin dar error
|
||||
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data)
|
||||
pass
|
||||
|
||||
cnt_next += 1
|
||||
if not data or not scrapertools.find_single_match(data, pattern):
|
||||
logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data)
|
||||
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el submenú
|
||||
item, data = generictools.fail_over_newpct1(item, pattern)
|
||||
|
||||
if not data: #Si no ha logrado encontrar nada, salimos
|
||||
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'))
|
||||
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
|
||||
elif item.channel_alt: #Si ha habido fail-over, lo comento
|
||||
host = host.replace(item.channel_alt, item.channel)
|
||||
|
||||
#Obtiene la dirección de la próxima página, si la hay
|
||||
try:
|
||||
@@ -824,6 +875,11 @@ def listado_busqueda(item):
|
||||
def findvideos(item):
|
||||
from core import channeltools
|
||||
logger.info()
|
||||
|
||||
#Renombramos el canal al nombre de clone elegido
|
||||
item.channel = channel_clone_name
|
||||
if item.category: item.category = channel_clone_name.capitalize()
|
||||
|
||||
itemlist = []
|
||||
|
||||
# Cualquiera de las tres opciones son válidas
|
||||
@@ -934,9 +990,20 @@ def findvideos(item):
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data)
|
||||
except:
|
||||
pass
|
||||
|
||||
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
|
||||
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
|
||||
if not data or not scrapertools.find_single_match(data, patron):
|
||||
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url + " / DATA: " + data)
|
||||
|
||||
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
|
||||
item, data = generictools.fail_over_newpct1(item, patron)
|
||||
if not data: #Si no ha logrado encontrar nada, salimos
|
||||
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
|
||||
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
|
||||
|
||||
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
|
||||
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
|
||||
|
||||
@@ -948,6 +1015,8 @@ def findvideos(item):
|
||||
else:
|
||||
item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía
|
||||
item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título
|
||||
if size:
|
||||
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
|
||||
item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía
|
||||
|
||||
#Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
|
||||
@@ -957,7 +1026,6 @@ def findvideos(item):
|
||||
item_local = item.clone()
|
||||
|
||||
# obtenemos la url torrent
|
||||
patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";'
|
||||
item_local.url = scrapertools.find_single_match(data, patron)
|
||||
if not item_local.url: #error
|
||||
logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
|
||||
@@ -969,17 +1037,17 @@ def findvideos(item):
|
||||
|
||||
#Ahora pintamos el link del Torrent, si lo hay
|
||||
if item_local.url: # Hay Torrent ?
|
||||
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent
|
||||
if size:
|
||||
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
|
||||
else:
|
||||
quality = item_local.quality
|
||||
item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent
|
||||
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías
|
||||
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos
|
||||
item_local.alive = "??" #Calidad del link sin verificar
|
||||
item_local.action = "play" #Visualizar vídeo
|
||||
item_local.server = "torrent" #Servidor
|
||||
if size:
|
||||
quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final del título
|
||||
else:
|
||||
quality = item_local.quality
|
||||
|
||||
|
||||
itemlist.append(item_local.clone(quality=quality)) #Pintar pantalla
|
||||
|
||||
logger.debug("TORRENT: " + item_local.url + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
|
||||
@@ -1163,9 +1231,20 @@ def findvideos(item):
|
||||
|
||||
def episodios(item):
|
||||
logger.info()
|
||||
|
||||
#Renombramos el canal al nombre de clone elegido
|
||||
item.channel = channel_clone_name
|
||||
if item.category: item.category = channel_clone_name.capitalize()
|
||||
|
||||
itemlist = []
|
||||
|
||||
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
|
||||
if not item.infoLabels['tmdb_id']:
|
||||
tmdb.set_infoLabels(item, True)
|
||||
|
||||
max_temp = 1
|
||||
if item.infoLabels['number_of_seasons']:
|
||||
max_temp = item.infoLabels['number_of_seasons']
|
||||
y = []
|
||||
if modo_ultima_temp and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
|
||||
patron = 'season (\d+)'
|
||||
@@ -1173,16 +1252,30 @@ def episodios(item):
|
||||
for x in matches:
|
||||
y += [int(x)]
|
||||
max_temp = max(y)
|
||||
|
||||
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
|
||||
if not item.infoLabels['tmdb_id']:
|
||||
tmdb.set_infoLabels(item, True)
|
||||
|
||||
|
||||
data = ''
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url).data)
|
||||
except: #Algún error de proceso, salimos
|
||||
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url)
|
||||
patron = '<ul class="%s">(.*?)</ul>' % "buscar-list" # item.pattern
|
||||
data_alt = ''
|
||||
if data: data_alt = scrapertools.get_match(data, patron)
|
||||
except: #Algún error de proceso
|
||||
pass
|
||||
|
||||
if "pelisyseries.com" in item.url:
|
||||
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
|
||||
else:
|
||||
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
|
||||
|
||||
#Verificamos si se ha cargado una página, y si además tiene la estructura correcta
|
||||
if not data_alt or not scrapertools.find_single_match(data_alt, pattern):
|
||||
logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url)
|
||||
|
||||
#Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el vídeo
|
||||
item, data = generictools.fail_over_newpct1(item, patron, pattern)
|
||||
|
||||
if not data: #No se ha encontrado ningún canal activo para este vídeo
|
||||
itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel.capitalize() + '[/COLOR]: Ningún canal NewPct1 activo'))
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'))
|
||||
return itemlist
|
||||
|
||||
@@ -1209,7 +1302,8 @@ def episodios(item):
|
||||
list_pages = [item.url]
|
||||
|
||||
season = max_temp
|
||||
if item.library_playcounts or item.tmdb_stat: #Comprobamos si realmente sabemos el num. máximo de temporadas
|
||||
#Comprobamos si realmente sabemos el num. máximo de temporadas
|
||||
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
|
||||
num_temporadas_flag = True
|
||||
else:
|
||||
num_temporadas_flag = False
|
||||
@@ -1226,11 +1320,11 @@ def episodios(item):
|
||||
if not data:
|
||||
raise
|
||||
except:
|
||||
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + data)
|
||||
logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / " + str(list_pages) + " / DATA: " + str(data))
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log'))
|
||||
return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
|
||||
|
||||
if "pelisyseries.com" in host:
|
||||
if "pelisyseries.com" in item.url:
|
||||
pattern = '<li[^>]*><div class.*?src="(?P<thumb>[^"]+)?".*?<a class.*?href="(?P<url>[^"]+).*?<h3[^>]+>(?P<info>.*?)?<\/h3>.*?<\/li>'
|
||||
else:
|
||||
pattern = '<li[^>]*><a href="(?P<url>[^"]+).*?<img.*?src="(?P<thumb>[^"]+)?".*?<h2[^>]+>(?P<info>.*?)?<\/h2>'
|
||||
@@ -1245,7 +1339,7 @@ def episodios(item):
|
||||
|
||||
#Empezamos a generar cada episodio
|
||||
for url, thumb, info in matches:
|
||||
if "pelisyseries.com" in host: #En esta web están en diferente orden
|
||||
if "pelisyseries.com" in item.url: #En esta web están en diferente orden
|
||||
interm = url
|
||||
url = thumb
|
||||
thumb = interm
|
||||
@@ -1273,6 +1367,10 @@ def episodios(item):
|
||||
|
||||
if scrapertools.find_single_match(info, '\[\d{3}\]'):
|
||||
info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info)
|
||||
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'):
|
||||
pattern = 'Temp.*?(?P<season>\d+).*?[c|C]ap.*?\.(?P<episode>\d+)?.*?(?:(?P<episode2>\d+))\]?\[(?P<lang>\w+)?(?P<quality>\w+)\]?'
|
||||
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'):
|
||||
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?(?P<episode>\d{2})?(?:.*?(?P<episode2>\d{2}))?.*?(?P<lang>\[\w+.*)\[.*?\]?'
|
||||
elif scrapertools.find_single_match(info, 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'):
|
||||
pattern = 'Temp.*?(?P<season>\d+).*?\[(?P<quality>.*?)\].*?Cap\w?\.\s\d?(?P<episode>\d{2})(?:.*?(?P<episode2>\d{2}))?.*?\[(?P<lang>\w+)\]?'
|
||||
elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'):
|
||||
@@ -1312,11 +1410,9 @@ def episodios(item):
|
||||
except:
|
||||
logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches))
|
||||
|
||||
#logger.error("TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / " + str(match['episode2']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
|
||||
if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1:
|
||||
#Si el num de temporada está fuera de control, se trata pone en num. de temporada actual
|
||||
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
|
||||
#logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern)
|
||||
logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches))
|
||||
match['season'] = season
|
||||
item_local.contentSeason = season
|
||||
else:
|
||||
@@ -1331,11 +1427,11 @@ def episodios(item):
|
||||
item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie
|
||||
item_local.quality = item_local.quality.replace("ALTA DEFINICION", "HDTV")
|
||||
|
||||
if match['lang'] and estado == False:
|
||||
match['lang'] = match['lang'].replace("- ", "")
|
||||
if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()):
|
||||
match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "")
|
||||
item_local.infoLabels['episodio_titulo'] = match['lang']
|
||||
item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo']
|
||||
|
||||
|
||||
item_local.contentEpisodeNumber = match['episode']
|
||||
|
||||
if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca
|
||||
@@ -1381,6 +1477,8 @@ def episodios(item):
|
||||
|
||||
# Pasada por TMDB y clasificación de lista por temporada y episodio
|
||||
tmdb.set_infoLabels(itemlist, True)
|
||||
|
||||
#logger.debug(item)
|
||||
|
||||
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
|
||||
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
|
||||
@@ -1395,7 +1493,7 @@ def actualizar_titulos(item):
|
||||
from platformcode import launcher
|
||||
|
||||
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
|
||||
|
||||
|
||||
#Volvemos a la siguiente acción en el canal
|
||||
return launcher.run(item)
|
||||
|
||||
@@ -1403,6 +1501,9 @@ def actualizar_titulos(item):
|
||||
def search(item, texto):
|
||||
logger.info("search:" + texto)
|
||||
# texto = texto.replace(" ", "+")
|
||||
|
||||
item.channel = channel_clone_name
|
||||
if item.category: item.category = channel_clone_name.capitalize()
|
||||
|
||||
try:
|
||||
item.post = "q=%s" % texto
|
||||
|
||||
@@ -33,6 +33,30 @@
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "clonenewpct1_channel_default",
|
||||
"type": "list",
|
||||
"label": "Clone de NewPct1 por defecto",
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"lvalues": [
|
||||
"Torrentrapid",
|
||||
"Torrentlocura",
|
||||
"Tumejortorrent",
|
||||
"Tvsinpagar",
|
||||
"Descargas2020",
|
||||
"Mispelisyseries"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "clonenewpct1_channels_list",
|
||||
"type": "text",
|
||||
"label": "Lista de clones de NewPct1 y orden de uso",
|
||||
"default": "('1', 'torrentrapid', 'torrentrapid.com', 'movie, tvshow, season, episode', ''), ('1', 'torrentlocura', 'torrentlocura.com', 'movie, tvshow, season, episode', ''), ('1', 'tumejortorrent', 'tumejortorrent.com', 'movie, tvshow, season, episode', ''), ('1', 'tvsinpagar', 'www.tvsinpagar.com', 'tvshow, season, episode', ''), ('1', 'descargas2020', 'descargas2020.com', 'movie, tvshow, season, episode', ''), ('1', 'mispelisyseries', 'mispelisyseries.com', 'movie, tvshow, season, episode', '')",
|
||||
"enabled": true,
|
||||
"visible": false
|
||||
},
|
||||
{
|
||||
"id": "seleccionar_ult_temporadda_activa",
|
||||
"type": "bool",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -494,9 +494,62 @@ def update_tvshow(item):
|
||||
p_dialog.close()
|
||||
|
||||
|
||||
def mark_content_as_watched2(item):
|
||||
logger.info()
|
||||
# logger.debug("item:\n" + item.tostring('\n'))
|
||||
|
||||
if filetools.exists(item.nfo):
|
||||
head_nfo, it = videolibrarytools.read_nfo(item.nfo)
|
||||
#logger.debug(it)
|
||||
|
||||
if item.contentType == 'movie':
|
||||
name_file = os.path.splitext(os.path.basename(item.nfo))[0]
|
||||
|
||||
if name_file != 'tvshow' :
|
||||
it.library_playcounts.update({name_file: item.playcount})
|
||||
|
||||
if item.contentType == 'episode' or item.contentType == 'list' or name_file == 'tvshow':
|
||||
# elif item.contentType == 'episode':
|
||||
name_file = os.path.splitext(os.path.basename(item.strm_path))[0]
|
||||
num_season = name_file [0]
|
||||
item.__setattr__('contentType', 'episode')
|
||||
item.__setattr__('contentSeason', num_season)
|
||||
#logger.debug(name_file)
|
||||
|
||||
else:
|
||||
name_file = item.contentTitle
|
||||
# logger.debug(name_file)
|
||||
|
||||
if not hasattr(it, 'library_playcounts'):
|
||||
it.library_playcounts = {}
|
||||
it.library_playcounts.update({name_file: item.playcount})
|
||||
|
||||
# se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada
|
||||
if item.contentType != 'movie':
|
||||
it = check_season_playcount(it, item.contentSeason)
|
||||
#logger.debug(it)
|
||||
|
||||
# Guardamos los cambios en item.nfo
|
||||
if filetools.write(item.nfo, head_nfo + it.tojson()):
|
||||
item.infoLabels['playcount'] = item.playcount
|
||||
logger.debug(item.playcount)
|
||||
|
||||
# if item.contentType == 'episodesss':
|
||||
# Actualizar toda la serie
|
||||
#new_item = item.clone(contentSeason=-1)
|
||||
#mark_season_as_watched(new_item)
|
||||
|
||||
if config.is_xbmc():
|
||||
from platformcode import xbmc_videolibrary
|
||||
xbmc_videolibrary.mark_content_as_watched_on_kodi(item , item.playcount)
|
||||
# logger.debug(item)
|
||||
|
||||
platformtools.itemlist_refresh()
|
||||
|
||||
|
||||
def mark_content_as_watched(item):
|
||||
logger.info()
|
||||
# logger.debug("item:\n" + item.tostring('\n'))
|
||||
logger.debug("item:\n" + item.tostring('\n'))
|
||||
|
||||
if filetools.exists(item.nfo):
|
||||
head_nfo, it = videolibrarytools.read_nfo(item.nfo)
|
||||
@@ -520,10 +573,11 @@ def mark_content_as_watched(item):
|
||||
if filetools.write(item.nfo, head_nfo + it.tojson()):
|
||||
item.infoLabels['playcount'] = item.playcount
|
||||
|
||||
if item.contentType == 'tvshow':
|
||||
if item.contentType == 'tvshow' and item.type != 'episode' :
|
||||
# Actualizar toda la serie
|
||||
new_item = item.clone(contentSeason=-1)
|
||||
mark_season_as_watched(new_item)
|
||||
|
||||
if config.is_xbmc(): #and item.contentType == 'episode':
|
||||
from platformcode import xbmc_videolibrary
|
||||
xbmc_videolibrary.mark_content_as_watched_on_kodi(item, item.playcount)
|
||||
@@ -555,7 +609,7 @@ def mark_season_as_watched(item):
|
||||
season, episode = season_episode.split("x")
|
||||
|
||||
if int(item.contentSeason) == -1 or int(season) == int(item.contentSeason):
|
||||
name_file = os.path.splitext(os.path.basename(f))[0]
|
||||
name_file = os.path.splitext(os.path.basename(i))[0]
|
||||
it.library_playcounts[name_file] = item.playcount
|
||||
episodios_marcados += 1
|
||||
|
||||
@@ -685,16 +739,19 @@ def check_season_playcount(item, season):
|
||||
|
||||
def check_tvshow_playcount(item, season):
|
||||
logger.info()
|
||||
# logger.debug(item)
|
||||
if season:
|
||||
temporadas_serie = 0
|
||||
temporadas_vistas_serie = 0
|
||||
for key, value in item.library_playcounts.iteritems():
|
||||
if key == ("season %s" % season):
|
||||
#if key.startswith("season %s" % season):
|
||||
if key.startswith("season" ):
|
||||
temporadas_serie += 1
|
||||
if value > 0:
|
||||
temporadas_vistas_serie += 1
|
||||
#logger.debug(temporadas_serie)
|
||||
|
||||
if temporadas_serie == temporadas_vistas_serie:
|
||||
if temporadas_serie == temporadas_vistas_serie:
|
||||
item.library_playcounts.update({item.title: 1})
|
||||
else:
|
||||
item.library_playcounts.update({item.title: 0})
|
||||
|
||||
@@ -22,28 +22,12 @@ def cachePage(url, post=None, headers=None, modoCache=None, timeout=None):
|
||||
def downloadpage(url, post=None, headers=None, follow_redirects=True, timeout=None, header_to_get=None):
|
||||
response = httptools.downloadpage(url, post=post, headers=headers, follow_redirects=follow_redirects,
|
||||
timeout=timeout)
|
||||
|
||||
if header_to_get:
|
||||
return response.headers.get(header_to_get)
|
||||
else:
|
||||
return response.data
|
||||
|
||||
|
||||
# def downloadpageWithResult(url, post=None, headers=None, follow_redirects=True, timeout=None, header_to_get=None):
|
||||
# response = httptools.downloadpage(url, post=post, headers=headers, follow_redirects=follow_redirects,
|
||||
# timeout=timeout)
|
||||
#
|
||||
# if header_to_get:
|
||||
# return response.headers.get(header_to_get)
|
||||
# else:
|
||||
# return response.data, response.code
|
||||
|
||||
|
||||
# def downloadpageWithoutCookies(url):
|
||||
# response = httptools.downloadpage(url, cookies=False)
|
||||
# return response.data
|
||||
|
||||
|
||||
def downloadpageGzip(url):
|
||||
response = httptools.downloadpage(url, add_referer=True)
|
||||
return response.data
|
||||
@@ -60,23 +44,12 @@ def get_header_from_response(url, header_to_get="", post=None, headers=None):
|
||||
return response.headers.get(header_to_get)
|
||||
|
||||
|
||||
# def get_headers_from_response(url, post=None, headers=None):
|
||||
# response = httptools.downloadpage(url, post=post, headers=headers, only_headers=True)
|
||||
# return response.headers.items()
|
||||
|
||||
|
||||
def read_body_and_headers(url, post=None, headers=None, follow_redirects=False, timeout=None):
|
||||
response = httptools.downloadpage(url, post=post, headers=headers, follow_redirects=follow_redirects,
|
||||
timeout=timeout)
|
||||
return response.data, response.headers
|
||||
|
||||
|
||||
# def anti_cloudflare(url, host="", headers=None, post=None, location=False):
|
||||
# # anti_cloudfare ya integrado en httptools por defecto
|
||||
# response = httptools.downloadpage(url, post=post, headers=headers)
|
||||
# return response.data
|
||||
|
||||
|
||||
def printMatches(matches):
|
||||
i = 0
|
||||
for match in matches:
|
||||
@@ -130,17 +103,6 @@ def unescape(text):
|
||||
else:
|
||||
# named entity
|
||||
try:
|
||||
'''
|
||||
if text[1:-1] == "amp":
|
||||
text = "&amp;"
|
||||
elif text[1:-1] == "gt":
|
||||
text = "&gt;"
|
||||
elif text[1:-1] == "lt":
|
||||
text = "&lt;"
|
||||
else:
|
||||
print text[1:-1]
|
||||
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]]).encode("utf-8")
|
||||
'''
|
||||
import htmlentitydefs
|
||||
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]]).encode("utf-8")
|
||||
except KeyError:
|
||||
@@ -385,27 +347,6 @@ def remove_show_from_title(title, show):
|
||||
return title
|
||||
|
||||
|
||||
# def getRandom(str):
|
||||
# return get_md5(str)
|
||||
|
||||
|
||||
# def unseo(cadena):
|
||||
# if cadena.upper().startswith("VER GRATIS LA PELICULA "):
|
||||
# cadena = cadena[23:]
|
||||
# elif cadena.upper().startswith("VER GRATIS PELICULA "):
|
||||
# cadena = cadena[20:]
|
||||
# elif cadena.upper().startswith("VER ONLINE LA PELICULA "):
|
||||
# cadena = cadena[23:]
|
||||
# elif cadena.upper().startswith("VER GRATIS "):
|
||||
# cadena = cadena[11:]
|
||||
# elif cadena.upper().startswith("VER ONLINE "):
|
||||
# cadena = cadena[11:]
|
||||
# elif cadena.upper().startswith("DESCARGA DIRECTA "):
|
||||
# cadena = cadena[17:]
|
||||
# return cadena
|
||||
|
||||
|
||||
# scrapertools.get_filename_from_url(media_url)[-4:]
|
||||
def get_filename_from_url(url):
|
||||
import urlparse
|
||||
parsed_url = urlparse.urlparse(url)
|
||||
@@ -465,7 +406,10 @@ def get_season_and_episode(title):
|
||||
try:
|
||||
matches = re.compile(patron, re.I).search(title)
|
||||
if matches:
|
||||
filename = matches.group(1).lstrip('0') + "x" + matches.group(2).zfill(2)
|
||||
if len(matches.group(1)) == 1:
|
||||
filename = matches.group(1) + "x" + matches.group(2).zfill(2)
|
||||
else:
|
||||
filename = matches.group(1).lstrip('0') + "x" + matches.group(2).zfill(2)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
@@ -473,27 +417,3 @@ def get_season_and_episode(title):
|
||||
logger.info("'" + title + "' -> '" + filename + "'")
|
||||
|
||||
return filename
|
||||
|
||||
|
||||
# def get_sha1(cadena):
|
||||
# try:
|
||||
# import hashlib
|
||||
# devuelve = hashlib.sha1(cadena).hexdigest()
|
||||
# except:
|
||||
# import sha
|
||||
# import binascii
|
||||
# devuelve = binascii.hexlify(sha.new(cadena).digest())
|
||||
#
|
||||
# return devuelve
|
||||
|
||||
|
||||
# def get_md5(cadena):
|
||||
# try:
|
||||
# import hashlib
|
||||
# devuelve = hashlib.md5(cadena).hexdigest()
|
||||
# except:
|
||||
# import md5
|
||||
# import binascii
|
||||
# devuelve = binascii.hexlify(md5.new(cadena).digest())
|
||||
#
|
||||
# return devuelve
|
||||
|
||||
@@ -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)
|
||||
@@ -52,7 +52,7 @@ def mark_auto_as_watched(item):
|
||||
item.playcount = 1
|
||||
sync_with_trakt = True
|
||||
from channels import videolibrary
|
||||
videolibrary.mark_content_as_watched(item)
|
||||
videolibrary.mark_content_as_watched2(item)
|
||||
break
|
||||
|
||||
time.sleep(30)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from platformcode import logger
|
||||
from lib import jsunpack
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
@@ -16,8 +17,10 @@ def test_video_exists(page_url):
|
||||
def get_video_url(page_url, user="", password="", video_password=""):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
data = httptools.downloadpage(page_url).data
|
||||
packed = scrapertools.find_single_match(data, "text/javascript'>(.*?)\s*</script>")
|
||||
unpacked = jsunpack.unpack(packed)
|
||||
video_urls = []
|
||||
videos = scrapertools.find_multiple_matches(data, 'file:"([^"]+).*?label:"([^"]+)')
|
||||
videos = scrapertools.find_multiple_matches(unpacked, 'file:"([^"]+).*?label:"([^"]+)')
|
||||
for video, label in videos:
|
||||
video_urls.append([label + " [clipwatching]", video])
|
||||
logger.info("Url: %s" %videos)
|
||||
|
||||
42
plugin.video.alfa/servers/cloudvideo.json
Normal file
42
plugin.video.alfa/servers/cloudvideo.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"active": true,
|
||||
"find_videos": {
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "https://cloudvideo.tv/embed-([a-z0-9]+).html",
|
||||
"url": "https://cloudvideo.tv/embed-\\1.html"
|
||||
}
|
||||
]
|
||||
},
|
||||
"free": true,
|
||||
"id": "cloudvideo",
|
||||
"name": "cloudvideo",
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "black_list",
|
||||
"label": "Incluir en lista negra",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"id": "favorites_servers_list",
|
||||
"label": "Incluir en lista de favoritos",
|
||||
"lvalues": [
|
||||
"No",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5"
|
||||
],
|
||||
"type": "list",
|
||||
"visible": false
|
||||
}
|
||||
],
|
||||
"thumbnail": "https://cloudvideo.tv/static/img/logo5.png"
|
||||
}
|
||||
43
plugin.video.alfa/servers/cloudvideo.py
Normal file
43
plugin.video.alfa/servers/cloudvideo.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# Conector Cloudvideo By Alfa development Group
|
||||
# --------------------------------------------------------
|
||||
|
||||
import re
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from lib import jsunpack
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
|
||||
data = httptools.downloadpage(page_url)
|
||||
|
||||
if data.code == 404:
|
||||
return False, "[Cloud] El archivo no existe o ha sido borrado"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("url=" + page_url)
|
||||
|
||||
video_urls = []
|
||||
data = httptools.downloadpage(page_url).data
|
||||
data = re.sub(r'"|\n|\r|\t| |<br>|\s{2,}', "", data)
|
||||
enc_data = scrapertools.find_single_match(data, "type='text/javascript'>(.*?)</script>")
|
||||
dec_data = jsunpack.unpack(enc_data)
|
||||
sources = scrapertools.find_single_match(dec_data, "sources:\[(.*?)]")
|
||||
patron = "{file:(.*?)}"
|
||||
matches = re.compile(patron, re.DOTALL).findall(sources)
|
||||
scrapertools.printMatches(matches)
|
||||
for url in matches:
|
||||
quality = 'm3u8'
|
||||
video_url = url
|
||||
if 'label' in url:
|
||||
url = url.split(',')
|
||||
video_url = url[0]
|
||||
quality = url[1].replace('label:','')
|
||||
video_urls.append(['cloudvideo [%s]' % quality, video_url])
|
||||
|
||||
return video_urls
|
||||
42
plugin.video.alfa/servers/filevideo.json
Normal file
42
plugin.video.alfa/servers/filevideo.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"active": true,
|
||||
"find_videos": {
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "https://www.filevideo.net/embed-(?:embed-|)([A-z0-9]+)",
|
||||
"url": "http://filevideo.net/embed-\\1.html"
|
||||
}
|
||||
]
|
||||
},
|
||||
"free": true,
|
||||
"id": "filevideo",
|
||||
"name": "filevideo",
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "black_list",
|
||||
"label": "Incluir en lista negra",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"id": "favorites_servers_list",
|
||||
"label": "Incluir en lista de favoritos",
|
||||
"lvalues": [
|
||||
"No",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5"
|
||||
],
|
||||
"type": "list",
|
||||
"visible": false
|
||||
}
|
||||
],
|
||||
"thumbnail": "https://s15.postimg.cc/b7jj9dbbf/filevideo.png"
|
||||
}
|
||||
42
plugin.video.alfa/servers/filevideo.py
Normal file
42
plugin.video.alfa/servers/filevideo.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from lib import jsunpack
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
|
||||
data = httptools.downloadpage(page_url).data
|
||||
|
||||
if "Not Found" in data or "File was deleted" in data:
|
||||
return False, "[Filevideo] El fichero no existe o ha sido borrado"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("url=" + page_url)
|
||||
|
||||
data = httptools.downloadpage(page_url).data
|
||||
enc_data = scrapertools.find_single_match(data, "type='text/javascript'>(eval.*?)\s*</script>")
|
||||
dec_data = jsunpack.unpack(enc_data)
|
||||
|
||||
video_urls = []
|
||||
media_urls = scrapertools.find_multiple_matches(dec_data, '\{file\s*:\s*"([^"]+)",label\s*:\s*"([^"]+)"\}')
|
||||
for media_url, label in media_urls:
|
||||
ext = scrapertools.get_filename_from_url(media_url)[-4:]
|
||||
video_urls.append(["%s %sp [filevideo]" % (ext, label), media_url])
|
||||
|
||||
video_urls.reverse()
|
||||
m3u8 = scrapertools.find_single_match(dec_data, '\{file\:"(.*?.m3u8)"\}')
|
||||
if m3u8:
|
||||
title = video_urls[-1][0].split(" ", 1)[1]
|
||||
video_urls.insert(0, [".m3u8 %s" % title, m3u8])
|
||||
|
||||
for video_url in video_urls:
|
||||
logger.info("%s - %s" % (video_url[0], video_url[1]))
|
||||
|
||||
return video_urls
|
||||
@@ -12,6 +12,8 @@ def test_video_exists(page_url):
|
||||
except:
|
||||
pass
|
||||
|
||||
if response.code == 404:
|
||||
return False, "[Rapidvideo] El archivo no existe ó ha sido borrado"
|
||||
if not response.data or "urlopen error [Errno 1]" in str(response.code):
|
||||
from platformcode import config
|
||||
if config.is_xbmc():
|
||||
|
||||
42
plugin.video.alfa/servers/upvid.json
Normal file
42
plugin.video.alfa/servers/upvid.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"active": true,
|
||||
"find_videos": {
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "https://upvid.co/embed-([a-z0-9]+).html",
|
||||
"url": "https://upvid.co/embed-\\1.html"
|
||||
}
|
||||
]
|
||||
},
|
||||
"free": true,
|
||||
"id": "upvid",
|
||||
"name": "upvid",
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "black_list",
|
||||
"label": "Incluir en lista negra",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"id": "favorites_servers_list",
|
||||
"label": "Incluir en lista de favoritos",
|
||||
"lvalues": [
|
||||
"No",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5"
|
||||
],
|
||||
"type": "list",
|
||||
"visible": false
|
||||
}
|
||||
],
|
||||
"thumbnail": "https://s15.postimg.cc/gz0tee0gb/zt_Oi_E6_S-_400x400.jpg"
|
||||
}
|
||||
83
plugin.video.alfa/servers/upvid.py
Normal file
83
plugin.video.alfa/servers/upvid.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# --------------------------------------------------------
|
||||
# Conector UpVID By Alfa development Group
|
||||
# --------------------------------------------------------
|
||||
|
||||
import re
|
||||
import urllib
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from platformcode import logger
|
||||
|
||||
import sys, os
|
||||
import re, base64
|
||||
from lib.aadecode import decode as aadecode
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
|
||||
data = httptools.downloadpage(page_url)
|
||||
|
||||
if data.code == 404:
|
||||
return False, "[upvid] El archivo no existe o ha sido borrado"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
def get_video_url(page_url, premium = False, user = "", password = "", video_password = ""):
|
||||
logger.info("url=" + page_url)
|
||||
|
||||
video_urls = []
|
||||
headers = {'referer': page_url}
|
||||
|
||||
for i in range(0, 3):
|
||||
data = httptools.downloadpage(page_url, headers=headers).data
|
||||
data = re.sub(r'"|\n|\r|\t| |<br>|\s{2,}', "", data)
|
||||
if '<input type=hidden' in data:
|
||||
break
|
||||
else:
|
||||
page_url = scrapertools.find_single_match(data, "iframe src=(.*?) scrolling")
|
||||
|
||||
|
||||
# logger.debug(data)
|
||||
# decodificar función para obtener función y clave
|
||||
# ------------------------------------------------
|
||||
code = re.findall('<script>\s*゚ω゚(.*?)</script>', data, flags=re.DOTALL)[0]
|
||||
text_decode = aadecode(code)
|
||||
funcion, clave = re.findall("func\.innerHTML = (\w*)\('([^']*)', ", text_decode, flags=re.DOTALL)[0]
|
||||
|
||||
# decodificar javascript en campos html hidden
|
||||
# --------------------------------------------
|
||||
oculto = re.findall('<input type=hidden value=([^ ]+) id=func', data, flags=re.DOTALL)[0]
|
||||
funciones = resuelve(clave, base64.b64decode(oculto))
|
||||
|
||||
oculto = re.findall('<input type=hidden value=([^ ]+) id=code', data, flags=re.DOTALL)[0]
|
||||
codigo = resuelve(clave, base64.b64decode(oculto))
|
||||
|
||||
url, type = scrapertools.find_single_match(funciones, "setAttribute\('src', '(.*?)'\);\s.*?type', 'video/(.*?)'")
|
||||
|
||||
video_urls.append(['upvid [%s]' % type ,url])
|
||||
|
||||
return video_urls
|
||||
|
||||
|
||||
def resuelve(r, o):
|
||||
a = '';
|
||||
n = 0
|
||||
e = range(256)
|
||||
for f in range(256):
|
||||
n = (n + e[f] + ord(r[(f % len(r))])) % 256
|
||||
t = e[f];
|
||||
e[f] = e[n];
|
||||
e[n] = t
|
||||
f = 0;
|
||||
n = 0
|
||||
for h in range(len(o)):
|
||||
f = (f + 1) % 256
|
||||
n = (n + e[f]) % 256
|
||||
t = e[f];
|
||||
e[f] = e[n];
|
||||
e[n] = t
|
||||
a += chr(ord(o[h]) ^ e[(e[f] + e[n]) % 256])
|
||||
return a
|
||||
42
plugin.video.alfa/servers/vidzella.json
Normal file
42
plugin.video.alfa/servers/vidzella.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"active": true,
|
||||
"find_videos": {
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "https://vidzella.me/e/([a-zA-Z0-9]+)",
|
||||
"url": "https://vidzella.me/e/\\1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"free": true,
|
||||
"id": "vidzella",
|
||||
"name": "vidzella",
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "black_list",
|
||||
"label": "Incluir en lista negra",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"id": "favorites_servers_list",
|
||||
"label": "Incluir en lista de favoritos",
|
||||
"lvalues": [
|
||||
"No",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5"
|
||||
],
|
||||
"type": "list",
|
||||
"visible": false
|
||||
}
|
||||
],
|
||||
"thumbnail": "https://s15.postimg.cc/albqao5pn/vidzella.png"
|
||||
}
|
||||
33
plugin.video.alfa/servers/vidzella.py
Normal file
33
plugin.video.alfa/servers/vidzella.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# Conector Vidzella By Alfa development Group
|
||||
# --------------------------------------------------------
|
||||
|
||||
import re
|
||||
from core import httptools
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
|
||||
data = httptools.downloadpage(page_url)
|
||||
|
||||
if data.code == 404:
|
||||
return False, "[Vidzella] El archivo no existe o ha sido borrado"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("url=" + page_url)
|
||||
|
||||
video_urls = []
|
||||
data = httptools.downloadpage(page_url).data
|
||||
data = re.sub(r'"|\n|\r|\t| |<br>|\s{2,}', "", data)
|
||||
logger.debug(data)
|
||||
patron = "src=([^ ]+) type='.*?/(.*?)'"
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
|
||||
for url, type in matches:
|
||||
video_urls.append(['vidzella %s' % type, url])
|
||||
|
||||
return video_urls
|
||||
42
plugin.video.alfa/servers/vivo.json
Normal file
42
plugin.video.alfa/servers/vivo.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"active": true,
|
||||
"find_videos": {
|
||||
"ignore_urls": [],
|
||||
"patterns": [
|
||||
{
|
||||
"pattern": "https://vivo.sx/([a-zA-Z0-9]+)",
|
||||
"url": "https://vivo.sx/\\1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"free": true,
|
||||
"id": "vivo",
|
||||
"name": "vivo",
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "black_list",
|
||||
"label": "Incluir en lista negra",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"id": "favorites_servers_list",
|
||||
"label": "Incluir en lista de favoritos",
|
||||
"lvalues": [
|
||||
"No",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5"
|
||||
],
|
||||
"type": "list",
|
||||
"visible": false
|
||||
}
|
||||
],
|
||||
"thumbnail": "https://s15.postimg.cc/oiyhtpdqj/vivo.png"
|
||||
}
|
||||
39
plugin.video.alfa/servers/vivo.py
Normal file
39
plugin.video.alfa/servers/vivo.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# Conector Vivo By Alfa development Group
|
||||
# --------------------------------------------------------
|
||||
|
||||
import re
|
||||
import base64
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
|
||||
def test_video_exists(page_url):
|
||||
logger.info("(page_url='%s')" % page_url)
|
||||
|
||||
data = httptools.downloadpage(page_url)
|
||||
|
||||
if data.code == 404:
|
||||
return False, "[Vivo] El archivo no existe o ha sido borrado"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
|
||||
logger.info("url=" + page_url)
|
||||
|
||||
video_urls = []
|
||||
data = httptools.downloadpage(page_url).data
|
||||
data = re.sub(r'"|\n|\r|\t| |<br>|\s{2,}', "", data)
|
||||
|
||||
enc_data = scrapertools.find_single_match(data, "Core.InitializeStream \('(.*?)'\)")
|
||||
logger.debug(enc_data)
|
||||
dec_data = base64.b64decode(enc_data)
|
||||
|
||||
logger.debug(dec_data)
|
||||
|
||||
for url in eval(dec_data):
|
||||
video_urls.append(['vivo', url])
|
||||
|
||||
return video_urls
|
||||
@@ -5,6 +5,10 @@
|
||||
{
|
||||
"pattern": "(vshare.io/v/[a-zA-Z0-9/-]+)",
|
||||
"url": "http://\\1"
|
||||
},
|
||||
{
|
||||
"pattern": "(vshare.eu/embed-[a-zA-Z0-9/-]+.html)",
|
||||
"url": "http://\\1"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -26,22 +26,25 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
if flowplayer:
|
||||
return [["FLV", flowplayer.group(1)]]
|
||||
|
||||
jsUnpack = jsunpack.unpack(data)
|
||||
logger.debug(jsUnpack)
|
||||
|
||||
video_urls = []
|
||||
try:
|
||||
jsUnpack = jsunpack.unpack(data)
|
||||
logger.debug(jsUnpack)
|
||||
fields = re.search("\[([^\]]+).*?parseInt\(value\)-(\d+)", jsUnpack)
|
||||
if fields:
|
||||
logger.debug("Values: " + fields.group(1))
|
||||
logger.debug("Substract: " + fields.group(2))
|
||||
substract = int(fields.group(2))
|
||||
|
||||
fields = re.search("\[([^\]]+).*?parseInt\(value\)-(\d+)", jsUnpack)
|
||||
if fields:
|
||||
logger.debug("Values: " + fields.group(1))
|
||||
logger.debug("Substract: " + fields.group(2))
|
||||
substract = int(fields.group(2))
|
||||
arrayResult = [chr(int(value) - substract) for value in fields.group(1).split(",")]
|
||||
strResult = "".join(arrayResult)
|
||||
logger.debug(strResult)
|
||||
videoSources = re.findall("<source[\s]+src=[\"'](?P<url>[^\"']+)[^>]+label=[\"'](?P<label>[^\"']+)", strResult)
|
||||
for url, label in videoSources:
|
||||
video_urls.append([label, url])
|
||||
video_urls.sort(key=lambda i: int(i[0].replace("p","")))
|
||||
except:
|
||||
url = scrapertools.find_single_match(data,'<source src="([^"]+)')
|
||||
video_urls.append(["MP4", url])
|
||||
|
||||
arrayResult = [chr(int(value) - substract) for value in fields.group(1).split(",")]
|
||||
strResult = "".join(arrayResult)
|
||||
logger.debug(strResult)
|
||||
videoSources = re.findall("<source[\s]+src=[\"'](?P<url>[^\"']+)[^>]+label=[\"'](?P<label>[^\"']+)", strResult)
|
||||
for url, label in videoSources:
|
||||
video_urls.append([label, url])
|
||||
video_urls.sort(key=lambda i: int(i[0].replace("p","")))
|
||||
return video_urls
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
{
|
||||
"pattern": "watchvideo.us/(?:embed-|)([A-z0-9]+)",
|
||||
"url": "http://watchvideo.us/embed-\\1.html"
|
||||
},
|
||||
{
|
||||
"pattern": "watchvideo17.us/(?:embed-|)([A-z0-9]+)",
|
||||
"url": "http://watchvideo.us/embed-\\1.html"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from lib import jsunpack
|
||||
from platformcode import logger
|
||||
|
||||
|
||||
@@ -20,15 +21,17 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
|
||||
logger.info("url=" + page_url)
|
||||
|
||||
data = httptools.downloadpage(page_url).data
|
||||
enc_data = scrapertools.find_single_match(data, "type='text/javascript'>(eval.*?)\s*</script>")
|
||||
dec_data = jsunpack.unpack(enc_data)
|
||||
|
||||
video_urls = []
|
||||
media_urls = scrapertools.find_multiple_matches(data, '\{file\s*:\s*"([^"]+)",label\s*:\s*"([^"]+)"\}')
|
||||
media_urls = scrapertools.find_multiple_matches(dec_data, '\{file\s*:\s*"([^"]+)",label\s*:\s*"([^"]+)"\}')
|
||||
for media_url, label in media_urls:
|
||||
ext = scrapertools.get_filename_from_url(media_url)[-4:]
|
||||
video_urls.append(["%s %sp [watchvideo]" % (ext, label), media_url])
|
||||
|
||||
video_urls.reverse()
|
||||
m3u8 = scrapertools.find_single_match(data, '\{file\:"(.*?.m3u8)"\}')
|
||||
m3u8 = scrapertools.find_single_match(dec_data, '\{file\:"(.*?.m3u8)"\}')
|
||||
if m3u8:
|
||||
title = video_urls[-1][0].split(" ", 1)[1]
|
||||
video_urls.insert(0, [".m3u8 %s" % title, m3u8])
|
||||
|
||||
@@ -13,11 +13,14 @@ from core import filetools
|
||||
from core import videolibrarytools
|
||||
from platformcode import config, logger
|
||||
from platformcode import platformtools
|
||||
from channels import videolibrary
|
||||
|
||||
|
||||
def update(path, p_dialog, i, t, serie, overwrite):
|
||||
logger.info("Actualizando " + path)
|
||||
insertados_total = 0
|
||||
#logger.debug(serie)
|
||||
head_nfo, it = videolibrarytools.read_nfo(path + '/tvshow.nfo')
|
||||
|
||||
# logger.debug("%s: %s" %(serie.contentSerieName,str(list_canales) ))
|
||||
for channel, url in serie.library_urls.items():
|
||||
@@ -35,6 +38,7 @@ def update(path, p_dialog, i, t, serie, overwrite):
|
||||
pathchannels = filetools.join(config.get_runtime_path(), "channels", serie.channel + '.py')
|
||||
logger.info("Cargando canal: " + pathchannels + " " +
|
||||
serie.channel)
|
||||
logger.debug(serie)
|
||||
|
||||
if serie.library_filter_show:
|
||||
serie.show = serie.library_filter_show.get(channel, serie.contentSerieName)
|
||||
@@ -46,10 +50,16 @@ def update(path, p_dialog, i, t, serie, overwrite):
|
||||
if int(overwrite) == 3:
|
||||
# Sobrescribir todos los archivos (tvshow.nfo, 1x01.nfo, 1x01 [canal].json, 1x01.strm, etc...)
|
||||
insertados, sobreescritos, fallidos = videolibrarytools.save_tvshow(serie, itemlist)
|
||||
serie= videolibrary.check_season_playcount(serie, serie.contentSeason)
|
||||
if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()):
|
||||
serie.infoLabels['playcount'] = serie.playcount
|
||||
else:
|
||||
insertados, sobreescritos, fallidos = videolibrarytools.save_episodes(path, itemlist, serie,
|
||||
silent=True,
|
||||
overwrite=overwrite)
|
||||
it = videolibrary.check_season_playcount(it, it.contentSeason)
|
||||
if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()):
|
||||
serie.infoLabels['playcount'] = serie.playcount
|
||||
insertados_total += insertados
|
||||
|
||||
except Exception, ex:
|
||||
|
||||
Reference in New Issue
Block a user