From 450b726087af7cbf0929d9865a538539dcb2b279 Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 18 Jul 2018 22:10:54 +0200 Subject: [PATCH] MejorTorrent: canal arreglado para nuevo dominio y estructura MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Se conserva el canal anterior para las geografías donde todavía funciona. En las geografías donde está intervenido se desactiva automáticamente. Las series se migrarán automáticamente al nuevo canal si el anterior se desactiva. La películas se traducirán al nuevo canal cada vez que se visualicen --- plugin.video.alfa/channels/mejortorrent.json | 92 +- plugin.video.alfa/channels/mejortorrent.py | 33 +- plugin.video.alfa/channels/mejortorrent1.json | 65 ++ plugin.video.alfa/channels/mejortorrent1.py | 1023 +++++++++++++++++ 4 files changed, 1169 insertions(+), 44 deletions(-) create mode 100644 plugin.video.alfa/channels/mejortorrent1.json create mode 100644 plugin.video.alfa/channels/mejortorrent1.py diff --git a/plugin.video.alfa/channels/mejortorrent.json b/plugin.video.alfa/channels/mejortorrent.json index edc84806..f8a27b94 100755 --- a/plugin.video.alfa/channels/mejortorrent.json +++ b/plugin.video.alfa/channels/mejortorrent.json @@ -1,57 +1,67 @@ { - "id": "mejortorrent", - "name": "Mejor Torrent", - "active": true, - "adult": false, - "language": ["*"], - "thumbnail": "mejortorrent.png", - "banner": "mejortorrent.png", + "active": true, + "adult": false, + "banner": "mejortorrent.png", "categories": [ - "torrent", - "movie", - "tvshow", + "torrent", + "movie", + "tvshow", "documentary" - ], + ], + "id": "mejortorrent", + "language": [ + "*" + ], + "name": "Mejor Torrent", "settings": [ { - "id": "include_in_global_search", - "type": "bool", - "label": "Incluir en busqueda global", - "default": true, - "enabled": true, + "default": "http://www.mejortorrent.com/", + "enabled": true, + "id": "domain_name", + "label": "URL actual de la Web Mejor Torrent", + "type": "text", "visible": true - }, + }, { - "id": "modo_grafico", - "type": "bool", - "label": "Buscar información extra (TMDB)", - "default": true, - "enabled": true, + "default": true, + "enabled": true, + "id": "include_in_global_search", + "label": "Incluir en busqueda global", + "type": "bool", "visible": true - }, + }, { - "id": "seleccionar_ult_temporadda_activa", - "type": "bool", - "label": "Seleccionar para Videoteca si estará activa solo la última Temporada", - "default": true, - "enabled": true, + "default": true, + "enabled": true, + "id": "modo_grafico", + "label": "Buscar información extra (TMDB)", + "type": "bool", "visible": true - }, + }, { - "id": "include_in_newest_peliculas", - "type": "bool", - "label": "Incluir en Novedades - Peliculas", - "default": true, - "enabled": true, + "default": true, + "enabled": true, + "id": "seleccionar_ult_temporadda_activa", + "label": "Seleccionar para Videoteca si estará activa solo la última Temporada", + "type": "bool", "visible": true - }, + }, { - "id": "include_in_newest_documentales", - "type": "bool", - "label": "Incluir en Novedades - Documentales", - "default": true, - "enabled": true, + "default": true, + "enabled": true, + "id": "include_in_newest_peliculas", + "label": "Incluir en Novedades - Peliculas", + "type": "bool", + "visible": true + }, + { + "default": true, + "enabled": true, + "id": "include_in_newest_documentales", + "label": "Incluir en Novedades - Documentales", + "type": "bool", "visible": true } - ] + ], + "thumbnail": ", thumb_intervenido_pn.jpeg" } \ No newline at end of file diff --git a/plugin.video.alfa/channels/mejortorrent.py b/plugin.video.alfa/channels/mejortorrent.py index 8fc53494..2a975f77 100755 --- a/plugin.video.alfa/channels/mejortorrent.py +++ b/plugin.video.alfa/channels/mejortorrent.py @@ -14,7 +14,8 @@ from platformcode import config, logger from core import tmdb from lib import generictools -host = "http://www.mejortorrent.com" +host = 'http://www.mejortorrent.com/' +#host = config.get_setting('domain_name', 'mejortorrent') __modo_grafico__ = config.get_setting('modo_grafico', 'mejortorrent') @@ -182,7 +183,12 @@ def listado(item): matches = re.compile(patron, re.DOTALL).findall(data) matches_cnt = len(matches) - if not matches and not 'Se han encontrado 0 resultados.' in data: #error + if not matches and not 'Se han encontrado 0 resultados.' in data: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_listado(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log')) return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos @@ -495,7 +501,12 @@ def listado_busqueda(item): matches += re.compile(patron, re.DOTALL).findall(data) matches_cnt = len(matches) - if not matches and not 'Se han encontrado 0 resultados.' and not "href='/juego-descargar-torrent" in data: #error + if not matches and not 'Se han encontrado 0 resultados.' and not "href='/juego-descargar-torrent" in data: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_listado(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log')) return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos @@ -706,6 +717,7 @@ def findvideos(item): itemlist = [] #Bajamos los datos de la página + data = '' try: if item.post: #Puede traer datos para una llamada "post". De momento usado para documentales, pero podrían ser series data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url, post=item.post).data) @@ -720,6 +732,16 @@ def findvideos(item): return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos matches = re.compile(patron, re.DOTALL).findall(data) + if not matches: + 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 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.category + ': ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web. Verificar en la Web y reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + #logger.debug(data) #logger.debug("PATRON: " + patron) #logger.debug(matches) @@ -814,6 +836,11 @@ def episodios(item): matches = re.compile(patron, re.DOTALL).findall(data) if not matches: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log')) return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos diff --git a/plugin.video.alfa/channels/mejortorrent1.json b/plugin.video.alfa/channels/mejortorrent1.json new file mode 100644 index 00000000..dd27bb1a --- /dev/null +++ b/plugin.video.alfa/channels/mejortorrent1.json @@ -0,0 +1,65 @@ +{ + "id": "mejortorrent1", + "name": "Mejor Torrent 1", + "active": true, + "adult": false, + "language": ["*"], + "thumbnail": "mejortorrent.png", + "banner": "mejortorrent.png", + "categories": [ + "torrent", + "movie", + "tvshow", + "documentary" + ], + "settings": [ + { + "id": "domain_name", + "type": "text", + "label": "URL actual de la Web Mejor Torrent", + "default": "https://mejortorrent1.com/", + "enabled": true, + "visible": true + }, + { + "id": "include_in_global_search", + "type": "bool", + "label": "Incluir en busqueda global", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "modo_grafico", + "type": "bool", + "label": "Buscar información extra (TMDB)", + "default": true, + "enabled": true, + "visible": true + }, + { + "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": true + }, + { + "id": "include_in_newest_documentales", + "type": "bool", + "label": "Incluir en Novedades - Documentales", + "default": true, + "enabled": true, + "visible": true + } + ] +} \ No newline at end of file diff --git a/plugin.video.alfa/channels/mejortorrent1.py b/plugin.video.alfa/channels/mejortorrent1.py new file mode 100644 index 00000000..8c82d512 --- /dev/null +++ b/plugin.video.alfa/channels/mejortorrent1.py @@ -0,0 +1,1023 @@ +# -*- coding: utf-8 -*- + +import re +import sys +import urllib +import urlparse + +from channelselector import get_thumb +from core import httptools +from core import scrapertools +from core import servertools +from core.item import Item +from platformcode import config, logger +from core import tmdb +from lib import generictools + +host = config.get_setting('domain_name', 'mejortorrent1') + +__modo_grafico__ = config.get_setting('modo_grafico', 'mejortorrent1') + +def mainlist(item): + logger.info() + + itemlist = [] + + thumb_pelis = get_thumb("channels_movie.png") + thumb_pelis_hd = get_thumb("channels_movie_hd.png") + thumb_series = get_thumb("channels_tvshow.png") + thumb_series_hd = get_thumb("channels_tvshow_hd.png") + thumb_series_az = get_thumb("channels_tvshow_az.png") + thumb_docus = get_thumb("channels_documentary.png") + thumb_buscar = get_thumb("search.png") + thumb_settings = get_thumb("setting_0.png") + + #itemlist.append(Item(channel=item.channel, title="Novedades", action="listado_busqueda", extra="novedades", tipo=False, + # url= host + "ultimos-torrents/", thumbnail=thumb_buscar)) + + itemlist.append(Item(channel=item.channel, title="Peliculas", action="submenu", extra="peliculas", + url= host, thumbnail=thumb_pelis)) + + itemlist.append(Item(channel=item.channel, title="Series", action="submenu", extra="series", + url= host, thumbnail=thumb_series)) + + itemlist.append(Item(channel=item.channel, title="Documentales", action="submenu", extra="documentales", + url= host, thumbnail=thumb_docus)) + + itemlist.append(Item(channel=item.channel, title="Buscar...", action="search", thumbnail=thumb_buscar, tipo=False)) + + itemlist.append( + Item(channel=item.channel, action="", title="[COLOR yellow]Configuración del Canal:[/COLOR]", url="", thumbnail=thumb_settings)) + itemlist.append( + Item(channel=item.channel, action="settingCanal", title="URL del Canal y otros", url="", thumbnail=thumb_settings)) + + return itemlist + + +def settingCanal(item): + from platformcode import platformtools + platformtools.show_channel_settings() + platformtools.itemlist_refresh() + return + + +def submenu(item): + logger.info() + itemlist = [] + + thumb_pelis = get_thumb("channels_movie.png") + thumb_pelis_hd = get_thumb("channels_movie_hd.png") + thumb_series = get_thumb("channels_tvshow.png") + thumb_series_hd = get_thumb("channels_tvshow_hd.png") + thumb_series_az = get_thumb("channels_tvshow_az.png") + thumb_docus = get_thumb("channels_documentary.png") + thumb_buscar = get_thumb("search.png") + thumb_settings = get_thumb("setting_0.png") + + if item.extra == "peliculas": + itemlist.append(Item(channel=item.channel, title="Peliculas", action="listado", extra="peliculas", tipo=False, + url= host + "peliculas/", thumbnail=thumb_pelis)) + itemlist.append(Item(channel=item.channel, title="Películas Listado Alfabético", action="alfabeto", + url= host + "listado?cat=peliculas&letra=", extra="peliculas", thumbnail=thumb_pelis)) + itemlist.append(Item(channel=item.channel, title="Peliculas HD", action="listado", extra="peliculas", tipo=False, + url= host + "peliculas-hd/", thumbnail=thumb_pelis_hd)) + itemlist.append(Item(channel=item.channel, title="Películas HD Listado Alfabético", action="alfabeto", + url= host + "listado?cat=peliculas hd&letra=", extra="peliculas", thumbnail=thumb_pelis)) + + elif item.extra == "series": + itemlist.append(Item(channel=item.channel, title="Series", action="listado", extra="series", tipo=False, + url= host + "series/", thumbnail=thumb_series)) + itemlist.append(Item(channel=item.channel, title="Series Listado Alfabético", action="alfabeto", extra="series", + url= host + "listado?cat=series&letra=", thumbnail=thumb_series_az)) + itemlist.append(Item(channel=item.channel, title="Series HD", action="listado", extra="series", tipo=False, + url= host + "series-hd/", thumbnail=thumb_series_hd)) + itemlist.append(Item(channel=item.channel, title="Series HD Listado Alfabético", action="alfabeto", extra="series", + url= host + "listado?cat=series hd&letra=", thumbnail=thumb_series_az)) + + elif item.extra == "documentales": + itemlist.append(Item(channel=item.channel, title="Documentales", action="listado", extra="documentales", tipo=False, + url= host + "documentales/", thumbnail=thumb_docus)) + itemlist.append(Item(channel=item.channel, title="Documentales Listado Alfabético", action="alfabeto", extra="documentales", url= host + "listado?cat=documentales&letra=", thumbnail=thumb_docus)) + itemlist.append(Item(channel=item.channel, title="Varios", action="listado", extra="varios", tipo=False, + url= host + "variados/", thumbnail=thumb_docus)) + itemlist.append(Item(channel=item.channel, title="Varios Listado Alfabético", action="alfabeto", extra="varios", url= host + "listado?cat=variados&letra=", thumbnail=thumb_docus)) + + return itemlist + + +def alfabeto(item): + logger.info() + itemlist = [] + + 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(channel=item.channel, action="listado", title=letra, extra=item.extra, tipo=True, url=item.url + letra.lower())) + + return itemlist + +def listado(item): + logger.info() + itemlist = [] + url_next_page ='' # Control de paginación + cnt_tot = 30 # Poner el num. máximo de items por página + + if item.category: + del item.category + if item.totalItems: + del item.totalItems + + try: + data = '' + data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url).data) + data = re.sub('\r\n', '', data).decode('utf8').encode('utf8') + data = data.replace("'", '"') + except: + logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + if not data: #Si la web está caída salimos sin dar error + logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + # En este canal las url's y los títulos tienen diferente formato dependiendo del contenido + if (item.extra == "peliculas" or item.extra == "varios") and item.tipo: #Desde Lista Alfabética + patron = '([^<]+)?<\/a>' + patron_enlace = '\/\/.*?\/(.*?)\/$' + patron_title = '([^<]+)<\/a>(\s*([^>]+)<\/b>)?' + item.action = "findvideos" + item.contentType = "movie" + pag = False #No hay paginación + elif (item.extra == "peliculas" or item.extra == "varios") and not item.tipo: #Desde Menú principal + patron = '?' + patron_enlace = '\/\/.*?\/(.*?)\/$' + patron_title = '([^<]+)<\/a>(\s*([^>]+)<\/b>)?' + item.action = "findvideos" + item.contentType = "movie" + pag = True #Sí hay paginación + cnt_tot = 20 # Poner el num. máximo de items por página. Parece que hay 18 + item.next_page = 'b' + elif item.extra == "series" and item.tipo: + patron = '([^<]+)?<\/a>' + patron_enlace = '\/\/.*?\/(.*?)-[temporada]?\d+[-|x]' + patron_title = '([^<]+)<\/a>(\s*([^>]+)<\/b>)?' + patron_title_ep = '\/\/.*?\/(.*?)-(\d{1,2})x(\d{1,2})(?:-al-\d{1,2}x\d{1,2})?-?(\d+p)?\/$' + patron_title_se = '\/\/.*?\/(.*?)temporada-?(?:\d+p-)?(\d{1,2})?-?(.*?)?\/$' + item.action = "episodios" + item.contentType = "season" + pag = False + cnt_tot = 10 # Se reduce el numero de items por página porque es un proceso pesado + elif item.extra == "series" and not item.tipo: + patron = '?' + patron_enlace = '\/\/.*?\/(.*?)-[temporada]?\d+[-|x]' + patron_title = '([^<]+)<\/a>(\s*([^>]+)<\/b>)?' + patron_title_ep = '\/\/.*?\/(.*?)-(\d{1,2})x(\d{1,2})(?:-al-\d{1,2}x\d{1,2})?-?(\d+p)?\/$' + patron_title_se = '\/\/.*?\/(.*?)temporada-?(?:\d+p-)?(\d{1,2})?-?(.*?)?\/$' + item.action = "episodios" + item.contentType = "season" + pag = True + cnt_tot = 10 # Se reduce el numero de items por página porque es un proceso pesado + elif item.extra == "documentales" and item.tipo: + patron = '([^<]+)?<\/a>' + patron_enlace = '\/\/.*?\/(.*?)-[temporada]?\d+[-|x]' + patron_title = '([^<]+)<\/a>(\s*([^>]+)<\/b>)?' + patron_title_ep = '\/\/.*?\/(.*?)-(\d{1,2})x(\d{1,2})(?:-al-\d{1,2}x\d{1,2})?-?(\d+p)?\/$' + patron_title_se = '\/\/.*?\/(.*?)temporada-?(?:\d+p-)?(\d{1,2})?-?(.*?)?\/$' + item.action = "episodios" + item.contentType = "tvshow" + pag = False + else: + patron = '?' + patron_enlace = '\/\/.*?\/(.*?)-[temporada]?\d+[-|x]' + patron_title = '([^<]+)<\/a>(\s*([^>]+)<\/b>)?' + patron_title_ep = '\/\/.*?\/(.*?)-(\d{1,2})x(\d{1,2})(?:-al-\d{1,2}x\d{1,2})?-?(\d+p)?\/$' + patron_title_se = '\/\/.*?\/(.*?)temporada-?(?:\d+p-)?(\d{1,2})?-?(.*?)?\/$' + item.action = "episodios" + item.contentType = "tvshow" + pag = True + item.next_page = 'b' + + # Preparamos la paginación. Las páginas alfabéticas no tienen paginación. + # El resto sí, pero con un número variable de links + if not item.cnt_pag: + cnt_pag = 0 + else: + cnt_pag = item.cnt_pag + del item.cnt_pag + if not item.cnt_pag_num: + cnt_pag_num = 0 # Número de página actual + else: + cnt_pag_num = item.cnt_pag_num + del item.cnt_pag_num + + matches = re.compile(patron, re.DOTALL).findall(data) + matches_cnt = len(matches) + if not matches and not 'Se han encontrado0 resultados.' in data: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_listado(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + + logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #Capturamos el num. de la última página para informala a pié de página. Opción para páginas sin paginación + if pag == False: + item.last_page = (len(matches) / cnt_tot) + 1 + + if not item.last_page and pag: #Capturamos el num. de la última página para informala a pié de página + item.last_page = -1 + #patron_next_page = " Siguiente >> <\/a>" + if "/documentales" in item.url: + patron_next_page = '\d+<\/a' + else: + patron_next_page = '&\w+;<\/a>&\w+;<\/div>' + url_next_page = urlparse.urljoin(item.url, scrapertools.find_single_match(data, patron_next_page) + str(cnt_pag_num + 2)) + #url_last_page = re.sub(r"\d+$", "9999", url_next_page) + #data_last = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(url_last_page).data) + if "/documentales" in item.url: + patron_last_page = '\d+<\/a> <\/div>' + else: + patron_last_page = '&\w+;<\/a>&\w+;<\/div>' + #patron_last_page = '(\d+)<\/span>' + if "/documentales" in item.url: + item.last_page = int(scrapertools.find_single_match(data, patron_last_page)) + else: + #item.last_page = int(scrapertools.find_single_match(data, patron_last_page)) * (len(matches) / cnt_tot) + item.last_page = int(scrapertools.find_single_match(data, patron_last_page)) + + if matches_cnt > cnt_tot and item.extra == "documentales" and pag: + item.next_page = '' + if item.next_page != 'b': + if matches_cnt > cnt_pag + cnt_tot: + url_next_page = item.url + matches = matches[cnt_pag:cnt_pag+cnt_tot] + next_page = '' + if matches_cnt <= cnt_pag + (cnt_tot * 2): + if pag: + next_page = 'b' + modo = 'continue' + else: + matches = matches[cnt_pag:cnt_pag+cnt_tot] + next_page = 'a' + #patron_next_page = " Siguiente >> <\/a>" + if "/documentales" in item.url: + patron_next_page = '\d+<\/a' + else: + patron_next_page = '&\w+;<\/a>&\w+;<\/div>' + matches_next_page = re.compile(patron_next_page, re.DOTALL).findall(data) + modo = 'continue' + if len(matches_next_page) > 0: + url_next_page = urlparse.urljoin(item.url, matches_next_page[0] + str(cnt_pag_num + 2)) + modo = 'next' + if item.next_page: + del item.next_page + + #logger.debug(data) + #logger.debug("PATRON1: " + patron + " / ") + #logger.debug(matches) + + # Primera pasada + # En la primera pasada se obtiene una información básica del título a partir de la url + # Para Series se obtienen la temporada y el episodio + # Se limpian algunas etiquetas del item inical. + for scrapedurl, scrapedthumbnail in matches: + item_local = item.clone() + item_local.tipo = True + del item_local.tipo + if item_local.totalItems: + del item_local.totalItems + if item_local.modo: + del item_local.modo + if item_local.next_page: + del item_local.next_page + item_local.pag = True + del item_local.pag + if item_local.text_color: + del item_local.text_color + item_local.last_page = 0 + del item_local.last_page + if item_local.cnt_pag_num: + del item_local.cnt_pag_num + + item_local.title = '' + item_local.context = "['buscar_trailer']" + + item_local.title = scrapertools.find_single_match(scrapedurl, patron_enlace) + item_local.title = item_local.title.replace("-", " ").capitalize() + item_local.url = scrapedurl + item_local.thumbnail = scrapedthumbnail + if "http" not in item_local.thumbnail: + item_local.thumbnail = '' + item_local.infoLabels['year'] = '-' # Al no saber el año, le ponemos "-" y TmDB lo calcula automáticamente + + # Para que el menú contextual muestre conrrectamente las opciones de añadir a Videoteca + if item_local.extra == "series": + if scrapertools.find_single_match(scrapedurl, patron_title_ep): + item_local.contentType = "episode" + else: + item_local.contentType = "season" + + # Poner nombre real de serie. Busca nº de temporada y capítulo + if item_local.extra == "series": + if item_local.contentType == "episode": + real_title, item_local.contentSeason, episodio, item_local.quality = scrapertools.find_single_match(scrapedurl, patron_title_ep) + + #Hay que buscar la raiz de la temporada + data_epi = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item_local.url).data) + url = scrapertools.find_single_match(data_epi, '.*

