# -*- coding: utf-8 -*- import re import urlparse from os import path from channels import renumbertools from core import config from core import filetools from core import httptools from core import logger from core import scrapertools from core.item import Item CHANNEL_HOST = "http://animeflv.me/" CHANNEL_DEFAULT_HEADERS = [ ["User-Agent", "Mozilla/5.0"], ["Accept-Encoding", "gzip, deflate"], ["Referer", CHANNEL_HOST] ] REGEX_NEXT_PAGE = r"class='current'>\d+?
  • )(.+?)(?:)' REGEX_THUMB = r'src="(http://media.animeflv\.me/uploads/thumbs/[^"]+?)"' REGEX_PLOT = r'Línea de historia:

    (.*?)' REGEX_URL = r'href="(http://animeflv\.me/Anime/[^"]+)">' REGEX_SERIE = r'{0}.+?{1}([^<]+?)

    (.+?)

    '.format(REGEX_THUMB, REGEX_URL) REGEX_EPISODE = r'href="(http://animeflv\.me/Ver/[^"]+?)">(?:)?(.+?)(\d+/\d+/\d+)' REGEX_GENERO = r'([^<]+)' def get_url_contents(url): html = httptools.downloadpage(url, headers=CHANNEL_DEFAULT_HEADERS).data # Elimina los espacios antes y despues de aperturas y cierres de etiquetas html = re.sub(r'>\s+<', '><', html) html = re.sub(r'>\s+', '>', html) html = re.sub(r'\s+<', '<', html) return html def get_cookie_value(): """ Obtiene las cookies de cloudflare """ cookie_file = path.join(config.get_data_path(), 'cookies.dat') cookie_data = filetools.read(cookie_file) cfduid = scrapertools.find_single_match( cookie_data, r"animeflv.*?__cfduid\s+([A-Za-z0-9\+\=]+)") cfduid = "__cfduid=" + cfduid + ";" cf_clearance = scrapertools.find_single_match( cookie_data, r"animeflv.*?cf_clearance\s+([A-Za-z0-9\+\=\-]+)") cf_clearance = " cf_clearance=" + cf_clearance cookies_value = cfduid + cf_clearance return cookies_value header_string = "|User-Agent=Mozilla/5.0&Referer=http://animeflv.me&Cookie=" + \ get_cookie_value() def __find_next_page(html): """ Busca el enlace a la pagina siguiente """ return scrapertools.find_single_match(html, REGEX_NEXT_PAGE) def __extract_info_from_serie(html): """ Extrae la información de una serie o pelicula desde su página Util para cuando una busqueda devuelve un solo resultado y animeflv.me redirecciona a la página de este. """ title = scrapertools.find_single_match(html, REGEX_TITLE) title = clean_title(title) url = scrapertools.find_single_match(html, REGEX_URL) thumbnail = scrapertools.find_single_match( html, REGEX_THUMB) + header_string plot = scrapertools.find_single_match(html, REGEX_PLOT) return [title, url, thumbnail, plot] def __sort_by_quality(items): """ Ordena los items por calidad en orden decreciente """ def func(item): return int(scrapertools.find_single_match(item.title, r'\[(.+?)\]')) return sorted(items, key=func, reverse=True) def clean_title(title): """ Elimina el año del nombre de las series o peliculas """ year_pattern = r'\([\d -]+?\)' return re.sub(year_pattern, '', title).strip() def __find_series(html): """ Busca series en un listado, ejemplo: resultados de busqueda, categorias, etc """ series = [] # Limitamos la busqueda al listado de series list_start = html.find('') list_end = html.find('
    ', list_start) list_html = html[list_start:list_end] for serie in re.finditer(REGEX_SERIE, list_html, re.S): thumbnail, url, title, plot = serie.groups() title = clean_title(title) thumbnail = thumbnail + header_string plot = scrapertools.htmlclean(plot) series.append([title, url, thumbnail, plot]) return series def mainlist(item): logger.info() itemlist = list() itemlist.append(Item(channel=item.channel, action="letras", title="Por orden alfabético")) itemlist.append(Item(channel=item.channel, action="generos", title="Por géneros", url=urlparse.urljoin(CHANNEL_HOST, "ListadeAnime"))) itemlist.append(Item(channel=item.channel, action="series", title="Por popularidad", url=urlparse.urljoin(CHANNEL_HOST, "/ListadeAnime/MasVisto"))) itemlist.append(Item(channel=item.channel, action="series", title="Novedades", url=urlparse.urljoin(CHANNEL_HOST, "ListadeAnime/Nuevo"))) itemlist.append(Item(channel=item.channel, action="series", title="Últimos", url=urlparse.urljoin(CHANNEL_HOST, "ListadeAnime/LatestUpdate"))) itemlist.append(Item(channel=item.channel, action="search", title="Buscar...", url=urlparse.urljoin(CHANNEL_HOST, "Buscar?s="))) itemlist = renumbertools.show_option(item.channel, itemlist) return itemlist def letras(item): logger.info() base_url = 'http://animeflv.me/ListadeAnime?c=' itemlist = [] itemlist.append(Item(channel=item.channel, action="series", title="#", url=base_url + "#", viewmode="movies_with_plot")) # Itera sobre las posiciones de las letras en la tabla ascii # 65 = A, 90 = Z for i in xrange(65, 91): letter = chr(i) logger.debug("title=[{0}], url=[{1}], thumbnail=[]".format( letter, base_url + letter)) itemlist.append(Item(channel=item.channel, action="series", title=letter, url=base_url + letter, viewmode="movies_with_plot")) return itemlist def generos(item): logger.info() itemlist = [] html = get_url_contents(item.url) generos = re.findall(REGEX_GENERO, html) for url, genero in generos: logger.debug( "title=[{0}], url=[{1}], thumbnail=[]".format(genero, url)) itemlist.append(Item(channel=item.channel, action="series", title=genero, url=url, plot='', viewmode="movies_with_plot")) return itemlist def search(item, texto): logger.info() texto = texto.replace(" ", "%20") item.url = "{0}{1}".format(item.url, texto) html = get_url_contents(item.url) try: # Se encontro un solo resultado y se redicciono a la página de la serie if html.find('Ver') >= 0: series = [__extract_info_from_serie(html)] # Se obtuvo una lista de resultados else: series = __find_series(html) items = [] for serie in series: title, url, thumbnail, plot = serie logger.debug("title=[{0}], url=[{1}], thumbnail=[{2}]".format( title, url, thumbnail)) items.append(Item(channel=item.channel, action="episodios", title=title, url=url, thumbnail=thumbnail, plot=plot, show=title, viewmode="movies_with_plot", context=renumbertools.context(item))) except: import sys for line in sys.exc_info(): logger.error("%s" % line) return [] return items def series(item): logger.info() page_html = get_url_contents(item.url) series = __find_series(page_html) items = [] for serie in series: title, url, thumbnail, plot = serie logger.debug("title=[{0}], url=[{1}], thumbnail=[{2}]".format( title, url, thumbnail)) items.append(Item(channel=item.channel, action="episodios", title=title, url=url, thumbnail=thumbnail, plot=plot, show=title, viewmode="movies_with_plot", context=renumbertools.context(item))) url_next_page = __find_next_page(page_html) if url_next_page: items.append(Item(channel=item.channel, action="series", title=">> Página Siguiente", url=url_next_page, thumbnail="", plot="", folder=True, viewmode="movies_with_plot")) return items def episodios(item): logger.info() itemlist = [] html_serie = get_url_contents(item.url) info_serie = __extract_info_from_serie(html_serie) plot = info_serie[3] if info_serie else '' episodes = re.findall(REGEX_EPISODE, html_serie, re.DOTALL) es_pelicula = False for url, title, date in episodes: episode = scrapertools.find_single_match(title, r'Episodio (\d+)') # El enlace pertenece a un episodio if episode: season = 1 episode = int(episode) season, episode = renumbertools.numbered_for_tratk( item.channel, item.show, season, episode) title = "{0}x{1:02d} {2} ({3})".format( season, episode, "Episodio " + str(episode), date) # El enlace pertenece a una pelicula else: title = "{0} ({1})".format(title, date) item.url = url es_pelicula = True logger.debug("title=[{0}], url=[{1}], thumbnail=[{2}]".format( title, url, item.thumbnail)) itemlist.append(Item(channel=item.channel, action="findvideos", title=title, url=url, thumbnail=item.thumbnail, plot=plot, show=item.show, fulltitle="{0} {1}".format(item.show, title), viewmode="movies_with_plot", folder=True)) # El sistema soporta la videoteca y se encontro por lo menos un episodio # o pelicula if config.get_videolibrary_support() and len(itemlist) > 0: if es_pelicula: item_title = "Añadir película a la videoteca" item_action = "add_pelicula_to_library" item_extra = "" else: item_title = "Añadir serie a la videoteca" item_action = "add_serie_to_library" item_extra = "episodios" itemlist.append(Item(channel=item.channel, title=item_title, url=item.url, action=item_action, extra=item_extra, show=item.show)) if not es_pelicula: itemlist.append(Item(channel=item.channel, title="Descargar todos los episodios", url=item.url, action="download_all_episodes", extra="episodios", show=item.show)) return itemlist def findvideos(item): logger.info() itemlist = [] page_html = get_url_contents(item.url) regex_api = r'http://player\.animeflv\.me/[^\"]+' iframe_url = scrapertools.find_single_match(page_html, regex_api) iframe_html = get_url_contents(iframe_url) regex_video_list = r'var part = \[([^\]]+)' videos_html = scrapertools.find_single_match(iframe_html, regex_video_list) videos = re.findall('"([^"]+)"', videos_html, re.DOTALL) qualities = ["360", "480", "720", "1080"] for quality_id, video_url in enumerate(videos): itemlist.append(Item(channel=item.channel, action="play", url=video_url, show=re.escape(item.show), title="Ver en calidad [{0}]".format(qualities[quality_id]), plot=item.plot, folder=True, fulltitle=item.title, viewmode="movies_with_plot")) return __sort_by_quality(itemlist)