@@ -113,6 +113,14 @@
|
||||
"14",
|
||||
"15"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "include_in_newest_4k",
|
||||
"type": "bool",
|
||||
"label": "Incluir en Novedades - 4K",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1086,3 +1086,29 @@ def search(item, texto):
|
||||
for line in sys.exc_info():
|
||||
logger.error("ERROR: %s: SEARCH" % line)
|
||||
return []
|
||||
|
||||
|
||||
def newest(categoria):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
item = Item()
|
||||
|
||||
try:
|
||||
if categoria == '4k':
|
||||
item.url = host + "categoria/4k/"
|
||||
item.extra = "peliculas"
|
||||
item.channel = channel
|
||||
item.category_new= 'newest'
|
||||
|
||||
itemlist = listado(item)
|
||||
if ">> Página siguiente" in itemlist[-1].title:
|
||||
itemlist.pop()
|
||||
|
||||
# Se captura la excepción, para no interrumpir al canal novedades si un canal falla
|
||||
except:
|
||||
import sys
|
||||
for line in sys.exc_info():
|
||||
logger.error("{0}".format(line))
|
||||
return []
|
||||
|
||||
return itemlist
|
||||
77
plugin.video.alfa/channels/rarbg.json
Normal file
77
plugin.video.alfa/channels/rarbg.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"id": "rarbg",
|
||||
"name": "Rarbg",
|
||||
"active": true,
|
||||
"adult": false,
|
||||
"language": [],
|
||||
"thumbnail": "https://dyncdn.me/static/20/img/logo_dark_nodomain2_optimized.png",
|
||||
"categories": [
|
||||
"torrent",
|
||||
"movie",
|
||||
"tvshow",
|
||||
"vo"
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"default": false,
|
||||
"enabled": true,
|
||||
"id": "include_in_global_search",
|
||||
"label": "Incluir en busqueda global",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"id": "modo_grafico",
|
||||
"label": "Buscar información extra (TMDB)",
|
||||
"type": "bool",
|
||||
"visible": true
|
||||
},
|
||||
{
|
||||
"id": "filter_languages",
|
||||
"type": "list",
|
||||
"label": "Mostrar enlaces en idioma...",
|
||||
"default": 0,
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"lvalues": [
|
||||
"No filtrar",
|
||||
"CAST",
|
||||
"LAT",
|
||||
"VO",
|
||||
"VOS",
|
||||
"VOSE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "timeout_downloadpage",
|
||||
"type": "list",
|
||||
"label": "Timeout (segs.) en descarga de páginas o verificación de servidores",
|
||||
"default": 5,
|
||||
"enabled": true,
|
||||
"visible": true,
|
||||
"lvalues": [
|
||||
"None",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "seleccionar_ult_temporadda_activa",
|
||||
"type": "bool",
|
||||
"label": "Seleccionar para Videoteca si estará activa solo la última Temporada",
|
||||
"default": true,
|
||||
"enabled": true,
|
||||
"visible": true
|
||||
}
|
||||
]
|
||||
}
|
||||
828
plugin.video.alfa/channels/rarbg.py
Normal file
828
plugin.video.alfa/channels/rarbg.py
Normal file
@@ -0,0 +1,828 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
import sys
|
||||
import urllib
|
||||
import urlparse
|
||||
import time
|
||||
|
||||
from channelselector import get_thumb
|
||||
from core import httptools
|
||||
from core import scrapertools
|
||||
from core import servertools
|
||||
from core.item import Item
|
||||
from platformcode import config, logger
|
||||
from core import tmdb
|
||||
from lib import generictools
|
||||
from channels import filtertools
|
||||
from channels import autoplay
|
||||
|
||||
|
||||
#IDIOMAS = {'CAST': 'Castellano', 'LAT': 'Latino', 'VO': 'Version Original'}
|
||||
IDIOMAS = {'Castellano': 'CAST', 'Latino': 'LAT', 'Version Original': 'VO'}
|
||||
list_language = IDIOMAS.values()
|
||||
list_quality = []
|
||||
list_servers = ['torrent']
|
||||
|
||||
host = 'https://rarbgmirror.xyz/'
|
||||
channel = 'rarbg'
|
||||
categoria = channel.capitalize()
|
||||
__modo_grafico__ = config.get_setting('modo_grafico', channel)
|
||||
modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', channel) #Actualización sólo últ. Temporada?
|
||||
timeout = config.get_setting('timeout_downloadpage', channel)
|
||||
|
||||
|
||||
def mainlist(item):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
|
||||
thumb_cartelera = get_thumb("now_playing.png")
|
||||
thumb_pelis = get_thumb("channels_movie.png")
|
||||
thumb_pelis_hd = get_thumb("channels_movie_hd.png")
|
||||
thumb_pelis_VO = get_thumb("channels_vos.png")
|
||||
thumb_series = get_thumb("channels_tvshow.png")
|
||||
thumb_series_hd = get_thumb("channels_tvshow_hd.png")
|
||||
thumb_series_VOD = get_thumb("videolibrary_tvshow.png")
|
||||
thumb_generos = get_thumb("genres.png")
|
||||
thumb_buscar = get_thumb("search.png")
|
||||
thumb_separador = get_thumb("next.png")
|
||||
thumb_settings = get_thumb("setting_0.png")
|
||||
|
||||
autoplay.init(item.channel, list_servers, list_quality)
|
||||
|
||||
itemlist.append(Item(channel=item.channel, url=host, title="[COLOR yellow]NOTA: Esta web puede considerar una intrusión[/COLOR]", folder=False, thumbnail=thumb_separador))
|
||||
itemlist.append(Item(channel=item.channel, url=host, title="[COLOR yellow]más de 1 usuario o 10 accesos por IP/Router.[/COLOR]", folder=False, thumbnail=thumb_separador))
|
||||
itemlist.append(Item(channel=item.channel, url=host, title="[COLOR yellow]Si es bloqueado, renueve la IP en el Router[/COLOR]", folder=False, thumbnail=thumb_separador))
|
||||
|
||||
itemlist.append(Item(channel=item.channel, title="Películas", action="listado", url=host + "torrents.php?category=movies&search=&order=data&by=DESC", thumbnail=thumb_pelis_VO, extra="peliculas"))
|
||||
itemlist.append(Item(channel=item.channel, title=" - Calidades", action="calidades", url=host + "torrents.php?category=movies&search=&order=data&by=DESC", thumbnail=thumb_pelis_hd, extra="peliculas"))
|
||||
#itemlist.append(Item(channel=item.channel, title=" - Géneros", action="generos", url=host + "catalog/movies/", thumbnail=thumb_generos, extra="peliculas"))
|
||||
|
||||
itemlist.append(Item(channel=item.channel, title="Series", action="listado", url=host + "torrents.php?category=2;18;41;49&search=&order=data&by=DESC", thumbnail=thumb_series_VOD, extra="series"))
|
||||
itemlist.append(Item(channel=item.channel, title=" - Calidades", action="calidades", url=host + "torrents.php?category=2;18;41;49&search=&order=data&by=DESC", thumbnail=thumb_series_hd, extra="series"))
|
||||
#itemlist.append(Item(channel=item.channel, title=" - Géneros", action="generos", url=host + "catalog/tv/", thumbnail=thumb_generos, extra="series"))
|
||||
|
||||
itemlist.append(Item(channel=item.channel, title="Buscar...", action="search", url=host + "?s=%s", thumbnail=thumb_buscar, extra="search"))
|
||||
|
||||
itemlist.append(Item(channel=item.channel, url=host, title="[COLOR yellow]Configuración:[/COLOR]", folder=False, thumbnail=thumb_separador))
|
||||
|
||||
itemlist.append(Item(channel=item.channel, action="configuracion", title="Configurar canal", thumbnail=thumb_settings))
|
||||
|
||||
autoplay.show_option(item.channel, itemlist) #Activamos Autoplay
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def configuracion(item):
|
||||
from platformcode import platformtools
|
||||
ret = platformtools.show_channel_settings()
|
||||
platformtools.itemlist_refresh()
|
||||
return
|
||||
|
||||
|
||||
def calidades(item):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
|
||||
data = ''
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, timeout=timeout).data)
|
||||
data = unicode(data, "utf-8", errors="replace").encode("utf-8")
|
||||
except:
|
||||
pass
|
||||
|
||||
patron = '<div align="[^"]+"><div style="[^"]+" id="divadvsearch">(.*?)<\/a><\/div><\/div><\/form><\/div>'
|
||||
#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):
|
||||
status, itemlist = check_blocked_IP(data, itemlist) #Comprobamos si la IP ha sido bloqueada
|
||||
if status:
|
||||
return itemlist #IP bloqueada
|
||||
|
||||
item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada
|
||||
if item.intervencion: #Sí ha sido clausurada judicialmente
|
||||
for clone_inter, autoridad in item.intervencion:
|
||||
thumb_intervenido = get_thumb(autoridad)
|
||||
itemlist.append(item.clone(action='', title="[COLOR yellow]" + clone_inter.capitalize() + ': [/COLOR]' + intervenido_judicial + '. Reportar el problema en el foro', thumbnail=thumb_intervenido))
|
||||
return itemlist #Salimos
|
||||
|
||||
logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url + data)
|
||||
|
||||
if not data: #Si no ha logrado encontrar nada, salimos
|
||||
itemlist.append(item.clone(action='', title=item.category + ': ERROR 01: SUBMENU: 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
|
||||
|
||||
data = scrapertools.find_single_match(data, patron) #Seleccionamos el bloque
|
||||
patron = '<div class="divadvscat"><input class="inputadvscat" type="checkbox" name="category\[.*?\]" value="[^"]+"\s*(?:.*?)?\/> <a href="([^"]+)">(.*?)<\/a>\s*<\/div>\s*'
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
|
||||
if not matches:
|
||||
logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
|
||||
itemlist.append(item.clone(action='', title=item.category + ': 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
|
||||
|
||||
#logger.debug(patron)
|
||||
#logger.debug(matches)
|
||||
#logger.debug(data)
|
||||
|
||||
itemlist.append(item.clone(action="listado", title="ALL", extra2="calidades"))
|
||||
|
||||
for scrapedurl, scrapedtitle in matches:
|
||||
if not "Mov" in scrapedtitle and item.extra == 'peliculas':
|
||||
continue
|
||||
if not "TV" in scrapedtitle and item.extra == 'series':
|
||||
continue
|
||||
|
||||
title = scrapedtitle.strip().replace('Movs/', '').replace('Movies/', '')
|
||||
url = urlparse.urljoin(host, scrapedurl + "&search=&order=data&by=DESC")
|
||||
|
||||
itemlist.append(item.clone(action="listado", title=title, url=url, extra2="calidades"))
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def listado(item):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
item.category = categoria
|
||||
|
||||
#logger.debug(item)
|
||||
|
||||
curr_page = 1 # Página inicial
|
||||
last_page = 99999 # Última página inicial
|
||||
if item.curr_page:
|
||||
curr_page = int(item.curr_page) # Si viene de una pasada anterior, lo usamos
|
||||
del item.curr_page # ... y lo borramos
|
||||
if item.last_page:
|
||||
last_page = int(item.last_page) # Si viene de una pasada anterior, lo usamos
|
||||
del item.last_page # ... y lo borramos
|
||||
|
||||
cnt_tot = 40 # Poner el num. máximo de items por página
|
||||
cnt_title = 0 # Contador de líneas insertadas en Itemlist
|
||||
inicio = time.time() # Controlaremos que el proceso no exceda de un tiempo razonable
|
||||
fin = inicio + 3 # Después de este tiempo pintamos (segundos)
|
||||
timeout_search = timeout # Timeout para descargas
|
||||
if item.extra == 'search':
|
||||
timeout_search = timeout * 2 # Timeout un poco más largo para las búsquedas
|
||||
if timeout_search < 5:
|
||||
timeout_search = 5 # Timeout un poco más largo para las búsquedas
|
||||
|
||||
#Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios
|
||||
title_lista = [] # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas
|
||||
if item.title_lista: # Si viene de una pasada anterior, la lista ya estará guardada
|
||||
title_lista.extend(item.title_lista) # Se usa la lista de páginas anteriores en Item
|
||||
del item.title_lista # ... limpiamos
|
||||
|
||||
if not item.extra2: # Si viene de Catálogo o de Alfabeto
|
||||
item.extra2 = ''
|
||||
|
||||
next_page_url = item.url
|
||||
#Máximo num. de líneas permitidas por TMDB. Máx de 3 segundos por Itemlist para no degradar el rendimiento
|
||||
while cnt_title <= cnt_tot * 0.50 and curr_page <= last_page and fin > time.time():
|
||||
|
||||
# Descarga la página
|
||||
data = ''
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)| ", "", httptools.downloadpage(next_page_url, timeout=timeout_search).data)
|
||||
data = unicode(data, "utf-8", errors="replace").encode("utf-8")
|
||||
except:
|
||||
pass
|
||||
|
||||
curr_page += 1 #Apunto ya a la página siguiente
|
||||
if not data and not item.extra2: #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'))
|
||||
break #si no hay más datos, algo no funciona, pintamos lo que tenemos
|
||||
|
||||
status, itemlist = check_blocked_IP(data, itemlist) #Comprobamos si la IP ha sido bloqueada
|
||||
if status:
|
||||
return itemlist #IP bloqueada
|
||||
|
||||
#Patrón para todo, incluido búsquedas en cualquier caso
|
||||
patron = '<tr class="lista2"><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*style="(?:[^"]+)?"><a href="[^"]+"><img src="([^"]+)?"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*\/><\/a><\/td><td\s*align="(?:[^"]+)?"\s*class="(?:[^"]+)?"><a onmouseover="(?:[^"]+)?"\s*onmouseout="(?:[^"]+)?"\s*href="[^"]+" title="[^"]+">([^<]+)<\/a>\s*<a href="([^"]+)"><img src="[^"]+"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*><\/a>\s*(?:<a href="([^"]+)"><img src="[^"]+"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*><\/a>)?\s*<br><span.*?<\/span>\s*<\/td><td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">.*?<\/td><td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">([^<]+)?<\/td><td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">\s*<font color="(?:[^"]+)?">(\d+)?<\/font>'
|
||||
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
if not matches and item.extra != 'search': #error
|
||||
item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada
|
||||
if item.intervencion: #Sí ha sido clausurada judicialmente
|
||||
item, itemlist = generictools.post_tmdb_episodios(item, itemlist) #Llamamos al método para el pintado del error
|
||||
return itemlist #Salimos
|
||||
|
||||
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'))
|
||||
break #si no hay más datos, algo no funciona, pintamos lo que tenemos
|
||||
if not matches and item.extra == 'search': #búsqueda vacía
|
||||
return itemlist #Salimos
|
||||
|
||||
#logger.debug("PATRON: " + patron)
|
||||
logger.debug(matches)
|
||||
#logger.debug(data)
|
||||
|
||||
#Buscamos la próxima y la última página
|
||||
patron_next = '<a href="([^"]+page=(\d+))" title="next page">'
|
||||
if item.extra == 'search':
|
||||
patron_last = '<a href="[^"]+"\s*title="page\s*\d+">\d+<\/a>\s*<b>(\d+)<\/b><\/div><\/div><\/td>'
|
||||
else:
|
||||
patron_last = 'title="previous page"[^<]+<\/a>\s*<a href="[^>]+>(\d+)<\/a>'
|
||||
|
||||
try:
|
||||
next_page_url, next_page = scrapertools.find_single_match(data, patron_next)
|
||||
next_page = int(next_page)
|
||||
next_page_url = item.url + '&page=' + str(next_page)
|
||||
except: #Si no lo encuentra, lo ponemos a 1
|
||||
#logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "<ul class=\"pagination\">.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
|
||||
next_page = 1
|
||||
#logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))
|
||||
|
||||
if last_page == 99999: #Si es el valor inicial, buscamos
|
||||
if item.extra == 'search':
|
||||
last_page = 99
|
||||
try:
|
||||
data_last = ''
|
||||
data_last = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)| ", "", httptools.downloadpage(item.url + '&page=%s' % last_page, timeout=timeout_search).data)
|
||||
data_last = unicode(data_last, "utf-8", errors="replace").encode("utf-8")
|
||||
last_page = int(scrapertools.find_single_match(data_last, patron_last)) #lo cargamos como entero
|
||||
except: #Si no lo encuentra, lo ponemos a 1
|
||||
#logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "<ul class=\"pagination\">.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
|
||||
last_page = next_page
|
||||
#logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))
|
||||
|
||||
#Empezamos el procesado de matches
|
||||
for scrapedthumbnail, scrapedtitle, scrapedurl, scrapedepisodes, scrapedsize, scrapedseeds in matches:
|
||||
|
||||
title = scrapedtitle
|
||||
if scrapedepisodes:
|
||||
url = scrapedepisodes
|
||||
else:
|
||||
url = scrapedurl
|
||||
size = scrapedsize
|
||||
title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace("ã", "a").replace("&etilde;", "e").replace("ĩ", "i").replace("õ", "o").replace("ũ", "u").replace("ñ", "ñ").replace("’", "'")
|
||||
|
||||
if scrapedurl in title_lista: #Si ya hemos procesado el título, lo ignoramos
|
||||
continue
|
||||
else:
|
||||
title_lista += [scrapedurl] #la añadimos a la lista de títulos
|
||||
|
||||
#cnt_title += 1
|
||||
item_local = item.clone() #Creamos copia de Item para trabajar
|
||||
if item_local.tipo: #... y limpiamos
|
||||
del item_local.tipo
|
||||
if item_local.totalItems:
|
||||
del item_local.totalItems
|
||||
if item_local.intervencion:
|
||||
del item_local.intervencion
|
||||
if item_local.viewmode:
|
||||
del item_local.viewmode
|
||||
item_local.extra2 = True
|
||||
del item_local.extra2
|
||||
item_local.text_bold = True
|
||||
del item_local.text_bold
|
||||
item_local.text_color = True
|
||||
del item_local.text_color
|
||||
|
||||
title_subs = [] #creamos una lista para guardar info importante
|
||||
item_local.language = ['VO'] #creamos lista para los idiomas
|
||||
item_local.quality = '' #iniciamos calidad
|
||||
item_local.thumbnail = scrapedthumbnail #iniciamos thumbnail
|
||||
|
||||
if item.extra == 'search':
|
||||
if scrapedepisodes:
|
||||
item_local.extra = 'series'
|
||||
else:
|
||||
item_local.extra = 'peliculas'
|
||||
|
||||
item_local.url = urlparse.urljoin(host, url) #guardamos la url final
|
||||
if item_local.extra != 'series':
|
||||
item_local.url += '&order=size&by=ASC' #guardamos la url final
|
||||
item_local.context = "['buscar_trailer']"
|
||||
|
||||
item_local.contentType = "movie" #por defecto, son películas
|
||||
item_local.action = "findvideos"
|
||||
|
||||
#Analizamos los formatos de la películas
|
||||
if item_local.extra == 'peliculas':
|
||||
patron_title = '(.*?)\.([1|2][9|0]\d{2})?\.(.*?)(?:-.*?)?$'
|
||||
if not scrapertools.find_single_match(title, patron_title):
|
||||
logger.error('ERROR tratando título PELI: ' + title)
|
||||
continue
|
||||
try:
|
||||
title, year, item_local.quality = scrapertools.find_single_match(title, patron_title)
|
||||
except:
|
||||
title = scrapedtitle
|
||||
year = ''
|
||||
item_local.quality = ''
|
||||
title = title.replace('.', ' ')
|
||||
item_local.quality = item_local.quality.replace('.', ' ')
|
||||
|
||||
#Analizamos los formatos de series, temporadas y episodios
|
||||
elif item_local.extra == 'series':
|
||||
patron_title = '(.*?)(\.[1|2][9|0]\d{2})?\.S\d{2}.*?\.([\d|A-Z]{2}.*?)(?:-.*?)?$'
|
||||
if not scrapertools.find_single_match(title, patron_title):
|
||||
patron_title = '(.*?)\.*([1|2][9|0]\d{2})?(?:\.\d{2}\.\d{2}).*?\.([\d|A-Z]{2}.*?)(?:-.*?)?$'
|
||||
if not scrapertools.find_single_match(title, patron_title):
|
||||
logger.error('ERROR tratando título SERIE: ' + title)
|
||||
continue
|
||||
try:
|
||||
title, year, item_local.quality = scrapertools.find_single_match(title, patron_title)
|
||||
except:
|
||||
title = scrapedtitle
|
||||
year = ''
|
||||
item_local.quality = ''
|
||||
title = title.replace('.', ' ')
|
||||
item_local.quality = item_local.quality.replace('.', ' ')
|
||||
year = '-'
|
||||
|
||||
item_local.contentType = "tvshow"
|
||||
item_local.action = "episodios"
|
||||
item_local.season_colapse = True #Muestra las series agrupadas por temporadas
|
||||
|
||||
#Limpiamos el título de la basura innecesaria
|
||||
title = re.sub(r'TV|Online', '', title, flags=re.IGNORECASE).strip()
|
||||
item_local.quality = re.sub(r'proper|unrated|directors|cut|german|repack|internal|real|korean|extended|masted|docu|oar|super|duper|amzn|uncensored|hulu', '', item_local.quality, flags=re.IGNORECASE).strip()
|
||||
|
||||
#Analizamos el año. Si no está claro ponemos '-'
|
||||
try:
|
||||
year_int = int(year)
|
||||
if year_int >= 1940 and year_int <= 2050:
|
||||
item_local.infoLabels["year"] = year_int
|
||||
else:
|
||||
item_local.infoLabels["year"] = '-'
|
||||
except:
|
||||
item_local.infoLabels["year"] = '-'
|
||||
|
||||
#Terminamos de limpiar el título
|
||||
title = re.sub(r'[\(|\[]\s+[\)|\]]', '', title)
|
||||
title = title.replace('()', '').replace('[]', '').strip().lower().title()
|
||||
item_local.from_title = title.strip().lower().title() #Guardamos esta etiqueta para posible desambiguación de título
|
||||
|
||||
#Salvamos el título según el tipo de contenido
|
||||
if item_local.contentType == "movie":
|
||||
item_local.contentTitle = title
|
||||
else:
|
||||
item_local.contentSerieName = title.strip().lower().title()
|
||||
|
||||
item_local.title = title.strip().lower().title()
|
||||
|
||||
#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.contentSeason_save = item_local.contentSeason
|
||||
del item_local.infoLabels['season']
|
||||
|
||||
#Ahora se filtra por idioma, si procede, y se pinta lo que vale
|
||||
if config.get_setting('filter_languages', channel) > 0: #Si hay idioma seleccionado, se filtra
|
||||
itemlist = filtertools.get_link(itemlist, item_local, list_language)
|
||||
else:
|
||||
itemlist.append(item_local.clone()) #Si no, pintar pantalla
|
||||
|
||||
cnt_title = len(itemlist) #Contador de líneas añadidas
|
||||
|
||||
#logger.debug(item_local)
|
||||
|
||||
#Pasamos a TMDB la lista completa Itemlist
|
||||
tmdb.set_infoLabels(itemlist, __modo_grafico__)
|
||||
|
||||
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
|
||||
item, itemlist = generictools.post_tmdb_listado(item, itemlist)
|
||||
|
||||
# Si es necesario añadir paginacion
|
||||
if curr_page <= last_page:
|
||||
if last_page:
|
||||
title = '%s de %s' % (curr_page-1, last_page)
|
||||
else:
|
||||
title = '%s' % curr_page-1
|
||||
|
||||
itemlist.append(Item(channel=item.channel, action="listado", title=">> Página siguiente " + title, title_lista=title_lista, url=next_page_url, extra=item.extra, extra2=item.extra2, last_page=str(last_page), curr_page=str(curr_page)))
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def findvideos(item):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
itemlist_t = [] #Itemlist total de enlaces
|
||||
itemlist_f = [] #Itemlist de enlaces filtrados
|
||||
if not item.language:
|
||||
item.language = ['VO'] #VO por defecto
|
||||
matches = []
|
||||
item.category = categoria
|
||||
|
||||
#logger.debug(item)
|
||||
|
||||
#Bajamos los datos de la página
|
||||
data = ''
|
||||
patron = '<tr class="lista2">\s*<td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*style="(?:[^"]+)?">\s*<a href="[^"]+">\s*<img src="([^"]+)?"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*\/><\/a><\/td>\s*<td\s*align="(?:[^"]+)?"(?:\s*width="[^"]+")?\s*class="(?:[^"]+)?">\s*<a onmouseover="(?:[^"]+)?"\s*onmouseout="(?:[^"]+)?"\s*href="([^"]+)" title="[^"]+">(.*?)<\/a>\s*<a href="[^"]+">\s*<img src="[^"]+"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*><\/a>(?:\s*<a.*?<\/a>)?\s*<br><span.*?<\/span>\s*<\/td>\s*<td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">.*?<\/td>\s*<td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">(.*?)?<\/td>\s*<td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">\s*<font color="(?:[^"]+)?">(\d+)?<\/font>'
|
||||
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, timeout=timeout).data)
|
||||
data = unicode(data, "utf-8", errors="replace").encode("utf-8")
|
||||
except:
|
||||
pass
|
||||
|
||||
if not data:
|
||||
logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url)
|
||||
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
|
||||
|
||||
status, itemlist = check_blocked_IP(data, itemlist) #Comprobamos si la IP ha sido bloqueada
|
||||
if status:
|
||||
return itemlist #IP bloqueada
|
||||
|
||||
matches = re.compile(patron, re.DOTALL).findall(data)
|
||||
if not matches: #error
|
||||
item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada
|
||||
if item.intervencion: #Sí ha sido clausurada judicialmente
|
||||
item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) #Llamamos al método para el pintado del error
|
||||
else:
|
||||
logger.error("ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web " + " / PATRON: " + patron + data)
|
||||
itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web. Verificar en la Web esto último y 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)
|
||||
|
||||
#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)
|
||||
|
||||
#Ahora tratamos los enlaces .torrent con las diferentes calidades
|
||||
for scrapedthumbnail, scrapedurl, scrapedtitle, scrapedsize, scrapedseeds in matches:
|
||||
#Generamos una copia de Item para trabajar sobre ella
|
||||
item_local = item.clone()
|
||||
title = scrapedtitle
|
||||
|
||||
#Analizamos los formatos de la películas y series
|
||||
if item_local.contentType == 'movie':
|
||||
patron_title = '(.*?)\.([1|2][9|0]\d{2})?\.(.*?)(?:-.*?)?$'
|
||||
if not scrapertools.find_single_match(title, patron_title):
|
||||
continue
|
||||
else:
|
||||
patron_title = '(.*?)(\.[1|2][9|0]\d{2})?\.S\d{2}.*?\.([\d|A-Z]{2}.*?)(?:-.*?)?$'
|
||||
if not scrapertools.find_single_match(title, patron_title):
|
||||
patron_title = '(.*?)\.*([1|2][9|0]\d{2})?(?:\.\d{2}\.\d{2}).*?\.([\d|A-Z]{2}.*?)(?:-.*?)?$'
|
||||
if not scrapertools.find_single_match(title, patron_title):
|
||||
continue
|
||||
|
||||
try:
|
||||
title, year, item_local.quality = scrapertools.find_single_match(title, patron_title)
|
||||
except:
|
||||
title = scrapedtitle
|
||||
year = ''
|
||||
item_local.quality = ''
|
||||
title = title.replace('.', ' ')
|
||||
item_local.quality = item_local.quality.replace('.', ' ')
|
||||
item_local.quality = re.sub(r'proper|unrated|directors|cut|german|repack|internal|real|korean|extended|masted|docu|oar|super|duper|amzn|uncensored|hulu', '', item_local.quality, flags=re.IGNORECASE).strip()
|
||||
|
||||
#Buscamos si ya tiene tamaño, si no, los buscamos en el archivo .torrent
|
||||
size = scrapedsize
|
||||
if size:
|
||||
item_local.title = '%s [%s]' % (item_local.title, size) #Agregamos size al final del título
|
||||
size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
|
||||
item_local.quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final de la calidad
|
||||
|
||||
#Añadimos los seeds en calidad, como información adicional
|
||||
if scrapedseeds:
|
||||
item_local.quality = '%s [Seeds: %s]' % (item_local.quality, scrapedseeds) #Agregamos seeds a la calidad
|
||||
|
||||
#Ahora pintamos el link del Torrent
|
||||
item_local.url = urlparse.urljoin(host, scrapedurl)
|
||||
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 y calidad, quitamos etiquetas vacías
|
||||
item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title)
|
||||
item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title)
|
||||
item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
|
||||
item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality)
|
||||
item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality)
|
||||
item_local.quality = item_local.quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
|
||||
|
||||
item_local.alive = "??" #Calidad del link sin verificar
|
||||
item_local.action = "play" #Visualizar vídeo
|
||||
item_local.server = "torrent" #Seridor Torrent
|
||||
|
||||
itemlist_t.append(item_local.clone()) #Pintar pantalla, si no se filtran idiomas
|
||||
|
||||
# Requerido para FilterTools
|
||||
if config.get_setting('filter_languages', channel) > 0: #Si hay idioma seleccionado, se filtra
|
||||
itemlist_f = filtertools.get_link(itemlist_f, item_local, list_language) #Pintar pantalla, si no está vacío
|
||||
|
||||
#logger.debug("TORRENT: " + scrapedurl + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
|
||||
#logger.debug(item_local)
|
||||
|
||||
if len(itemlist_f) > 0: #Si hay entradas filtradas...
|
||||
itemlist.extend(itemlist_f) #Pintamos pantalla filtrada
|
||||
else:
|
||||
if config.get_setting('filter_languages', channel) > 0 and len(itemlist_t) > 0: #Si no hay entradas filtradas ...
|
||||
thumb_separador = get_thumb("next.png") #... pintamos todo con aviso
|
||||
itemlist.append(Item(channel=item.channel, url=host, title="[COLOR red][B]NO hay elementos con el idioma seleccionado[/B][/COLOR]", thumbnail=thumb_separador))
|
||||
itemlist.extend(itemlist_t) #Pintar pantalla con todo si no hay filtrado
|
||||
|
||||
# Requerido para AutoPlay
|
||||
autoplay.start(itemlist, item) #Lanzamos Autoplay
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def play(item): #Permite preparar la descarga de los .torrents y subtítulos externos
|
||||
logger.info()
|
||||
itemlist = []
|
||||
headers = []
|
||||
import os
|
||||
from core import downloadtools
|
||||
from core import ziptools
|
||||
|
||||
#buscamos la url del .torrent
|
||||
patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*width="(?:[^"]+)?">\s*Torrent:<\/td><td class="(?:[^"]+)?">\s*<img src="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*border="(?:[^"]+)?"\s*\/>\s*<a onmouseover="(?:[^"]+)?"\s*onmouseout="(?:[^"]+)?" href="([^"]+)">.*?<\/a>'
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, timeout=timeout).data)
|
||||
data = unicode(data, "utf-8", errors="replace").encode("utf-8")
|
||||
except:
|
||||
pass
|
||||
status, itemlist = check_blocked_IP(data, itemlist) #Comprobamos si la IP ha sido bloqueada
|
||||
if status:
|
||||
return itemlist #IP bloqueada
|
||||
if not scrapertools.find_single_match(data, patron):
|
||||
return itemlist
|
||||
item.url = urlparse.urljoin(host, scrapertools.find_single_match(data, patron))
|
||||
|
||||
#buscamos subtítulos en español
|
||||
patron = '<tr><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*>\s*Subs.*?<\/td><td class="(?:[^"]+)?"\s*>(.*?)(?:<br\/>)?<\/td><\/tr>'
|
||||
data_subt = scrapertools.find_single_match(data, patron)
|
||||
if data_subt:
|
||||
patron = '<a href="([^"]+)"\s*onmouseover="return overlib\('
|
||||
patron += "'Download Spanish subtitles'"
|
||||
patron += '\)"\s*onmouseout="(?:[^"]+)?"\s*><img src="(?:[^"]+)?"\s*><\/a>'
|
||||
subt = scrapertools.find_single_match(data_subt, patron)
|
||||
if subt:
|
||||
item.subtitle = urlparse.urljoin(host, subt)
|
||||
|
||||
if item.subtitle: #Si hay urls de sub-títulos, se descargan
|
||||
headers.append(["User-Agent", httptools.get_user_agent()]) #Se busca el User-Agent por defecto
|
||||
videolibrary_path = config.get_videolibrary_path() #Calculamos el path absoluto a partir de la Videoteca
|
||||
if videolibrary_path.lower().startswith("smb://"): #Si es una conexión SMB, usamos userdata local
|
||||
videolibrary_path = config.get_data_path() #Calculamos el path absoluto a partir de Userdata
|
||||
videolibrary_path = os.path.join(videolibrary_path, "subtitles")
|
||||
#Primero se borra la carpeta de subtitulos para limpiar y luego se crea
|
||||
if os.path.exists(videolibrary_path):
|
||||
import shutil
|
||||
shutil.rmtree(videolibrary_path, ignore_errors=True)
|
||||
time.sleep(1)
|
||||
if not os.path.exists(videolibrary_path):
|
||||
os.mkdir(videolibrary_path)
|
||||
subtitle_name = 'Rarbg-ES_SUBT.zip' #Nombre del archivo de sub-títulos
|
||||
subtitle_folder_path = os.path.join(videolibrary_path, subtitle_name) #Path de descarga
|
||||
ret = downloadtools.downloadfile(item.subtitle, subtitle_folder_path, headers=headers, continuar=True, silent=True)
|
||||
|
||||
if os.path.exists(subtitle_folder_path):
|
||||
# Descomprimir zip dentro del addon
|
||||
# ---------------------------------
|
||||
try:
|
||||
unzipper = ziptools.ziptools()
|
||||
unzipper.extract(subtitle_folder_path, videolibrary_path)
|
||||
except:
|
||||
import xbmc
|
||||
xbmc.executebuiltin('XBMC.Extract("%s", "%s")' % (subtitle_folder_path, videolibrary_path))
|
||||
time.sleep(1)
|
||||
|
||||
# Borrar el zip descargado
|
||||
# ------------------------
|
||||
os.remove(subtitle_folder_path)
|
||||
|
||||
#Tomo el primer archivo de subtítulos como valor por defecto
|
||||
for raiz, subcarpetas, ficheros in os.walk(videolibrary_path):
|
||||
for f in ficheros:
|
||||
if f.endswith(".srt"):
|
||||
#f_es = 'rarbg_subtitle.spa.srt'
|
||||
f_es = scrapertools.find_single_match(item.url, '&f=(.*?).torrent$').replace('.', ' ').replace('-', ' ').lower() + '.spa.srt'
|
||||
if not f_es:
|
||||
f_es = item.infoLabels['originaltitle'] + '.spa.srt'
|
||||
f_es = f_es.replace(':', '').lower()
|
||||
os.rename(os.path.join(videolibrary_path, f), os.path.join(videolibrary_path, f_es))
|
||||
item.subtitle = os.path.join(videolibrary_path, f_es) #Archivo de subtitulos
|
||||
break
|
||||
break
|
||||
|
||||
itemlist.append(item.clone()) #Reproducción normal
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def episodios(item):
|
||||
logger.info()
|
||||
itemlist = []
|
||||
item.category = categoria
|
||||
|
||||
#logger.debug(item)
|
||||
|
||||
if item.from_title:
|
||||
item.title = item.from_title
|
||||
|
||||
#Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
|
||||
season_display = 0
|
||||
if item.contentSeason:
|
||||
if item.season_colapse: #Si viene del menú de Temporadas...
|
||||
season_display = item.contentSeason #... salvamos el num de sesión a pintar
|
||||
item.from_num_season_colapse = season_display
|
||||
del item.season_colapse
|
||||
item.contentType = "tvshow"
|
||||
if item.from_title_season_colapse:
|
||||
item.title = item.from_title_season_colapse
|
||||
del item.from_title_season_colapse
|
||||
if item.infoLabels['title']:
|
||||
del item.infoLabels['title']
|
||||
del item.infoLabels['season']
|
||||
if item.contentEpisodeNumber:
|
||||
del item.infoLabels['episode']
|
||||
if season_display == 0 and item.from_num_season_colapse:
|
||||
season_display = item.from_num_season_colapse
|
||||
|
||||
# Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca
|
||||
if not item.infoLabels['tmdb_id']:
|
||||
tmdb.set_infoLabels(item, True)
|
||||
|
||||
modo_ultima_temp_alt = modo_ultima_temp
|
||||
if item.ow_force == "1": #Si hay un traspaso de canal o url, se actualiza todo
|
||||
modo_ultima_temp_alt = False
|
||||
|
||||
max_temp = 1
|
||||
if item.infoLabels['number_of_seasons']:
|
||||
max_temp = item.infoLabels['number_of_seasons']
|
||||
y = []
|
||||
if modo_ultima_temp_alt and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca
|
||||
patron = 'season (\d+)'
|
||||
matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts))
|
||||
for x in matches:
|
||||
y += [int(x)]
|
||||
max_temp = max(y)
|
||||
|
||||
# Descarga la página
|
||||
data = '' #Inserto en num de página en la url
|
||||
try:
|
||||
data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)| ", "", httptools.downloadpage(item.url, timeout=timeout).data)
|
||||
data = unicode(data, "utf-8", errors="replace").encode("utf-8")
|
||||
except: #Algún error de proceso, salimos
|
||||
pass
|
||||
|
||||
if not data:
|
||||
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
|
||||
|
||||
status, itemlist = check_blocked_IP(data, itemlist) #Comprobamos si la IP ha sido bloqueada
|
||||
if status:
|
||||
return itemlist #IP bloqueada
|
||||
|
||||
#Capturamos las temporadas de episodios dentro de la serie
|
||||
patron_temp = '<h1\s*class="[^"]+">Season\s*(\d+)<\/h1><div class="tvcontent"><div id="[^"]+"><\/div>(.*?<\/div><\/div>)(?:<script>.*?<\/script>)?<\/div>'
|
||||
temp_serie = re.compile(patron_temp, re.DOTALL).findall(data)
|
||||
|
||||
for season_num, temporada in temp_serie:
|
||||
patron = '<div id="episode_(\d+)"><div class="[^"]+">\s*<a onclick="[^"]+"\s*class="[^"]+"><div class="[^"]+">.*?\s*(\d+)<\/div>\s*(.*?)\s*<'
|
||||
matches = re.compile(patron, re.DOTALL).findall(temporada)
|
||||
if not matches: #error
|
||||
item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada
|
||||
if item.intervencion: #Sí ha sido clausurada judicialmente
|
||||
item, itemlist = generictools.post_tmdb_episodios(item, itemlist) #Llamamos al método para el pintado del error
|
||||
return itemlist #Salimos
|
||||
|
||||
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)
|
||||
#logger.debug(data)
|
||||
|
||||
season = max_temp
|
||||
#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
|
||||
|
||||
if modo_ultima_temp_alt and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
|
||||
if int(season_num) < max_temp:
|
||||
break #Sale del bucle actual del FOR
|
||||
|
||||
# Recorremos todos los episodios generando un Item local por cada uno en Itemlist
|
||||
for epi_id, episode_num, scrapedtitle in matches:
|
||||
item_local = item.clone()
|
||||
item_local.action = "findvideos"
|
||||
item_local.contentType = "episode"
|
||||
item_local.extra = "episodios"
|
||||
if item_local.library_playcounts:
|
||||
del item_local.library_playcounts
|
||||
if item_local.library_urls:
|
||||
del item_local.library_urls
|
||||
if item_local.path:
|
||||
del item_local.path
|
||||
if item_local.update_last:
|
||||
del item_local.update_last
|
||||
if item_local.update_next:
|
||||
del item_local.update_next
|
||||
if item_local.channel_host:
|
||||
del item_local.channel_host
|
||||
if item_local.active:
|
||||
del item_local.active
|
||||
if item_local.contentTitle:
|
||||
del item_local.infoLabels['title']
|
||||
if item_local.season_colapse:
|
||||
del item_local.season_colapse
|
||||
|
||||
item_local.title = ''
|
||||
item_local.context = "['buscar_trailer']"
|
||||
item_local.url = urlparse.urljoin(host, 'tv.php?ajax=1&tvepisode=%s' % epi_id)
|
||||
title = scrapedtitle
|
||||
item_local.language = ['VO']
|
||||
if not item_local.infoLabels['poster_path']:
|
||||
item_local.thumbnail = item_local.infoLabels['thumbnail']
|
||||
epi_rango = False
|
||||
|
||||
try:
|
||||
item_local.contentSeason = int(season_num)
|
||||
if 'season pack' in title.lower():
|
||||
item_local.contentEpisodeNumber = 1
|
||||
epi_rango = True
|
||||
else:
|
||||
item_local.contentEpisodeNumber = int(episode_num)
|
||||
except:
|
||||
logger.error('ERROR al extraer Temporada/Episodio: ' + title)
|
||||
item_local.contentSeason = 1
|
||||
item_local.contentEpisodeNumber = 0
|
||||
|
||||
#Si son episodios múltiples, lo extraemos
|
||||
if epi_rango:
|
||||
item_local.infoLabels['episodio_titulo'] = 'al 99'
|
||||
item_local.title = '%sx%s al 99 - Season Pack' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))
|
||||
else:
|
||||
item_local.title = '%sx%s - %s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), scrapedtitle)
|
||||
|
||||
if season_display > 0:
|
||||
if item_local.contentSeason > season_display:
|
||||
continue
|
||||
elif item_local.contentSeason < season_display:
|
||||
break
|
||||
|
||||
itemlist.append(item_local.clone())
|
||||
|
||||
#logger.debug(item_local)
|
||||
|
||||
if len(itemlist) > 1:
|
||||
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
|
||||
|
||||
if item.season_colapse and not item.add_videolibrary: #Si viene de listado, mostramos solo Temporadas
|
||||
item, itemlist = generictools.post_tmdb_seasons(item, itemlist)
|
||||
|
||||
if not item.season_colapse: #Si no es pantalla de Temporadas, pintamos todo
|
||||
# Pasada por TMDB y clasificación de lista por temporada y episodio
|
||||
tmdb.set_infoLabels(itemlist, True)
|
||||
|
||||
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
|
||||
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
|
||||
|
||||
#logger.debug(item)
|
||||
|
||||
return itemlist
|
||||
|
||||
|
||||
def check_blocked_IP(data, itemlist):
|
||||
logger.info()
|
||||
thumb_separador = get_thumb("next.png")
|
||||
|
||||
if 'Please wait while we try to verify your browser...' in data:
|
||||
logger.error("ERROR 99: La IP ha sido bloqueada por la Web" + " / DATA: " + data)
|
||||
itemlist.append(Item(channel=channel, url=host, title="[COLOR yellow]La IP ha sido bloqueada por la Web.[/COLOR]", folder=False, thumbnail=thumb_separador))
|
||||
itemlist.append(Item(channel=channel, url=host, title="[COLOR yellow]Fuerce la renovación de la IP en el Router[/COLOR]", folder=False, thumbnail=thumb_separador))
|
||||
|
||||
return (True, itemlist)
|
||||
return (False, itemlist)
|
||||
|
||||
|
||||
def actualizar_titulos(item):
|
||||
logger.info()
|
||||
|
||||
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 item
|
||||
|
||||
|
||||
def search(item, texto):
|
||||
logger.info()
|
||||
texto = texto.replace(" ", "+")
|
||||
|
||||
try:
|
||||
item.url = host + 'torrents.php?category=2;18;41;49;14;48;17;44;45;47;50;51;52;42;46&search=%s' % texto
|
||||
item.extra = 'search'
|
||||
|
||||
if texto != '':
|
||||
return listado(item)
|
||||
except:
|
||||
import sys
|
||||
import traceback
|
||||
for line in sys.exc_info():
|
||||
logger.error("{0}".format(line))
|
||||
logger.error(traceback.format_exc())
|
||||
return []
|
||||
|
||||
@@ -394,11 +394,11 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
|
||||
p_dialog = platformtools.dialog_progress(config.get_localized_string(20000), config.get_localized_string(60064))
|
||||
p_dialog.update(0, config.get_localized_string(60065))
|
||||
|
||||
channel_alt = generictools.verify_channel(serie.channel) #Preparamos para añadir las urls de emergencia
|
||||
channel_alt = generictools.verify_channel(serie.channel) #Preparamos para añadir las urls de emergencia
|
||||
emergency_urls_stat = config.get_setting("emergency_urls", channel_alt) #El canal quiere urls de emergencia?
|
||||
emergency_urls_succ = False
|
||||
channel = __import__('channels.%s' % channel_alt, fromlist=["channels.%s" % channel_alt])
|
||||
if serie.torrent_caching_fail: #Si el proceso de conversión ha fallado, no se cachean
|
||||
if serie.torrent_caching_fail: #Si el proceso de conversión ha fallado, no se cachean
|
||||
emergency_urls_stat = 0
|
||||
del serie.torrent_caching_fail
|
||||
|
||||
@@ -420,10 +420,10 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
|
||||
if emergency_urls_stat == 1 and not e.emergency_urls and e.contentType == 'episode': #Guardamos urls de emergencia?
|
||||
if not silent:
|
||||
p_dialog.update(0, 'Cacheando enlaces y archivos .torrent...', e.title) #progress dialog
|
||||
if json_path in ficheros: #Si existe el .json sacamos de ahí las urls
|
||||
if overwrite: #pero solo si se se sobrescriben los .json
|
||||
if json_path in ficheros: #Si existe el .json sacamos de ahí las urls
|
||||
if overwrite: #pero solo si se se sobrescriben los .json
|
||||
json_epi = Item().fromjson(filetools.read(json_path)) #Leemos el .json
|
||||
if json_epi.emergency_urls: #si existen las urls de emergencia...
|
||||
if json_epi.emergency_urls: #si existen las urls de emergencia...
|
||||
e.emergency_urls = json_epi.emergency_urls #... las copiamos
|
||||
else: #y si no...
|
||||
e = emergency_urls(e, channel, json_path) #... las generamos
|
||||
@@ -734,20 +734,22 @@ def emergency_urls(item, channel=None, path=None):
|
||||
"""
|
||||
#lanazamos un "lookup" en el "findvideos" del canal para obtener los enlaces de emergencia
|
||||
try:
|
||||
if channel == None: #Si el llamador no ha aportado la estructura de channel, se crea
|
||||
if channel == None: #Si el llamador no ha aportado la estructura de channel, se crea
|
||||
channel = generictools.verify_channel(item.channel) #Se verifica si es un clon, que devuelva "newpct1"
|
||||
channel = __import__('channels.%s' % channel, fromlist=["channels.%s" % channel])
|
||||
if hasattr(channel, 'findvideos'): #Si el canal tiene "findvideos"...
|
||||
item.videolibray_emergency_urls = True #... se marca como "lookup"
|
||||
channel_save = item.channel #... guarda el canal original por si hay fail-over en Newpct1
|
||||
channel_save = item.channel #... guarda el canal original por si hay fail-over en Newpct1
|
||||
item_res = getattr(channel, 'findvideos')(item) #... se procesa Findvideos
|
||||
item_res.channel = channel_save #... restaura el canal original por si hay fail-over en Newpct1
|
||||
item_res.channel = channel_save #... restaura el canal original por si hay fail-over en Newpct1
|
||||
item_res.category = channel_save.capitalize() #... y la categoría
|
||||
del item_res.videolibray_emergency_urls #... y se borra la marca de lookup
|
||||
except:
|
||||
logger.error('ERROR al procesar el título en Findvideos del Canal: ' + item.channel + ' / ' + item.title)
|
||||
logger.error(traceback.format_exc())
|
||||
item_res = item.clone() #Si ha habido un error, se devuelve el Item original
|
||||
item_res = item.clone() #Si ha habido un error, se devuelve el Item original
|
||||
if item_res.videolibray_emergency_urls:
|
||||
del item_res.videolibray_emergency_urls #... y se borra la marca de lookup
|
||||
|
||||
#Si el usuario ha activado la opción "emergency_urls_torrents", se descargarán los archivos .torrent de cada título
|
||||
else: #Si se han cacheado con éxito los enlaces...
|
||||
@@ -772,10 +774,10 @@ def emergency_urls(item, channel=None, path=None):
|
||||
except:
|
||||
logger.error('ERROR al cachear el .torrent de: ' + item.channel + ' / ' + item.title)
|
||||
logger.error(traceback.format_exc())
|
||||
item_res = item.clone() #Si ha habido un error, se devuelve el Item original
|
||||
item_res = item.clone() #Si ha habido un error, se devuelve el Item original
|
||||
|
||||
#logger.debug(item_res.emergency_urls)
|
||||
return item_res #Devolvemos el Item actualizado con los enlaces de emergencia
|
||||
return item_res #Devolvemos el Item actualizado con los enlaces de emergencia
|
||||
|
||||
|
||||
def caching_torrents(url, torrents_path=None, timeout=10, lookup=False, data_torrent=False):
|
||||
@@ -794,42 +796,42 @@ def caching_torrents(url, torrents_path=None, timeout=10, lookup=False, data_tor
|
||||
"""
|
||||
|
||||
if torrents_path == None:
|
||||
videolibrary_path = config.get_videolibrary_path() #Calculamos el path absoluto a partir de la Videoteca
|
||||
videolibrary_path = config.get_videolibrary_path() #Calculamos el path absoluto a partir de la Videoteca
|
||||
if not videolibrary_path:
|
||||
torrents_path = ''
|
||||
if data_torrent:
|
||||
return (torrents_path, torrent_file)
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
torrents_path = filetools.join(videolibrary_path, 'temp_torrents_Alfa', 'cliente_torrent_Alfa.torrent') #path de descarga temporal
|
||||
if '.torrent' not in torrents_path:
|
||||
torrents_path += '.torrent' #path para dejar el .torrent
|
||||
torrents_path_encode = filetools.encode(torrents_path) #encode utf-8 del path
|
||||
torrents_path += '.torrent' #path para dejar el .torrent
|
||||
torrents_path_encode = filetools.encode(torrents_path) #encode utf-8 del path
|
||||
|
||||
if url.endswith(".rar") or url.startswith("magnet:"): #No es un archivo .torrent
|
||||
if url.endswith(".rar") or url.startswith("magnet:"): #No es un archivo .torrent
|
||||
logger.error('No es un archivo Torrent: ' + url)
|
||||
torrents_path = ''
|
||||
if data_torrent:
|
||||
return (torrents_path, torrent_file)
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
|
||||
try:
|
||||
response = httptools.downloadpage(url, timeout=timeout) #Descargamos el .torrent
|
||||
response = httptools.downloadpage(url, timeout=timeout) #Descargamos el .torrent
|
||||
if not response.sucess:
|
||||
logger.error('Archivo .torrent no encontrado: ' + url)
|
||||
torrents_path = ''
|
||||
if data_torrent:
|
||||
return (torrents_path, torrent_file)
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
torrent_file = response.data
|
||||
|
||||
if "used CloudFlare" in torrent_file: #Si tiene CloudFlare, usamos este proceso
|
||||
if "used CloudFlare" in torrent_file: #Si tiene CloudFlare, usamos este proceso
|
||||
response = httptools.downloadpage("http://anonymouse.org/cgi-bin/anon-www.cgi/" + url.strip(), timeout=timeout)
|
||||
if not response.sucess:
|
||||
logger.error('Archivo .torrent no encontrado: ' + url)
|
||||
torrents_path = ''
|
||||
if data_torrent:
|
||||
return (torrents_path, torrent_file)
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
torrent_file = response.data
|
||||
|
||||
if not scrapertools.find_single_match(torrent_file, '^d\d+:.*?\d+:'): #No es un archivo .torrent (RAR, ZIP, HTML,..., vacío)
|
||||
@@ -837,19 +839,19 @@ def caching_torrents(url, torrents_path=None, timeout=10, lookup=False, data_tor
|
||||
torrents_path = ''
|
||||
if data_torrent:
|
||||
return (torrents_path, torrent_file)
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
return torrents_path #Si hay un error, devolvemos el "path" vacío
|
||||
|
||||
if not lookup:
|
||||
if not filetools.write(torrents_path_encode, torrent_file): #Salvamos el .torrent
|
||||
if not filetools.write(torrents_path_encode, torrent_file): #Salvamos el .torrent
|
||||
logger.error('ERROR: Archivo .torrent no escrito: ' + torrents_path_encode)
|
||||
torrents_path = '' #Si hay un error, devolvemos el "path" vacío
|
||||
torrent_file = '' #... y el buffer del .torrent
|
||||
torrents_path = '' #Si hay un error, devolvemos el "path" vacío
|
||||
torrent_file = '' #... y el buffer del .torrent
|
||||
if data_torrent:
|
||||
return (torrents_path, torrent_file)
|
||||
return torrents_path
|
||||
except:
|
||||
torrents_path = '' #Si hay un error, devolvemos el "path" vacío
|
||||
torrent_file = '' #... y el buffer del .torrent
|
||||
torrents_path = '' #Si hay un error, devolvemos el "path" vacío
|
||||
torrent_file = '' #... y el buffer del .torrent
|
||||
logger.error('Error en el proceso de descarga del .torrent: ' + url + ' / ' + torrents_path_encode)
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
|
||||
@@ -423,10 +423,10 @@ def post_tmdb_listado(item, itemlist):
|
||||
else:
|
||||
title = '%s -Temporada !!!' % (title)
|
||||
|
||||
elif item.action == "search":
|
||||
elif item.action == "search" or item.extra == "search":
|
||||
title += " -Serie-"
|
||||
|
||||
if (item_local.extra == "varios" or item_local.extra == "documentales") and (item.action == "search" or item.action == "listado_busqueda"):
|
||||
if (item_local.extra == "varios" or item_local.extra == "documentales") and (item.action == "search" or item.extra == "search" or item.action == "listado_busqueda"):
|
||||
title += " -Varios-"
|
||||
item_local.contentTitle += " -Varios-"
|
||||
|
||||
@@ -764,6 +764,17 @@ def post_tmdb_episodios(item, itemlist):
|
||||
del item_local.library_filter_show
|
||||
if item_local.extra2:
|
||||
del item_local.extra2
|
||||
item_local.wanted = 'xyz'
|
||||
del item_local.wanted
|
||||
item_local.text_color = 'xyz'
|
||||
del item_local.text_color
|
||||
item_local.tmdb_stat = 'xyz'
|
||||
del item_local.tmdb_stat
|
||||
item_local.totalItems = 'xyz'
|
||||
del item_local.totalItems
|
||||
item_local.unify = 'xyz'
|
||||
del item_local.unify
|
||||
|
||||
#logger.debug(item_local)
|
||||
|
||||
#Ajustamos el nombre de la categoría si es un clone de NewPct1
|
||||
@@ -868,9 +879,9 @@ def post_tmdb_episodios(item, itemlist):
|
||||
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.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+\]\[\[?-?\s?\]?\]\[\/COLOR\]', '', item_local.title).strip()
|
||||
item_local.title = re.sub(r'\s?\[COLOR \w+\]-?\s?\[\/COLOR\]', '', item_local.title).strip()
|
||||
item_local.title = item_local.title.replace(".", ",").replace("GB", "G B").replace("Gb", "G b").replace("gb", "g b").replace("MB", "M B").replace("Mb", "M b").replace("mb", "m b")
|
||||
@@ -1831,11 +1842,11 @@ def redirect_clone_newpct1(item, head_nfo=None, it=None, path=False, overwrite=F
|
||||
#Cuando en el .json se activa "Borrar", "emergency_urls = 2", se borran todos los enlaces existentes
|
||||
#Cuando en el .json se activa "Actualizar", "emergency_urls = 3", se actualizan todos los enlaces existentes
|
||||
|
||||
status_migration = regenerate_clones() #TEMPORAL: Reparación de Videoteca con Newpct1
|
||||
|
||||
"""
|
||||
verify_cached_torrents() #TEMPORAL: verificamos si los .torrents son correctos
|
||||
try: #Si ha habido errores, vemos la lista y los reparamos
|
||||
status_migration = regenerate_clones() #TEMPORAL: Reparación de Videoteca con Newpct1
|
||||
|
||||
verify_cached_torrents() #TEMPORAL: verificamos si los .torrents son correctos
|
||||
try: #Si ha habido errores, vemos la lista y los reparamos
|
||||
json_error_path = filetools.join(config.get_runtime_path(), 'error_cached_torrents.json')
|
||||
if filetools.exists(json_error_path): #hay erroer que hay que reparar?
|
||||
from core import jsontools
|
||||
|
||||
@@ -57,7 +57,7 @@ def get_platform(full_version=False):
|
||||
"16": "jarvis", "17": "krypton", "18": "leia"}
|
||||
code_db = {'10': 'MyVideos37.db', '11': 'MyVideos60.db', '12': 'MyVideos75.db',
|
||||
'13': 'MyVideos78.db', '14': 'MyVideos90.db', '15': 'MyVideos93.db',
|
||||
'16': 'MyVideos99.db', '17': 'MyVideos107.db', '18': 'MyVideos113.db'}
|
||||
'16': 'MyVideos99.db', '17': 'MyVideos107.db', '18': 'MyVideos116.db'}
|
||||
|
||||
num_version = xbmc.getInfoLabel('System.BuildVersion')
|
||||
num_version = re.match("\d+\.\d+", num_version).group(0)
|
||||
|
||||
Reference in New Issue
Block a user