.*?)<\/td>(?P.*?)<\/span><\/p><\/td>(?P.*?)<\/td>'
+
+ matches = re.compile(patron, re.DOTALL).findall(data)
+ if not matches and not 'Lo sentimos, no tenemos nada que mostrar' in data: #error
+ item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada
+ if item.intervencion: #Sí ha sido clausurada judicialmente
+ item, itemlist = generictools.post_tmdb_episodios(item, itemlist) #Llamamos al método para el pintado del error
+ return itemlist #Salimos
+
+ logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data)
+ itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log'))
+ break #si no hay más datos, algo no funciona, pintamos lo que tenemos
+
+ #logger.debug("PATRON: " + patron)
+ #logger.debug(matches)
+ #logger.debug(data)
+
+ #Buscamos la url de paginado y la última página
+ if item.extra2 == 'alfabeto': #patrón especial
+ patron = "Pagina \d+ of (\d+)<\/span>(\d+)<\/span>"
+ patron += ''
+ else:
+ patron = ''
+ patron += " (\d+)<\/span>.*?(\d+)<\/a>"
+ patron += 'Siguiente'
+
+ if last_page == 99999: #Si es el valor inicial, buscamos
+ try:
+ if item.extra2 == 'alfabeto': #patrón especial
+ last_page, curr_page, next_page_url = scrapertools.find_single_match(data, patron)
+ else:
+ curr_page, last_page, next_page_url = scrapertools.find_single_match(data, patron)
+ curr_page = int(curr_page)
+ last_page = int(last_page)
+ except: #Si no lo encuentra, lo ponemos a 1
+ #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron)
+ curr_page = 1
+ last_page = 0
+ next_page_url = item.url + '/page/1'
+ #logger.debug('curr_page: ' + str(curr_page) + ' / last_page: ' + str(last_page) + ' / url: ' + next_page_url)
+ if last_page > 1:
+ curr_page += 1 #Apunto ya a la página siguiente
+ next_page_url = re.sub(r'\/page\/\d+', '/page/%s' % curr_page, next_page_url)
+
+ #Empezamos el procesado de matches
+ for scrapedurl, scrapedthumb, scrapedtype, scrapedtitle, scrapedduration, scrapedyear, scrapedquality in matches:
+ if item.extra2 == 'alfabeto': #Cambia el orden de tres parámetros
+ duration = scrapedquality
+ year = scrapedduration
+ quality = scrapedyear
+ else: #lo estándar
+ duration = scrapedduration
+ year = scrapedyear
+ quality = scrapedquality
+
+ #estandarizamos la duración
+ if 'h' not in duration:
+ duration = '0:' + duration.replace('m', '')
+ else:
+ duration = duration.replace('h ', ':').replace('m', '')
+ duration = re.sub(r',.*?\]', ']', duration)
+ if '0:0' in duration or ',' in duration:
+ duration = ''
+ else:
+ try:
+ hora, minuto = duration.split(':')
+ duration = '%s:%s h' % (str(hora).zfill(2), str(minuto).zfill(2))
+ except:
+ duration = ''
+
+ #Algunos enlaces no filtran tipos, lo hago aquí
+ if item.extra2 in ['alfabeto', 'CAST', 'LAT', 'VOSE', 'popular'] or item.category_new == 'newest':
+ if item.extra == 'peliculas' and 'tv' in scrapedtype.lower():
+ continue
+ elif item.extra == 'series' and not 'tv' in scrapedtype.lower():
+ continue
+
+ title = scrapedtitle
+ title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace("ã", "a").replace("&etilde;", "e").replace("ĩ", "i").replace("õ", "o").replace("ũ", "u").replace("ñ", "ñ").replace("’", "'")
+
+ cnt_title += 1
+
+ item_local = item.clone() #Creamos copia de Item para trabajar
+ if item_local.tipo: #... y limpiamos
+ 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.intervencion:
+ del item_local.intervencion
+ if item_local.viewmode:
+ del item_local.viewmode
+ item_local.text_bold = True
+ del item_local.text_bold
+ item_local.text_color = True
+ del item_local.text_color
+ if item_local.url_plus:
+ del item_local.url_plus
+
+ title_subs = [] #creamos una lista para guardar info importante
+ item_local.language = [] #iniciamos Lenguaje
+ item_local.quality = quality #guardamos la calidad, si la hay
+ item_local.url = scrapedurl #guardamos el thumb
+ item_local.thumbnail = scrapedthumb #guardamos el thumb
+ item_local.context = "['buscar_trailer']"
+
+ item_local.contentType = "movie" #por defecto, son películas
+ item_local.action = "findvideos"
+
+ #Analizamos los formatos de series
+ if '-serie-tv-' in scrapedurl or item_local.extra == 'series' or 'tv' in scrapedtype.lower():
+ item_local.contentType = "tvshow"
+ item_local.action = "episodios"
+ item_local.season_colapse = True #Muestra las series agrupadas por temporadas
+
+ #Buscamos calidades adicionales
+ if "3d" in title.lower() and not "3d" in item_local.quality.lower():
+ if item_local.quality:
+ item_local.quality += " 3D"
+ else:
+ item_local.quality = "3D"
+ title = re.sub('3D', '', title, flags=re.IGNORECASE)
+ title = title.replace('[]', '')
+ if item_local.quality:
+ item_local.quality += ' %s' % scrapertools.find_single_match(title, '\[(.*?)\]')
+ else:
+ item_local.quality = '%s' % scrapertools.find_single_match(title, '\[(.*?)\]')
+
+ #Detectamos idiomas
+ if 'LAT' in item.extra2:
+ item_local.language += ['LAT']
+ elif 'VOSE' in item.extra2:
+ item_local.language += ['VOSE']
+ if item_local.extra2: del item_local.extra2
+
+ if ("latino" in scrapedurl.lower() or "latino" in title.lower()) and "LAT" not in item_local.language:
+ item_local.language += ['LAT']
+ elif ('subtitulado' in scrapedurl.lower() or 'subtitulado' in title.lower() or 'vose' in title.lower()) and "VOSE" not in item_local.language:
+ item_local.language += ['VOSE']
+ elif ('version-original' in scrapedurl.lower() or 'version original' in title.lower() or 'vo' in title.lower()) and "VO" not in item_local.language:
+ item_local.language += ['VO']
+
+ if item_local.language == []:
+ item_local.language = ['CAST']
+
+ #Detectamos info interesante a guardar para después de TMDB
+ if scrapertools.find_single_match(title, '[m|M].*?serie'):
+ title = re.sub(r'[m|M]iniserie', '', title)
+ title_subs += ["Miniserie"]
+ if scrapertools.find_single_match(title, '[s|S]aga'):
+ title = re.sub(r'[s|S]aga', '', title)
+ title_subs += ["Saga"]
+ if scrapertools.find_single_match(title, '[c|C]olecc'):
+ title = re.sub(r'[c|C]olecc...', '', title)
+ title_subs += ["Colección"]
+
+ 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() or "v.e." in title.lower()or "v e " in title.lower():
+ title_subs += ["[V. Extendida]"]
+ title = title.replace("Version Extendida", "").replace("(Version Extendida)", "").replace("V. Extendida", "").replace("VExtendida", "").replace("V Extendida", "").replace("V.Extendida", "").replace("V Extendida", "").replace("V.E.", "").replace("V E ", "").replace("V:Extendida", "")
+
+ #Analizamos el año. Si no está claro ponemos '-'
+ try:
+ yeat_int = int(year)
+ if yeat_int >= 1970 and yeat_int <= 2040:
+ item_local.infoLabels["year"] = yeat_int
+ else:
+ item_local.infoLabels["year"] = '-'
+ except:
+ item_local.infoLabels["year"] = '-'
+
+ #Empezamos a limpiar el título en varias pasadas
+ patron = '\s?-?\s?(line)?\s?-\s?$'
+ regex = re.compile(patron, re.I)
+ title = regex.sub("", title)
+ title = re.sub(r'\(\d{4}\s*?\)', '', title)
+ title = re.sub(r'\[\d{4}\s*?\]', '', title)
+ title = re.sub(r'[s|S]erie', '', title)
+ title = re.sub(r'- $', '', title)
+
+ #Limpiamos el título de la basura innecesaria
+ title = re.sub(r'TV|Online|Spanish|Torrent|en Espa\xc3\xb1ol|Español|Latino|Subtitulado|Blurayrip|Bluray rip|\[.*?\]|R2 Pal|\xe3\x80\x90 Descargar Torrent \xe3\x80\x91|Completa|Temporada|Descargar|Torren', '', title, flags=re.IGNORECASE)
+
+ title = title.replace("Dual", "").replace("dual", "").replace("Subtitulada", "").replace("subtitulada", "").replace("Subt", "").replace("subt", "").replace("(Proper)", "").replace("(proper)", "").replace("Proper", "").replace("proper", "").replace("#", "").replace("(Latino)", "").replace("Latino", "").replace("LATINO", "").replace("Spanish", "").replace("Trailer", "").replace("Audio", "")
+ title = title.replace("HDTV-Screener", "").replace("DVDSCR", "").replace("TS ALTA", "").replace("- HDRip", "").replace("(HDRip)", "").replace("- Hdrip", "").replace("(microHD)", "").replace("(DVDRip)", "").replace("HDRip", "").replace("(BR-LINE)", "").replace("(HDTS-SCREENER)", "").replace("(BDRip)", "").replace("(BR-Screener)", "").replace("(DVDScreener)", "").replace("TS-Screener", "").replace(" TS", "").replace(" Ts", "").replace(" 480p", "").replace(" 480P", "").replace(" 720p", "").replace(" 720P", "").replace(" 1080p", "").replace(" 1080P", "").replace("DVDRip", "").replace(" Dvd", "").replace(" DVD", "").replace(" V.O", "").replace(" Unrated", "").replace(" UNRATED", "").replace(" unrated", "").replace("screener", "").replace("TS-SCREENER", "").replace("TSScreener", "").replace("HQ", "").replace("AC3 5.1", "").replace("Telesync", "").replace("Line Dubbed", "").replace("line Dubbed", "").replace("LineDuB", "").replace("Line", "").replace("XviD", "").replace("xvid", "").replace("XVID", "").replace("Mic Dubbed", "").replace("HD", "").replace("V2", "").replace("CAM", "").replace("VHS.SCR", "").replace("Dvd5", "").replace("DVD5", "").replace("Iso", "").replace("ISO", "").replace("Reparado", "").replace("reparado", "").replace("DVD9", "").replace("Dvd9", "")
+
+ #Terminamos de limpiar el título
+ title = re.sub(r'\??\s?\d*?\&.*', '', title)
+ title = re.sub(r'[\(|\[]\s+[\)|\]]', '', title)
+ title = title.replace('()', '').replace('[]', '').strip().lower().title()
+
+ #Limpiamos el año del título, siempre que no sea todo el título o una cifra de más dígitos
+ if not scrapertools.find_single_match(title, '\d{5}'):
+ title_alt = title
+ title_alt = re.sub(r'[\[|\(]?\d{4}[\)|\]]?', '', title_alt).strip()
+ if title_alt:
+ title = title_alt
+
+ item_local.from_title = title.strip().lower().title() #Guardamos esta etiqueta para posible desambiguación de título
+
+ #Salvamos el título según el tipo de contenido
+ if item_local.contentType == "movie":
+ item_local.contentTitle = title.strip().lower().title()
+ else:
+ item_local.contentSerieName = title.strip().lower().title()
+
+ item_local.title = title.strip().lower().title()
+
+ #Añadimos la duración a la Calidad
+ if duration:
+ if item_local.quality:
+ item_local.quality += ' [%s]' % duration
+ else:
+ item_local.quality = '[%s]' % duration
+
+ #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
+
+ itemlist.append(item_local.clone()) #Pintar pantalla
+
+ #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)
+
+ # Si es necesario añadir paginacion
+ if curr_page <= last_page:
+ if last_page > 1:
+ title = '%s de %s' % (curr_page-1, last_page)
+ else:
+ title = '%s' % curr_page-1
+
+ itemlist.append(Item(channel=item.channel, action="listado", title=">> Página siguiente " + title, title_lista=title_lista, url=next_page_url, extra=item.extra, extra2=item.extra2, last_page=str(last_page), curr_page=str(curr_page)))
+
+ return itemlist
+
+
+def findvideos(item):
+ logger.info()
+ itemlist = []
+ matches = []
+ item.category = categoria
+
+ item.extra2 = 'xyz'
+ del item.extra2
+
+ #logger.debug(item)
+
+ #Bajamos los datos de la página
+ data = ''
+ patron = ']+href="([^"]+)"[^<]+ | ]+>(.*?) | ]+>(.*?) | (.*?)'
+ try:
+ data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url, timeout=timeout).data)
+ data = unicode(data, "utf-8", errors="replace").encode("utf-8")
+ data = re.sub(r""", '"', data)
+ data = re.sub(r"<", '<', data)
+ except:
+ pass
+
+ if not data:
+ logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url)
+ itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': 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
+
+ matches = re.compile(patron, re.DOTALL).findall(data)
+ if not matches and not scrapertools.find_single_match(data, 'data-TPlayerNv="Opt\d+">.*? (.*?)'): #error
+ logger.error("ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web " + " / PATRON: " + patron + data)
+ itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web. Verificar en la Web esto último y reportar el error con el log'))
+ return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos
+
+ #logger.debug("PATRON: " + patron)
+ #logger.debug(matches)
+ #logger.debug(data)
+
+ #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
+ item, itemlist = generictools.post_tmdb_findvideos(item, itemlist)
+
+ #Ahora tratamos los enlaces .torrent
+ for scrapedurl, scrapedserver, language, quality in matches: #leemos los torrents con la diferentes calidades
+ #Generamos una copia de Item para trabajar sobre ella
+ item_local = item.clone()
+
+ if 'torrent' not in scrapedserver.lower(): #Si es un servidor Directo, lo dejamos para luego
+ continue
+
+ item_local.url = scrapedurl
+ if '.io/' in item_local.url:
+ item_local.url = re.sub(r'http.?:\/\/\w+\.\w+\/', host, item_local.url) #Aseguramos el dominio del canal
+
+ #Detectamos idiomas
+ if ("latino" in scrapedurl.lower() or "latino" in language.lower()) and "LAT" not in item_local.language:
+ item_local.language += ['LAT']
+ elif ('subtitulado' in scrapedurl.lower() or 'subtitulado' in language.lower() or 'vose' in language.lower()) and "VOSE" not in item_local.language:
+ item_local.language += ['VOSE']
+ elif ('version-original' in scrapedurl.lower() or 'version original' in language.lower() or 'vo' in language.lower()) and "VO" not in item_local.language:
+ item_local.language += ['VO']
+
+ if item_local.language == []:
+ item_local.language = ['CAST']
+
+ #Añadimos la calidad y copiamos la duración
+ item_local.quality = quality
+ if scrapertools.find_single_match(item.quality, '(\[\d+:\d+\ h])'):
+ item_local.quality += ' [/COLOR][COLOR white]%s' % scrapertools.find_single_match(item.quality, '(\[\d+:\d+\ h])')
+
+ #Buscamos si ya tiene tamaño, si no, los buscamos en el archivo .torrent
+ size = scrapertools.find_single_match(item_local.quality, '\s\[(\d+,?\d*?\s\w\s?[b|B])\]')
+ if not size:
+ size = generictools.get_torrent_size(item_local.url) #Buscamos el tamaño en el .torrent
+ if size:
+ item_local.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item_local.title) #Quitamos size de título, si lo traía
+ item_local.title = '%s [%s]' % (item_local.title, size) #Agregamos size al final del título
+ size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b')
+ item_local.quality = re.sub(r'\s\[\d+,?\d*?\s\w\s?[b|B]\]', '', item_local.quality) #Quitamos size de calidad, si lo traía
+ item_local.quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final de la calidad
+
+ #Ahora pintamos el link del Torrent
+ item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language))
+
+ #Preparamos título y calidad, quitamos etiquetas vacías
+ item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title)
+ item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title)
+ item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
+ item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality)
+ item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality).strip()
+ item_local.quality = item_local.quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip()
+
+ item_local.alive = "??" #Calidad del link sin verificar
+ item_local.action = "play" #Visualizar vídeo
+ item_local.server = "torrent" #Servidor Torrent
+
+ itemlist.append(item_local.clone()) #Pintar pantalla
+
+ #logger.debug("TORRENT: " + scrapedurl + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
+ #logger.debug(item_local)
+
+ #Ahora tratamos los Servidores Directos
+ titles = re.compile('data-TPlayerNv="Opt\d+">.*? (.*?)', re.DOTALL).findall(data)
+ urls = re.compile('id="Opt\d+"> | |