0: + title_foot += ' de %s' % str(item.last_page) + itemlist.append( + Item(channel=item.channel, action="listado", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + title_foot, url=url_next_page, next_page=next_page, cnt_pag=cnt_pag, pag=pag, modo=modo, extra=item.extra, tipo=item.tipo, last_page=item.last_page, cnt_pag_num=cnt_pag_num)) + + #logger.debug(url_next_page + " / " + next_page + " / " + str(matches_cnt) + " / " + str(cnt_pag) + " / " + str(pag) + " / " + modo + " / " + item.extra + " / " + str(item.tipo)) + + return itemlist + + +def listado_busqueda(item): + logger.info() + itemlist = [] + url_next_page ='' # Controlde paginación + cnt_tot = 39 # Poner el num. máximo de items por página. Dejamos que la web lo controle + cnt_title = 0 # Contador de líneas insertadas en Itemlist + cnt_pag = 0 # Contador de líneas leídas de Matches + cnt_next = 0 # Contador de páginas leidas antes de pintar la pantalla + total_pag = 10 # Líneas por página de la web + curr_page_num = 1 # Página actual + category = "" # Guarda la categoria que viene desde una busqueda global + matches = [] + + if item.url_next_page: + url_next_page = item.url_next_page + else: + url_next_page = item.url + + #Máximo num. de líneas permitidas por TMDB. Máx de 5 páginas por Itemlist para no degradar el rendimiento + while cnt_title <= cnt_tot and cnt_next < 5: + + status = False # Calidad de los datos leídos + try: + data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(url_next_page, post=item.post).data) + data = re.sub('\r\n', '', data).decode('utf8').encode('utf8') + data = data.replace("'", '"') + except: + logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + if not data: #Si la web está caída salimos sin dar error + logger.error("ERROR 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO_BUSQUEDA:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + cnt_next += 1 + # busca series y Novedades + patron = '\(([^>]+)\)<\/a><\/td>' #título + patron += '([^>]+)<\/td><\/tr>' #calidad y tipo de contenido + matches_alt = scrapertools.find_multiple_matches(data, patron) + + i = 0 + if len(matches_alt) > 0: + status = True + for scrapedurl, scrapedtitle, scrapedquality, scrapedtype in matches_alt: + if scrapedtype not in ['Juegos', 'Capitulos', 'Musica']: #limpiamos de contenidos no deseados + matches.append(matches_alt[i]) #acumulamos los títulos + i += 1 + cnt_title = len(matches) #número de títulos a pintar + + if not matches_alt and not 'Se han encontrado0 resultado(s).' in data and not "Introduce alguna palabra para buscar con al menos 3 letras" in data and status is False: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_listado(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + + logger.error("ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO_BUSQUEDA: Ha cambiado la estructura de la Web. Reportar el error con el log')) + item, itemlist = generictools.post_tmdb_listado(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #Capturamos el num. de la última página para informala a pié de página + try: + last_page = int(scrapertools.find_single_match(data, 'Se han encontrado(\d+)<\/b> resultado\(s\).')) + last_page = (last_page / total_pag) + 1 + except: + last_page = 0 + pass + + curr_page_num = int(scrapertools.find_single_match(url_next_page, '\/page\/(\d+)\/$')) + if (curr_page_num + 1) <= last_page: #Tenemos la pantalla llena? + url_next_page = re.sub(r'\/page\/\d+\/$', '/page/%s/' % str(curr_page_num + 1), url_next_page) #actualizamos el num. pag. + else: + url_next_page = '' #si no hay más página, limpiamos para salir + cnt_title = 99 + + if cnt_title >= cnt_tot * 0.75: #Si el num. de títulos supera el límite, salimos del loop + cnt_title = 99 + + #logger.debug("MATCHES: ") + #logger.debug(matches) + #logger.debug(data) + + for scrapedurl, scrapedtitle_alt, scrapedquality, scrapedtype in matches: + # Creamos "item_local" y lo limpiamos un poco de algunos restos de item + item_local = item.clone() + if item_local.category: + category = item.category + del item_local.category + item_local.tipo = True + del item_local.tipo + if item_local.totalItems: + del item_local.totalItems + if item_local.text_color: + del item_local.text_color + if item_local.cnt_pag_num: + del item_local.cnt_pag_num + item_local.url = scrapedurl + item_local.contentThumbnail = '' + item_local.thumbnail = '' + item_local.title = '' + item_local.context = "['buscar_trailer']" + item_local.infoLabels['year'] = '-' # Al no saber el año, le ponemos "-" y TmDB lo calcula automáticamente + + # Limpiamos títulos, Sacamos datos de calidad, audio y lenguaje + scrapedtitle = re.sub('\r\n', '', scrapedtitle_alt).decode('utf8').encode('utf8').strip() + title = scrapedtitle + title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ") + + title_subs = [] + + #Determinamos y marcamos idiomas distintos del castellano + item_local.language = [] + if "[subs" in title.lower() or "[vos" in title.lower() or "v.o.s" in title.lower() or "vo" in title.lower(): + item_local.language += ["VOS"] + title = title.replace(" [Subs. integrados]", "").replace(" [subs. Integrados]", "").replace(" [VOSE", "").replace(" [VOS", "").replace(" (V.O.S.E)", "").replace(" VO", "") + if "latino" in title.lower() or "argentina" in title.lower(): + item_local.language += ["LAT"] + title = title.replace(" Latino", "").replace(" latino", "").replace(" Argentina", "").replace(" argentina", "") + title = title.replace("Castellano", "").replace("castellano", "").replace("inglés", "").replace("ingles", "").replace("Inglés", "").replace("Ingles", "") + + if "3d" in title or "3D" in title: #Reservamos info para después de TMDB + item_local.quality += " 3D" + title = title.replace(" [3d]", "").replace(" 3d", "").replace(" [3D]", "").replace(" 3D", "") + if "audio" in title.lower(): #Reservamos info de audio para después de TMDB + title_subs += ['[%s]' % scrapertools.find_single_match(title, r'(\[[a|A]udio.*?\])')] + title = re.sub(r'\[[a|A]udio.*?\]', '', title) + if "[dual" in title.lower(): + item_local.language[0:0] = ["DUAL"] + title = title = re.sub(r'\[D|dual.*?\]', '', title) + if scrapertools.find_single_match(title, r'-\s[m|M].*?serie'): + title = re.sub(r'-\s[m|M].*?serie', '', title) + title_subs += ["Miniserie"] + + if title.endswith('.'): + title = title[:-1] + + if not title: + title = "SIN TÍTULO" + title = scrapertools.remove_htmltags(title) + + # Ahora preparamos el título y la calidad tanto para series como para documentales y películas + if item.extra == "novedades" and ("Series" in scrapedtype or "Documentales" in scrapedtype): + item_local.quality = scrapertools.find_single_match(scrapedtitle, '.*?\[(.*?)\]') + else: + item_local.quality = scrapertools.remove_htmltags(scrapedquality).decode('utf8').encode('utf8') + item_local.quality = item_local.quality.replace("(", "").replace(")", "").replace("[", "").replace("]", "").replace("Documental", "").replace("documental", "") + + #Preparamos la información básica para TMDB + if "Series" in scrapedtype or "Documentales" in scrapedtype: + item_local.action = "episodios" + if "Series" in scrapedtype: + item_local.extra = "series" + else: + item_local.extra = "documentales" + item_local.contentType = "season" + + title = re.sub(r'\[\d+.*?\]', '', title) # Quitar la calidad del título + item_local.contentSerieName = scrapertools.find_single_match(title, '(.*?) Temporada \d+\s?').strip() + if not item_local.contentSerieName: + item_local.contentSerieName = title.strip() + if item_local.infoLabels['title']: + del item_local.infoLabels['title'] + title = item_local.contentSerieName + item_local.title = title + if not item_local.contentSerieName: + item_local.contentSerieName = "SIN TITULO" + item_local.contentSeason = scrapertools.find_single_match(scrapedurl, 'temporada-?(?:\d+p-)?(\d{1,2})[-|\/]') + if not item_local.contentSeason: + item_local.contentSeason = 1 + + if "(hdrip" in title.lower() or "(br" in title.lower() or "(vhsrip" in title.lower() or "(dvdrip" in title.lower() or "(fullb" in title.lower() or "(blu" in title.lower() or "(4k" in title.lower() or "(hevc" in title.lower() or "(imax" in title.lower() or "extendida" in title.lower() or "[720p]" in title.lower() or "[1080p]" in title.lower(): + if not item_local.quality: + item_local.quality = scrapertools.find_single_match(title, r'\(.*?\)?\(.*?\)') + if not item_local.quality: + item_local.quality = scrapertools.find_single_match(title, r'[\[|\(](.*?)[\)|\]]') + title = re.sub(r'\(.*?\)?\(.*?\)', '', title) + title = re.sub(r'[\[|\(].*?[\)|\]]', '', title) + if not item_local.quality: + if "fullbluray" in title.lower(): + item_local.quality = "FullBluRay" + title = title.replace("FullBluRay", "").replace("fullbluray", "") + if "4k" in title.lower() or "hdr" in title.lower(): + item_local.quality = "4K" + title = title.replace("4k-hdr", "").replace("4K-HDR", "").replace("hdr", "").replace("HDR", "").replace("4k", "").replace("4K", "") + title = title.replace("(", "").replace(")", "").replace("[", "").replace("]", "").strip() + item_local.title = title + + if "Peliculas" in scrapedtype or "Variados" in scrapedtype: + item_local.action = "findvideos" + item_local.extra = "peliculas" + item_local.contentType = "movie" + item_local.contentTitle = title + if "Variados" in scrapedtype: + item_local.extra = "varios" + + if "saga" in item_local.contentTitle.lower() or "saga" in item_local.contentSerieName.lower(): + item_local.contentTitle = item_local.contentTitle.replace("Saga ", "").replace("Saga", "") + item_local.contentSerieName = item_local.contentSerieName.replace("Saga ", "").replace("Saga", "") + title_subs += ["Saga"] + if "colecc" in item_local.contentTitle.lower() or "colecc" in item_local.contentSerieName.lower(): + item_local.contentTitle = item_local.contentTitle.replace("Coleccion ", "").replace("Coleccion", "") + item_local.contentSerieName = item_local.contentSerieName.replace("Coleccion ", "").replace("Coleccion", "") + title_subs += ["Coleccion"] + + #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()) + + #logger.debug(item_local) + + if not 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 + + #Llamamos a TMDB para que complete InfoLabels desde itemlist. Mejor desde itemlist porque envía las queries en paralelo + tmdb.set_infoLabels(itemlist, __modo_grafico__) + + #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB + item, itemlist = generictools.post_tmdb_listado(item, itemlist) + + if url_next_page: + title_foot = str(curr_page_num) + if last_page > 0: + title_foot += ' de %s' % str(last_page) + itemlist.append( + Item(channel=item.channel, action="listado_busqueda", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + title_foot, url=url_next_page, extra=item.extra)) + + return itemlist + + +def findvideos(item): + logger.info() + itemlist = [] + + data = '' + torrent_data = '' + headers = {'Content-Type': 'application/x-www-form-urlencoded', 'Referer': item.url} #Necesario para el Post del .Torrent + + #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) + + #Bajamos los datos de la página de todo menos de Documentales y Varios + if not item.post: + try: + data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url).data) + data = data.replace('"', "'") + patron = "
Formato:<\/b>&\w+;\s?([^<]+)
'): + item_local.quality = scrapertools.find_single_match(data, 'Formato:<\/b>&\w+;\s?([^<]+)
') + elif "hdtv" in item_local.url.lower() or "720p" in item_local.url.lower() or "1080p" in item_local.url.lower() or "4k" in item_local.url.lower(): + item_local.quality = scrapertools.find_single_match(item_local.url, '.*?_([H|7|1|4].*?)\.torrent') + item_local.quality = item_local.quality.replace("_", " ") + + # Extrae el tamaño del vídeo + if scrapertools.find_single_match(data, 'Tama.*?:<\/b>&\w+;\s?([^<]+B)Tama.*?:<\/b>&\w+;\s?([^<]+B))", "", httptools.downloadpage(item.url).data) + data = data.replace('"', "'") + except: #Algún error de proceso, salimos + logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log')) + return itemlist + + # Selecciona en tramo que nos interesa + data = scrapertools.find_single_match(data, "(.*?)<\/form>") + + # Prepara el patrón de búsqueda + if item.extra == "documentales": + patron = "" + url, value2, name2 = scrapertools.find_single_match(data, patron) + patron = "" + else: + patron = "[^<]+<\/a><\/td>]+>]+>([^<]+)?<\/div><\/td>" + matches = re.compile(patron, re.DOTALL).findall(data) + if not matches: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_episodios(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + + logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #logger.debug("PATRON: " + patron) + #logger.debug(matches) + #logger.debug(data) + + # Recorremos todos los episodios generando un Item local por cada uno en Itemlist + for scrapedurl, year in matches: + item_local = item.clone() + item_local.action = "findvideos" + item_local.contentType = "episode" + item_local.extra = "episodios" + if item_local.library_playcounts: + del item_local.library_playcounts + if item_local.library_urls: + del item_local.library_urls + if item_local.path: + del item_local.path + if item_local.update_last: + del item_local.update_last + if item_local.update_next: + del item_local.update_next + if item_local.channel_host: + del item_local.channel_host + + item_local.title = '' + item_local.context = "['buscar_trailer']" + item_local.url = scrapedurl + + if item.extra == "documentales": #llamada con post + name1 = scrapedurl + value1 = year + item_local.url = item.url + item_local.url_post = url + item_local.post = '%s=%s&%s=%s' % (name1, value1, name2, value2) + item_local.contentSeason = 1 + try: + item_local.contentEpisodeNumber = int(value1) + 1 + except: + item_local.contentEpisodeNumber = 1 + + else: + scrapedtemp, scrapedepi = scrapertools.find_single_match(item_local.url, "\/.*?-(\d{1,2})x(\d{1,2})[-|\/]") + scrapedepi2 = scrapertools.find_single_match(item_local.url, "\/.*?-\d{1,2}x\d{1,2}-al-\d{1,2}x(\d{1,2})[-|\/]") + item_local.title = '%sx%s -' % (scrapedtemp, str(scrapedepi).zfill(2)) + try: + item_local.contentSeason = int(scrapedtemp) + except: + item_local.contentSeason = 1 + try: + item_local.contentEpisodeNumber = int(scrapedepi) + except: + item_local.contentEpisodeNumber = 1 + try: + scrapedepi2 = int(scrapedepi2) + except: + scrapedepi2 = '' + + if scrapedepi2: + item_local.title = '%sx%s al %s -' % (scrapedtemp, str(scrapedepi).zfill(2), str(scrapedepi2).zfill(2)) + #item_local.infoLabels['episodio_titulo'] = 'al %s' % scrapedepi2 + else: + item_local.title = '%sx%s -' % (scrapedtemp, str(scrapedepi).zfill(2)) + + if year: + item_local.infoLabels['year'] = scrapertools.find_single_match(year, r"(\d{4})") + + itemlist.append(item_local.clone()) + + if len(itemlist) > 1: + itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos + + # 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) + + return itemlist + + +def actualizar_titulos(item): + logger.info() + itemlist = [] + + from platformcode import launcher + + item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels + + #Volvemos a la siguiente acción en el canal + return launcher.run(item) + + +def search(item, texto): + itemlist = [] + logger.info("search:" + texto) + texto = texto.replace(" ", "+") + + item.url = host + "search/%s/page/1/" % (texto) + + try: + itemlist = listado_busqueda(item) + return itemlist + + # Se captura la excepción, para no interrumpir al buscador global si un canal falla + except: + for line in sys.exc_info(): + logger.error("%s" % line) + return [] + + +def newest(categoria): + logger.info() + itemlist = [] + item = Item() + try: + if categoria == 'peliculas': + item.url = host + "peliculas/" + item.extra = "novedades" + item.channel = "mejortorrent1" + item.tipo = False + itemlist = listado_busqueda(item) + if "Pagina siguiente >>" in itemlist[-1].title: + itemlist.pop() + + if categoria == 'documentales': + item.url = host + "documentales/" + item.extra = "documentales" + item.channel = "mejortorrent1" + item.tipo = False + itemlist = listado(item) + if "Pagina 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