From a548fec38d6dc4528aadc30c3d55c47ea687c81d Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 22 Aug 2018 17:37:08 +0200 Subject: [PATCH 1/3] EstrenosGo: canal reestructurado MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Soporta adicionalmente: - Películas por categorías, años y alfabeto - Series completas, con episodios agrupados por temporadas - Episodios por años y alfabeto, con opción de transformación en series completas - Búsquedas, transformando episodios en series - Vídeos por Torrent además de Directos - Videoteca de Series - Control de página inteligente, en función de los items y del tiempo de proceso - Mejoras de títulos, con calidades e idiomas --- plugin.video.alfa/channels/estrenosgo.json | 64 +- plugin.video.alfa/channels/estrenosgo.py | 1248 +++++++++++++++++--- 2 files changed, 1162 insertions(+), 150 deletions(-) diff --git a/plugin.video.alfa/channels/estrenosgo.json b/plugin.video.alfa/channels/estrenosgo.json index de9ace77..5e335051 100755 --- a/plugin.video.alfa/channels/estrenosgo.json +++ b/plugin.video.alfa/channels/estrenosgo.json @@ -3,13 +3,69 @@ "name": "EstrenosGo", "active": true, "adult": false, - "language": ["cast"], - "fanart": "https://github.com/master-1970/resources/raw/master/images/fanart/estrenosgo.png", - "thumbnail": "https://github.com/master-1970/resources/raw/master/images/squares/estrenosgo.png", + "language": ["cast", "LAT", "VOSE", "VOS"], + "fanart": "estrenosgo.png", + "thumbnail": "estrenosgo.png", "banner": "estrenosgo.png", "categories": [ "movie", "tvshow", - "torrent" + "torrent", + "direct" + ], + "settings": [ + { + "default": true, + "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": "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 + }, + { + "id": "include_in_newest_peliculas", + "type": "bool", + "label": "Incluir en Novedades - Peliculas", + "default": true, + "enabled": true, + "visible": false + } ] } \ No newline at end of file diff --git a/plugin.video.alfa/channels/estrenosgo.py b/plugin.video.alfa/channels/estrenosgo.py index f5f52bd0..5fc11c5f 100644 --- a/plugin.video.alfa/channels/estrenosgo.py +++ b/plugin.video.alfa/channels/estrenosgo.py @@ -1,205 +1,1161 @@ # -*- coding: utf-8 -*- import re +import sys +import urllib +import urlparse +import time + from channelselector import get_thumb -from core import channeltools 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 core import tmdb +from lib import generictools -HOST = 'http://estrenosby.net/' # 'http://estrenosli.org/' -parameters = channeltools.get_channel_parameters('estrenosgo') -fanart_host = parameters['fanart'] -thumbnail_host = parameters['thumbnail'] +host = 'http://estrenosby.net/' # 'http://estrenosli.org/' color1, color2, color3 = ['0xFF58D3F7', '0xFF2E64FE', '0xFF0404B4'] +__modo_grafico__ = config.get_setting('modo_grafico', 'estrenosgo') +modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', 'estrenosgo') #Actualización sólo últ. Temporada? +timeout = config.get_setting('timeout_downloadpage', 'estrenosgo') def mainlist(item): logger.info() itemlist = [] - item.url = HOST - item.text_color = color2 - item.fanart = fanart_host + item.url = host + + 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_buscar = get_thumb("search.png") + thumb_separador = get_thumb("next.png") + thumb_cabecera = get_thumb("nofolder.png") - item.thumbnail = "https://github.com/master-1970/resources/raw/master/images/genres/0/Directors%20Chair.png" - itemlist.append(item.clone(title="Películas:", folder=False, text_color=color3, text_bold=True)) - itemlist.append(item.clone(title=" Cartelera", action="listado", url=HOST + "descarga-0-58126-0-0-fx-1-1-.fx")) - itemlist.append(item.clone(title=" DVD-RIP", action="listado", url=HOST + "descarga-0-581210-0-0-fx-1-1.fx")) - itemlist.append(item.clone(title=" HD-RIP", action="listado", url=HOST + "descarga-0-58128-0-0-fx-1-1-.fx")) + itemlist.append(Item(channel=item.channel, url=host, title="PELÍCULAS: ", folder=False, thumbnail=thumb_pelis)) + itemlist.append(Item(channel=item.channel, title=" - Cartelera", action="categorias", url=item.url + "descarga-0-58126", thumbnail=thumb_cartelera, extra="cartelera")) + itemlist.append(Item(channel=item.channel, title=" - DVD-RIP", action="categorias", url=item.url + "descarga-0-581210", thumbnail=thumb_pelis, extra="DVD-RIP")) + itemlist.append(Item(channel=item.channel, title=" - HD-RIP", action="categorias", url=item.url + "descarga-0-58128", thumbnail=thumb_pelis_hd, extra="HD-RIP")) + itemlist.append(Item(channel=item.channel, title=" - Subtituladas", action="categorias", url=item.url + "descarga-0-58127", thumbnail=thumb_pelis_VO, extra="VOSE")) + itemlist.append(Item(channel=item.channel, title=" - Versión Original", action="categorias", url=item.url + "descarga-0-5812255", thumbnail=thumb_pelis_VO, extra="VO")) + + itemlist.append(Item(channel=item.channel, url=host, title="", folder=False, thumbnail=thumb_separador)) + + itemlist.append(Item(channel=item.channel, url=host, title="Series", action="submenu", thumbnail=thumb_series, extra="series")) - itemlist.append(item.clone(title="", folder=False, thumbnail=thumbnail_host)) - - item.thumbnail = "https://github.com/master-1970/resources/raw/master/images/genres/0/TV%20Series.png" - itemlist.append(item.clone(title="Series:", folder=False, text_color=color3, text_bold=True)) - itemlist.append(item.clone(title=" Nuevos episodios", action="listado", - url=HOST + "descarga-0-58122-0-0-fx-1-1.fx")) + itemlist.append(Item(channel=item.channel, url=host, title="", folder=False, thumbnail=thumb_separador)) + + itemlist.append(Item(channel=item.channel, title="Buscar...", action="search", url=host + "descarga-0-0-0-0-fx-1-%s-sch-titulo-", thumbnail=thumb_buscar, extra="search")) return itemlist + +def submenu(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_buscar = get_thumb("search.png") + thumb_separador = get_thumb("next.png") + thumb_cabecera = get_thumb("nofolder.png") + if item.extra == "series": + + itemlist.append(item.clone(title="Series completas:", action="listado", url=item.url + "descarga-0-58122-0-0-fx-1-1-.fx", thumbnail=thumb_series_VOD, extra="series")) + itemlist.append(item.clone(title="Nuevos episodios", action="listado", url=item.url + "descarga-0-58122-0-0-fx-1-1-.fx", thumbnail=thumb_series, extra="episodios")) + itemlist.append(item.clone(title=" - Año", action="search", url=item.url + "descarga-0-58122-0-%s-fx-1-1-.fx", thumbnail=thumb_series, extra="episodios")) + itemlist.append(item.clone(title=" - Alfabético A-Z", action="alfabeto", url=item.url + "descarga-0-58122-0-0-%s-1-1-.fx", thumbnail=thumb_series, extra="episodios")) + + return itemlist + + +def categorias(item): + logger.info() + + itemlist = [] + + if item.extra3: + extra3 = item.extra3 + del item.extra3 + else: + extra3 = False + + data = '' + try: + data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url + '-0-0-fx-1-1-.fx', timeout=timeout).data) + except: + pass + + patron = '
(.*?)<\/a><\/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): + 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) + #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ú + + 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 = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") + 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(matches) + + #Insertamos las cabeceras para todas las peliculas de la Aalidad, por Año, Alfabético, por Género, y Otras Calidades + if not extra3: + itemlist.append(item.clone(title=item.extra.upper(), action="listado", url=item.url + '-0-0-fx-1-1-.fx')) + itemlist.append(item.clone(title="Año", action="search", url=item.url + '-0-%s-fx-1-1-.fx')) + itemlist.append(item.clone(title="Alfabético A-Z", action="alfabeto", url=item.url + '-0-0-%s-1-1-.fx')) + itemlist.append(item.clone(title="Géneros", url=item.url + '-0-0-fx-1-1-.fx')) + + for scrapedurl, scrapedtitle in matches: + title = scrapedtitle.strip() + + #Preguntamos por las entradas que corresponden al "extra" + if extra3 == 'now': + if scrapedtitle.lower() in ['ac3 51', 'bluray rip', 'series', 'serie', 'subtitulada', 'vose', 'bdrip', 'dvdscreener', 'brscreener r6', 'brscreener', 'webscreener', 'dvd', 'hdrip', 'screener', 'screeer', 'webrip', 'brrip', 'dvb', 'dvdrip', 'dvdsc', 'dvdsc - r6', 'hdts', 'hdtv', 'kvcd', 'line', 'ppv', 'telesync', 'ts hq', 'ts hq proper', '480p', '720p', 'ac3', 'bluray', 'camrip', 'ddc', 'hdtv - screener', 'tc screener', 'ts screener', 'ts screener alto', 'ts screener medio', 'vhs screener']: + itemlist.append(item.clone(action="listado", title=title, url=scrapedurl, extra2="categorias")) + + elif scrapedtitle.lower() in ['ac3 51', 'bluray rip', 'series', 'serie', 'subtitulada', 'vose', 'bdrip', 'dvdscreener', 'brscreener r6', 'brscreener', 'webscreener', 'dvd', 'hdrip', 'screener', 'screeer', 'webrip', 'brrip', 'dvb', 'dvdrip', 'dvdsc', 'dvdsc - r6', 'hdts', 'hdtv', 'kvcd', 'line', 'ppv', 'telesync', 'ts hq', 'ts hq proper', '480p', '720p', 'ac3', 'bluray', 'camrip', 'ddc', 'hdtv - screener', 'tc screener', 'ts screener', 'ts screener alto', 'ts screener medio', 'vhs screener']: + extra3 = 'next' + + else: + itemlist.append(item.clone(action="listado", title=" " + title.title(), url=scrapedurl, extra2="categorias")) + + if extra3 == 'next': + itemlist.append(item.clone(action="categorias", title="Otras Calidades", url=item.url + '-0-0-fx-1-1-.fx', extra2="categorias", extra3='now')) + + return itemlist + + +def alfabeto(item): + logger.info() + itemlist = [] + + itemlist.append(item.clone(action="listado", title="0-9", url=item.url % "_")) + + for letra in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']: + itemlist.append(item.clone(action="listado", title=letra, url=item.url % letra)) + + return itemlist + + def listado(item): logger.info() itemlist = [] - data = httptools.downloadpage(item.url).data - data = re.sub(r"\n|\r|\t|\s{2}| ", "", data) + #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 + item.url = item.url.replace('-1-.fx', '-%s-.fx') + + 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 + 10 # 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 - patron = '
.*?' - patron += ' time.time(): + + # Descarga la página + data = '' + url = item.url % curr_page #Inserto en num de página en la url + try: + data = re.sub(r"\n|\r|\t|\s{2}|()| ", "", httptools.downloadpage(url, timeout=timeout_search).data) + data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") + except: + pass + + curr_page += 1 #Apunto ya a la página siguiente + 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: " + 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 - matches = scrapertools.find_multiple_matches(data, patron) - for thumbnail, title, cat_padres, cat_hijos, opciones in matches: - # logger.debug(thumbnail + "\n" + title + "\n" + cat_padres + "\n" + cat_hijos + "\n" + opciones) - # Obtenemos el año del titulo y eliminamos lo q sobre - patron = '\d{4}$' - year = scrapertools.find_single_match(title, patron) - if year: - title = re.sub(patron, "", title) - patron = '\s?-?\s?(line)?\s?-\s?$' - regex = re.compile(patron, re.I) - title = regex.sub("", title) + #Patrón para todo menos para Series completas + patron = '
' + patron += ')| ", "", httptools.downloadpage(scrapedurl, timeout=timeout).data) + data_serie = unicode(data_serie, "iso-8859-1", errors="replace").encode("utf-8") + except: + pass + + if not data_serie: #Si la web está caída salimos sin dar error. Pintamos el episodio + logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + scrapedurl + " / SERIE: " + cat_sec) + else: + patron_serie = '
.*?.*?<\/a>.*?' + url = scrapertools.find_single_match(data_serie, patron_serie) #buscamos la url de la serie completa + if url: + url = host + url + extra = 'series' #es una serie completa + title_lista += [cat_sec] #la añadimos a la lista de series completas procesadas + title = cat_sec #salvamos el título de la serie completa + else: + url = scrapedurl #No se encuentra la Serie, se trata como Episodio suelto - # Si es necesario añadir paginacion - patron = '
.*?' - patron += 'Siguiente' - url_next_page = scrapertools.find_single_match(data, patron) - if url_next_page: - itemlist.append(Item(channel=item.channel, action="listado", title=">> Página siguiente", - thumbnail=thumbnail_host, url=HOST + url_next_page, folder=True, - text_color=color3, text_bold=True)) + elif "Archivo Torrent" not in scrapedenlace and "Video Online" not in scrapedenlace: #Si no tiene enlaces pasamos + continue + + 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.post_num: + del item_local.post_num + if item_local.category: + del item_local.category + 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 = [] #creamos lista para los idiomas + item_local.quality = '' #iniciamos calidad + quality_alt = '' + if 'series' not in cat_ppal: #si no son series, contiene la calidad + quality_alt = cat_sec.lower().strip() + item_local.extra = extra #guardamos el extra procesado + item_local.url = url #guardamos la url final + item_local.thumbnail = host[:-1] + scrapedthumbnail #guardamos el thumb + 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 ('cartelera' in cat_ppal or item.extra == "cartelera") and not item.extra2: + item_local.quality = cat_sec.lower().capitalize() + if 'peliculas-dvdrip' in cat_ppal or item_local.extra == 'DVD-RIP': + item_local.quality = 'DVD-RIP' + elif 'HDRIP' in cat_ppal or item_local.extra == 'HD-RIP': + item_local.quality = 'HD-RIP' + elif 'subtituladas' in cat_ppal or item_local.extra == 'VOSE': + item_local.language += ['VOSE'] + elif 'Version Original' in cat_ppal or item_local.extra == 'VO': + item_local.language += ['VO'] + + #Analizamos los formatos de series, temporadas y episodios + elif item_local.extra == 'series': + item_local.contentType = "tvshow" + item_local.action = "episodios" + item_local.season_colapse = True #Muestra las series agrupadas por temporadas + elif 'series' in cat_ppal or item_local.extra == 'episodios': + item_local.contentType = "episode" + item_local.extra = "episodios" + if "Temp" in title or "emporada" in title: + try: + item_local.contentSeason = int(scrapertools.find_single_match(title, '[t|T]emp.*?(\d+)')) + except: + item_local.contentSeason = 1 + title = re.sub(r'[t|T]emp.*?\d+', '', title) + title_subs += ["Temporada"] + item_local.contentType = "season" + item_local.extra = "season" + + if item_local.contentType == "movie": #para las peliculas ponemos el mismo extra + item_local.extra = "peliculas" + + #Detectamos idiomas + if "Latino" in cat_sec or "latino" in cat_sec or "Latino" in title or "latino" in title or "LATINO" in title: + item_local.language += ['LAT'] + elif "VOSE" in cat_sec or "VOS" in cat_sec or "VOSE" in title or "VOS" in title: + item_local.language += ['VOSE'] + + if item_local.language == []: + item_local.language = ['CAST'] + + #Procesamos calidades + if not item_local.quality: + if quality_alt in ['dvdscreener', 'brscreener r6', 'brscreener', 'webscreener', 'dvd', 'hdrip', 'screener', 'screeer', 'webrip', 'brrip', 'dvb', 'dvdrip', 'dvdsc', 'dvdsc - r6', 'hdts', 'hdtv', 'kvcd', 'line', 'ppv', 'telesync', 'ts hq', 'ts hq proper', '480p', '720p', 'ac3', 'bluray', 'camrip', 'ddc', 'hdtv - screener', 'tc screener', 'ts screener', 'ts screener alto', 'ts screener medio', 'vhs screener']: + item_local.quality = quality_alt.capitalize() + + #Detectamos el año + patron = '(\d{4})\s*?(?:\)|\])?$' + item_local.infoLabels["year"] = '-' + year = '' + year = scrapertools.find_single_match(title, patron) + if year: + title_alt = re.sub(patron, "", title) + title_alt = title_alt.strip() + if title_alt: + title = title_alt + try: + year = int(year) + if year >= 1970 and year <= 2040: + item_local.infoLabels["year"] = year + except: + pass + + #Detectamos info importante a guardar para después de TMDB + if scrapertools.find_single_match(title, '[m|M].*?serie'): + title = re.sub(r'[m|M]iniserie', '', title) + title_subs += ["Miniserie"] + if scrapertools.find_single_match(title, '[s|S]aga'): + title = re.sub(r'[s|S]aga', '', title) + title_subs += ["Saga"] + if scrapertools.find_single_match(title, '[c|C]olecc'): + title = re.sub(r'[c|C]olecc...', '', title) + title_subs += ["Colección"] + + #Empezamos a limpiar el título en varias pasadas + patron = '\s?-?\s?(line)?\s?-\s?$' + regex = re.compile(patron, re.I) + title = regex.sub("", title) + title = re.sub(r'\(\d{4}\s*?\)', '', title) + title = re.sub(r'\[\d{4}\s*?\]', '', title) + title = re.sub(r'- $', '', title) + title = re.sub(r'\d+[M|m|G|g][B|b]', '', title) + + #Limpiamos el título de la basura innecesaria + 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", "").replace("LATINO", "").replace("Spanish", "").replace("Esp", "").replace("Trailer", "").replace("Audio", "") + title = title.replace("HDTV-Screener", "").replace("DVDSCR", "").replace("TS ALTA", "").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", "").replace(" 480p", "").replace(" 480P", "").replace(" 720p", "").replace(" 720P", "").replace(" 1080p", "").replace(" 1080P", "").replace("DVDRip", "").replace(" Dvd", "").replace(" DVD", "").replace(" V.O", "").replace(" Unrated", "").replace(" UNRATED", "").replace(" unrated", "").replace("screener", "").replace("TS-SCREENER", "").replace("TSScreener", "").replace("HQ", "").replace("AC3 5.1", "").replace("Telesync", "").replace("Line Dubbed", "").replace("line Dubbed", "").replace("LineDuB", "").replace("Line", "").replace("XviD", "").replace("xvid", "").replace("XVID", "").replace("Mic Dubbed", "").replace("HD", "").replace("V2", "").replace("CAM", "").replace("VHS.SCR", "") + + #Obtenemos temporada y episodio si se trata de Episodios + if item_local.contentType == "episode": + patron = '(\d+)[x|X](\d+)' + try: + item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(title, patron) + except: + item_local.contentSeason = 1 + item_local.contentEpisodeNumber = 0 + + #Si son eisodios múltiples, lo extraemos + patron1 = '\d+[x|X]\d+.?(?:y|Y|al|Al)?.?\d+[x|X](\d+)' + epi_rango = scrapertools.find_single_match(title, patron1) + if epi_rango: + item_local.infoLabels['episodio_titulo'] = 'al %s' % epi_rango + title = re.sub(patron1, '', title) + else: + title = re.sub(patron, '', title) + + #Terminamos de limpiar el título + title = re.sub(r'\??\s?\d*?\&.*', '', title) + 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() + + if item_local.contentType == "episode": + item_local.title = '%sx%s ' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2)) + item_local.extra3 = 'completa' + else: + 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'] + + itemlist.append(item_local.clone()) #Pintar pantalla + + #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=item.url, extra=item.extra, extra2=item.extra2, last_page=str(last_page), curr_page=str(curr_page))) return itemlist + +def listado_series(item): + logger.info() + itemlist = [] + matches = [] + matches_current = 0 + pag = 30 + + #logger.debug(item) + + #Control de paginación + matches = item.matches #Restauramos la matches de la primera pasada + del item.matches + matches_tot = len(matches) #La web no pagina las Series, lo tenemos que controlar + if item.matches_current: #Llevamos los contadores de cuánto hemos pintado y cuánto queda + matches_current = item.matches_current + if matches_tot >= matches_current + pag: + item.matches_current = matches_current + pag #Establecemos el bloque a pintar en este pasada + else: + item.matches_current = matches_tot + #logger.debug(matches[matches_current:item.matches_current]) + + #procesamos una página + for scrapedurl, scrapedtitle in matches[matches_current:item.matches_current]: + item_local = item.clone() #Creamos copia de Item para trabajar + + if scrapertools.find_single_match(scrapedtitle, '\d+[x|X]\d+'): #Si es episodio suelto, pasamos + continue + + if item_local.tipo: + del item_local.tipo + if item_local.totalItems: + del item_local.totalItems + if item_local.post_num: + del item_local.post_num + if item_local.category: + del item_local.category + if item_local.intervencion: + del item_local.intervencion + if item_local.viewmode: + del item_local.viewmode + if item_local.matches_current: + del item_local.matches_current + 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 + + #Iniciamos variables + title_subs = [] + item_local.language = [] + item_local.quality = '' + title = scrapedtitle + + #Empezamos a construir el Item de salida + item_local.url = scrapedurl + item_local.context = "['buscar_trailer']" + item_local.contentType = "tvshow" + item_local.action = "episodios" + item_local.season_colapse = True #Muestra las series agrupadas por temporadas + + #Tratamos idiomas, aunque hay poco... + if "Latino" in title or "latino" in title: + item_local.language += ['LAT'] + elif "VOSE" in title or "VOS" in title: + item_local.language += ['VOSE'] + + if item_local.language == []: + item_local.language = ['CAST'] + + #Establecemos el título + item_local.contentSerieName = title.strip().lower().title() + item_local.title = title.strip().lower().title() + item_local.from_title = title.strip().lower().title() + + itemlist.append(item_local.clone()) #Pintar pantalla + + #logger.debug(item_local) + + #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, __modo_grafico__) + + #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB + item, itemlist = generictools.post_tmdb_listado(item, itemlist) + + #Control de siguiente página + if matches_tot > item.matches_current: + pag_tot = matches_tot / pag + pag_cur = item.matches_current / pag + + itemlist.append(Item(channel=item.channel, action="listado_series", title=">> Página siguiente (" + str(pag_cur) + " de " + str(pag_tot) + ")", url=item.url, text_color=color3, text_bold=True, extra=item.extra, matches_current=item.matches_current, matches=matches)) + + return itemlist + + def findvideos(item): logger.info() itemlist = [] - list_opciones = [] - IDIOMAS = {"banderita1": "Español", "banderita2": "VOSE", "banderita3": "Latino"} + + #logger.debug(item) + + IDIOMAS = {"banderita1": "CAST", "banderita2": "VOSE", "banderita3": "LAT"} - url = HOST + "ver-online-" + item.url - - data = httptools.downloadpage(url).data - data = re.sub(r"\n|\r|\t|\s{2}| ", "", data) + #Bajamos los datos de la página + data_torrent = '' + data_directo = '' + try: + url = item.url.replace('/descargar-', '/descargar-torrent-').replace('.fx', '-aportes.fx') + data_torrent = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(url, timeout=timeout).data) + url = item.url.replace('/descargar-', '/ver-online-').replace('.fx', '-aportes.fx') + data_directo = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(url, timeout=timeout).data) + except: + pass + + if not data_torrent and not data_directo: + 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 patron = '
Ver Online<\/a>.*?href="([^"]+)">') != url: #error + logger.error("ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web " + " / PATRON: " + patron) + 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')) + if data_torrent: + logger.error(data_torrent) + if data_directo: + logger.error(data_directo) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #logger.debug("PATRON: " + patron) + #logger.debug(matches_torrent) + #logger.debug(matches_directo) + #logger.debug(data_torrent) + #logger.debug(data_directo) + + #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) + + #Si es un Episodio suelto, tratamos de poner un enlace a la Serie completa + if item.extra3 == 'completa': + del item.extra3 + item_local = item.clone() + + #Salvamos lo imprescindible y reinicialmos InfoLabels + tmdb_id = item.infoLabels['tmdb_id'] + item_local.infoLabels = {} + item_local.unify = True + del item_local.unify + + #Restauramos lo básico + item.infoLabels['tmdb_id'] = tmdb_id + item_local.contentSerieName = item_local.from_title + item_local.title = item_local.from_title + item_local.quality = '' + item.infoLabels['year'] = '-' + item_local.contentType = 'tvshow' + item_local.extra = 'series' + item_local.action = 'episodios' + item_local.season_colapse = True #Muestra las series agrupadas por temporadas + + #Buscamos la url de la serie y verificamos que existe + patron_serie = '
' + item_local.url = scrapertools.find_single_match(data_torrent, patron_serie) #buscamos la url de la serie completa + if not item_local.url: + item_local.url = scrapertools.find_single_match(data_directo, patron_serie) #buscamos la url de la serie completa + if item_local.url: + item_local.url = item_local.url.replace('descargar-torrent', 'descarga').replace('-0-0-0-0-fx-', '-0-0-fx-') + try: + tmdb.set_infoLabels(item_local, True) #TMDB de la serie completa + except: + pass + + #Solo si hay url de Serie lo pintamos + itemlist.append(item_local.clone(title="** [COLOR yelow]Ver la Serie COMPLETA[/COLOR] **")) - for url, banderita in matches: - idioma = "" - if banderita in IDIOMAS: - idioma = " [%s]" % IDIOMAS[banderita] + #Ahora tratamos los enlaces .torrent + itemlist_alt = [] #Usamos una lista intermedia para poder ordenar los episodios + if matches_torrent: + for scrapedurl, scrapedquality, scrapedlang in matches_torrent: #leemos los torrents con la diferentes calidades + #Generamos una copia de Item para trabajar sobre ella + item_local = item.clone() + + item_local.url = scrapedurl #Guardamos la url intermedia + + if scrapedquality and not '--' in scrapedquality: #Salvamos la calidad, si la hay + item_local.quality = scrapedquality.lower().capitalize() + + if scrapertools.find_single_match(item.quality, '(\[\d+:\d+ h\])'): #Salvamos la duración + item_local.quality += ' [COLOR white]%s' % scrapertools.find_single_match(item.quality, '(\[\d+:\d+ h\])') #Copiamos la duración - data = httptools.downloadpage(url).data - data = re.sub(r"\n|\r|\t|\s{2}| ", "", data) - - if item.extra == 'multi-episodie': - patron = '
Video Online:([^<]+).*?)", "", httptools.downloadpage(item_local.url, timeout=timeout).data) + except: + pass + + patron = '
Descargar Torrent: <\/span>
»\s?(.*?)\s?«<\/a>' matches = re.compile(patron, re.DOTALL).findall(data) - for capitulo, url in matches: - s = servertools.findvideos(url, skip=True) - if s: - itemlist.append(item.clone(url=s[0][1], action="play", folder=False, server=s[0][2], - title="Ver %s en %s%s" % ( - capitulo.strip(), s[0][2].capitalize(), idioma), - thumbnail2=item.thumbnail, - thumbnail=get_thumb("server_" + s[0][2] + ".png"), - language = idioma)) - else: - import os - for s in servertools.findvideos(data): - itemlist.append(item.clone(url=s[1], action="play", folder=False, server=s[2], - title="Ver en %s%s" % (s[2].capitalize(), idioma), - thumbnail2=item.thumbnail, - thumbnail=os.path.join(config.get_runtime_path(), "resources", "media", - "servers", "server_" + s[2] + ".png"), - language = idioma)) + + if not data or not matches: + logger.error("ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / URL: " + item_local.url + " / DATA: " + data) + continue #si no hay más datos, algo no funciona, pasamos a Ver Online + + #logger.debug(patron) + #logger.debug(matches) + #logger.debug(data) + + for scrapedtorrent, scrapedtitle in matches: + quality = item_local.quality + qualityscraped = '' + if not item_local.contentEpisodeNumber and item_local.contentType == 'episode': + item_local.contentEpisodeNumber = 0 + + #Si son episodios múltiples, los listamos con sus títulos + if len(matches) > 1 or len(itemlist_alt) > 1: + if item_local.contentType == 'episode' or item_local.contentType == 'season': + if scrapertools.find_single_match(scrapedtitle, '(\d+[x|X]\d+(?:-\d{1,2})?)'): + qualityscraped = '%s' % scrapertools.find_single_match(scrapedtitle, '(\d+[x|X]\d+(?:-\d{1,2})?)') + if scrapertools.find_single_match(scrapedtitle, '\d+[x|X](\d+)'): + item_local.contentEpisodeNumber = int(scrapertools.find_single_match(scrapedtitle, '\d+[x|X](\d+)')) + elif scrapertools.find_single_match(scrapedtitle, '[c|C]ap.*?(\d+)'): + item_local.contentEpisodeNumber = int(scrapertools.find_single_match(scrapedtitle, '[c|C]ap.*?(\d+)')) + elif scrapertools.find_single_match(scrapedtorrent, '[s|S]\d{1,2}[e|E](\d{1,2})'): + item_local.contentEpisodeNumber = int(scrapertools.find_single_match(scrapedtorrent, '[s|S]\d{1,2}[e|E](\d{1,2})')) + if not qualityscraped: + qualityscraped = '%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2)) + else: + qualityscraped = '%s' % scrapedtitle + + #Si todavía no sabemos el num de Episodio, lo buscamos + if not item_local.contentEpisodeNumber and item_local.contentType == 'episode': + try: + if scrapertools.find_single_match(scrapedtitle, '(\d+)[x|X](\d+)'): + item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(scrapedtitle, '(\d+)[x|X](\d+)') + qualityscraped = '%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2)) + except: + pass + + #Buscamos calidades + if scrapertools.find_single_match(scrapedtitle, '(\d+p)'): + qualityscraped += ' ' + scrapertools.find_single_match(scrapedtitle, '(\d+p)') + if qualityscraped: + quality = '[%s] %s' % (qualityscraped, item_local.quality) - # Insertar items "Buscar trailer" y "Añadir a la videoteca" - if itemlist and item.extra == "movie": - if item.contentQuality: - title = "%s [%s]" % (item.contentTitle, item.contentQuality) - else: - title = item.contentTitle + #Ahora pintamos el link del Torrent + item_local.url = host + scrapedtorrent + 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) #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_alt.append(item_local.clone(quality=quality)) #Pintar pantalla - itemlist.insert(0, item.clone(channel="trailertools", action="buscartrailer", - text_color=color3, title=title, viewmode="list")) + #logger.debug("TORRENT: " + scrapedtorrent + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + scrapedsize + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName) + #logger.debug(item_local) + + #Si son múltiples episodios, ordenamos + if len(itemlist_alt) > 1 and (item.contentType == 'episode' or item.contentType == 'season'): + itemlist_alt = sorted(itemlist_alt, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos + tmdb.set_infoLabels(itemlist_alt, True) #TMDB de la lista de episodios + itemlist.extend(itemlist_alt) - if config.get_videolibrary_support(): - itemlist.append(Item(channel=item.channel, title="Añadir película a la videoteca", - action="add_pelicula_to_library", url=item.url, text_color="green", - contentTitle=item.contentTitle, extra="library", thumbnail=thumbnail_host)) + #Ahora tratamos los servidores directo + itemlist_alt = [] + if matches_directo: + for scrapedurl, scrapedquality, scrapedlang in matches_directo: #leemos los torrents con la diferentes calidades + #Generamos una copia de Item para trabajar sobre ella + item_local = item.clone() + + item_local.url = scrapedurl #Guardamos la url intermedia + + if scrapedquality: + item_local.quality = scrapedquality + + if scrapertools.find_single_match(item.quality, '(\[\d+:\d+ h\])'): #Salvamos la duración + item_local.quality += ' [COLOR white]%s' % scrapertools.find_single_match(item.quality, '(\[\d+:\d+ h\])') #Copiamos la duración + + if scrapedlang in IDIOMAS: + item_local.language = ["%s" % IDIOMAS[scrapedlang]] #Salvamos el idioma, si lo hay + + #Leemos la página con el enlace al Servidor + try: + data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item_local.url, timeout=timeout).data) + except: + pass + + patron = '
Video Online:\s?([^<]+)?<\/span>

