- )", "", httptools.downloadpage(item.url, timeout=timeout).data)
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
patron = '
- ]*>[^"]+).*?' #título
pattern += '
[^"]+)?".*?' #thumb pattern += ' \[.*?)?<\/h2.*?' #calidad pattern += ' \d+-\d+-(?P \d{4})?<\/span>*.?' #año pattern += ' (?P \d+[\.|\s].*?[GB|MB])?<\/span>' #tamaño (significativo para peliculas) matches_alt = re.compile(pattern, re.DOTALL).findall(data) if not matches_alt and not ' ( 0 ) Resultados encontrados ' in data_alt and not '
- ]*>[^"]+)?".*?[^"]+).*?
]+>(?P
.*?)?<\/h3>.*?<\/li>' else: pattern = ' - ]*>[^"]+)?".*?
]+>(?P
.*?)?<\/h2>' #Verificamos si se ha cargado una página, y si además tiene la estructura correcta if not data_alt or not scrapertools.find_single_match(data_alt, pattern): 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 01: EPISODIOS: La Web no responde o la URL es erronea: " + item.url) logger.error(pattern + 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, pattern) 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 #Busca y pre-carga todas las páginas de episodios que componen las serie, para obtener la url de cada 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) list_pages = [item.url] for x in range(act_page + 1, last_page + 1): #carga cada página para obtener la url de la siguiente #LAS SIGUIENTES 3 LINEAS ANULADAS: no es necesario leer la pagína siguiente. Se supone que está activa #response = httptools.downloadpage('%s%s'% (url,x)) #if response.sucess: # list_pages.append("%s%s" % (url, x)) #Guarda la url de la siguiente página en una lista list_pages.append("%s%s" % (url, x)) #Guarda la url de la siguiente página en una lista else: list_pages = [item.url] 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 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 = '
- (.*?)
- ]*>
[^"]+)?".*?[^"]+).*?]+>(?P
.*?)?<\/h3>.*?<\/li>' else: pattern = ' - ]*>[^"]+)?".*?
]+>(?P
.*?)?<\/h2>' matches = re.compile(pattern, re.DOTALL).findall(data) 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 #logger.debug("patron: " + pattern) #logger.debug(matches) #Empezamos a generar cada episodio for scrapedurl, scrapedthumb, info in matches: url = scrapedurl thumb = scrapedthumb 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.url = url item_local.contentThumbnail = thumb estado = True #Buena calidad de datos por defecto if "\d+)?)<.+?]+>(?P .*?)?<\/span>\s*Calidad\s*]+>" \ "[\[]\s*(?P .*?)?\s*[\]]<\/span>" if not scrapertools.find_single_match(info, pattern): if "especial" in info.lower(): # Capitulos Especiales pattern = ".*?[^>]+>.*?Temporada.*?\[.*?(?P \d+).*?\].*?Capitulo.*?\[\s*(?P \d+).*?\]?(?:.*?(?P \d+)?)<.+?]+>(?P .*?)?<\/span>\s*Calidad\s*]+>[\[]\s*(?P .*?)?\s*[\]]<\/span>" elif "miniserie" in info.lower() or "completa" in info.lower(): # Series o miniseries completa logger.debug("patron episodioNEW - MINISERIE: " + info) info = '>%sTemporada %s Capitulo 01_99 - Español Castellano Calidad [%s]' % (item_local.contentSerieName, season, item_local.quality) if not scrapertools.find_single_match(info, pattern): #en caso de error de formato, creo uno básico logger.debug("patron episodioNEW: " + pattern) logger.debug(info) logger.debug(item_local.url) info = '>%sTemporada %s Capitulo 0 - Español Castellano Calidad [%s]' % (item_local.contentSerieName, season, item_local.quality) else: # old style. Se intenta buscar un patrón que encaje con los diversos formatos antiguos. Si no, se crea pattern = '\[(?P .*?)\]\[Cap.(?P \d).*?(?P \d{2})(?:_(?P \d+)(?P \d{2}))?\].*?(?P .*)?' #Patrón básico por defecto if scrapertools.find_single_match(info, '\[\d{3}\]'): info = re.sub(r'\[(\d{3}\])', r'[Cap.\1', info) elif scrapertools.find_single_match(info, 'Temp.*?(?P \d+).*?[c|C]ap.*?\.(?P \d+)?.*?(?:(?P \d+))\]?\[(?P \w+)?(?P \w+)\]?'): pattern = 'Temp.*?(?P \d+).*?[c|C]ap.*?\.(?P \d+)?.*?(?:(?P \d+))\]?\[(?P \w+)?(?P \w+)\]?' elif scrapertools.find_single_match(info, 'Temp.*?(?P \d+).*?\[(?P .*?)\].*?(?P \d{2})?(?:.*?(?P \d{2}))?.*?(?P \[\w+.*)\[.*?\]?'): pattern = 'Temp.*?(?P \d+).*?\[(?P .*?)\].*?(?P \d{2})?(?:.*?(?P \d{2}))?.*?(?P \[\w+.*)\[.*?\]?' elif scrapertools.find_single_match(info, 'Temp.*?(?P \d+).*?\[(?P .*?)\].*?Cap\w?\.\s\d?(?P \d{2})(?:.*?(?P \d{2}))?.*?\[(?P \w+)\]?'): pattern = 'Temp.*?(?P \d+).*?\[(?P .*?)\].*?Cap\w?\.\s\d?(?P \d{2})(?:.*?(?P \d{2}))?.*?\[(?P \w+)\]?' elif scrapertools.find_single_match(info, '\[Cap.\d{2}_\d{2}\]'): info = re.sub(r'\[Cap.(\d{2})_(\d{2})\]', r'[Cap.1\1_1\2]', info) elif scrapertools.find_single_match(info, '\[Cap.([A-Za-z]+)\]'): info = re.sub(r'\[Cap.([A-Za-z]+)\]', '[Cap.100]', info) elif "completa" in info.lower(): info = info.replace("COMPLETA", "Caps. 01_99") pattern = 'Temp.*?(?P \d+).*?Cap\w?\.\s\d?(?P \d{2})(?:.*?(?P \d{2}))?.*?\[(?P .*?)\].*?\[(?P \w+)\]?' if not scrapertools.find_single_match(info, pattern): #en caso de error de formato, creo uno básico logger.debug(info) info = '%s - Temp.%s [Caps. 01_99][%s][Spanish]' % (item_local.contentSerieName, season, item_local.quality) if scrapertools.find_single_match(info, '\[Cap.\d{2,3}'): pattern = "\[(?P .*?)\].*?\[Cap.(?P \d).*?(?P \d{2})(?:_(?P \d+)" \ "(?P \d{2}))?.*?\].*?(?:\[(?P .*?)\])?" elif scrapertools.find_single_match(info, 'Cap.\d{2,3}'): pattern = ".*?Temp.*?\s(?P .*?)\s.*?Cap.(?P \d).*?(?P \d{2})(?:_(?P \d+)(?P \d{2}))?.*?\s(?P .*)?" elif scrapertools.find_single_match(info, '(?P .*?)?(?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 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 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 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']) match['episode'] = int(match['episode']) except: logger.error("ERROR 07: EPISODIOS: Error en número de Temporada o Episodio: " + " / TEMPORADA/EPISODIO: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / MATCHES: " + str(matches)) if num_temporadas_flag and match['season'] != season and match['season'] > max_temp + 1: #Si el num de temporada está fuera de control, se trata pone en num. de temporada actual logger.error("ERROR 07: EPISODIOS: Num. de Temporada fuera de rango " + " / TEMPORADA: " + str(match['season']) + " / " + str(match['episode']) + " / NUM_TEMPORADA: " + str(max_temp) + " / " + str(season) + " / PATRON: " + pattern + " / MATCHES: " + str(matches)) match['season'] = season item_local.contentSeason = season else: item_local.contentSeason = match['season'] season = match['season'] if match['episode'] > 0: num_temporadas_flag = True if season > max_temp: 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 = item_local.quality.replace("ALTA DEFINICION", "HDTV") if match['lang'] and (estado == False or "especia" in str(match['lang']).lower()): match['lang'] = match['lang'].replace("- ", "").replace("[", "").replace("]", "") item_local.infoLabels['episodio_titulo'] = match['lang'] item_local.infoLabels['title'] = item_local.infoLabels['episodio_titulo'] 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 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 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 #if ('%sx%s' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2))) in item.library_playcounts: # continue if item_local.active: del item_local.active if item_local.contentTitle: del item_local.infoLabels['title'] item_local.context = "['buscar_trailer']" item_local.action = "findvideos" item_local.contentType = "episode" item_local.extra = "episodios" itemlist.append(item_local.clone()) data = '' 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) #logger.debug(item) #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() 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("search:" + texto) # texto = texto.replace(" ", "+") try: item.url = host + "buscar" item.post = "q=%s" % texto item.pattern = "buscar-list" itemlist = listado_busqueda(item) return itemlist # Se captura la excepción, para no interrumpir al buscador global si un canal falla except: import sys for line in sys.exc_info(): logger.error("%s" % line) return [] def newest(categoria): logger.info() itemlist = [] item = Item() item.title = "newest" item.category = "newest" item.channel = channel_py try: if categoria == 'peliculas': item.url = host + 'ultimas-descargas/' value = 757 item.post = "categoryIDR=%s&date=%s" % (value, fecha_rango) item.extra = "novedades" item.action = "listado_busqueda" itemlist = listado_busqueda(item) elif categoria == 'series': item.url = host + 'ultimas-descargas/' value = 767 item.post = "categoryIDR=%s&date=%s" % (value, fecha_rango) item.extra = "novedades" item.action = "listado_busqueda" itemlist = listado_busqueda(item) elif categoria == '4k': item.url = host + 'ultimas-descargas/' value = 1027 item.post = "categoryIDR=%s&date=%s" % (value, fecha_rango) item.extra = "novedades" item.action = "listado_busqueda" itemlist = listado_busqueda(item) elif categoria == 'anime': item.url = host + 'anime/' item.extra = "peliculas" item.action = "listado" itemlist = listado(item) elif categoria == 'documentales': item.url = host + 'ultimas-descargas/' value = 780 item.post = "categoryIDR=%s&date=%s" % (value, fecha_rango) item.extra = "novedades" item.action = "listado_busqueda" itemlist = listado_busqueda(item) elif categoria == 'latino': item.url = host + 'ultimas-descargas/' value = 1527 item.post = "categoryIDR=%s&date=%s" % (value, fecha_rango) item.extra = "novedades" item.action = "listado_busqueda" itemlist = listado_busqueda(item) if ">> Página siguiente" in itemlist[-1].title or "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 - ]*>[^"]+)?".*?
- (.*?)
- (.*?)
( 0 ) Resultados encontrados ' in data):
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 01: LISTADO: La Web no responde o ha cambiado de URL: " + 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 submenú
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: 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
#Establecemos los valores básicos en función del tipo de contenido
if item.extra == "peliculas":
item.action = "findvideos"
item.contentType = "movie"
pag = True #Sí hay paginación
elif item.extra == "series" and not "/miniseries" in item.url:
item.action = "episodios"
item.contentType = "tvshow"
pag = True
elif item.extra == "varios" or "/miniseries" in item.url:
item.action = "findvideos"
item.contentType = "movie"
pag = True
#Selecciona el tramo de la página con el listado de contenidos
patron = '(.*?)
'
if data:
fichas = scrapertools.get_match(data, patron)
if not fichas and not '( 0 ) Resultados encontrados ' in data: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
itemlist.append(item.clone(action='', title=item.category + ': 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
elif '( 0 ) Resultados encontrados ' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = ']+>.*?' # el thumbnail
patron += '(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.category + ': 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("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
patron_last_page = 'Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
else:
post_num = int(item.post_num) + 1
if not total_pag:
total_pag = 1
#Calcula las páginas del canal por cada página de la web
total_pag = int(total_pag) * int((float(len(matches))/float(cnt_tot)) + 0.999999)
# Preparamos la paginación.
if not item.cnt_pag:
cnt_pag = 0
else:
cnt_pag = item.cnt_pag
del item.cnt_pag
matches_cnt = len(matches)
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 = 'Next<\/a>'
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])
modo = 'next'
# Avanzamos el contador de líneas en una página
if item.next_page:
del item.next_page
if modo == 'next':
cnt_pag = 0
else:
cnt_pag += cnt_tot
#Tratamos todos los contenidos, creardo una variable local de Item
for scrapedurl, scrapedtitle, scrapedthumbnail, scrapedtitle_alt, calidad in matches:
item_local = item.clone()
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
item_local.title = ''
item_local.context = "['buscar_trailer']"
# Limpiamos títulos, Sacamos datos de calidad, audio y lenguaje
title = re.sub('\r\n', '', scrapedtitle).decode('iso-8859-1').encode('utf8').strip()
#title = re.sub('\r\n', '', scrapedtitle).decode('utf-8').encode('utf-8').strip()
title_alt = re.sub('\r\n', '', scrapedtitle_alt).decode('iso-8859-1').encode('utf8').strip()
#title_alt = re.sub('\r\n', '', scrapedtitle_alt).decode('utf-8').encode('utf-8').strip()
title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace(".", " ")
title_alt = title_alt.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ")
item_local.quality = calidad
title_subs = []
#Determinamos y marcamos idiomas distintos del castellano
item_local.language = []
if "[vos" in title.lower() or "v.o.s" in title.lower() or "vo" in title.lower() or "subs" in title.lower() or ".com/pelicula/" in scrapedurl or ".com/series-vo" in scrapedurl or "-vo/" in scrapedurl or "vos" in calidad.lower() or "vose" in calidad.lower() or "v.o.s" in calidad.lower() or "sub" in calidad.lower() or ".com/peliculas-vo" in item.url:
item_local.language += ["VOS"]
title = title.replace(" [Subs. integrados]", "").replace(" [subs. Integrados]", "").replace(" [VOSE", "").replace(" [VOS", "").replace(" (V.O.S.E)", "").replace(" VO", "").replace("Subtitulos", "")
if "latino" in title.lower() or "argentina" in title.lower() or "-latino/" in scrapedurl or "latino" in calidad.lower() or "argentina" in calidad.lower():
item_local.language += ["LAT"]
#Guardamos info de 3D en calidad y limpiamos
if "3d" in title.lower():
if not "3d" in item_local.quality.lower():
item_local.quality = item_local.quality + " 3D"
calidad3D = scrapertools.find_single_match(title, r'\s(3[d|D]\s\w+)')
if calidad3D:
item_local.quality = item_local.quality.replace("3D", calidad3D)
title = re.sub(r'\s3[d|D]\s\w+', '', title)
title = re.sub(r'\s3[d|D]', '', title)
title_alt = re.sub(r'\s3[d|D]\s\w+', '', title_alt)
title_alt = re.sub(r'\s3[d|D]', '', title_alt)
if "imax" in title.lower():
item_local.quality = item_local.quality + " IMAX"
title = title.replace(" IMAX", "").replace(" imax", "")
title_alt = title_alt.replace(" IMAX", "").replace(" imax", "")
if "2d" in title.lower():
title = title.replace("(2D)", "").replace("(2d)", "").replace("2D", "").replace("2d", "")
title_subs += ["[2D]"]
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
title = re.sub(r' [t|T]emp.*?\d+x\d+', '', title)
title = re.sub(r' [t|T]emp.*?\d+', '', title)
title = re.sub(r' [c|C]ap.*?\d+', '', title)
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() or "multileng" in title.lower() or "multileng" in item_local.quality.lower() or (("espa" in title.lower() or "spani" in title.lower()) and "VOS" in item_local.language):
item_local.language[0:0] = ["DUAL"]
title = re.sub(r'\[[D|d]ual.*?\]', '', title)
title = re.sub(r'\[[M|m]ultileng.*?\]', '', title)
item_local.quality = re.sub(r'\[[M|m]ultileng.*?\]', '', item_local.quality)
if "duolog" in title.lower():
title_subs += ["[Saga]"]
title = title.replace(" Duologia", "").replace(" duologia", "").replace(" Duolog", "").replace(" duolog", "")
if "trilog" in title.lower():
title_subs += ["[Saga]"]
title = title.replace(" Trilogia", "").replace(" trilogia", "").replace(" Trilog", "").replace(" trilog", "")
if "extendida" in title.lower():
title_subs += ["[V. Extendida]"]
title = title.replace(" Version Extendida", "").replace(" (Version Extendida)", "").replace(" V. Extendida", "").replace(" VExtendida", "").replace(" V Extendida", "")
if "saga" in title.lower():
title = title.replace(" Saga Completa", "").replace(" saga sompleta", "").replace(" Saga", "").replace(" saga", "")
title_subs += ["[Saga]"]
if "colecc" in title.lower() or "completa" in title.lower():
title = title.replace(" Coleccion", "").replace(" coleccion", "").replace(" Colecci", "").replace(" colecci", "").replace(" Completa", "").replace(" completa", "").replace(" COMPLETA", "")
if scrapertools.find_single_match(title, r'(- [m|M].*?serie ?\w+)'):
title = re.sub(r'- [m|M].*?serie ?\w+', '', title)
title_subs += ["[Miniserie]"]
#Limpiamos restos en título
title = title.replace("Castellano", "").replace("castellano", "").replace("inglés", "").replace("ingles", "").replace("Inglés", "").replace("Ingles", "").replace("Ingl", "").replace("Engl", "").replace("Calidad", "").replace("de la Serie", "")
title_alt = title_alt.replace("Castellano", "").replace("castellano", "").replace("inglés", "").replace("ingles", "").replace("Inglés", "").replace("Ingles", "").replace("Ingl", "").replace("Engl", "").replace("Calidad", "").replace("de la Serie", "")
#Limpiamos cabeceras y colas del título
title = re.sub(r'Descargar\s\w+\-\w+', '', title)
title = re.sub(r'\(COMPLE.*?\)', '', title)
title = re.sub(r'\(\d{4}\)$', '', title)
title = re.sub(r'\d{4}$', '', title)
title = re.sub(r' \d+x\d+', '', title)
title = re.sub(r' x\d+', '', title)
title = title.replace("Ver online ", "").replace("Descarga Serie HD ", "").replace("Descargar Serie HD ", "").replace("Descarga Serie ", "").replace("Descargar Serie ", "").replace("Ver en linea ", "").replace("Ver en linea", "").replace("en Full HD", "").replace("en hd ", "").replace("en HD ", "").replace("HD ", "").replace("(Proper)", "").replace("RatDVD", "").replace("DVDRiP", "").replace("DVDRIP", "").replace("DVDRip", "").replace("DVDR", "").replace("DVD9", "").replace("DVD", "").replace("DVBRIP", "").replace("DVB", "").replace("LINE", "").replace("calidad", " ").replace("- ES ", "").replace("ES ", "").replace("COMPLETA", "").replace("(", "-").replace(")", "-").replace(".", " ").strip()
title = title.replace("Descargar torrent ", "").replace("Descarga Gratis", "").replace("Descarga gratis", "").replace("Descargar Gratis", "").replace("Descargar gratis", "").replace("en gratis", "").replace("gratis gratis", "").replace("Gratisgratis", "").replace("Descargar Estreno ", "").replace("Descargar Estrenos ", "").replace("Pelicula en latino ", "").replace("Descargar Pelicula ", "").replace("Descargar pelicula ", "").replace("Descargar Peliculas ", "").replace("Descargar peliculas ", "").replace("Descargar Todas ", "").replace("Descargar Otras ", "").replace("Descargar ", "").replace("Descarga ", "").replace("Descargar ", "").replace("Decargar ", "").replace("Bajar ", "").replace("HDRIP ", "").replace("HDRiP ", "").replace("HDRip ", "").replace("RIP ", "").replace("Rip", "").replace("RiP", "").replace("XviD", "").replace("AC3 5.1", "").replace("AC3", "").replace("1080p ", "").replace("720p ", "").replace("DVD-Screener ", "").replace("TS-Screener ", "").replace("Screener ", "").replace("BdRemux ", "").replace("BR ", "").replace("4KULTRA", "").replace("FULLBluRay", "").replace("FullBluRay", "").replace("en BluRay", "").replace("BluRay en", "").replace("Bluray en", "").replace("BluRay", "").replace("Bonus Disc", "").replace("de Cine ", "").replace("TeleCine ", "").replace("latino", "").replace("Latino", "").replace("argentina", "").replace("Argentina", "").replace("++Sub", "").replace("+-+Sub", "").strip()
if title.endswith("torrent gratis"): title = title[:-15]
if title.endswith("gratis"): title = title[:-7]
if title.endswith("torrent"): title = title[:-8]
if title.endswith("en HD"): title = title[:-6]
if title.endswith(" -"): title = title[:-2]
if "en espa" in title: title = title[:-11]
item_local.quality = item_local.quality.replace("gratis ", "")
if "HDR" in title:
title = title.replace(" HDR", "")
if not "HDR" in item_local.quality:
item_local.quality += " HDR"
title = title.strip()
title_alt = title_alt.strip()
item_local.quality = item_local.quality.strip()
if not title: #Usamos solo el title_alt en caso de que no exista el título original
title = title_alt
if not title:
title = "SIN TITULO"
#Limpieza final del título y guardado en las variables según su tipo de contenido
title = scrapertools.remove_htmltags(title)
item_local.title = title
item_local.from_title = title #Guardamos esta etiqueta para posible desambiguación de título
if item_local.contentType == "movie":
item_local.contentTitle = title
else:
item_local.contentSerieName = title
#Guardamos el resto de variables del vídeo
item_local.url = scrapedurl
item_local.thumbnail = scrapedthumbnail
item_local.contentThumbnail = scrapedthumbnail
#Guardamos el año que puede venir en la url, por si luego no hay resultados desde TMDB
year = ''
if item_local.contentType == "movie":
year = scrapertools.find_single_match(scrapedurl, r'(\d{4})')
if year >= "1900" and year <= "2040" and year != "2020":
title_subs += [year]
item_local.infoLabels['year'] = '-'
#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
#Agrega el item local a la lista itemlist
itemlist.append(item_local.clone())
#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)
if len(itemlist) == 0:
itemlist.append(Item(channel=item.channel, action="mainlist", title="No se ha podido cargar el listado"))
else:
if url_next_page:
itemlist.append(
Item(channel=item.channel, action="listado", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + str(post_num) + " de " + str(total_pag), url=url_next_page, next_page=next_page, cnt_pag=cnt_pag, post_num=post_num, pag=pag, modo=modo, extra=item.extra))
#logger.debug(url_next_page + " / " + next_page + " / " + str(matches_cnt) + " / " + str(cnt_pag)+ " / " + str(total_pag) + " / " + str(pag) + " / " + modo + " / " + item.extra)
return itemlist
def listado_busqueda(item):
logger.info()
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
item.channel_host = host
item.category_new = ''
if item.category:
item.category_new = item.category
item.category = scrapertools.find_single_match(item.url, 'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').capitalize()
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
itemlist = []
cnt_tot = 40 # 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
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
data = ''
if item.cnt_pag:
cnt_pag = item.cnt_pag # Se guarda en la lista de páginas anteriores en Item
del item.cnt_pag
if item.totalItems:
del item.totalItems
if item.text_bold:
del item.text_bold
if item.text_color:
del item.text_color
#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 = item.title_lista # Se usa la lista de páginas anteriores en Item
title_lista_alt = []
for url in title_lista:
title_lista_alt += [url] #hacemos una copia no vinculada de title_lista
matches = []
cnt_next = 0
total_pag = 1
post_num = 1
#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:
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post, timeout=timeout_search).data)
except:
pass
cnt_next += 1
if item.extra == "novedades":
pattern = '.*?(.*?)
' % item.pattern #seleccionamos el bloque que nos interesa
if not data or (not scrapertools.find_single_match(data, pattern) and not '( 0 ) Resultados encontrados ' in data):
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 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / 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 submenú
item, data = generictools.fail_over_newpct1(item, pattern)
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: 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
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
post_actual = item.post #Guardamos el post actual por si hay overflow de Itemlist y hay que hechar marcha atrás
if item.extra == "novedades":
get, post, total_pag = scrapertools.find_single_match(data, '.*?Next<\/a>.*?Last<\/a>')
else:
get, post, total_pag = scrapertools.find_single_match(data, '.*?Next<\/a>.*?onClick=".*?\(\'([^"]+)\'\);">Last<\/a>)')
except:
post = False
cnt_next = 99 #No hay más páginas. Salir del bucle después de procesar ésta
if post: #puntero a la siguiente página. Cada página de la web tiene 30 entradas
if "pg" in item.post:
item.post = re.sub(r"pg=(\d+)", "pg=%s" % post, item.post)
else:
item.post += "&pg=%s" % post
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
if item.extra == "novedades":
pattern = '.*?(.*?)
' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
if item.extra == "novedades":
pattern = '[^"]+)"[^>]*>' #título
pattern += '
]*src="(?P[^"]+)"?.*?' #thumb
pattern += '<\/h2><\/a>(?P.*?)?' #calidad
pattern += '<(?P.*?)?' #año
pattern += '>Tama.*?\s(?P\d+[.|\s].*?[GB|MB])?\s?<\/strong>' #tamaño (significativo para peliculas)
else:
pattern = ' ' 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
#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
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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
title_lista_alt_for += [scrapedurl_alt]
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
#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:
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
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, scrapedyear, scrapedsize in matches:
cnt_pag += 1
#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.
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
if scrapedurl 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]
if "juego/" in scrapedurl or "xbox" in scrapedurl.lower() 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
#Creamos una copia de Item para cada contenido
item_local = item.clone()
if item_local.category_new:
del item_local.category_new
if item_local.tipo:
del item_local.tipo
if item_local.totalItems:
del item_local.totalItems
if item_local.post:
del item_local.post
if item_local.pattern:
del item_local.pattern
if item_local.title_lista:
del item_local.title_lista
item_local.adult = True
del item_local.adult
item_local.folder = True
del item_local.folder
if item_local.intervencion:
del item_local.intervencion
item_local.title = ''
item_local.context = "['buscar_trailer']"
item_local.contentType = ""
url = scrapedurl
title_subs = []
#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
#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:
try:
data_serie = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item_local.url, timeout=timeout).data)
except:
pass
pattern = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
if not data_serie or (not scrapertools.find_single_match(data_serie, pattern) and not '( 0 ) Resultados encontrados ' in data and not '
' 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
title_subs += ["ERR"]
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 = '.*?.*? 0:
palabra = scrapertools.find_single_match(title, r'(^[A-Za-z0-9_.-?ñ]+)')
if not palabra:
break
title = title.replace(palabra, '')
title = re.sub(r'^\s+\??', '', title)
title = re.sub(r'^-\s?', '', title)
titulo += palabra + " "
palabra = ""
title = titulo.title()
if title.endswith("torrent gratis"): title = title[:-15]
if title.endswith("gratis"): title = title[:-7]
if title.endswith("torrent"): title = title[:-8]
if title.endswith("en HD"): title = title[:-6]
if title.endswith(" -"): title = title[:-2]
if "en espa" in title: title = title[:-11]
#title = re.sub(r'^\s', '', title)
title = title.replace("a?o", 'año').replace("a?O", 'año').replace("A?o", 'Año').replace("A?O", 'Año').strip()
#Preparamos calidad
item_local.quality = item_local.quality.replace("[ ", "").replace(" ]", "") #Preparamos calidad para Series
item_local.quality = re.sub(r'\[\d{4}\]', '', item_local.quality) #Quitar año, si lo tiene
item_local.quality = re.sub(r'\[Cap.*?\]', '', item_local.quality) #Quitar episodios, si lo tiene
item_local.quality = re.sub(r'\[Docu.*?\]', '', item_local.quality) #Quitar tipo contenidos, si lo tiene
#Mirar si es DUAL
if "VOS" in item_local.language and "DUAL" not in item_local.language and ("[sp" in item_local.quality.lower() or "espa" in item_local.quality.lower() or "cast" in item_local.quality.lower() or "spani" in item_local.quality.lower()):
item_local.language[0:0] = ["DUAL"]
if ("[es-" in item_local.quality.lower() or (("cast" in item_local.quality.lower() or "espa" in item_local.quality.lower() or "spani" in item_local.quality.lower()) and ("eng" in item_local.quality.lower() or "ing" in item_local.quality.lower()))) and "DUAL" not in item_local.language: #Mirar si es DUAL
item_local.language[0:0] = ["DUAL"] #Salvar DUAL en idioma
item_local.quality = re.sub(r'\[[es|ES]-\w+]', '', item_local.quality) #borrar DUAL
item_local.quality = re.sub(r'[\s|-][c|C]aste.+', '', item_local.quality) #Borrar después de Castellano
item_local.quality = re.sub(r'[\s|-][e|E]spa.+', '', item_local.quality) #Borrar después de Español
item_local.quality = re.sub(r'[\s|-|\[][s|S]pani.+', '', item_local.quality) #Borrar después de Spanish
item_local.quality = re.sub(r'[\s|-][i|I|e|E]ngl.+', '', item_local.quality) #Borrar después de Inglés-English
item_local.quality = item_local.quality.replace("[", "").replace("]", " ").replace("ALTA DEFINICION", "HDTV").replace(" Cap", "")
#Borrar palabras innecesarias restantes
item_local.quality = item_local.quality.replace("Espaol", "").replace("Español", "").replace("Espa", "").replace("Castellano ", "").replace("Castellano", "").replace("Spanish", "").replace("English", "").replace("Ingles", "").replace("Latino", "").replace("+Subs", "").replace("-Subs", "").replace("Subs", "").replace("VOSE", "").replace("VOS", "").strip()
#Limpieza final del título y guardado en las variables según su tipo de contenido
item_local.title = title
item_local.from_title = title #Guardamos esta etiqueta para posible desambiguación de título
if item_local.contentType == "movie":
item_local.contentTitle = title
size = scrapedsize.replace(".", ",")
item_local.quality = '%s [%s]' % (item_local.quality, size)
else:
item_local.contentSerieName = title
#Guardamos el resto de variables del vídeo
item_local.url = url
item_local.thumbnail = scrapedthumbnail
item_local.contentThumbnail = scrapedthumbnail
#Guardamos el año que puede venir en la url, por si luego no hay resultados desde TMDB
try:
year = int(scrapedyear)
except:
year = ""
year = str(year)
if year >= "1900" and year <= "2040" and year != "2020":
title_subs += [year]
item_local.infoLabels['year'] = '-'
#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
# Codigo para rescatar lo que se pueda en pelisy.series.com de Series para la Videoteca. la URL apunta al capítulo y no a la Serie. Nombre de Serie frecuentemente en blanco. Se obtiene de Thumb, así como el id de la serie
if ("/serie" in item_local.url or "-serie" in item_local.url) and "pelisyseries.com" in item_local.channel_host:
#Extraer la calidad de la serie basados en la info de la url
if "seriehd" in item_local.url:
calidad_mps = "series-hd/"
elif "serievo" in item_local.url or "serie-vo" in item_local.url:
calidad_mps = "series-vo/"
else:
calidad_mps = "series/"
if "no_image" in scrapedthumbnail:
real_title_mps = item_local.title
else:
real_title_mps = re.sub(r'.*?\/\d+_', '', scrapedthumbnail)
real_title_mps = re.sub(r'\.\w+.*?', '', real_title_mps)
#Extraer el ID de la serie desde Thumbs (4 dígitos). Si no hay, nulo
if "/0_" not in scrapedthumbnail and not "no_image" in scrapedthumbnail:
serieid = scrapertools.find_single_match(scrapedthumbnail, r'\/\w\/(?P\d+)')
if len(serieid) > 5:
serieid = ""
else:
serieid = ""
#detectar si la url creada de tvshow es válida o hay que volver atras
url_id = host + calidad_mps + real_title_mps + "/" + serieid #A veces necesita el serieid...
url_tvshow = host + calidad_mps + real_title_mps + "/" #... otras no. A probar...
#Leemos la página, a ver si es una página de episodios
data_serie = data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(url_id, timeout=timeout).data)
data_serie = unicode(data_serie, "iso-8859-1", errors="replace").encode("utf-8")
data_serie = data_serie.replace("chapters", "buscar-list")
pattern = '(.*?)
' % "buscar-list" #Patrón de lista de episodios
if not scrapertools.find_single_match(data_serie, pattern) and serieid: #no es válida la página,
#intentarlo con la otra url
data_serie = data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(url_tvshow, timeout=timeout).data)
data_serie = unicode(data_serie, "iso-8859-1", errors="replace").encode("utf-8")
data_serie = data_serie.replace("chapters", "buscar-list")
if not scrapertools.find_single_match(data_serie, pattern): #No ha habido suerte ...
item_local.contentType = "movie" #tratarlo el capítulo como película
item_local.extra = "peliculas"
else:
item_local.url = url_tvshow #Cambiamos url de episodio por el de serie
else:
item_local.url = url_id #Cambiamos url de episodio por el de serie
#logger.debug("url: " + item_local.url + " / title o/n: " + item_local.title + " / " + real_title_mps + " / calidad_mps : " + calidad_mps + " / contentType : " + item_local.contentType)
item_local.title = real_title_mps.replace('-', ' ').title().strip() #Esperemos que el nuevo título esté bien
item_local.contentSerieName = item_local.title
#Agrega el item local a la lista itemlist
itemlist.append(item_local.clone())
#if not item.category_new: #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)
if post:
itemlist.append(item.clone(channel=item.channel, action="listado_busqueda", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + str(post_num) + " de " + str(total_pag), thumbnail=get_thumb("next.png"), title_lista=title_lista, cnt_pag=cnt_pag))
#logger.debug("Titulos: " + str(len(itemlist)) + " Matches: " + str(len(matches)) + " Post: " + str(item.post) + " / " + str(post_actual) + " / " + str(total_pag))
return itemlist
def findvideos(item):
logger.info()
itemlist = []
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
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
item, data = generictools.fail_over_newpct1(item, verify_fo)
# Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/")
item.url = item.url.replace(".com/", ".com/descarga-torrent/")
#Función para limitar la verificación de enlaces de Servidores para Ver online y Descargas
try:
#Inicializamos las variables por si hay un error en medio del proceso
channel_exclude = []
ver_enlaces = []
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
#Leemos las opciones de permitir Servidores para Ver Online y Descargas
#Cargamos en .json del canal para ver las listas de valores en settings
channel_exclude = channeltools.get_channel_json(item.channel)
for settings in channel_exclude['settings']: #Se recorren todos los settings
if settings['id'] == "clonenewpct1_excluir1_enlaces_veronline": #lista de enlaces a excluir
max_excl = int(settings['max_excl']) #Máximo número de servidores excluidos
channel_exclude = settings['lvalues'] #Cargamos la lista de servidores
if settings['id'] == "clonenewpct1_ver_enlaces_descargas": #Número de enlances a ver o verificar
ver_enlaces = settings['lvalues'] #Cargamos la lista de num. de enlaces
#Primer loop para enlaces de Ver Online.
#Carga la variable de ver
ver_enlaces_veronline = int(config.get_setting("clonenewpct1_ver_enlaces_veronline", item.channel))
if ver_enlaces_veronline == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0
ver_enlaces_veronline = -1
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
verificar_enlaces_veronline = -1
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
verificar_enlaces_veronline_validos = int(config.get_setting("clonenewpct1_verificar_enlaces_veronline_validos", item.channel))
#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
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
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
ver_enlaces_descargas = -1
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
verificar_enlaces_descargas = -1
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
verificar_enlaces_descargas_validos = int(config.get_setting("clonenewpct1_verificar_enlaces_descargas_validos", item.channel))
#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
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
x += 1
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)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
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
# Descarga la página
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url, timeout=timeout).data)
except:
pass
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
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
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
#Añadimos el tamaño para todos
size = scrapertools.find_single_match(data, '(?:)?<\/div><\/div><\/div>)') #Seleccionar el bloque para evitar duplicados
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
data = data.replace("http://tumejorserie.com/descargar/url_encript.php?link=", "(")
data = re.sub(r'javascript:;" onClick="popup\("http:\/\/(?:www.)?' + host_dom + '\w{1,9}\/library\/include\/ajax\/get_modallinks.php\?links=', "", data)
# Nuevo sistema de scrapeo de servidores creado por Torrentlocula, compatible con otros clones de Newpct1
patron = '<\/div[^<]+([^<]+)?<\/div[^<]+([^<]+)?'
patron += '<\/div[^<]+([^<]+)?<\/div[^<]+([^<]+)?<'
enlaces_ver = re.compile(patron, re.DOTALL).findall(data)
enlaces_descargar = enlaces_ver
#logger.debug(enlaces_ver)
#Recorre todos los links de VER, si está permitido
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
break
if "ver" in title.lower():
servidor = servidor.replace("streamin", "streaminto")
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
mostrar_server = servertools.is_server_enabled(servidor)
#logger.debug("VER: url: " + enlace + " / title: " + title + " / servidor: " + servidor + " / idioma: " + idioma)
#Si el servidor es válido, se comprueban si los links están activos
if mostrar_server:
try:
if cnt_enl_ver <= ver_enlaces_veronline or ver_enlaces_veronline == -1:
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
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
else:
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
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
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
item_local.action = "play"
item_local.server = servidor
item_local.url = enlace
item_local.title = item_local.title.replace("[]", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip()
itemlist.append(item_local.clone())
except:
pass
#Ahora vemos los enlaces de DESCARGAR
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:
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=""))
#Recorre todos los links de DESCARGAR
cnt_enl_ver = 1
cnt_enl_verif = 1
for logo, servidor, idioma, calidad, enlace, title in enlaces_descargar:
if ver_enlaces_descargas == 0:
break
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
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)
#Recorremos cada una de las partes. Vemos si el primer link está activo. Si no lo está ignoramos todo el enlace
p = 1
for enlace in partes:
if not item.unify: #Si titles Inteligentes NO seleccionados:
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))
else:
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
mostrar_server = servertools.is_server_enabled(servidor)
#Si el servidor es válido, se comprueban si los links están activos
if mostrar_server:
try:
if cnt_enl_ver <= ver_enlaces_descargas or ver_enlaces_descargas == -1:
devuelve = servertools.findvideosbyserver(enlace, servidor) #activo el link ?
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"
if devuelve:
enlace = devuelve[0][1]
#Verifica si está activo el primer link. Si no lo está se ignora el enlace-servidor entero
if p <= 2:
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor, timeout=timeout) #activo el link ?
if verificar_enlaces_descargas_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:
ver_enlaces_descargas = 0 #FORZAR SALIR de DESCARGAS
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:
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:
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)
logger.debug(item_local.alive + ": ALIVE / " + title + " / " + servidor + " / " + enlace)
break
#Preparamos el resto de variables de Item para descargar los vídeos
item_local.action = "play"
item_local.server = servidor
item_local.url = enlace
item_local.title = parte_title.replace("[]", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title).strip()
itemlist.append(item_local.clone())
except:
pass
return itemlist
def episodios(item):
logger.info()
itemlist = []
#logger.debug(item)
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
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
item, data = generictools.fail_over_newpct1(item, verify_fo)
#Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
if item.contentSeason:
del item.infoLabels['season']
if item.contentEpisodeNumber:
del item.infoLabels['episode']
# 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)
data = ''
data_alt = ''
try:
if "pelisyseries.com" in item.url:
patron = '(.*?)
' % "chapters" # item.pattern
else:
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
pass
if "pelisyseries.com" in item.url:
pattern = '
( 0 ) Resultados encontrados ' in data: #no hay vídeos
return itemlist
else:
return itemlist
page_extra = clase
#Scrapea los datos de cada vídeo. Título alternativo se mantiene, aunque no se usa de momento
patron = ']+>.*?' # el thumbnail
patron += '(.*?)?<\/h2>' # titulo alternativo. Se trunca en títulos largos
patron += '([^<].*?)?<' # la calidad
matches = re.compile(patron, re.DOTALL).findall(fichas)
if not matches: #error
logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + fichas)
itemlist.append(item.clone(action='', title=item.category + ': 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("MATCHES: " + str(len(matches)))
#logger.debug(matches)
#logger.debug("patron: " + patron + " / fichas: " + fichas)
# Identifico la página actual y el total de páginas para el pie de página
patron_last_page = 'Last<\/a><\/li>'
total_pag = scrapertools.find_single_match(data, patron_last_page)
if not item.post_num:
post_num = 1
else:
post_num = int(item.post_num) + 1
if not total_pag:
total_pag = 1
#Calcula las páginas del canal por cada página de la web
total_pag = int(total_pag) * int((float(len(matches))/float(cnt_tot)) + 0.999999)
# Preparamos la paginación.
if not item.cnt_pag:
cnt_pag = 0
else:
cnt_pag = item.cnt_pag
del item.cnt_pag
matches_cnt = len(matches)
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 = 'Next<\/a>'
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])
modo = 'next'
# Avanzamos el contador de líneas en una página
if item.next_page:
del item.next_page
if modo == 'next':
cnt_pag = 0
else:
cnt_pag += cnt_tot
#Tratamos todos los contenidos, creardo una variable local de Item
for scrapedurl, scrapedtitle, scrapedthumbnail, scrapedtitle_alt, calidad in matches:
item_local = item.clone()
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
item_local.title = ''
item_local.context = "['buscar_trailer']"
# Limpiamos títulos, Sacamos datos de calidad, audio y lenguaje
title = re.sub('\r\n', '', scrapedtitle).decode('iso-8859-1').encode('utf8').strip()
#title = re.sub('\r\n', '', scrapedtitle).decode('utf-8').encode('utf-8').strip()
title_alt = re.sub('\r\n', '', scrapedtitle_alt).decode('iso-8859-1').encode('utf8').strip()
#title_alt = re.sub('\r\n', '', scrapedtitle_alt).decode('utf-8').encode('utf-8').strip()
title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace(".", " ")
title_alt = title_alt.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ")
item_local.quality = calidad
title_subs = []
#Determinamos y marcamos idiomas distintos del castellano
item_local.language = []
if "[vos" in title.lower() or "v.o.s" in title.lower() or "vo" in title.lower() or "subs" in title.lower() or ".com/pelicula/" in scrapedurl or ".com/series-vo" in scrapedurl or "-vo/" in scrapedurl or "vos" in calidad.lower() or "vose" in calidad.lower() or "v.o.s" in calidad.lower() or "sub" in calidad.lower() or ".com/peliculas-vo" in item.url:
item_local.language += ["VOS"]
title = title.replace(" [Subs. integrados]", "").replace(" [subs. Integrados]", "").replace(" [VOSE", "").replace(" [VOS", "").replace(" (V.O.S.E)", "").replace(" VO", "").replace("Subtitulos", "")
if "latino" in title.lower() or "argentina" in title.lower() or "-latino/" in scrapedurl or "latino" in calidad.lower() or "argentina" in calidad.lower():
item_local.language += ["LAT"]
#Guardamos info de 3D en calidad y limpiamos
if "3d" in title.lower():
if not "3d" in item_local.quality.lower():
item_local.quality = item_local.quality + " 3D"
calidad3D = scrapertools.find_single_match(title, r'\s(3[d|D]\s\w+)')
if calidad3D:
item_local.quality = item_local.quality.replace("3D", calidad3D)
title = re.sub(r'\s3[d|D]\s\w+', '', title)
title = re.sub(r'\s3[d|D]', '', title)
title_alt = re.sub(r'\s3[d|D]\s\w+', '', title_alt)
title_alt = re.sub(r'\s3[d|D]', '', title_alt)
if "imax" in title.lower():
item_local.quality = item_local.quality + " IMAX"
title = title.replace(" IMAX", "").replace(" imax", "")
title_alt = title_alt.replace(" IMAX", "").replace(" imax", "")
if "2d" in title.lower():
title = title.replace("(2D)", "").replace("(2d)", "").replace("2D", "").replace("2d", "")
title_subs += ["[2D]"]
#Extraemos info adicional del título y la guardamos para después de TMDB
if "temp" in title.lower() or "cap" in title.lower(): #Eliminamos Temporada, solo nos interesa la serie completa
title = re.sub(r' - [t|T]emp\w+ \d+ Comp\w+\d+[x|X]\d+', ' Completa', title)
title = re.sub(r' - [t|T]emp\w+ \d+x\d+', '', title)
title = re.sub(r' - [t|T]emp\w+ \d+', '', title)
title = re.sub(r' - [t|T]emp\w+.*?\d+', '', title)
title = re.sub(r' [t|T]emp.*?\d+x\d+', '', title)
title = re.sub(r' [t|T]emp.*?\d+', '', title)
title = re.sub(r' [c|C]ap.*?\d+', '', title)
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() or "multileng" in title.lower() or "multileng" in item_local.quality.lower() or (("espa" in title.lower() or "spani" in title.lower()) and "VOS" in item_local.language):
item_local.language[0:0] = ["DUAL"]
title = re.sub(r'\[[D|d]ual.*?\]', '', title)
title = re.sub(r'\[[M|m]ultileng.*?\]', '', title)
item_local.quality = re.sub(r'\[[M|m]ultileng.*?\]', '', item_local.quality)
if "duolog" in title.lower():
title_subs += ["[Saga]"]
title = title.replace(" Duologia", "").replace(" duologia", "").replace(" Duolog", "").replace(" duolog", "")
if "trilog" in title.lower():
title_subs += ["[Saga]"]
title = title.replace(" Trilogia", "").replace(" trilogia", "").replace(" Trilog", "").replace(" trilog", "")
if "extendida" in title.lower():
title_subs += ["[V. Extendida]"]
title = title.replace(" Version Extendida", "").replace(" (Version Extendida)", "").replace(" V. Extendida", "").replace(" VExtendida", "").replace(" V Extendida", "")
if "saga" in title.lower():
title = title.replace(" Saga Completa", "").replace(" saga sompleta", "").replace(" Saga", "").replace(" saga", "")
title_subs += ["[Saga]"]
if "colecc" in title.lower() or "completa" in title.lower():
title = title.replace(" Coleccion", "").replace(" coleccion", "").replace(" Colecci", "").replace(" colecci", "").replace(" Completa", "").replace(" completa", "").replace(" COMPLETA", "")
if scrapertools.find_single_match(title, r'(- [m|M].*?serie ?\w+)'):
title = re.sub(r'- [m|M].*?serie ?\w+', '', title)
title_subs += ["[Miniserie]"]
#Limpiamos restos en título
title = title.replace("Castellano", "").replace("castellano", "").replace("inglés", "").replace("ingles", "").replace("Inglés", "").replace("Ingles", "").replace("Ingl", "").replace("Engl", "").replace("Calidad", "").replace("de la Serie", "")
title_alt = title_alt.replace("Castellano", "").replace("castellano", "").replace("inglés", "").replace("ingles", "").replace("Inglés", "").replace("Ingles", "").replace("Ingl", "").replace("Engl", "").replace("Calidad", "").replace("de la Serie", "")
#Limpiamos cabeceras y colas del título
title = re.sub(r'Descargar\s\w+\-\w+', '', title)
title = re.sub(r'\(COMPLE.*?\)', '', title)
title = re.sub(r'\(\d{4}\)$', '', title)
title = re.sub(r'\d{4}$', '', title)
title = re.sub(r' \d+x\d+', '', title)
title = re.sub(r' x\d+', '', title)
title = title.replace("Ver online ", "").replace("Descarga Serie HD ", "").replace("Descargar Serie HD ", "").replace("Descarga Serie ", "").replace("Descargar Serie ", "").replace("Ver en linea ", "").replace("Ver en linea", "").replace("en Full HD", "").replace("en hd ", "").replace("en HD ", "").replace("HD ", "").replace("(Proper)", "").replace("RatDVD", "").replace("DVDRiP", "").replace("DVDRIP", "").replace("DVDRip", "").replace("DVDR", "").replace("DVD9", "").replace("DVD", "").replace("DVBRIP", "").replace("DVB", "").replace("LINE", "").replace("calidad", " ").replace("- ES ", "").replace("ES ", "").replace("COMPLETA", "").replace("(", "-").replace(")", "-").replace(".", " ").strip()
title = title.replace("Descargar torrent ", "").replace("Descarga Gratis", "").replace("Descarga gratis", "").replace("Descargar Gratis", "").replace("Descargar gratis", "").replace("en gratis", "").replace("gratis gratis", "").replace("Gratisgratis", "").replace("Descargar Estreno ", "").replace("Descargar Estrenos ", "").replace("Pelicula en latino ", "").replace("Descargar Pelicula ", "").replace("Descargar pelicula ", "").replace("Descargar Peliculas ", "").replace("Descargar peliculas ", "").replace("Descargar Todas ", "").replace("Descargar Otras ", "").replace("Descargar ", "").replace("Descarga ", "").replace("Descargar ", "").replace("Decargar ", "").replace("Bajar ", "").replace("HDRIP ", "").replace("HDRiP ", "").replace("HDRip ", "").replace("RIP ", "").replace("Rip", "").replace("RiP", "").replace("XviD", "").replace("AC3 5.1", "").replace("AC3", "").replace("1080p ", "").replace("720p ", "").replace("DVD-Screener ", "").replace("TS-Screener ", "").replace("Screener ", "").replace("BdRemux ", "").replace("BR ", "").replace("4KULTRA", "").replace("FULLBluRay", "").replace("FullBluRay", "").replace("en BluRay", "").replace("BluRay en", "").replace("Bluray en", "").replace("BluRay", "").replace("Bonus Disc", "").replace("de Cine ", "").replace("TeleCine ", "").replace("latino", "").replace("Latino", "").replace("argentina", "").replace("Argentina", "").replace("++Sub", "").replace("+-+Sub", "").strip()
if title.endswith("torrent gratis"): title = title[:-15]
if title.endswith("gratis"): title = title[:-7]
if title.endswith("torrent"): title = title[:-8]
if title.endswith("en HD"): title = title[:-6]
if title.endswith(" -"): title = title[:-2]
if "en espa" in title: title = title[:-11]
item_local.quality = item_local.quality.replace("gratis ", "")
if "HDR" in title:
title = title.replace(" HDR", "")
if not "HDR" in item_local.quality:
item_local.quality += " HDR"
title = title.strip()
title_alt = title_alt.strip()
item_local.quality = item_local.quality.strip()
if not title: #Usamos solo el title_alt en caso de que no exista el título original
title = title_alt
if not title:
title = "SIN TITULO"
#Limpieza final del título y guardado en las variables según su tipo de contenido
title = scrapertools.remove_htmltags(title)
item_local.title = title
item_local.from_title = title #Guardamos esta etiqueta para posible desambiguación de título
if item_local.contentType == "movie":
item_local.contentTitle = title
else:
item_local.contentSerieName = title
#Guardamos el resto de variables del vídeo
item_local.url = scrapedurl
item_local.thumbnail = scrapedthumbnail
item_local.contentThumbnail = scrapedthumbnail
#Guardamos el año que puede venir en la url, por si luego no hay resultados desde TMDB
year = ''
if item_local.contentType == "movie":
year = scrapertools.find_single_match(scrapedurl, r'(\d{4})')
if year >= "1900" and year <= "2040" and year != "2020":
title_subs += [year]
item_local.infoLabels['year'] = '-'
#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
#Agrega el item local a la lista itemlist
itemlist.append(item_local.clone())
#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)
if len(itemlist) == 0:
itemlist.append(Item(channel=item.channel, action="mainlist", title="No se ha podido cargar el listado"))
else:
if url_next_page:
itemlist.append(
Item(channel=item.channel, action="listado", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + str(post_num) + " de " + str(total_pag), url=url_next_page, next_page=next_page, cnt_pag=cnt_pag, post_num=post_num, pag=pag, modo=modo, extra=item.extra))
#logger.debug(url_next_page + " / " + next_page + " / " + str(matches_cnt) + " / " + str(cnt_pag)+ " / " + str(total_pag) + " / " + str(pag) + " / " + modo + " / " + item.extra)
return itemlist
def listado_busqueda(item):
logger.info()
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
item.channel_host = host
item.category_new = ''
if item.category:
item.category_new = item.category
item.category = scrapertools.find_single_match(item.url, 'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').capitalize()
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
itemlist = []
cnt_tot = 40 # 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
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
data = ''
if item.cnt_pag:
cnt_pag = item.cnt_pag # Se guarda en la lista de páginas anteriores en Item
del item.cnt_pag
if item.totalItems:
del item.totalItems
if item.text_bold:
del item.text_bold
if item.text_color:
del item.text_color
#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 = item.title_lista # Se usa la lista de páginas anteriores en Item
title_lista_alt = []
for url in title_lista:
title_lista_alt += [url] #hacemos una copia no vinculada de title_lista
matches = []
cnt_next = 0
total_pag = 1
post_num = 1
#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:
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item.url, post=item.post, timeout=timeout_search).data)
except:
pass
cnt_next += 1
if item.extra == "novedades":
pattern = '.*?(.*?)
' % item.pattern #seleccionamos el bloque que nos interesa
if not data or (not scrapertools.find_single_match(data, pattern) and not '( 0 ) Resultados encontrados ' in data):
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 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / 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 submenú
item, data = generictools.fail_over_newpct1(item, pattern)
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: 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
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
post_actual = item.post #Guardamos el post actual por si hay overflow de Itemlist y hay que hechar marcha atrás
if item.extra == "novedades":
get, post, total_pag = scrapertools.find_single_match(data, '.*?Next<\/a>.*?Last<\/a>')
else:
get, post, total_pag = scrapertools.find_single_match(data, '.*?Next<\/a>.*?onClick=".*?\(\'([^"]+)\'\);">Last<\/a>)')
except:
post = False
cnt_next = 99 #No hay más páginas. Salir del bucle después de procesar ésta
if post: #puntero a la siguiente página. Cada página de la web tiene 30 entradas
if "pg" in item.post:
item.post = re.sub(r"pg=(\d+)", "pg=%s" % post, item.post)
else:
item.post += "&pg=%s" % post
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
if item.extra == "novedades":
pattern = '.*?(.*?)
' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
if item.extra == "novedades":
pattern = '[^"]+)"[^>]*>' #título
pattern += '
]*src="(?P[^"]+)"?.*?' #thumb
pattern += '<\/h2><\/a>(?P.*?)?' #calidad
pattern += '<(?P.*?)?' #año
pattern += '>Tama.*?\s(?P\d+[.|\s].*?[GB|MB])?\s?<\/strong>' #tamaño (significativo para peliculas)
else:
pattern = ' ' 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
#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
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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
title_lista_alt_for += [scrapedurl_alt]
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
#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:
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
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, scrapedyear, scrapedsize in matches:
cnt_pag += 1
#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.
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
if scrapedurl 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]
if "juego/" in scrapedurl or "xbox" in scrapedurl.lower() 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
#Creamos una copia de Item para cada contenido
item_local = item.clone()
if item_local.category_new:
del item_local.category_new
if item_local.tipo:
del item_local.tipo
if item_local.totalItems:
del item_local.totalItems
if item_local.post:
del item_local.post
if item_local.pattern:
del item_local.pattern
if item_local.title_lista:
del item_local.title_lista
item_local.adult = True
del item_local.adult
item_local.folder = True
del item_local.folder
if item_local.intervencion:
del item_local.intervencion
item_local.title = ''
item_local.context = "['buscar_trailer']"
item_local.contentType = ""
url = scrapedurl
title_subs = []
#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
#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:
try:
data_serie = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item_local.url, timeout=timeout).data)
except:
pass
pattern = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
if not data_serie or (not scrapertools.find_single_match(data_serie, pattern) and not '( 0 ) Resultados encontrados ' in data and not '
' 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
title_subs += ["ERR"]
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 = '.*?.*? 0:
palabra = scrapertools.find_single_match(title, r'(^[A-Za-z0-9_.-?ñ]+)')
if not palabra:
break
title = title.replace(palabra, '')
title = re.sub(r'^\s+\??', '', title)
title = re.sub(r'^-\s?', '', title)
titulo += palabra + " "
palabra = ""
title = titulo.title()
if title.endswith("torrent gratis"): title = title[:-15]
if title.endswith("gratis"): title = title[:-7]
if title.endswith("torrent"): title = title[:-8]
if title.endswith("en HD"): title = title[:-6]
if title.endswith(" -"): title = title[:-2]
if "en espa" in title: title = title[:-11]
#title = re.sub(r'^\s', '', title)
title = title.replace("a?o", 'año').replace("a?O", 'año').replace("A?o", 'Año').replace("A?O", 'Año').strip()
#Preparamos calidad
item_local.quality = item_local.quality.replace("[ ", "").replace(" ]", "") #Preparamos calidad para Series
item_local.quality = re.sub(r'\[\d{4}\]', '', item_local.quality) #Quitar año, si lo tiene
item_local.quality = re.sub(r'\[Cap.*?\]', '', item_local.quality) #Quitar episodios, si lo tiene
item_local.quality = re.sub(r'\[Docu.*?\]', '', item_local.quality) #Quitar tipo contenidos, si lo tiene
#Mirar si es DUAL
if "VOS" in item_local.language and "DUAL" not in item_local.language and ("[sp" in item_local.quality.lower() or "espa" in item_local.quality.lower() or "cast" in item_local.quality.lower() or "spani" in item_local.quality.lower()):
item_local.language[0:0] = ["DUAL"]
if ("[es-" in item_local.quality.lower() or (("cast" in item_local.quality.lower() or "espa" in item_local.quality.lower() or "spani" in item_local.quality.lower()) and ("eng" in item_local.quality.lower() or "ing" in item_local.quality.lower()))) and "DUAL" not in item_local.language: #Mirar si es DUAL
item_local.language[0:0] = ["DUAL"] #Salvar DUAL en idioma
item_local.quality = re.sub(r'\[[es|ES]-\w+]', '', item_local.quality) #borrar DUAL
item_local.quality = re.sub(r'[\s|-][c|C]aste.+', '', item_local.quality) #Borrar después de Castellano
item_local.quality = re.sub(r'[\s|-][e|E]spa.+', '', item_local.quality) #Borrar después de Español
item_local.quality = re.sub(r'[\s|-|\[][s|S]pani.+', '', item_local.quality) #Borrar después de Spanish
item_local.quality = re.sub(r'[\s|-][i|I|e|E]ngl.+', '', item_local.quality) #Borrar después de Inglés-English
item_local.quality = item_local.quality.replace("[", "").replace("]", " ").replace("ALTA DEFINICION", "HDTV").replace(" Cap", "")
#Borrar palabras innecesarias restantes
item_local.quality = item_local.quality.replace("Espaol", "").replace("Español", "").replace("Espa", "").replace("Castellano ", "").replace("Castellano", "").replace("Spanish", "").replace("English", "").replace("Ingles", "").replace("Latino", "").replace("+Subs", "").replace("-Subs", "").replace("Subs", "").replace("VOSE", "").replace("VOS", "").strip()
#Limpieza final del título y guardado en las variables según su tipo de contenido
item_local.title = title
item_local.from_title = title #Guardamos esta etiqueta para posible desambiguación de título
if item_local.contentType == "movie":
item_local.contentTitle = title
size = scrapedsize.replace(".", ",")
item_local.quality = '%s [%s]' % (item_local.quality, size)
else:
item_local.contentSerieName = title
#Guardamos el resto de variables del vídeo
item_local.url = url
item_local.thumbnail = scrapedthumbnail
item_local.contentThumbnail = scrapedthumbnail
#Guardamos el año que puede venir en la url, por si luego no hay resultados desde TMDB
try:
year = int(scrapedyear)
except:
year = ""
year = str(year)
if year >= "1900" and year <= "2040" and year != "2020":
title_subs += [year]
item_local.infoLabels['year'] = '-'
#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
# Codigo para rescatar lo que se pueda en pelisy.series.com de Series para la Videoteca. la URL apunta al capítulo y no a la Serie. Nombre de Serie frecuentemente en blanco. Se obtiene de Thumb, así como el id de la serie
if ("/serie" in item_local.url or "-serie" in item_local.url) and "pelisyseries.com" in item_local.channel_host:
#Extraer la calidad de la serie basados en la info de la url
if "seriehd" in item_local.url:
calidad_mps = "series-hd/"
elif "serievo" in item_local.url or "serie-vo" in item_local.url:
calidad_mps = "series-vo/"
else:
calidad_mps = "series/"
if "no_image" in scrapedthumbnail:
real_title_mps = item_local.title
else:
real_title_mps = re.sub(r'.*?\/\d+_', '', scrapedthumbnail)
real_title_mps = re.sub(r'\.\w+.*?', '', real_title_mps)
#Extraer el ID de la serie desde Thumbs (4 dígitos). Si no hay, nulo
if "/0_" not in scrapedthumbnail and not "no_image" in scrapedthumbnail:
serieid = scrapertools.find_single_match(scrapedthumbnail, r'\/\w\/(?P\d+)')
if len(serieid) > 5:
serieid = ""
else:
serieid = ""
#detectar si la url creada de tvshow es válida o hay que volver atras
url_id = host + calidad_mps + real_title_mps + "/" + serieid #A veces necesita el serieid...
url_tvshow = host + calidad_mps + real_title_mps + "/" #... otras no. A probar...
#Leemos la página, a ver si es una página de episodios
data_serie = data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(url_id, timeout=timeout).data)
data_serie = unicode(data_serie, "iso-8859-1", errors="replace").encode("utf-8")
data_serie = data_serie.replace("chapters", "buscar-list")
pattern = '(.*?)
' % "buscar-list" #Patrón de lista de episodios
if not scrapertools.find_single_match(data_serie, pattern) and serieid: #no es válida la página,
#intentarlo con la otra url
data_serie = data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(url_tvshow, timeout=timeout).data)
data_serie = unicode(data_serie, "iso-8859-1", errors="replace").encode("utf-8")
data_serie = data_serie.replace("chapters", "buscar-list")
if not scrapertools.find_single_match(data_serie, pattern): #No ha habido suerte ...
item_local.contentType = "movie" #tratarlo el capítulo como película
item_local.extra = "peliculas"
else:
item_local.url = url_tvshow #Cambiamos url de episodio por el de serie
else:
item_local.url = url_id #Cambiamos url de episodio por el de serie
#logger.debug("url: " + item_local.url + " / title o/n: " + item_local.title + " / " + real_title_mps + " / calidad_mps : " + calidad_mps + " / contentType : " + item_local.contentType)
item_local.title = real_title_mps.replace('-', ' ').title().strip() #Esperemos que el nuevo título esté bien
item_local.contentSerieName = item_local.title
#Agrega el item local a la lista itemlist
itemlist.append(item_local.clone())
#if not item.category_new: #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)
if post:
itemlist.append(item.clone(channel=item.channel, action="listado_busqueda", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + str(post_num) + " de " + str(total_pag), thumbnail=get_thumb("next.png"), title_lista=title_lista, cnt_pag=cnt_pag))
#logger.debug("Titulos: " + str(len(itemlist)) + " Matches: " + str(len(matches)) + " Post: " + str(item.post) + " / " + str(post_actual) + " / " + str(total_pag))
return itemlist
def findvideos(item):
logger.info()
itemlist = []
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
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
item, data = generictools.fail_over_newpct1(item, verify_fo)
# Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/")
item.url = item.url.replace(".com/", ".com/descarga-torrent/")
#Función para limitar la verificación de enlaces de Servidores para Ver online y Descargas
try:
#Inicializamos las variables por si hay un error en medio del proceso
channel_exclude = []
ver_enlaces = []
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
#Leemos las opciones de permitir Servidores para Ver Online y Descargas
#Cargamos en .json del canal para ver las listas de valores en settings
channel_exclude = channeltools.get_channel_json(item.channel)
for settings in channel_exclude['settings']: #Se recorren todos los settings
if settings['id'] == "clonenewpct1_excluir1_enlaces_veronline": #lista de enlaces a excluir
max_excl = int(settings['max_excl']) #Máximo número de servidores excluidos
channel_exclude = settings['lvalues'] #Cargamos la lista de servidores
if settings['id'] == "clonenewpct1_ver_enlaces_descargas": #Número de enlances a ver o verificar
ver_enlaces = settings['lvalues'] #Cargamos la lista de num. de enlaces
#Primer loop para enlaces de Ver Online.
#Carga la variable de ver
ver_enlaces_veronline = int(config.get_setting("clonenewpct1_ver_enlaces_veronline", item.channel))
if ver_enlaces_veronline == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0
ver_enlaces_veronline = -1
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
verificar_enlaces_veronline = -1
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
verificar_enlaces_veronline_validos = int(config.get_setting("clonenewpct1_verificar_enlaces_veronline_validos", item.channel))
#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
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
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
ver_enlaces_descargas = -1
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
verificar_enlaces_descargas = -1
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
verificar_enlaces_descargas_validos = int(config.get_setting("clonenewpct1_verificar_enlaces_descargas_validos", item.channel))
#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
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
x += 1
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)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
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
# Descarga la página
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url, timeout=timeout).data)
except:
pass
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
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
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
#Añadimos el tamaño para todos
size = scrapertools.find_single_match(data, '(?:)?<\/div><\/div><\/div>)') #Seleccionar el bloque para evitar duplicados
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
data = data.replace("http://tumejorserie.com/descargar/url_encript.php?link=", "(")
data = re.sub(r'javascript:;" onClick="popup\("http:\/\/(?:www.)?' + host_dom + '\w{1,9}\/library\/include\/ajax\/get_modallinks.php\?links=', "", data)
# Nuevo sistema de scrapeo de servidores creado por Torrentlocula, compatible con otros clones de Newpct1
patron = '<\/div[^<]+([^<]+)?<\/div[^<]+([^<]+)?'
patron += '<\/div[^<]+([^<]+)?<\/div[^<]+([^<]+)?<'
enlaces_ver = re.compile(patron, re.DOTALL).findall(data)
enlaces_descargar = enlaces_ver
#logger.debug(enlaces_ver)
#Recorre todos los links de VER, si está permitido
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
break
if "ver" in title.lower():
servidor = servidor.replace("streamin", "streaminto")
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
mostrar_server = servertools.is_server_enabled(servidor)
#logger.debug("VER: url: " + enlace + " / title: " + title + " / servidor: " + servidor + " / idioma: " + idioma)
#Si el servidor es válido, se comprueban si los links están activos
if mostrar_server:
try:
if cnt_enl_ver <= ver_enlaces_veronline or ver_enlaces_veronline == -1:
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
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
else:
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
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
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
item_local.action = "play"
item_local.server = servidor
item_local.url = enlace
item_local.title = item_local.title.replace("[]", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip()
itemlist.append(item_local.clone())
except:
pass
#Ahora vemos los enlaces de DESCARGAR
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:
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=""))
#Recorre todos los links de DESCARGAR
cnt_enl_ver = 1
cnt_enl_verif = 1
for logo, servidor, idioma, calidad, enlace, title in enlaces_descargar:
if ver_enlaces_descargas == 0:
break
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
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)
#Recorremos cada una de las partes. Vemos si el primer link está activo. Si no lo está ignoramos todo el enlace
p = 1
for enlace in partes:
if not item.unify: #Si titles Inteligentes NO seleccionados:
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))
else:
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
mostrar_server = servertools.is_server_enabled(servidor)
#Si el servidor es válido, se comprueban si los links están activos
if mostrar_server:
try:
if cnt_enl_ver <= ver_enlaces_descargas or ver_enlaces_descargas == -1:
devuelve = servertools.findvideosbyserver(enlace, servidor) #activo el link ?
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"
if devuelve:
enlace = devuelve[0][1]
#Verifica si está activo el primer link. Si no lo está se ignora el enlace-servidor entero
if p <= 2:
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor, timeout=timeout) #activo el link ?
if verificar_enlaces_descargas_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:
ver_enlaces_descargas = 0 #FORZAR SALIR de DESCARGAS
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:
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:
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)
logger.debug(item_local.alive + ": ALIVE / " + title + " / " + servidor + " / " + enlace)
break
#Preparamos el resto de variables de Item para descargar los vídeos
item_local.action = "play"
item_local.server = servidor
item_local.url = enlace
item_local.title = parte_title.replace("[]", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title).strip()
itemlist.append(item_local.clone())
except:
pass
return itemlist
def episodios(item):
logger.info()
itemlist = []
#logger.debug(item)
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
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
item, data = generictools.fail_over_newpct1(item, verify_fo)
#Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
if item.contentSeason:
del item.infoLabels['season']
if item.contentEpisodeNumber:
del item.infoLabels['episode']
# 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)
data = ''
data_alt = ''
try:
if "pelisyseries.com" in item.url:
patron = '(.*?)
' % "chapters" # item.pattern
else:
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
pass
if "pelisyseries.com" in item.url:
pattern = '
- (.*?)
( 0 ) Resultados encontrados ' in data):
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 01: LISTADO_BUSQUEDA: La Web no responde o ha cambiado de URL: " + item.url + item.post + " / 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 submenú
item, data = generictools.fail_over_newpct1(item, pattern)
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: 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
elif item.channel_alt: #Si ha habido fail-over, lo comento
host = host.replace(item.channel_alt, item.channel)
#Obtiene la dirección de la próxima página, si la hay
try:
post_actual = item.post #Guardamos el post actual por si hay overflow de Itemlist y hay que hechar marcha atrás
if item.extra == "novedades":
get, post, total_pag = scrapertools.find_single_match(data, '.*?Next<\/a>.*?Last<\/a>')
else:
get, post, total_pag = scrapertools.find_single_match(data, '.*?Next<\/a>.*?onClick=".*?\(\'([^"]+)\'\);">Last<\/a>)')
except:
post = False
cnt_next = 99 #No hay más páginas. Salir del bucle después de procesar ésta
if post: #puntero a la siguiente página. Cada página de la web tiene 30 entradas
if "pg" in item.post:
item.post = re.sub(r"pg=(\d+)", "pg=%s" % post, item.post)
else:
item.post += "&pg=%s" % post
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
if item.extra == "novedades":
pattern = '.*?(.*?)
' % item.pattern #seleccionamos el bloque que nos interesa
data_alt = data
data = scrapertools.get_match(data, pattern)
if item.extra == "novedades":
pattern = '[^"]+)"[^>]*>' #título
pattern += '
]*src="(?P[^"]+)"?.*?' #thumb
pattern += '<\/h2><\/a>(?P.*?)?' #calidad
pattern += '<(?P.*?)?' #año
pattern += '>Tama.*?\s(?P\d+[.|\s].*?[GB|MB])?\s?<\/strong>' #tamaño (significativo para peliculas)
else:
pattern = ' ' 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
#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
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 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 ".com/serie" in scrapedurl or "/serie" in scrapedurl or "-serie" in scrapedurl or "varios/" in scrapedurl:
title_lista_alt_for += [scrapedurl_alt]
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
#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:
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
title_lista_alt.extend(title_lista_alt_for)
#logger.debug("PATRON: " + pattern)
#logger.debug(matches)
#logger.debug(title_lista_alt)
#logger.debug(data)
cnt_title = 0
for scrapedurl, scrapedtitle, scrapedthumbnail, calidad, scrapedyear, scrapedsize in matches:
cnt_pag += 1
#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.
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
if scrapedurl 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]
if "juego/" in scrapedurl or "xbox" in scrapedurl.lower() 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
#Creamos una copia de Item para cada contenido
item_local = item.clone()
if item_local.category_new:
del item_local.category_new
if item_local.tipo:
del item_local.tipo
if item_local.totalItems:
del item_local.totalItems
if item_local.post:
del item_local.post
if item_local.pattern:
del item_local.pattern
if item_local.title_lista:
del item_local.title_lista
item_local.adult = True
del item_local.adult
item_local.folder = True
del item_local.folder
if item_local.intervencion:
del item_local.intervencion
item_local.title = ''
item_local.context = "['buscar_trailer']"
item_local.contentType = ""
url = scrapedurl
title_subs = []
#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
#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:
try:
data_serie = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(item_local.url, timeout=timeout).data)
except:
pass
pattern = 'class="btn-torrent">.*?window.location.href = "(.*?)";' #Patron para .torrent
if not data_serie or (not scrapertools.find_single_match(data_serie, pattern) and not '( 0 ) Resultados encontrados ' in data and not '
- .*?Next<\/a>.*?onClick=".*?\(\'([^"]+)\'\);">Last<\/a>)')
except:
post = False
cnt_next = 99 #No hay más páginas. Salir del bucle después de procesar ésta
if post: #puntero a la siguiente página. Cada página de la web tiene 30 entradas
if "pg" in item.post:
item.post = re.sub(r"pg=(\d+)", "pg=%s" % post, item.post)
else:
item.post += "&pg=%s" % post
post_num = int(post)-1 #Guardo página actual
# Preparamos un patron que pretence recoger todos los datos significativos del video
if item.extra == "novedades":
pattern = '
- (.*?)
( 0 ) Resultados encontrados ' in data and not '
.*? 0:
palabra = scrapertools.find_single_match(title, r'(^[A-Za-z0-9_.-?ñ]+)')
if not palabra:
break
title = title.replace(palabra, '')
title = re.sub(r'^\s+\??', '', title)
title = re.sub(r'^-\s?', '', title)
titulo += palabra + " "
palabra = ""
title = titulo.title()
if title.endswith("torrent gratis"): title = title[:-15]
if title.endswith("gratis"): title = title[:-7]
if title.endswith("torrent"): title = title[:-8]
if title.endswith("en HD"): title = title[:-6]
if title.endswith(" -"): title = title[:-2]
if "en espa" in title: title = title[:-11]
#title = re.sub(r'^\s', '', title)
title = title.replace("a?o", 'año').replace("a?O", 'año').replace("A?o", 'Año').replace("A?O", 'Año').strip()
#Preparamos calidad
item_local.quality = item_local.quality.replace("[ ", "").replace(" ]", "") #Preparamos calidad para Series
item_local.quality = re.sub(r'\[\d{4}\]', '', item_local.quality) #Quitar año, si lo tiene
item_local.quality = re.sub(r'\[Cap.*?\]', '', item_local.quality) #Quitar episodios, si lo tiene
item_local.quality = re.sub(r'\[Docu.*?\]', '', item_local.quality) #Quitar tipo contenidos, si lo tiene
#Mirar si es DUAL
if "VOS" in item_local.language and "DUAL" not in item_local.language and ("[sp" in item_local.quality.lower() or "espa" in item_local.quality.lower() or "cast" in item_local.quality.lower() or "spani" in item_local.quality.lower()):
item_local.language[0:0] = ["DUAL"]
if ("[es-" in item_local.quality.lower() or (("cast" in item_local.quality.lower() or "espa" in item_local.quality.lower() or "spani" in item_local.quality.lower()) and ("eng" in item_local.quality.lower() or "ing" in item_local.quality.lower()))) and "DUAL" not in item_local.language: #Mirar si es DUAL
item_local.language[0:0] = ["DUAL"] #Salvar DUAL en idioma
item_local.quality = re.sub(r'\[[es|ES]-\w+]', '', item_local.quality) #borrar DUAL
item_local.quality = re.sub(r'[\s|-][c|C]aste.+', '', item_local.quality) #Borrar después de Castellano
item_local.quality = re.sub(r'[\s|-][e|E]spa.+', '', item_local.quality) #Borrar después de Español
item_local.quality = re.sub(r'[\s|-|\[][s|S]pani.+', '', item_local.quality) #Borrar después de Spanish
item_local.quality = re.sub(r'[\s|-][i|I|e|E]ngl.+', '', item_local.quality) #Borrar después de Inglés-English
item_local.quality = item_local.quality.replace("[", "").replace("]", " ").replace("ALTA DEFINICION", "HDTV").replace(" Cap", "")
#Borrar palabras innecesarias restantes
item_local.quality = item_local.quality.replace("Espaol", "").replace("Español", "").replace("Espa", "").replace("Castellano ", "").replace("Castellano", "").replace("Spanish", "").replace("English", "").replace("Ingles", "").replace("Latino", "").replace("+Subs", "").replace("-Subs", "").replace("Subs", "").replace("VOSE", "").replace("VOS", "").strip()
#Limpieza final del título y guardado en las variables según su tipo de contenido
item_local.title = title
item_local.from_title = title #Guardamos esta etiqueta para posible desambiguación de título
if item_local.contentType == "movie":
item_local.contentTitle = title
size = scrapedsize.replace(".", ",")
item_local.quality = '%s [%s]' % (item_local.quality, size)
else:
item_local.contentSerieName = title
#Guardamos el resto de variables del vídeo
item_local.url = url
item_local.thumbnail = scrapedthumbnail
item_local.contentThumbnail = scrapedthumbnail
#Guardamos el año que puede venir en la url, por si luego no hay resultados desde TMDB
try:
year = int(scrapedyear)
except:
year = ""
year = str(year)
if year >= "1900" and year <= "2040" and year != "2020":
title_subs += [year]
item_local.infoLabels['year'] = '-'
#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
# Codigo para rescatar lo que se pueda en pelisy.series.com de Series para la Videoteca. la URL apunta al capítulo y no a la Serie. Nombre de Serie frecuentemente en blanco. Se obtiene de Thumb, así como el id de la serie
if ("/serie" in item_local.url or "-serie" in item_local.url) and "pelisyseries.com" in item_local.channel_host:
#Extraer la calidad de la serie basados en la info de la url
if "seriehd" in item_local.url:
calidad_mps = "series-hd/"
elif "serievo" in item_local.url or "serie-vo" in item_local.url:
calidad_mps = "series-vo/"
else:
calidad_mps = "series/"
if "no_image" in scrapedthumbnail:
real_title_mps = item_local.title
else:
real_title_mps = re.sub(r'.*?\/\d+_', '', scrapedthumbnail)
real_title_mps = re.sub(r'\.\w+.*?', '', real_title_mps)
#Extraer el ID de la serie desde Thumbs (4 dígitos). Si no hay, nulo
if "/0_" not in scrapedthumbnail and not "no_image" in scrapedthumbnail:
serieid = scrapertools.find_single_match(scrapedthumbnail, r'\/\w\/(?P\d+)')
if len(serieid) > 5:
serieid = ""
else:
serieid = ""
#detectar si la url creada de tvshow es válida o hay que volver atras
url_id = host + calidad_mps + real_title_mps + "/" + serieid #A veces necesita el serieid...
url_tvshow = host + calidad_mps + real_title_mps + "/" #... otras no. A probar...
#Leemos la página, a ver si es una página de episodios
data_serie = data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(url_id, timeout=timeout).data)
data_serie = unicode(data_serie, "iso-8859-1", errors="replace").encode("utf-8")
data_serie = data_serie.replace("chapters", "buscar-list")
pattern = '(.*?)
' % "buscar-list" #Patrón de lista de episodios
if not scrapertools.find_single_match(data_serie, pattern) and serieid: #no es válida la página,
#intentarlo con la otra url
data_serie = data = re.sub(r"\n|\r|\t|\s{2,}", "", httptools.downloadpage(url_tvshow, timeout=timeout).data)
data_serie = unicode(data_serie, "iso-8859-1", errors="replace").encode("utf-8")
data_serie = data_serie.replace("chapters", "buscar-list")
if not scrapertools.find_single_match(data_serie, pattern): #No ha habido suerte ...
item_local.contentType = "movie" #tratarlo el capítulo como película
item_local.extra = "peliculas"
else:
item_local.url = url_tvshow #Cambiamos url de episodio por el de serie
else:
item_local.url = url_id #Cambiamos url de episodio por el de serie
#logger.debug("url: " + item_local.url + " / title o/n: " + item_local.title + " / " + real_title_mps + " / calidad_mps : " + calidad_mps + " / contentType : " + item_local.contentType)
item_local.title = real_title_mps.replace('-', ' ').title().strip() #Esperemos que el nuevo título esté bien
item_local.contentSerieName = item_local.title
#Agrega el item local a la lista itemlist
itemlist.append(item_local.clone())
#if not item.category_new: #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)
if post:
itemlist.append(item.clone(channel=item.channel, action="listado_busqueda", title="[COLOR gold][B]Pagina siguiente >> [/B][/COLOR]" + str(post_num) + " de " + str(total_pag), thumbnail=get_thumb("next.png"), title_lista=title_lista, cnt_pag=cnt_pag))
#logger.debug("Titulos: " + str(len(itemlist)) + " Matches: " + str(len(matches)) + " Post: " + str(item.post) + " / " + str(post_actual) + " / " + str(total_pag))
return itemlist
def findvideos(item):
logger.info()
itemlist = []
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
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
item, data = generictools.fail_over_newpct1(item, verify_fo)
# Cualquiera de las tres opciones son válidas
# item.url = item.url.replace(".com/",".com/ver-online/")
# item.url = item.url.replace(".com/",".com/descarga-directa/")
item.url = item.url.replace(".com/", ".com/descarga-torrent/")
#Función para limitar la verificación de enlaces de Servidores para Ver online y Descargas
try:
#Inicializamos las variables por si hay un error en medio del proceso
channel_exclude = []
ver_enlaces = []
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
#Leemos las opciones de permitir Servidores para Ver Online y Descargas
#Cargamos en .json del canal para ver las listas de valores en settings
channel_exclude = channeltools.get_channel_json(item.channel)
for settings in channel_exclude['settings']: #Se recorren todos los settings
if settings['id'] == "clonenewpct1_excluir1_enlaces_veronline": #lista de enlaces a excluir
max_excl = int(settings['max_excl']) #Máximo número de servidores excluidos
channel_exclude = settings['lvalues'] #Cargamos la lista de servidores
if settings['id'] == "clonenewpct1_ver_enlaces_descargas": #Número de enlances a ver o verificar
ver_enlaces = settings['lvalues'] #Cargamos la lista de num. de enlaces
#Primer loop para enlaces de Ver Online.
#Carga la variable de ver
ver_enlaces_veronline = int(config.get_setting("clonenewpct1_ver_enlaces_veronline", item.channel))
if ver_enlaces_veronline == 1: #a "Todos" le damos valor -1. Para "No" dejamos 0
ver_enlaces_veronline = -1
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
verificar_enlaces_veronline = -1
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
verificar_enlaces_veronline_validos = int(config.get_setting("clonenewpct1_verificar_enlaces_veronline_validos", item.channel))
#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
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
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
ver_enlaces_descargas = -1
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
verificar_enlaces_descargas = -1
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
verificar_enlaces_descargas_validos = int(config.get_setting("clonenewpct1_verificar_enlaces_descargas_validos", item.channel))
#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
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
x += 1
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)
logger.error(verificar_enlaces_veronline)
logger.error(verificar_enlaces_veronline_validos)
logger.error(excluir_enlaces_veronline)
logger.error(ver_enlaces_descargas)
logger.error(verificar_enlaces_descargas)
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
# Descarga la página
data = ''
try:
data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url, timeout=timeout).data)
except:
pass
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
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
data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
data = data.replace("$!", "#!").replace("'", "\"").replace("ñ", "ñ").replace("//pictures", "/pictures")
#Añadimos el tamaño para todos
size = scrapertools.find_single_match(data, '(?:)?<\/div><\/div><\/div>)') #Seleccionar el bloque para evitar duplicados
host_dom = host.replace("https://", "").replace("http://", "").replace("www.", "")
data = data.replace("http://tumejorserie.com/descargar/url_encript.php?link=", "(")
data = re.sub(r'javascript:;" onClick="popup\("http:\/\/(?:www.)?' + host_dom + '\w{1,9}\/library\/include\/ajax\/get_modallinks.php\?links=', "", data)
# Nuevo sistema de scrapeo de servidores creado por Torrentlocula, compatible con otros clones de Newpct1
patron = '<\/div[^<]+([^<]+)?<\/div[^<]+([^<]+)?'
patron += '<\/div[^<]+([^<]+)?<\/div[^<]+([^<]+)?<'
enlaces_ver = re.compile(patron, re.DOTALL).findall(data)
enlaces_descargar = enlaces_ver
#logger.debug(enlaces_ver)
#Recorre todos los links de VER, si está permitido
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
break
if "ver" in title.lower():
servidor = servidor.replace("streamin", "streaminto")
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
mostrar_server = servertools.is_server_enabled(servidor)
#logger.debug("VER: url: " + enlace + " / title: " + title + " / servidor: " + servidor + " / idioma: " + idioma)
#Si el servidor es válido, se comprueban si los links están activos
if mostrar_server:
try:
if cnt_enl_ver <= ver_enlaces_veronline or ver_enlaces_veronline == -1:
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
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
else:
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
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
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
item_local.action = "play"
item_local.server = servidor
item_local.url = enlace
item_local.title = item_local.title.replace("[]", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip()
itemlist.append(item_local.clone())
except:
pass
#Ahora vemos los enlaces de DESCARGAR
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:
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=""))
#Recorre todos los links de DESCARGAR
cnt_enl_ver = 1
cnt_enl_verif = 1
for logo, servidor, idioma, calidad, enlace, title in enlaces_descargar:
if ver_enlaces_descargas == 0:
break
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
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)
#Recorremos cada una de las partes. Vemos si el primer link está activo. Si no lo está ignoramos todo el enlace
p = 1
for enlace in partes:
if not item.unify: #Si titles Inteligentes NO seleccionados:
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))
else:
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
mostrar_server = servertools.is_server_enabled(servidor)
#Si el servidor es válido, se comprueban si los links están activos
if mostrar_server:
try:
if cnt_enl_ver <= ver_enlaces_descargas or ver_enlaces_descargas == -1:
devuelve = servertools.findvideosbyserver(enlace, servidor) #activo el link ?
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"
if devuelve:
enlace = devuelve[0][1]
#Verifica si está activo el primer link. Si no lo está se ignora el enlace-servidor entero
if p <= 2:
item_local.alive = "??" #Se asume poe defecto que es link es dudoso
if verificar_enlaces_descargas != 0: #Se quiere verificar si el link está activo?
if cnt_enl_verif <= verificar_enlaces_descargas or verificar_enlaces_descargas == -1: #contador?
#Llama a la subfunción de check_list_links(itemlist) para primer link de servidor
item_local.alive = servertools.check_video_link(enlace, servidor, timeout=timeout) #activo el link ?
if verificar_enlaces_descargas_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:
ver_enlaces_descargas = 0 #FORZAR SALIR de DESCARGAS
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:
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:
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)
logger.debug(item_local.alive + ": ALIVE / " + title + " / " + servidor + " / " + enlace)
break
#Preparamos el resto de variables de Item para descargar los vídeos
item_local.action = "play"
item_local.server = servidor
item_local.url = enlace
item_local.title = parte_title.replace("[]", "").strip()
item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip()
item_local.title = re.sub(r'\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title).strip()
itemlist.append(item_local.clone())
except:
pass
return itemlist
def episodios(item):
logger.info()
itemlist = []
#logger.debug(item)
#Renombramos el canal al nombre de clone elegido. Actualizados URL
host = scrapertools.find_single_match(item.url, '(http.?\:\/\/(?:www.)?\w+\.\w+\/)')
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
item, data = generictools.fail_over_newpct1(item, verify_fo)
#Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
if item.contentSeason:
del item.infoLabels['season']
if item.contentEpisodeNumber:
del item.infoLabels['episode']
# 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)
data = ''
data_alt = ''
try:
if "pelisyseries.com" in item.url:
patron = '(.*?)
' % "chapters" # item.pattern
else:
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
pass
if "pelisyseries.com" in item.url:
pattern = '
- (.*?)
- (.*?)
- (.*?)