diff --git a/plugin.video.alfa/channels/subtorrents.json b/plugin.video.alfa/channels/subtorrents.json new file mode 100644 index 00000000..4d5db68a --- /dev/null +++ b/plugin.video.alfa/channels/subtorrents.json @@ -0,0 +1,85 @@ +{ + "id": "subtorrents", + "name": "SubTorrents", + "active": true, + "adult": false, + "language": ["cast", "lat"], + "thumbnail": "https://www.subtorrents.tv/wp-content/themes/SubTorrent/css/images/logo2.png", + "categories": [ + "movie", + "tvshow", + "torrent", + "vos" + ], + "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": "filter_languages", + "type": "list", + "label": "Mostrar enlaces en idioma...", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "No filtrar", + "CAST", + "LAT", + "VO", + "VOS", + "VOSE" + ] + }, + { + "id": "timeout_downloadpage", + "type": "list", + "label": "Timeout (segs.) en descarga de páginas o verificación de servidores", + "default": 10, + "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/subtorrents.py b/plugin.video.alfa/channels/subtorrents.py new file mode 100644 index 00000000..6e5ebe34 --- /dev/null +++ b/plugin.video.alfa/channels/subtorrents.py @@ -0,0 +1,779 @@ +# -*- coding: utf-8 -*- + +import re +import sys +import urllib +import urlparse +import time + +from channelselector import get_thumb +from core import httptools +from core import scrapertools +from core import servertools +from core.item import Item +from platformcode import config, logger +from core import tmdb +from lib import generictools +from channels import filtertools +from channels import autoplay + + +#IDIOMAS = {'CAST': 'Castellano', 'LAT': 'Latino', 'VO': 'Version Original'} +IDIOMAS = {'Castellano': 'CAST', 'Latino': 'LAT', 'Version Original': 'VO'} +list_language = IDIOMAS.values() +list_quality = [] +list_servers = ['torrent'] + +host = 'https://www.subtorrents.tv/' +sufix = '.tv/' +channel = 'subtorrents' +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_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") + thumb_settings = get_thumb("setting_0.png") + + autoplay.init(item.channel, list_servers, list_quality) + + itemlist.append(Item(channel=item.channel, url=host, title="Películas", action="submenu", thumbnail=thumb_pelis_hd, extra="peliculas")) + + itemlist.append(Item(channel=item.channel, url=host, title="Series", action="submenu", thumbnail=thumb_series, extra="series")) + + itemlist.append(Item(channel=item.channel, title="Buscar...", action="search", url=host + "?s=%s", thumbnail=thumb_buscar, extra="search")) + + itemlist.append(Item(channel=item.channel, url=host, title="[COLOR yellow]Configuración:[/COLOR]", folder=False, thumbnail=thumb_separador)) + + itemlist.append(Item(channel=item.channel, action="configuracion", title="Configurar canal", thumbnail=thumb_settings)) + + autoplay.show_option(item.channel, itemlist) #Activamos Autoplay + + return itemlist + + +def configuracion(item): + from platformcode import platformtools + ret = platformtools.show_channel_settings() + platformtools.itemlist_refresh() + return + + +def submenu(item): + logger.info() + itemlist = [] + + thumb_cartelera = get_thumb("now_playing.png") + thumb_latino = get_thumb("channels_latino") + thumb_pelis = get_thumb("channels_movie.png") + thumb_pelis_AZ = get_thumb("channels_movie_az.png") + thumb_pelis_hd = get_thumb("channels_movie_hd.png") + thumb_series = get_thumb("channels_tvshow.png") + thumb_series_AZ = get_thumb("channels_tvshow_az.png") + thumb_buscar = get_thumb("search.png") + thumb_separador = get_thumb("next.png") + thumb_settings = get_thumb("setting_0.png") + thumb_series = get_thumb("channels_tvshow.png") + + if item.extra == "peliculas": + + itemlist.append(Item(channel=item.channel, title="Novedades", action="listado", url=host + "peliculas-subtituladas/?filtro=estrenos", thumbnail=thumb_cartelera, extra="peliculas")) + itemlist.append(Item(channel=item.channel, title=" Castellano o Latino", action="listado", url=host + "peliculas-subtituladas/?filtro=estrenos&filtro2=audio-latino", thumbnail=thumb_latino, extra="peliculas")) + itemlist.append(Item(channel=item.channel, title="Películas", action="listado", url=host + "peliculas-subtituladas", thumbnail=thumb_pelis, extra="peliculas")) + itemlist.append(Item(channel=item.channel, title=" Castellano o Latino", action="listado", url=host + "peliculas-subtituladas/?filtro=audio-latino", thumbnail=thumb_latino, extra="peliculas")) + itemlist.append(Item(channel=item.channel, title=" Alfabético A-Z", action="alfabeto", url=host + "peliculas-subtituladas/?s=letra-%s", thumbnail=thumb_pelis_AZ, extra="peliculas")) + itemlist.append(Item(channel=item.channel, title="3D", action="listado", url=host + "peliculas-3d/", thumbnail=thumb_pelis, extra="peliculas")) + itemlist.append(Item(channel=item.channel, title="Calidad DVD", action="listado", url=host + "calidad/dvd-full/", thumbnail=thumb_pelis, extra="peliculas")) + + if item.extra == "series": + + itemlist.append(item.clone(title="Series", action="listado", url=item.url + "series/", thumbnail=thumb_series, extra="series")) + itemlist.append(item.clone(title=" Alfabético A-Z", action="alfabeto", url=item.url + "series/?s=letra-%s", thumbnail=thumb_series_AZ, extra="series")) + + 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 + 5 # 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.5 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, "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: " + item.url + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + break #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #Patrón para todo, menos para Series completas, incluido búsquedas en cualquier caso + patron = ']+>[^<]+<\/a><\/td>.*?(\d+)?<\/td>([^<]+)?<\/td>([^<]+)?<\/td><\/tr>' + + #Si son series completas, ponemos un patrón especializado + if item.extra == 'series': + patron = '<(td)><[^>]+src="[^"]+\/(\d{4})[^"]+"[^>]+>(?:(\d+))?\s*(?:(\d+))?<\/a>' + + 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')) + break #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_last = "