From ad129617f8e79ffcefb800a2695c2f35c205bff2 Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 29 Aug 2018 12:16:13 +0200 Subject: [PATCH] DivXtotal: nuevo canal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Películas por géneros y alfabeto - Series completas agrupadas por temporadas - Búsquedas - 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 --- plugin.video.alfa/channels/divxtotal.json | 68 ++ plugin.video.alfa/channels/divxtotal.py | 780 ++++++++++++++++++++++ plugin.video.alfa/channels/estrenosgo.py | 45 +- 3 files changed, 879 insertions(+), 14 deletions(-) create mode 100644 plugin.video.alfa/channels/divxtotal.json create mode 100644 plugin.video.alfa/channels/divxtotal.py diff --git a/plugin.video.alfa/channels/divxtotal.json b/plugin.video.alfa/channels/divxtotal.json new file mode 100644 index 00000000..bf1c4ac6 --- /dev/null +++ b/plugin.video.alfa/channels/divxtotal.json @@ -0,0 +1,68 @@ +{ + "id": "divxtotal", + "name": "Divxtotal", + "active": true, + "adult": false, + "language": ["cast"], + "thumbnail": "http://imgur.com/Madj03A.jpg", + "categories": [ + "torrent", + "movie", + "tvshow" + ], + "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/divxtotal.py b/plugin.video.alfa/channels/divxtotal.py new file mode 100644 index 00000000..8b3ca25e --- /dev/null +++ b/plugin.video.alfa/channels/divxtotal.py @@ -0,0 +1,780 @@ +# -*- coding: utf-8 -*- + +import re +import sys +import urllib +import urlparse +import time + +from channelselector import get_thumb +from core import httptools +from core import scrapertools +from core import servertools +from core.item import Item +from platformcode import config, logger +from core import tmdb +from lib import generictools + +host = 'https://www.divxtotal3.net/' +channel = 'divxtotal' +categoria = channel.capitalize() +color1, color2, color3 = ['0xFF58D3F7', '0xFF2E64FE', '0xFF0404B4'] +__modo_grafico__ = config.get_setting('modo_grafico', channel) +modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', channel) #Actualización sólo últ. Temporada? +timeout = config.get_setting('timeout_downloadpage', channel) + + +def mainlist(item): + logger.info() + itemlist = [] + + thumb_cartelera = get_thumb("now_playing.png") + thumb_pelis_hd = get_thumb("channels_movie_hd.png") + thumb_series = get_thumb("channels_tvshow.png") + thumb_buscar = get_thumb("search.png") + thumb_separador = get_thumb("next.png") + + item.url_plus = "peliculas/" + itemlist.append(Item(channel=item.channel, title="Películas", action="categorias", url=host + item.url_plus, url_plus=item.url_plus, thumbnail=thumb_cartelera, extra="Películas")) + item.url_plus = "peliculas-hd/" + itemlist.append(Item(channel=item.channel, title="Películas HD", action="categorias", url=host + item.url_plus, url_plus=item.url_plus, thumbnail=thumb_pelis_hd, extra="Películas HD")) + item.url_plus = "peliculas-dvdr/" + itemlist.append(Item(channel=item.channel, title="Películas DVDR", action="categorias", url=host + item.url_plus, url_plus=item.url_plus, thumbnail=thumb_pelis_hd, extra="Películas DVDR")) + + 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(channel=item.channel, url=host, title="", folder=False, thumbnail=thumb_separador)) + + itemlist.append(Item(channel=item.channel, title="Buscar...", action="search", url=host + "?s=%s", thumbnail=thumb_buscar, extra="search")) + + return itemlist + + +def submenu(item): + logger.info() + itemlist = [] + + thumb_series = get_thumb("channels_tvshow.png") + + if item.extra == "series": + + item.url_plus = "serie/" + itemlist.append(item.clone(title="Series completas", action="listado", url=item.url + item.url_plus, url_plus=item.url_plus, thumbnail=thumb_series, extra="series")) + itemlist.append(item.clone(title="Alfabético A-Z", action="alfabeto", url=item.url + item.url_plus + "?s=letra-%s", url_plus=item.url_plus, thumbnail=thumb_series, extra="series")) + + 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, timeout=timeout).data) + data = unicode(data, "utf-8", errors="replace").encode("utf-8") + except: + pass + + patron = '
  • (.*?)<\/a><\/li>' + #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 + + 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(item.url_plus) + #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="Todas las " + item.extra.upper(), action="listado")) + itemlist.append(item.clone(title="Alfabético A-Z", action="alfabeto", url=item.url + "?s=letra-%s")) + itemlist.append(item.clone(title="Géneros", url=item.url)) + + for scrapedurl, scrapedtitle in matches: + if item.url_plus not in scrapedurl: + continue + if "Todas" in scrapedtitle: + continue + + 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.capitalize(), 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 % "0")) + + 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.lower())) + + return itemlist + + +def listado(item): + logger.info() + itemlist = [] + item.category = categoria + + #logger.debug(item) + + curr_page = 1 # Página inicial + last_page = 99999 # Última página inicial + if item.curr_page: + curr_page = int(item.curr_page) # Si viene de una pasada anterior, lo usamos + del item.curr_page # ... y lo borramos + if item.last_page: + last_page = int(item.last_page) # Si viene de una pasada anterior, lo usamos + del item.last_page # ... y lo borramos + + cnt_tot = 40 # Poner el num. máximo de items por página + cnt_title = 0 # Contador de líneas insertadas en Itemlist + inicio = time.time() # Controlaremos que el proceso no exceda de un tiempo razonable + fin = inicio + 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 + + #Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios + title_lista = [] # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas + if item.title_lista: # Si viene de una pasada anterior, la lista ya estará guardada + title_lista.extend(item.title_lista) # Se usa la lista de páginas anteriores en Item + del item.title_lista # ... limpiamos + + if not item.extra2: # Si viene de Catálogo o de Alfabeto + item.extra2 = '' + + next_page_url = item.url + #Máximo num. de líneas permitidas por TMDB. Máx de 10 segundos por Itemlist para no degradar el rendimiento + while cnt_title <= cnt_tot * 0.45 and curr_page <= last_page and fin > time.time(): + + # Descarga la página + data = '' + try: + data = re.sub(r"\n|\r|\t|\s{2}|()| ", "", httptools.downloadpage(next_page_url, timeout=timeout_search).data) + data = unicode(data, "utf-8", errors="replace").encode("utf-8") + except: + pass + + curr_page += 1 #Apunto ya a la página siguiente + if not data and not item.extra2: #Si la web está caída salimos sin dar error + logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #Patrón para todo, menos para Series completas, incluido búsquedas en cualquier caso + patron = '<\/td>(?:)?(.*?)(?:<\/a>)?<\/td>.*?<\/td>(.*?)<\/td><\/tr>' + + #Si son series completas, ponemos un patrón especializado + if item.extra == 'series': + patron = '

    <\/div>' + + matches = re.compile(patron, re.DOTALL).findall(data) + if not matches and not '

    Lo sentimos, pero que esta buscando algo que no esta aqui.

    ' in data and not item.extra2 and not '

    Sin 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_episodios(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + + logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log')) + 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) + + #Buscamos la próxima y la última página + patron_next = "