# -*- 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.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") thumb_settings = get_thumb("setting_0.png") autoplay.init(item.channel, list_servers, list_quality) 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")) 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_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 = '
Lo sentimos, pero que esta buscando algo que no esta aqui. <\/div>'
matches = re.compile(patron, re.DOTALL).findall(data)
if not matches 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_next = ".*?\(current\).*?href='([^']+)'>(\d+)<\/a><\/li>"
#patron_last = "
.*?\(current\).*?href='[^']+'>\d+<\/a><\/li>.*?href='[^']+\/(\d+)\/(?:\?s=[^']+)?'>&\w+;<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"
patron_last = "
.*?\(current\).*?href='[^']+'>\d+<\/a><\/li>.*?href='[^']+\/(\d+)\/(?:\?[^']+)?'>(?:\d+)?(?:&\w+;<\/span>)?<\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"
try:
next_page_url, next_page = scrapertools.find_single_match(data, patron_next)
next_page = int(next_page)
except: #Si no lo encuentra, lo ponemos a 1
#logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "
.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
next_page = 1
#logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))
if last_page == 99999: #Si es el valor inicial, buscamos
try:
last_page = int(scrapertools.find_single_match(data, patron_last)) #lo cargamos como entero
except: #Si no lo encuentra, lo ponemos a 1
#logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "
.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
last_page = next_page
#logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))
#Empezamos el procesado de matches
for scrapedurl, scrapedtitle, cat_ppal, size in matches:
if "/programas" in scrapedurl or "/otros" in scrapedurl:
continue
title = scrapedtitle
url = scrapedurl
title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace("ã", "a").replace("&etilde;", "e").replace("ĩ", "i").replace("õ", "o").replace("ũ", "u").replace("ñ", "ñ").replace("’", "'")
extra = item.extra
#Si es una búsqueda, convierte los episodios en Series completas, aptas para la Videoteca
if extra == 'search' and '/series' in scrapedurl and not "Temp" in title and not "emporada" in title:
if scrapedurl in title_lista: #Si ya hemos procesado la serie, pasamos de los episodios adicionales
continue
# Descarga la página del episodio, buscando el enlace a la serie completa
data_serie = ''
try:
data_serie = re.sub(r"\n|\r|\t|\s{2}|()| ", "", httptools.downloadpage(scrapedurl, timeout=timeout).data)
data = unicode(data, "utf-8", 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: " + scrapedurl)
else:
patron_serie = '
(.*?)(.*?)<\/a><\/td>
<\/td> .*?<\/td><\/tr>'
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)
season = max_temp
#Comprobamos si realmente sabemos el num. máximo de temporadas
if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat):
num_temporadas_flag = True
else:
num_temporadas_flag = False
# Recorremos todos los episodios generando un Item local por cada uno en Itemlist
for language, scrapedtitle, scrapedurl, scrapedthumbnail in matches:
item_local = item.clone()
item_local.action = "findvideos"
item_local.contentType = "episode"
item_local.extra = "episodios"
if item_local.library_playcounts:
del item_local.library_playcounts
if item_local.library_urls:
del item_local.library_urls
if item_local.path:
del item_local.path
if item_local.update_last:
del item_local.update_last
if item_local.update_next:
del item_local.update_next
if item_local.channel_host:
del item_local.channel_host
if item_local.active:
del item_local.active
if item_local.contentTitle:
del item_local.infoLabels['title']
if item_local.season_colapse:
del item_local.season_colapse
item_local.title = ''
item_local.context = "['buscar_trailer']"
item_local.url = scrapedurl
title = scrapedtitle
item_local.language = []
lang = language.strip()
if not lang:
item_local.language += ['CAST']
elif 'vo' in lang.lower() or 'v.o' in lang.lower() or 'vo' in title.lower() or 'v.o' in title.lower():
item_local.language += ['VO']
elif 'vose' in lang.lower() or 'v.o.s.e' in lang.lower() or 'vose' in title.lower() or 'v.o.s.e' in title.lower():
item_local.language += ['VOSE']
elif 'latino' in lang.lower() or 'latino' in title.lower():
item_local.language += ['LAT']
try:
item_local.contentEpisodeNumber = 0
if 'miniserie' in title.lower():
item_local.contentSeason = 1
title = title.replace('miniserie', '').replace('MiniSerie', '')
elif 'completa' in title.lower():
patron = '[t|T].*?(\d+) [c|C]ompleta'
if scrapertools.find_single_match(title, patron):
item_local.contentSeason = int(scrapertools.find_single_match(title, patron))
if not item_local.contentSeason:
#Extraemos los episodios
patron = '(\d{1,2})[x|X](\d{1,2})'
item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(title, patron)
item_local.contentSeason = int(item_local.contentSeason)
item_local.contentEpisodeNumber = int(item_local.contentEpisodeNumber)
except:
logger.error('ERROR al extraer Temporada/Episodio: ' + title)
item_local.contentSeason = 1
item_local.contentEpisodeNumber = 0
#Si son eisodios múltiples, lo extraemos
patron1 = '\d+[x|X]\d{1,2}.?(?:y|Y|al|Al)?(?:\d+[x|X]\d{1,2})?.?(?:y|Y|al|Al)?.?\d+[x|X](\d{1,2})'
epi_rango = scrapertools.find_single_match(title, patron1)
if epi_rango:
item_local.infoLabels['episodio_titulo'] = 'al %s' % epi_rango
item_local.title = '%sx%s al %s -' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), str(epi_rango).zfill(2))
else:
item_local.title = '%sx%s -' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))
if modo_ultima_temp_alt and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca
if item_local.contentSeason < max_temp:
break #Sale del bucle actual del FOR
if season_display > 0:
if item_local.contentSeason > season_display:
continue
elif item_local.contentSeason < season_display:
break
itemlist.append(item_local.clone())
#logger.debug(item_local)
if len(itemlist) > 1:
itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos
if item.season_colapse and not item.add_videolibrary: #Si viene de listado, mostramos solo Temporadas
item, itemlist = generictools.post_tmdb_seasons(item, itemlist)
if not item.season_colapse: #Si no es pantalla de Temporadas, pintamos todo
# Pasada por TMDB y clasificación de lista por temporada y episodio
tmdb.set_infoLabels(itemlist, True)
#Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
#logger.debug(item)
return itemlist
def actualizar_titulos(item):
logger.info()
item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
#Volvemos a la siguiente acción en el canal
return item
def search(item, texto):
logger.info()
#texto = texto.replace(" ", "+")
try:
item.url = 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 + "peliculas-dvdr/"
item.extra = "Películas DVDR"
item.channel = channel
item.category_new= 'newest'
itemlist = listado(item)
if ">> Página siguiente" in itemlist[-1].title:
itemlist.pop()
# Se captura la excepción, para no interrumpir al canal novedades si un canal falla
except:
import sys
for line in sys.exc_info():
logger.error("{0}".format(line))
return []
return itemlist