1 or len(itemlist_alt) > 1) and not servidor in scrapedtitle: + if not capitulo and (item_local.contentType == 'episode' or item_local.contentType == 'season'): + if scrapertools.find_single_match(scrapedtitle, '(\d+[x|X]\d+(?:-\d{1,2})?)'): + qualityscraped = '%s' % scrapertools.find_single_match(scrapedtitle, '(\d+[x|X]\d+(?:-\d{1,2})?)') + if scrapertools.find_single_match(scrapedtitle, '\d+[x|X](\d+)'): + item_local.contentEpisodeNumber = int(scrapertools.find_single_match(scrapedtitle, '\d+[x|X](\d+)')) + elif scrapertools.find_single_match(scrapedtitle, '[c|C]ap.*?(\d+)'): + item_local.contentEpisodeNumber = int(scrapertools.find_single_match(scrapedtitle, '[c|C]ap.*?(\d+)')) + elif scrapertools.find_single_match(scrapedtorrent, '[s|S]\d{1,2}[e|E](\d{1,2})'): + item_local.contentEpisodeNumber = int(scrapertools.find_single_match(scrapedtorrent, '[s|S]\d{1,2}[e|E](\d{1,2})')) + if not qualityscraped: + qualityscraped = '%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2)) + elif capitulo: + if scrapertools.find_single_match(capitulo, '\d+[x|X](\d+)'): + item_local.contentEpisodeNumber = int(scrapertools.find_single_match(scrapedtitle, '\d+[x|X](\d+)')) + qualityscraped = '%s' % capitulo + else: + qualityscraped = '%s' % scrapedtitle + + #Si todavía no sabemos el num de Episodio, lo buscamos + if not item_local.contentEpisodeNumber and item_local.contentType == 'episode': + try: + if scrapertools.find_single_match(scrapedtitle, '(\d+)[x|X](\d+)'): + item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(scrapedtitle, '(\d+)[x|X](\d+)') + qualityscraped = '%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2)) + except: + pass + + #Buscamos calidades + if scrapertools.find_single_match(scrapedenlace, '(\d+p)'): + qualityscraped += ' ' + scrapertools.find_single_match(scrapedenlace, '(\d+p)') + if qualityscraped: + quality = '[%s] %s' % (qualityscraped, item_local.quality) + + if scrapertools.find_single_match(item.url, '(\d+x\d+.*?\d+x\d+)') and not capitulo and not qualityscraped: + quality = '[%s] %s' % (scrapertools.find_single_match(scrapedenlace, '(\d+x\d+)'), quality) + elif capitulo and not qualityscraped: + quality = '[%s] %s' % (capitulo, quality) + + #Verificamos el si el enlace del servidor está activo + if config.get_setting("hidepremium"): #Si no se aceptan servidore premium, se ignoran + mostrar_server = servertools.is_server_enabled(servidor) + + try: #Obtenemos el enlace + if mostrar_server: + devuelve = servertools.findvideosbyserver(scrapedenlace, servidor) #existe el link ? + if devuelve: + enlace = devuelve[0][1] #Se guarda el link + if not enlace: + continue + + item_local.alive = servertools.check_video_link(enlace, servidor, timeout=timeout) #activo el link ? + #Si el link no está activo se ignora + if item_local.alive == "??": #dudoso + item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (servidor.capitalize(), quality, str(item_local.language)) + elif item_local.alive.lower() == "no": #No está activo. Lo preparo, pero no lo pinto + item_local.title = '[COLOR red][%s][/COLOR] [COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.alive, servidor.capitalize(), quality, str(item_local.language)) + logger.debug(item_local.alive + ": ALIVE / " + servidor + " / " + enlace) + raise + else: #Sí está activo + item_local.title = '[COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (servidor.capitalize(), quality, str(item_local.language)) + + #Ahora pintamos el link Directo + item_local.url = enlace + item_local.title = '[COLOR yellow][%s][/COLOR] [COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.alive, servidor.capitalize(), quality, str(item_local.language)) #Preparamos título de Directo + 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.action = "play" #Visualizar vídeo + item_local.server = servidor #Seridor Directo + + itemlist_alt.append(item_local.clone(quality=quality)) #Pintar pantalla + except: + pass + + #logger.debug("DIRECTO: " + scrapedenlace + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + scrapedsize + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName) + #logger.debug(item_local) + + #Si son múltiples episodios, ordenamos + if len(itemlist_alt) > 1 and (item.contentType == 'episode' or item.contentType == 'season'): + itemlist_alt = sorted(itemlist_alt, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos + tmdb.set_infoLabels(itemlist_alt, True) #TMDB de la lista de episodios + itemlist.extend(itemlist_alt) return itemlist - -def play(item): + +def episodios(item): logger.info() itemlist = [] + + #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 + url_item = item.url.replace('1-.fx', '%s-.fx').replace('-1.fx', '-%s.fx') + 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 - # Cambiamos el thumbnail del server por el de la pelicula - itemlist.append(item.clone(thumbnail=item.thumbnail2)) + # 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) + + while curr_page <= last_page: + + # Descarga la página + data = '' + url = url_item % curr_page #Inserto en num de página en la url + try: + data = re.sub(r"\n|\r|\t|\s{2}|()| ", "", httptools.downloadpage(url, timeout=timeout).data) + data = unicode(data, "iso-8859-1", 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 + + curr_page += 1 #Apunto ya a la página siguiente + + #Usamos el mismo patrón que en listado + patron = '
' + patron += ' 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 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: + if item.extra == "search": + item.url = item.url + texto + "-sch.fx" + else: + item.url = item.url % texto + + if texto != '': + return listado(item) + except: + import sys + for line in sys.exc_info(): + logger.error("{0}".format(line)) + return [] + + +def newest(categoria): + logger.info() + itemlist = [] + item = Item() + + try: + if categoria == 'peliculas': + item.url = host + 'descarga-0-58128-0-0-fx-1-1-.fx' + item.extra = "HD-RIP" + item.channel = "estrenosgo" + 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 From 7b9337a8501f63af156307096709e134ef083280 Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 22 Aug 2018 17:37:56 +0200 Subject: [PATCH 2/3] DatoPorn: cambio de estructura --- plugin.video.alfa/channels/datoporn.py | 21 ++++++++++++++------- plugin.video.alfa/servers/datoporn.py | 8 +++++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/plugin.video.alfa/channels/datoporn.py b/plugin.video.alfa/channels/datoporn.py index a63ebc25..b70f37af 100755 --- a/plugin.video.alfa/channels/datoporn.py +++ b/plugin.video.alfa/channels/datoporn.py @@ -1,5 +1,7 @@ # -*- coding: utf-8 -*- +import re + from core import httptools from core import scrapertools from platformcode import logger @@ -9,8 +11,8 @@ def mainlist(item): logger.info() itemlist = [] - itemlist.append(item.clone(action="categorias", title="Categorías", url="http://dato.porn/categories_all")) - itemlist.append(item.clone(title="Buscar...", action="search")) + itemlist.append(item.clone(action="categorias", title="Categorías", url="http://dato.porn/categories_all", contentType="movie", viewmode="movie")) + itemlist.append(item.clone(title="Buscar...", action="search", contentType="movie", viewmode="movie")) return itemlist @@ -25,22 +27,27 @@ def lista(item): itemlist = [] # Descarga la pagina - data = httptools.downloadpage(item.url).data + data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url).data) # Extrae las entradas - patron = '
\s*(.*?).*?(.*?)' + patron = '
\s*(.*?)<\/span><\/div><\/a>.*?class="title">(.*?)<\/a>.*?<\/a><\/span><\/div> ' matches = scrapertools.find_multiple_matches(data, patron) for scrapedurl, scrapedthumbnail, duration, scrapedtitle in matches: if "/embed-" not in scrapedurl: - scrapedurl = scrapedurl.replace("dato.porn/", "dato.porn/embed-") + ".html" + #scrapedurl = scrapedurl.replace("dato.porn/", "dato.porn/embed-") + ".html" + scrapedurl = scrapedurl.replace("datoporn.co/", "datoporn.co/embed-") + ".html" if duration: scrapedtitle = "%s - %s" % (duration, scrapedtitle) + scrapedtitle += ' gb' + scrapedtitle = scrapedtitle.replace(":", "'") + #logger.debug(scrapedurl + ' / ' + scrapedthumbnail + ' / ' + duration + ' / ' + scrapedtitle) itemlist.append(item.clone(action="play", title=scrapedtitle, url=scrapedurl, thumbnail=scrapedthumbnail, server="datoporn", fanart=scrapedthumbnail.replace("_t.jpg", ".jpg"))) - # Extrae la marca de siguiente página - next_page = scrapertools.find_single_match(data, 'Next') + # Extrae la marca de siguiente página + #next_page = scrapertools.find_single_match(data, 'Next') + next_page = scrapertools.find_single_match(data, 'Next') if next_page and itemlist: itemlist.append(item.clone(action="lista", title=">> Página Siguiente", url=next_page)) diff --git a/plugin.video.alfa/servers/datoporn.py b/plugin.video.alfa/servers/datoporn.py index e5b98efd..47f04015 100755 --- a/plugin.video.alfa/servers/datoporn.py +++ b/plugin.video.alfa/servers/datoporn.py @@ -25,7 +25,10 @@ def get_video_url(page_url, premium=False, user="", password="", video_password= media_urls = scrapertools.find_multiple_matches(data, 'file\:"([^"]+\.mp4)",label:"([^"]+)"') if not media_urls: match = scrapertools.find_single_match(data, "p,a,c,k(.*?)") - data = jsunpack.unpack(match) + try: + data = jsunpack.unpack(match) + except: + pass media_urls = scrapertools.find_multiple_matches(data, 'file\:"([^"]+\.mp4)",label:"([^"]+)"') # Extrae la URL @@ -41,6 +44,9 @@ def get_video_url(page_url, premium=False, user="", password="", video_password= sorted(calidades) m3u8 = scrapertools.find_single_match(data, 'file\:"([^"]+\.m3u8)"') + if not m3u8: + m3u8 = str(scrapertools.find_multiple_matches(data, 'player.updateSrc\({src:.?"([^"]+\.m3u8)"')).replace("['", "").replace("']", "") + calidades = ['720p'] if m3u8: video_urls.insert(0, [".m3u8 %s [datoporn]" % calidades[-1], m3u8]) From 5d3e7f38de106d8444e9d677b3daa4dfee4a3353 Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 22 Aug 2018 17:38:54 +0200 Subject: [PATCH 3/3] NewPct1: mejoras de alta disponibilidad episodios --- plugin.video.alfa/channels/elitetorrent.py | 1 + plugin.video.alfa/channels/mejortorrent1.py | 6 +- plugin.video.alfa/channels/newpct1.json | 2 +- plugin.video.alfa/channels/newpct1.py | 534 +++++++++++--------- plugin.video.alfa/lib/generictools.py | 135 +++-- 5 files changed, 380 insertions(+), 298 deletions(-) diff --git a/plugin.video.alfa/channels/elitetorrent.py b/plugin.video.alfa/channels/elitetorrent.py index c4b74f07..0faf759c 100644 --- a/plugin.video.alfa/channels/elitetorrent.py +++ b/plugin.video.alfa/channels/elitetorrent.py @@ -377,6 +377,7 @@ def newest(categoria): if categoria == 'torrent': item.url = host item.extra = "peliculas" + item.category_new= 'newest' itemlist = listado(item) if itemlist[-1].title == "Página siguiente >>": diff --git a/plugin.video.alfa/channels/mejortorrent1.py b/plugin.video.alfa/channels/mejortorrent1.py index 4718f6a8..f2cf315f 100644 --- a/plugin.video.alfa/channels/mejortorrent1.py +++ b/plugin.video.alfa/channels/mejortorrent1.py @@ -1008,10 +1008,11 @@ def newest(categoria): try: if categoria == 'peliculas': item.url = host + "peliculas/" - item.extra = "novedades" + item.extra = "peliculas" item.channel = "mejortorrent1" + item.category_new= 'newest' item.tipo = False - itemlist = listado_busqueda(item) + itemlist = listado(item) if "Pagina siguiente >>" in itemlist[-1].title: itemlist.pop() @@ -1019,6 +1020,7 @@ def newest(categoria): item.url = host + "documentales/" item.extra = "documentales" item.channel = "mejortorrent1" + item.category_new= 'newest' item.tipo = False itemlist = listado(item) if "Pagina siguiente >>" in itemlist[-1].title: diff --git a/plugin.video.alfa/channels/newpct1.json b/plugin.video.alfa/channels/newpct1.json index c01d3a25..63ed5864 100644 --- a/plugin.video.alfa/channels/newpct1.json +++ b/plugin.video.alfa/channels/newpct1.json @@ -534,7 +534,7 @@ { "id": "include_in_newest_latino", "type": "bool", - "label": "Incluir en Novedades - Documentales", + "label": "Incluir en Novedades - Latino", "default": true, "enabled": true, "visible": false diff --git a/plugin.video.alfa/channels/newpct1.py b/plugin.video.alfa/channels/newpct1.py index ed7d1ed5..489713fc 100644 --- a/plugin.video.alfa/channels/newpct1.py +++ b/plugin.video.alfa/channels/newpct1.py @@ -62,9 +62,9 @@ elif fecha_rango == 4: fecha_rango = 'Siempre' episodio_serie = config.get_setting('clonenewpct1_serie_episodio_novedades', channel_py) #Episodio o serie para Novedades #Temporal, sólo para actualizar newpct1_data.json con otro valor por defecto -channel_banned = config.get_setting('clonenewpct1_excluir1_enlaces_veronline', channel_py) #1er Canal baneado -if channel_banned == 9: - config.set_setting('clonenewpct1_excluir1_enlaces_veronline', 22, channel_py) #se pone el nuevo valor por defecto +#channel_banned = config.get_setting('clonenewpct1_excluir1_enlaces_veronline', channel_py) #1eer Canal baneado +#if channel_banned == 9: +# config.set_setting('clonenewpct1_excluir1_enlaces_veronline', 22, channel_py) #se pone el nuevo valor por defecto def mainlist(item): @@ -86,9 +86,9 @@ def mainlist(item): thumb_buscar = get_thumb("search.png") thumb_settings = get_thumb("setting_0.png") - if channel_clone_name == "*** DOWN ***": #Ningún clones activo !!! + if channel_clone_name == "*** DOWN ***": #Ningún clones activo !!! itemlist.append(item.clone(action='', title="[COLOR yellow]Ningún canal NewPct1 activo[/COLOR]")) - return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos y salimos + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos y salimos itemlist.append(Item(channel=item.channel, action="submenu_novedades", title="Novedades", url=item.channel_host + "ultimas-descargas/", extra="novedades", thumbnail=thumb_pelis, category=item.category, channel_host=item.channel_host)) @@ -148,8 +148,8 @@ def submenu(item): if not data: #Si no ha logrado encontrar nada, salimos itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.category + '[/COLOR]: Ningún canal NewPct1 activo')) 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 - elif item.channel_alt: #Si ha habido fail-over, lo comento + 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.category + '[/COLOR] [ALT ] en uso')) itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] inaccesible')) @@ -157,15 +157,15 @@ def submenu(item): del item.channel_alt data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") - data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com - if "pelisyseries.com" in item.channel_host and item.extra == "varios": #compatibilidad con mispelisy.series.com + data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com + if "pelisyseries.com" in item.channel_host and item.extra == "varios": #compatibilidad con mispelisy.series.com data = '
  • Documentales
  • ' else: - data = scrapertools.get_match(data, patron) #Seleccionamos el trozo que nos interesa + data = scrapertools.get_match(data, patron) #Seleccionamos el trozo que nos interesa if not data: 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 + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos patron = '
  • ([^>]+)<\/a><\/li>' matches = re.compile(patron, re.DOTALL).findall(data) @@ -173,7 +173,7 @@ def submenu(item): 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 + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos for scrapedurl, scrapedtitle in matches: title = scrapedtitle.strip() @@ -197,7 +197,7 @@ def submenu_novedades(item): itemlist_alt = [] data = '' - timeout_search=timeout * 2 #Más tiempo para Novedades, que es una búsqueda + timeout_search=timeout * 2 #Más tiempo para Novedades, que es una búsqueda thumb_settings = get_thumb("setting_0.png") #Establecer los valores del .json por si se entra directamente desde un favorito @@ -206,9 +206,9 @@ def submenu_novedades(item): item.category = scrapertools.find_single_match(item.url, 'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').capitalize() item.extra = "novedades" - if channel_clone_name == "*** DOWN ***": #Ningún clones activo !!! + if channel_clone_name == "*** DOWN ***": #Ningún clones activo !!! itemlist.append(item.clone(action='', title="[COLOR yellow]Ningún canal NewPct1 activo[/COLOR]")) - return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos y salimos + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos y salimos try: data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, timeout=timeout_search).data) @@ -229,20 +229,20 @@ def submenu_novedades(item): #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 + if not data: #Si no ha logrado encontrar nada, salimos itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.category + '[/COLOR]: Ningún canal NewPct1 activo')) 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 - elif item.channel_alt: #Si ha habido fail-over, lo comento + 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.category + '[/COLOR] [ALT ] en uso')) itemlist.append(item.clone(action='', title="[COLOR yellow]" + item.channel_alt.capitalize() + '[/COLOR] inaccesible')) if item.url_alt: del item.url_alt del item.channel_alt - data = scrapertools.get_match(data, patron) #Seleccionamos el trozo que nos interesa + data = scrapertools.get_match(data, patron) #Seleccionamos el trozo que nos interesa data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") - data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com + data = data.replace("'", '"').replace('/series"', '/series/"') #Compatibilidad con mispelisy.series.com patron = '
  • ' in data_alt: #error logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data_alt) itemlist.append(item.clone(action='', title=item.category + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log')) - item, itemlist = generictools.post_tmdb_listado(item, itemlist) #Pintamos los datos de fail-over, si los hay - return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + item, itemlist = generictools.post_tmdb_listado(item, itemlist) #Pintamos los datos de fail-over, si los hay + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos #Ahora se hace una simulación para saber cuantas líneas podemos albergar en este Itemlist. #Se controlará cuantas páginas web se tienen que leer para rellenar la lista, sin pasarse - title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE + title_lista_alt_for = [] #usamos está lista de urls para el FOR, luego la integramos en la del WHILE for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, year, size in matches_alt: #Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas #Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora #Cuando llega al num. máximo de entradas por página, la pinta y guarda los contadores y la lista de series scrapedurl_alt = scrapedurl - if "pelisyseries.com" in host: #Excepción para mispelisyseries.com. - scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - scrapedurl_alt = re.sub(r'\/\d{5,7}', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item - continue # solo guardamos la url para series y docus + if "pelisyseries.com" in host: #Excepción para mispelisyseries.com. + scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + scrapedurl_alt = re.sub(r'\/\d{5,7}', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + if scrapedurl_alt in title_lista_alt: # si ya se ha tratado, pasamos al siguiente item + continue # solo guardamos la url para series y docus - if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item - continue # solo guardamos la url para series y docus + if scrapedurl_alt in title_lista_alt or scrapedurl_alt in title_lista_alt_for or scrapedthumbnail in title_lista_alt or scrapedthumbnail in title_lista_alt_for: # si ya se ha tratado, pasamos al siguiente item + continue # solo guardamos la url para series y docus if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl: title_lista_alt_for += [scrapedurl_alt] + title_lista_alt_for += [scrapedthumbnail] - if "juego/" in scrapedurl: # no mostramos lo que no sean videos + if "juego/" in scrapedurl: # no mostramos lo que no sean videos continue - cnt_title += 1 # Sería una línea real más para Itemlist + cnt_title += 1 # Sería una línea real más para Itemlist #Control de página - if cnt_title > cnt_tot*0.65: #si se acerca al máximo num. de lineas por pagina, tratamos lo que tenemos - cnt_next = 99 #Casi completo, no sobrepasar con la siguiente página + if cnt_title > cnt_tot*0.65: #si se acerca al máximo num. de lineas por pagina, tratamos lo que tenemos + cnt_next = 99 #Casi completo, no sobrepasar con la siguiente página if cnt_title > cnt_tot: - cnt_title = 99 #Sobrepasado el máximo. Ignoro página actual - item.post = post_actual #Restauro puntero "next" a la página actual, para releearla en otra pasada - post_num -= 1 #Restauro puntero a la página actual en el pie de página + cnt_title = 99 #Sobrepasado el máximo. Ignoro página actual + item.post = post_actual #Restauro puntero "next" a la página actual, para releearla en otra pasada + post_num -= 1 #Restauro puntero a la página actual en el pie de página break if cnt_title <= cnt_tot: - matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página + matches.extend(matches_alt) #Acumulamos las entradas a tratar. Si nos hemos pasado ignoro última página title_lista_alt.extend(title_lista_alt_for) #logger.debug("PATRON: " + pattern) @@ -813,26 +815,28 @@ def listado_busqueda(item): #Realiza un control de las series que se añaden, ya que el buscador devuelve episodios y no las series completas #Se analiza si la url de la serie ya se ha listado antes. Si es así, esa entrada se ignora #El control de página ya se ha realizado más arriba - if "pelisyseries.com" in host: #Excepción para mispelisyseries.com. + if "pelisyseries.com" in host: #Excepción para mispelisyseries.com. scrapedurl_alt = scrapedurl - scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - scrapedurl_alt = re.sub(r'\/\d{5,7}', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie - if scrapedurl_alt in title_lista: # si ya se ha tratado, pasamos al siguiente item - continue # solo guardamos la url para series y docus + scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+-al-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-\d+', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + scrapedurl_alt = re.sub(r'\/[c|C]ap.*?-', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + scrapedurl_alt = re.sub(r'\/\d{5,7}', '', scrapedurl_alt) #Scrapeo el capítulo para hacerlo serie + if scrapedurl_alt in title_lista: # si ya se ha tratado, pasamos al siguiente item + continue # solo guardamos la url para series y docus - if scrapedurl in title_lista: # si ya se ha tratado, pasamos al siguiente item - continue # solo guardamos la url para series y docus + if scrapedurl in title_lista or scrapedthumbnail in title_lista: # si ya se ha tratado, pasamos al siguiente item + continue # solo guardamos la url para series y docus if ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl: if "pelisyseries.com" in host: title_lista += [scrapedurl_alt] else: title_lista += [scrapedurl] + title_lista += [scrapedthumbnail] + if ("juego/" in scrapedurl or "xbox" in scrapedurl.lower()) and not "/serie" in scrapedurl or "xbox" in scrapedtitle.lower() or "windows" in scrapedtitle.lower() or "windows" in calidad.lower() or "nintendo" in scrapedtitle.lower() or "xbox" in calidad.lower() or "epub" in calidad.lower() or "pdf" in calidad.lower() or "pcdvd" in calidad.lower() or "crack" in calidad.lower(): # no mostramos lo que no sean videos continue - cnt_title += 1 # Sería una línea real más para Itemlist + cnt_title += 1 # Sería una línea real más para Itemlist #Creamos una copia de Item para cada contenido item_local = item.clone() @@ -864,9 +868,9 @@ def listado_busqueda(item): #Si son episodios sueltos de Series que vienen de Novedades, se busca la url de la Serie if item.extra == "novedades" and "/serie" in url and episodio_serie == 1: item_local.url = url - item_local.extra2 = 'serie_episodios' #Creamos acción temporal excluyente para otros clones - if item_local.category == 'Mispelisyseries': #Esta web no gestiona bien el cambio de episodio a Serie - pattern = 'class="btn-torrent">.*?window.location.href = "([^"]+)";' #Patron para .torrent + item_local.extra2 = 'serie_episodios' #Creamos acción temporal excluyente para otros clones + if item_local.category == 'Mispelisyseries': #Esta web no gestiona bien el cambio de episodio a Serie + pattern = 'class="btn-torrent">.*?window.location.href = "([^"]+)";' #Patron para .torrent #Como no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el cambio de episodio por serie item_local, data_serie = generictools.fail_over_newpct1(item_local, pattern) else: @@ -875,25 +879,25 @@ def listado_busqueda(item): except: pass - pattern = 'class="btn-torrent">.*?window.location.href = "([^"]+)";' #Patron para .torrent + pattern = '' in data): logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item_local.url + " / DATA: " + data_serie) #Si no hay datos consistentes, llamamos al método de fail_over para que encuentre un canal que esté activo y pueda gestionar el cambio de episodio por serie item_local, data_serie = generictools.fail_over_newpct1(item_local, pattern) - if not data_serie: #Si no ha logrado encontrar nada, salimos + if not data_serie: #Si no ha logrado encontrar nada, salimos title_subs += ["ERR"] - elif item_local.channel_alt: #Si ha habido fail-over, lo comento + elif item_local.channel_alt: #Si ha habido fail-over, lo comento url = url.replace(item_local.channel_alt, item_local.category.lower()) title_subs += ["ALT"] try: - pattern = '
    .*?

    .*? 1: #para los demás valores, tomamos los de la lista + if ver_enlaces_veronline > 1: #para los demás valores, tomamos los de la lista ver_enlaces_veronline = int(ver_enlaces[ver_enlaces_veronline]) #Carga la variable de verificar verificar_enlaces_veronline = int(config.get_setting("clonenewpct1_verificar_enlaces_veronline", item.channel)) - if verificar_enlaces_veronline == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0 + if verificar_enlaces_veronline == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0 verificar_enlaces_veronline = -1 - if verificar_enlaces_veronline > 1: #para los demás valores, tomamos los de la lista + if verificar_enlaces_veronline > 1: #para los demás valores, tomamos los de la lista verificar_enlaces_veronline = int(ver_enlaces[verificar_enlaces_veronline]) #Carga la variable de contar sólo los servidores verificados @@ -1217,26 +1222,26 @@ def findvideos(item): #Carga la variable de lista de servidores excluidos x = 1 - for x in range(1, max_excl+1): #recorremos todas las opciones de canales exluidos + for x in range(1, max_excl+1): #recorremos todas las opciones de canales exluidos valor = str(config.get_setting("clonenewpct1_excluir%s_enlaces_veronline" % x, item.channel)) valor = int(valor) - if valor > 0: #Evitamos "No" - excluir_enlaces_veronline += [channel_exclude[valor]] #Añadimos el nombre de servidor excluido a la lista + if valor > 0: #Evitamos "No" + excluir_enlaces_veronline += [channel_exclude[valor]] #Añadimos el nombre de servidor excluido a la lista x += 1 #Segundo loop para enlaces de Descargar. #Carga la variable de ver ver_enlaces_descargas = int(config.get_setting("clonenewpct1_ver_enlaces_descargas", item.channel)) - if ver_enlaces_descargas == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0 + if ver_enlaces_descargas == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0 ver_enlaces_descargas = -1 - if ver_enlaces_descargas > 1: #para los demás valores, tomamos los de la lista + if ver_enlaces_descargas > 1: #para los demás valores, tomamos los de la lista ver_enlaces_descargas = int(ver_enlaces[ver_enlaces_descargas]) #Carga la variable de verificar verificar_enlaces_descargas = int(config.get_setting("clonenewpct1_verificar_enlaces_descargas", item.channel)) - if verificar_enlaces_descargas == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0 + if verificar_enlaces_descargas == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0 verificar_enlaces_descargas = -1 - if verificar_enlaces_descargas > 1: #para los demás valores, tomamos los de la lista + if verificar_enlaces_descargas > 1: #para los demás valores, tomamos los de la lista verificar_enlaces_descargas = int(ver_enlaces[verificar_enlaces_descargas]) #Carga la variable de contar sólo los servidores verificados @@ -1244,14 +1249,14 @@ def findvideos(item): #Carga la variable de lista de servidores excluidos x = 1 - for x in range(1, max_excl+1): #recorremos todas las opciones de canales exluidos + for x in range(1, max_excl+1): #recorremos todas las opciones de canales exluidos valor = str(config.get_setting("clonenewpct1_excluir%s_enlaces_descargas" % x, item.channel)) valor = int(valor) - if valor > 0: #Evitamos "No" - excluir_enlaces_descargas += [channel_exclude[valor]] #Añadimos el nombre de servidor excluido a la lista + if valor > 0: #Evitamos "No" + excluir_enlaces_descargas += [channel_exclude[valor]] #Añadimos el nombre de servidor excluido a la lista x += 1 - except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables + except Exception, ex: #En caso de error, lo mostramos y reseteamos todas las variables logger.error("Error en la lectura de parámentros del .json del canal: " + item.channel + " \n%s" % ex) #Mostrar los errores logger.error(ver_enlaces_veronline) @@ -1263,53 +1268,82 @@ def findvideos(item): logger.error(verificar_enlaces_descargas_validos) logger.error(excluir_enlaces_descargas) #Resetear las variables a sus valores por defecto - ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online - verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online - verificar_enlaces_veronline_validos = True #"¿Contar sólo enlaces 'verificados' en Ver Online?" - excluir_enlaces_veronline = [] #Lista vacía de servidores excluidos en Ver Online - ver_enlaces_descargas = 0 #Ver todos los enlaces Descargar - verificar_enlaces_descargas = -1 #Verificar todos los enlaces Descargar - verificar_enlaces_descargas_validos = True #"¿Contar sólo enlaces 'verificados' en Descargar?" - excluir_enlaces_descargas = [] #Lista vacía de servidores excluidos en Descargar + ver_enlaces_veronline = -1 #Ver todos los enlaces Ver Online + verificar_enlaces_veronline = -1 #Verificar todos los enlaces Ver Online + verificar_enlaces_veronline_validos = True #"¿Contar sólo enlaces 'verificados' en Ver Online?" + excluir_enlaces_veronline = [] #Lista vacía de servidores excluidos en Ver Online + ver_enlaces_descargas = 0 #Ver todos los enlaces Descargar + verificar_enlaces_descargas = -1 #Verificar todos los enlaces Descargar + verificar_enlaces_descargas_validos = True #"¿Contar sólo enlaces 'verificados' en Descargar?" + excluir_enlaces_descargas = [] #Lista vacía de servidores excluidos en Descargar # Descarga la página data = '' try: data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url, timeout=timeout).data) + data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures") + url_servidores = item.url + category_servidores = item.category + data_servidores = data #salvamos data para verificar servidores, si es necesario except: pass - patron = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent + 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): - 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 - return itemlist #Salimos + 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 + return itemlist #Salimos 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.category + ': 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 + if not data: #Si no ha logrado encontrar nada, verificamos si hay servidores + cnt_servidores = 0 + item.category = category_servidores #restauramos valores originales + item.url = url_servidores + + # Nuevo sistema de scrapeo de servidores creado por Torrentlocula, compatible con otros clones de Newpct1 + patron = '
    <\/div[^<]+
    ([^<]+)?<\/div[^<]+
    ([^<]+)?' + patron += '<\/div[^<]+
    ([^<]+)?<\/div[^<]+
    (?:)?<\/div><\/div><\/div>)') #Seleccionar el bloque para evitar duplicados @@ -1365,15 +1399,15 @@ def findvideos(item): cnt_enl_ver = 1 cnt_enl_verif = 1 for logo, servidor, idioma, calidad, enlace, title in enlaces_ver: - if ver_enlaces_veronline == 0: #Si no se quiere Ver Online, se sale del bloque + if ver_enlaces_veronline == 0: #Si no se quiere Ver Online, se sale del bloque break if "ver" in title.lower(): servidor = servidor.replace("streamin", "streaminto") - if servidor.capitalize() in excluir_enlaces_veronline: #Servidor excluido, pasamos al siguiente + if servidor.capitalize() in excluir_enlaces_veronline: #Servidor excluido, pasamos al siguiente continue mostrar_server = True - if config.get_setting("hidepremium"): #Si no se aceptan servidore premium, se ignoran + if config.get_setting("hidepremium"): #Si no se aceptan servidore premium, se ignoran mostrar_server = servertools.is_server_enabled(servidor) #logger.debug("VER: url: " + enlace + " / title: " + title + " / servidor: " + servidor + " / idioma: " + idioma) @@ -1382,37 +1416,37 @@ def findvideos(item): if mostrar_server: try: if cnt_enl_ver <= ver_enlaces_veronline or ver_enlaces_veronline == -1: - devuelve = servertools.findvideosbyserver(enlace, servidor) #existe el link ? + devuelve = servertools.findvideosbyserver(enlace, servidor) #existe el link ? if verificar_enlaces_veronline == 0: cnt_enl_ver += 1 else: - break #Si se ha agotado el contador de verificación, se sale de Ver Online + break #Si se ha agotado el contador de verificación, se sale de Ver Online - if devuelve: #Hay link - enlace = devuelve[0][1] #Se guarda el link - item_local.alive = "??" #Se asume poe defecto que es link es dudoso - if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo? + if devuelve: #Hay link + enlace = devuelve[0][1] #Se guarda el link + item_local.alive = "??" #Se asume poe defecto que es link es dudoso + if verificar_enlaces_veronline != 0: #Se quiere verificar si el link está activo? if cnt_enl_verif <= verificar_enlaces_veronline or verificar_enlaces_veronline == -1: #contador? #Llama a la subfunción de check_list_links(itemlist) para cada link de servidor item_local.alive = servertools.check_video_link(enlace, servidor, timeout=timeout) #activo el link ? - if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos? - if item_local.alive == "Ok": #Sí - cnt_enl_verif += 1 #Movemos los contadores - cnt_enl_ver += 1 #Movemos los contadores - else: #Si no es necesario que sean links válidos, sumamos - cnt_enl_verif += 1 #Movemos los contadores - cnt_enl_ver += 1 #Movemos los contadores + if verificar_enlaces_veronline_validos: #Los links tienen que ser válidos para contarlos? + if item_local.alive == "Ok": #Sí + cnt_enl_verif += 1 #Movemos los contadores + cnt_enl_ver += 1 #Movemos los contadores + else: #Si no es necesario que sean links válidos, sumamos + cnt_enl_verif += 1 #Movemos los contadores + cnt_enl_ver += 1 #Movemos los contadores else: - break #Si se ha agotado el contador de verificación, se sale de Ver Online + break #Si se ha agotado el contador de verificación, se sale de Ver Online #Si el link no está activo se ignora - if item_local.alive == "??": #dudoso + if item_local.alive == "??": #dudoso item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (servidor.capitalize(), item_local.quality, str(item_local.language)) elif item_local.alive.lower() == "no": #No está activo. Lo preparo, pero no lo pinto item_local.title = '[COLOR red][%s][/COLOR] [COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.alive, servidor.capitalize(), item_local.quality, str(item_local.language)) logger.debug(item_local.alive + ": ALIVE / " + title + " / " + servidor + " / " + enlace) raise - else: #Sí está activo + else: #Sí está activo item_local.title = '[COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (servidor.capitalize(), item_local.quality, str(item_local.language)) #Preparamos el resto de variables de Item para ver los vídeos en directo @@ -1430,7 +1464,7 @@ def findvideos(item): if len(enlaces_descargar) > 0 and ver_enlaces_descargas != 0: #Pintamos un pseudo-título de Descargas - if not item.unify: #Si Titulos Inteligentes NO seleccionados: + if not item.unify: #Si Titulos Inteligentes NO seleccionados: itemlist.append(item_local.clone(title="[COLOR gold]**- Enlaces Descargar: -**[/COLOR]", action="")) else: itemlist.append(item_local.clone(title="[COLOR gold] Enlaces Descargar: [/COLOR]", action="")) @@ -1444,10 +1478,10 @@ def findvideos(item): if "Ver" not in title: servidor = servidor.replace("uploaded", "uploadedto") - partes = enlace.split(" ") #Partimos el enlace en cada link de las partes - title = "Descarga" #Usamos la palabra reservada de Unify para que no formatee el título + partes = enlace.split(" ") #Partimos el enlace en cada link de las partes + title = "Descarga" #Usamos la palabra reservada de Unify para que no formatee el título - if servidor.capitalize() in excluir_enlaces_descargas: #Servidor excluido, pasamos al siguiente + if servidor.capitalize() in excluir_enlaces_descargas: #Servidor excluido, pasamos al siguiente continue #logger.debug("DESCARGAR: url: " + enlace + " / title: " + title + title + " / servidor: " + servidor + " / idioma: " + idioma) @@ -1461,7 +1495,7 @@ def findvideos(item): parte_title = "[COLOR yellow]%s-[/COLOR] %s %s/%s [COLOR limegreen]-%s[/COLOR] [COLOR red]-%s[/COLOR]" % (servidor.capitalize(), title, p, len(partes), item_local.quality, str(item_local.language)) p += 1 mostrar_server = True - if config.get_setting("hidepremium"): #Si no se aceptan servidore premium, se ignoran + if config.get_setting("hidepremium"): #Si no se aceptan servidore premium, se ignoran mostrar_server = servertools.is_server_enabled(servidor) #Si el servidor es válido, se comprueban si los links están activos @@ -1472,8 +1506,8 @@ def findvideos(item): if verificar_enlaces_descargas == 0: cnt_enl_ver += 1 else: - ver_enlaces_descargas = 0 #FORZAR SALIR de DESCARGAS - break #Si se ha agotado el contador de verificación, se sale de "Enlace" + ver_enlaces_descargas = 0 #FORZAR SALIR de DESCARGAS + break #Si se ha agotado el contador de verificación, se sale de "Enlace" if devuelve: enlace = devuelve[0][1] @@ -1489,20 +1523,20 @@ def findvideos(item): if item_local.alive == "Ok": #Sí cnt_enl_verif += 1 #Movemos los contadores cnt_enl_ver += 1 #Movemos los contadores - else: #Si no es necesario que sean links válidos, sumamos + else: #Si no es necesario que sean links válidos, sumamos cnt_enl_verif += 1 #Movemos los contadores cnt_enl_ver += 1 #Movemos los contadores else: ver_enlaces_descargas = 0 #FORZAR SALIR de DESCARGAS - break #Si se ha agotado el contador de verificación, se sale de "Enlace" + break #Si se ha agotado el contador de verificación, se sale de "Enlace" - if item_local.alive == "??": #dudoso - if not item.unify: #Si titles Inteligentes NO seleccionados: + if item_local.alive == "??": #dudoso + if not item.unify: #Si titles Inteligentes NO seleccionados: parte_title = '[COLOR yellow][?][/COLOR] %s' % (parte_title) else: parte_title = '[COLOR yellow]%s[/COLOR]-%s' % (item_local.alive, parte_title) - elif item_local.alive.lower() == "no": #No está activo. Lo preparo, pero no lo pinto - if not item.unify: #Si titles Inteligentes NO seleccionados: + elif item_local.alive.lower() == "no": #No está activo. Lo preparo, pero no lo pinto + if not item.unify: #Si titles Inteligentes NO seleccionados: parte_title = '[COLOR red][%s][/COLOR] %s' % (item_local.alive, parte_title) else: parte_title = '[COLOR red]%s[/COLOR]-%s' % (item_local.alive, parte_title) @@ -1534,14 +1568,14 @@ def episodios(item): item.channel_host = host item.category = scrapertools.find_single_match(item.url, 'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').capitalize() - verify_fo = True #Verificamos si el clone a usar está activo + verify_fo = True #Verificamos si el clone a usar está activo item, data = generictools.fail_over_newpct1(item, verify_fo) #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 + 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" @@ -1559,19 +1593,19 @@ def episodios(item): # Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca if not item.infoLabels['tmdb_id']: try: - tmdb.set_infoLabels(item, True) #TMDB de cada Temp + tmdb.set_infoLabels(item, True) #TMDB de cada Temp except: pass modo_ultima_temp_alt = modo_ultima_temp - if item.ow_force == "1": #Si hay un traspaso de canal o url, se actualiza todo + 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 + 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: @@ -1582,13 +1616,13 @@ def episodios(item): data_alt = '' try: if "pelisyseries.com" in item.url: - patron = '
      (.*?)
    ' % "chapters" # item.pattern + patron = '
      (.*?)
    ' % "chapters" # item.pattern else: - patron = '
      (.*?)
    ' % "buscar-list" # item.pattern + patron = '
      (.*?)
    ' % "buscar-list" # item.pattern data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, timeout=timeout).data) if data: data_alt = scrapertools.get_match(data, patron) - except: #Algún error de proceso + except: #Algún error de proceso pass if "pelisyseries.com" in item.url: @@ -1609,7 +1643,7 @@ def episodios(item): #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 + 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.category + ': 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 @@ -1622,7 +1656,7 @@ def episodios(item): act_page = int(scrapertools.find_single_match(item.url, r'\/pg\/(\d+)')) #Num página actual else: act_page = 1 - pattern = '
  • Last<\/a>' #Busca última página + pattern = '
  • Last<\/a>' #Busca última página full_url = scrapertools.find_single_match(pagination, pattern) url, last_page = scrapertools.find_single_match(full_url, r'(.*?\/pg\/)(\d+)') last_page = int(last_page) @@ -1642,32 +1676,32 @@ def episodios(item): num_temporadas_flag = True else: num_temporadas_flag = False - for page in list_pages: #Recorre la lista de páginas + for page in list_pages: #Recorre la lista de páginas if not list_pages: break try: if not data: data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(page, timeout=timeout).data) data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8") - data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com - pattern = '
      (.*?)
    ' % "buscar-list" # item.pattern + data = data.replace("chapters", "buscar-list") #Compatibilidad con mispelisy.series.com + pattern = '
      (.*?)
    ' % "buscar-list" # item.pattern data = scrapertools.get_match(data, pattern) if not data: raise except: 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.category + ': 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 + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos if "pelisyseries.com" in item.url: pattern = ']*>
    ]+>(?P.*?)?<\/h3>.*?<\/li>' else: pattern = ']*>]+>(?P.*?)?<\/h2>' matches = re.compile(pattern, re.DOTALL).findall(data) - if not matches: #error + if not matches: #error logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + data) itemlist.append(item.clone(action='', title=item.category + ': 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 + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos #logger.debug("patron: " + pattern) #logger.debug(matches) @@ -1676,32 +1710,32 @@ def episodios(item): for scrapedurl, scrapedthumb, info in matches: url = scrapedurl thumb = scrapedthumb - if "pelisyseries.com" in item.url: #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 - item_local = item.clone() #Creamos copia local de Item por episodio + item_local = item.clone() #Creamos copia local de Item por episodio item_local.url = url item_local.contentThumbnail = thumb - estado = True #Buena calidad de datos por defecto + estado = True #Buena calidad de datos por defecto - if ".*?)?(?P\d)[x|X|\.](?P\d{2})\s?(?:_(?P\d+)(?P\d{2}))?.*?(?P.*)?'): pattern = "(?P.*?)?(?P\d)[x|X|\.](?P\d{2})\s?(?:_(?P\d+)(?P\d{2}))?.*?(?P.*)?" - estado = False #Mala calidad de datos - if not scrapertools.find_single_match(info, pattern): #en caso de error de formato, creo uno básico + estado = False #Mala calidad de datos + if not scrapertools.find_single_match(info, pattern): #en caso de error de formato, creo uno básico logger.debug("patron episodioOLD: " + pattern) logger.debug(info) logger.debug(item_local.url) info = '%s - Temp.%s [%s][Cap.%s00][Spanish]' % (item_local.contentSerieName, season, item_local.quality, season) - estado = False #Mala calidad de datos + estado = False #Mala calidad de datos r = re.compile(pattern) match = [m.groupdict() for m in r.finditer(info)][0] if not match: #error logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + pattern + " / DATA: " + info) itemlist.append(item.clone(action='', title=item.category + ': 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 + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos - if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico + if match['season'] is None: match['season'] = season #Si no se encuentran valores, pero poner lo básico if match['episode'] is None: match['episode'] = "0" try: match['season'] = int(match['season']) @@ -1766,7 +1800,7 @@ def episodios(item): max_temp = season if match['quality'] and not item_local.quality and estado == True: - item_local.quality = match['quality'] #Si hay quality se coge, si no, la de la serie + 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 or "especia" in str(match['lang']).lower()): @@ -1775,18 +1809,18 @@ def episodios(item): item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo'] - if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca + if match['episode'] == 0: match['episode'] = 1 #Evitar errores en Videoteca item_local.contentEpisodeNumber = match['episode'] - if match["episode2"]: #Hay episodio dos? es una entrada múltiple? - item_local.title = "%sx%s al %s -" % (str(match["season"]), str(match["episode"]).zfill(2), str(match["episode2"]).zfill(2)) #Creamos un título con el rango de episodios - else: #Si es un solo episodio, se formatea ya + if match["episode2"]: #Hay episodio dos? es una entrada múltiple? + item_local.title = "%sx%s al %s -" % (str(match["season"]), str(match["episode"]).zfill(2), str(match["episode2"]).zfill(2)) #Creamos un título con el rango de episodios + else: #Si es un solo episodio, se formatea ya item_local.title = "%sx%s -" % (match["season"], str(match["episode"]).zfill(2)) - if modo_ultima_temp_alt and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca + if modo_ultima_temp_alt and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca if item_local.contentSeason < max_temp: - list_pages = [] #Sale del bucle de leer páginas - break #Sale del bucle actual del FOR de episodios por página + list_pages = [] #Sale del bucle de leer páginas + break #Sale del bucle actual del FOR de episodios por página #if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts: # continue @@ -1816,10 +1850,10 @@ def episodios(item): 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 + 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 + 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) diff --git a/plugin.video.alfa/lib/generictools.py b/plugin.video.alfa/lib/generictools.py index 639d374d..d569c642 100644 --- a/plugin.video.alfa/lib/generictools.py +++ b/plugin.video.alfa/lib/generictools.py @@ -248,7 +248,7 @@ def post_tmdb_listado(item, itemlist): #logger.debug(item_local) item_local.last_page = 0 - del item_local.last_page #Borramos restos de paginación + del item_local.last_page #Borramos restos de paginación if item_local.contentSeason_save: #Restauramos el num. de Temporada item_local.contentSeason = item_local.contentSeason_save @@ -268,7 +268,7 @@ def post_tmdb_listado(item, itemlist): 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 + if "audio" in title_subs.lower(): #se restaura info de Audio 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 @@ -280,13 +280,7 @@ def post_tmdb_listado(item, itemlist): title_add = '%s -%s-' % (title_add, title_subs) #se agregan el resto de etiquetas salvadas item_local.title_subs = [] del item_local.title_subs - - if item_local.from_title: - if item_local.contentType == 'movie': - item_local.contentTitle = item_local.from_title - else: - item_local.contentSerieName = item_local.from_title - + #Preparamos el Rating del vídeo rating = '' try: @@ -319,6 +313,15 @@ def post_tmdb_listado(item, itemlist): if item_local.infoLabels['aired']: item_local.infoLabels['year'] = scrapertools.find_single_match(str(item_local.infoLabels['aired']), r'\/(\d{4})') + if item_local.from_title: + if item_local.contentType == 'movie': + item_local.contentTitle = item_local.from_title + item_local.title = item_local.from_title + else: + item_local.contentSerieName = item_local.from_title + if item_local.contentType == 'season': + item_local.title = item_local.from_title + # Preparamos el título para series, con los núm. de temporadas, si las hay if item_local.contentType in ['season', 'tvshow', 'episode']: if item_local.contentType == "episode": @@ -738,10 +741,10 @@ def post_tmdb_episodios(item, itemlist): 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 "Temporada" in item_local.title: #Compatibilizamos "Temporada" con Unify + 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 - if " al 99" in item_local.title.lower(): #Temporada completa. Buscamos num total de episodios de la temporada + if " al " in item_local.title: #Si son episodios múltiples, ponemos nombre de serie + if " al 99" in item_local.title.lower(): #Temporada completa. Buscamos num total de episodios de la temporada item_local.title = item_local.title.replace("99", str(num_episodios)) item_local.title = '%s %s' % (item_local.title, item_local.contentSerieName) item_local.infoLabels['episodio_titulo'] = '%s - %s [%s] [%s]' % (scrapertools.find_single_match(item_local.title, r'(al \d+)'), item_local.contentSerieName, item_local.infoLabels['year'], rating) @@ -886,7 +889,7 @@ def post_tmdb_findvideos(item, itemlist): En Itemlist devuelve un Item con el pseudotítulo. Ahí el canal irá agregando el resto. """ - logger.debug(item) + #logger.debug(item) #Creción de título general del vídeo a visualizar en Findvideos itemlist = [] @@ -900,6 +903,10 @@ def post_tmdb_findvideos(item, itemlist): item.unify = config.get_setting("unify") except: item.unify = config.get_setting("unify") + + if item.contentSeason_save: #Restauramos el num. de Temporada + item.contentSeason = item.contentSeason_save + del item.contentSeason_save #Salvamos la información de max num. de episodios por temporada para despues de TMDB num_episodios = item.contentEpisodeNumber @@ -988,20 +995,26 @@ def post_tmdb_findvideos(item, itemlist): item.category = item.channel.capitalize() #Formateamos de forma especial el título para un episodio + title = '' + title_gen = '' if item.contentType == "episode": #Series title = '%sx%s' % (str(item.contentSeason), str(item.contentEpisodeNumber).zfill(2)) #Temporada y Episodio if item.infoLabels['temporada_num_episodios']: title = '%s (de %s)' % (title, str(item.infoLabels['temporada_num_episodios'])) #Total Episodios #Si son episodios múltiples, y viene de Videoteca, ponemos nombre de serie - if " al " in item.title and not " al " in item.infoLabels['episodio_titulo']: - title = '%s al %s - ' % (title, scrapertools.find_single_match(item.title, 'al (\d+)')) + if (" al " in item.title or " Al " in item.title) and not "al " in item.infoLabels['episodio_titulo']: + title = '%s al %s - ' % (title, scrapertools.find_single_match(item.title, '[al|Al] (\d+)')) else: title = '%s %s' % (title, item.infoLabels['episodio_titulo']) #Título Episodio - title_gen = '%s, %s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] [%s]' % (title, item.contentSerieName, item.infoLabels['year'], rating, item.quality, str(item.language), scrapertools.find_single_match(item.title, '\s\[(\d+,?\d*?\s\w[b|B])\]')) #Rating, Calidad, Idioma, Tamaño + title_gen = '%s, ' % title + + if item.contentType == "episode" or item.contentType == "season": #Series o Temporadas + title_gen += '%s [COLOR yellow][%s][/COLOR] [%s] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] [%s]' % (item.contentSerieName, item.infoLabels['year'], rating, item.quality, str(item.language), scrapertools.find_single_match(item.title, '\s\[(\d+,?\d*?\s\w[b|B])\]')) #Rating, Calidad, Idioma, Tamaño if item.infoLabels['status'] and item.infoLabels['status'].lower() == "ended": title_gen = '[TERM.] %s' % title_gen #Marca cuando la Serie está terminada y no va a haber más producción item.title = title_gen + else: #Películas title = item.title title_gen = item.title @@ -1041,10 +1054,11 @@ def post_tmdb_findvideos(item, itemlist): item.quality = '[COLOR yellow][%s][/COLOR] %s' % (channel, item.quality) #agregamos la opción de Añadir a Videoteca para péliculas (no series) - if item.contentType == 'movie' and item.contentChannel != "videolibrary": + if (item.contentType == 'movie' or item.contentType == 'season') and item.contentChannel != "videolibrary": #Permitimos la actualización de los títulos, bien para uso inmediato, o para añadir a la videoteca itemlist.append(item.clone(title="** [COLOR yelow]Actualizar Títulos - vista previa videoteca[/COLOR] **", action="actualizar_titulos", extra="películas", tmdb_stat=False, from_action=item.action, from_title_tmdb=item.title, from_update=True)) + if item.contentType == 'movie' and item.contentChannel != "videolibrary": itemlist.append(item.clone(title="**-[COLOR yellow] Añadir a la videoteca [/COLOR]-**", action="add_pelicula_to_library", extra="películas", from_action=item.action, from_title_tmdb=item.title)) #Añadimos la opción de ver trailers @@ -1171,6 +1185,7 @@ def fail_over_newpct1(item, patron, patron2=None, timeout=None): data = '' channel_failed = '' + url_alt = [] if not item.category: item.category = scrapertools.find_single_match(item.url, 'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').capitalize() if not item.extra2: @@ -1226,48 +1241,78 @@ def fail_over_newpct1(item, patron, patron2=None, timeout=None): item.url_alt = channel_url_failed item.url = channel_url_failed item.url = item.url.replace(channel_host_failed, channel_host) + url_alt += [item.url] #salvamos la url para el bucle item.channel_host = 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... + url_alt = [item.url] #salvamos la url para el bucle, pero de momento ignoramos la inicial con código de serie + + #si es un episodio, generalizamos la url para que se pueda encontrar en otro clone. Quitamos la calidad del final de la url + elif item.action == "findvideos" and item.contentType == "episode": + try: + #quitamos el 0 a la izquierda del episodio. Algunos clones no lo aceptan + inter1, inter2, inter3 = scrapertools.find_single_match(item.url, '(http.*?\/temporada-\d+.*?\/capitulo.?-)(\d+)(.*?\/)') + inter2 = re.sub(r'^0', '', inter2) + if inter1 + inter2 + inter3 not in url_alt: + url_alt += [inter1 + inter2 + inter3] + + #en este formato solo quitamos la calidad del final de la url + if scrapertools.find_single_match(item.url, 'http.*?\/temporada-\d+.*?\/capitulo.?-\d+.*?\/') not in url_alt: + url_alt += [scrapertools.find_single_match(item.url, 'http.*?\/temporada-\d+.*?\/capitulo.?-\d+.*?\/')] + except: + logger.error("ERROR 88: " + item.action + ": Error al convertir la url: " + item.url) + logger.debug('URLs convertidas: ' + str(url_alt)) if patron == True: #solo nos han pedido verificar el clone return (item, data) #nos vamos, con un nuevo clone - #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=timeout).data) - else: - data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url, timeout=timeout).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 + #Leemos la nueva url.. Puede haber varias alternativas a la url original + for url in url_alt: + try: + if item.post: + data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(url, post=item.post, timeout=timeout).data) + else: + data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(url, timeout=timeout).data) + data_comillas = data.replace("'", "\"") + except: + data = '' + if not data: #no ha habido suerte, probamos con la siguiente url + logger.error("ERROR 01: " + item.action + ": La Web no responde o la URL es erronea: " + 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 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) + #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 patron: + data_alt = scrapertools.find_single_match(data, patron) + if not data_alt: + data_alt = scrapertools.find_single_match(data_comillas, 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: " + url + " / Patron: " + patron) + web_intervenida(item, data) + data = '' + continue + else: + item.url = url #guardamos la url que funciona + break #por fin !!! Este canal parece que funciona + else: + logger.error("ERROR 02: " + item.action + ": Ha cambiado la estructura de la Web: " + url + " / Patron: " + patron) web_intervenida(item, data) data = '' continue - else: - 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) - web_intervenida(item, data) - data = '' + + if not data: #no ha habido suerte, probamos con el siguiente clone + url_alt = [] continue + else: + break - del item.extra2 #Borramos acción temporal excluyente - if not data: #Si no ha logrado encontrar nada, salimos limpiando variables + del item.extra2 #Borramos acción temporal excluyente + if not data: #Si no ha logrado encontrar nada, salimos limpiando variables if item.channel == channel_py: if item.channel_alt: item.category = item.channel_alt.capitalize()