Exemple #1
0
def episodios(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    if item.from_title:
        item.title = item.from_title
    item.extra2 = 'xyz'
    del item.extra2

    #Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
    season_display = 0
    if item.contentSeason:
        if item.season_colapse:  #Si viene del menú de Temporadas...
            season_display = item.contentSeason  #... salvamos el num de sesión a pintar
            item.from_num_season_colapse = season_display
            del item.season_colapse
            item.contentType = "tvshow"
            if item.from_title_season_colapse:
                item.title = item.from_title_season_colapse
                del item.from_title_season_colapse
                if item.infoLabels['title']:
                    del item.infoLabels['title']
        del item.infoLabels['season']
    if item.contentEpisodeNumber:
        del item.infoLabels['episode']
    if season_display == 0 and item.from_num_season_colapse:
        season_display = item.from_num_season_colapse

    # Obtener la información actualizada de la Serie.  TMDB es imprescindible para Videoteca
    if not item.infoLabels['tmdb_id']:
        tmdb.set_infoLabels(item, True)

    # Descarga la página
    data = ''  #Inserto en num de página en la url
    try:
        data = httptools.downloadpage(item.url, timeout=timeout).data
        data = unicode(data, "utf-8", errors="replace").encode("utf-8")
    except:  #Algún error de proceso, salimos
        pass

    if not data:
        logger.error(
            "ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" +
            item.url)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': 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

    #Buscamos los episodios
    matches = jsontools.load(data)
    if not matches:  #error
        item = generictools.web_intervenida(
            item, data)  #Verificamos que no haya sido clausurada
        if item.intervencion:  #Sí ha sido clausurada judicialmente
            item, itemlist = generictools.post_tmdb_episodios(
                item, itemlist)  #Llamamos al método para el pintado del error
            return itemlist  #Salimos

        logger.error(
            "ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web: " +
            data)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web.  Reportar el error con el log'
            ))
        return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

    #logger.debug(matches)

    # Recorremos todos los episodios generando un Item local por cada uno en Itemlist
    for temporada in matches.get("temporadas", []):
        if season_display > 0 and temporada.get(
                "numerotemporada",
                0) != season_display:  #si no es nuestra temp., pasamos
            continue

        #Si hay más de una temporada, solo las enumeramos
        if len(matches.get("temporadas", [])) > 1 and item.season_colapse:
            item_local = item.clone()  #creo una copia de Item
            item_local.action = "findvideos"  #y lo preparo para la reproducción
            item_local.contentType = "episode"
            item_local.extra = "episodios"

            item_local.contentSeason = temporada.get(
                "numerotemporada", 1)  #Guardo el num. de temporada
            item_local.contentEpisodeNumber = 1  #relleno el num. de episodio por compatibilidad
            itemlist.append(item_local.clone())  #lo pinto
            continue  #Paso a la siguiente temporada

        #Aquí tratamos todos los episodios de una temporada
        season = temporada.get("numerotemporada", 1)
        for episodio in temporada.get("capituls", []):

            item_local = item.clone()  #creo una copia de Item
            item_local.action = "findvideos"  #y lo preparo para la reproducción
            item_local.contentType = "episode"
            item_local.extra = "episodios"
            if item_local.library_playcounts:
                del item_local.library_playcounts
            if item_local.library_urls:
                del item_local.library_urls
            if item_local.path:
                del item_local.path
            if item_local.update_last:
                del item_local.update_last
            if item_local.update_next:
                del item_local.update_next
            if item_local.channel_host:
                del item_local.channel_host
            if item_local.active:
                del item_local.active
            if item_local.contentTitle:
                del item_local.infoLabels['title']
            if item_local.season_colapse:
                del item_local.season_colapse
            if item_local.tmdb_stat:
                del item_local.tmdb_stat

            item_local.title = ''
            item_local.context = "['buscar_trailer']"
            title = episodio.get("nomcapitul", "")  #título del episodio
            info_epi = episodio.get("infocapitul",
                                    "")  #información adicional del episodio
            item_local.language = []
            item_local.url = []

            if episodio.get("links",
                            {}).get("magnet"):  #buscamos los magnets activos
                url = episodio.get("links",
                                   {}).get("magnet")  #salvamos el magnet
                quality = episodio.get("links", {}).get(
                    "calitat", "")  #salvamos la calidad del magnet
                item_local.url += [(url, quality)
                                   ]  #guardamos todo como url para findvideos
                item_local.quality = quality.strip(
                )  #agregamos a la calidad del título

            if not item_local.language:
                item_local.language += ['CAST']  #Castellano por defecto

            #Buscamos la Temporada y el Episodio
            try:
                item_local.contentSeason = int(
                    season)  #Copiamos el num. de Temporada
            except:
                item_local.contentSeason = 1  #Si hay error, lo dejamos en 1
            try:
                item_local.contentEpisodeNumber = int(
                    episodio.get("numerocapitul",
                                 1))  #Copiamos el num. de Episodio
            except:
                item_local.contentEpisodeNumber = 1  #Si hay error, lo dejamos en 1
            if 'miniserie' in title.lower(
            ):  #Si es una Miniserie, lo ajustamos
                if not item_local.contentSeason:
                    item_local.contentSeason = 1
                title = title.replace('miniserie', '').replace('MiniSerie', '')

            #Si son episodios múltiples, lo extraemos
            patron1 = '\d+[x|X]\d{1,2}.?(?:y|Y|al|Al)?.?(?:(?:\d+[x|X])?(\d{1,2}))?'
            epi_rango = scrapertools.find_single_match(info_epi, patron1)
            if epi_rango:
                item_local.infoLabels['episodio_titulo'] = 'al %s ' % epi_rango
                item_local.title = '%sx%s al %s -' % (
                    str(item_local.contentSeason),
                    str(item_local.contentEpisodeNumber).zfill(2),
                    str(epi_rango).zfill(2))
            else:
                item_local.title = '%sx%s -' % (
                    str(item_local.contentSeason),
                    str(item_local.contentEpisodeNumber).zfill(2))
                item.infoLabels['episodio_titulo'] = '%s' % title

            itemlist.append(item_local.clone())

            #logger.debug(item_local)

    if len(itemlist) > 1:
        itemlist = sorted(itemlist,
                          key=lambda it:
                          (int(it.contentSeason), int(it.contentEpisodeNumber)
                           ))  #clasificamos

    if item.season_colapse and not item.add_videolibrary:  #Si viene de listado, mostramos solo Temporadas
        item, itemlist = generictools.post_tmdb_seasons(item, itemlist)

    if not item.season_colapse:  #Si no es pantalla de Temporadas, pintamos todo
        # Pasada por TMDB y clasificación de lista por temporada y episodio
        tmdb.set_infoLabels(itemlist, True)

        #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
        item, itemlist = generictools.post_tmdb_episodios(item, itemlist)

    #logger.debug(item)

    return itemlist
Exemple #2
0
def episodios(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    if item.from_title:
        item.title = item.from_title

    #Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
    season_display = 0
    if item.contentSeason:
        if item.season_colapse:  #Si viene del menú de Temporadas...
            season_display = item.contentSeason  #... salvamos el num de sesión a pintar
            item.from_num_season_colapse = season_display
            del item.season_colapse
            item.contentType = "tvshow"
            if item.from_title_season_colapse:
                item.title = item.from_title_season_colapse
                del item.from_title_season_colapse
                if item.infoLabels['title']:
                    del item.infoLabels['title']
        del item.infoLabels['season']
    if item.contentEpisodeNumber:
        del item.infoLabels['episode']
    if season_display == 0 and item.from_num_season_colapse:
        season_display = item.from_num_season_colapse

    # Obtener la información actualizada de la Serie.  TMDB es imprescindible para Videoteca
    try:
        tmdb.set_infoLabels(item, True, idioma_busqueda='es,en')
    except:
        pass

    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)

    # Descarga la página
    data = ''  #Inserto en num de página en la url
    try:
        data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                      httptools.downloadpage(item.url, timeout=timeout).data)
        data = unicode(data, "utf-8", errors="replace").encode("utf-8")
    except:  #Algún error de proceso, salimos
        pass

    if not data:
        logger.error(
            "ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" +
            item.url)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': 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

    status, itemlist = check_blocked_IP(
        data, itemlist)  #Comprobamos si la IP ha sido bloqueada
    if status:
        return itemlist  #IP bloqueada

    #Capturamos las temporadas de episodios dentro de la serie
    patron_temp = '<h1\s*class="[^"]+">Season\s*(\d+)<\/h1><div class="tvcontent"><div id="[^"]+"><\/div>(.*?<\/div><\/div>)(?:<script>.*?<\/script>)?<\/div>'
    temp_serie = re.compile(patron_temp, re.DOTALL).findall(data)

    for season_num, temporada in temp_serie:
        patron = '<div id="episode_(\d+)"><div class="[^"]+">\s*<a onclick="[^"]+"\s*class="[^"]+"><div class="[^"]+">.*?\s*(\d+)<\/div>\s*(.*?)\s*<'
        matches = re.compile(patron, re.DOTALL).findall(temporada)
        if not matches:  #error
            item = generictools.web_intervenida(
                item, data)  #Verificamos que no haya sido clausurada
            if item.intervencion:  #Sí ha sido clausurada judicialmente
                item, itemlist = generictools.post_tmdb_episodios(
                    item,
                    itemlist)  #Llamamos al método para el pintado del error
                return itemlist  #Salimos

            logger.error(
                "ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " +
                " / PATRON: " + patron + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web.  Reportar el error con el log'
                ))
            return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        #logger.debug("PATRON: " + patron)
        #logger.debug(matches)
        #logger.debug(data)

        season = max_temp
        #Comprobamos si realmente sabemos el num. máximo de temporadas
        if item.library_playcounts or (item.infoLabels['number_of_seasons']
                                       and item.tmdb_stat):
            num_temporadas_flag = True
        else:
            num_temporadas_flag = False

        if modo_ultima_temp_alt and item.library_playcounts:  #Si solo se actualiza la última temporada de Videoteca
            if int(season_num) < max_temp:
                break  #Sale del bucle actual del FOR

        # Recorremos todos los episodios generando un Item local por cada uno en Itemlist
        for epi_id, episode_num, scrapedtitle in matches:
            item_local = item.clone()
            item_local.action = "findvideos"
            item_local.contentType = "episode"
            item_local.extra = "episodios"
            if item_local.library_playcounts:
                del item_local.library_playcounts
            if item_local.library_urls:
                del item_local.library_urls
            if item_local.path:
                del item_local.path
            if item_local.update_last:
                del item_local.update_last
            if item_local.update_next:
                del item_local.update_next
            if item_local.channel_host:
                del item_local.channel_host
            if item_local.active:
                del item_local.active
            if item_local.contentTitle:
                del item_local.infoLabels['title']
            if item_local.season_colapse:
                del item_local.season_colapse

            item_local.title = ''
            item_local.context = "['buscar_trailer']"
            item_local.url = urlparse.urljoin(
                host, 'tv.php?ajax=1&tvepisode=%s' % epi_id)
            title = scrapedtitle
            item_local.language = ['VO']
            if not item_local.infoLabels['poster_path']:
                item_local.thumbnail = item_local.infoLabels['thumbnail']
            epi_rango = False

            try:
                item_local.contentSeason = int(season_num)
                if 'season pack' in title.lower():
                    item_local.contentEpisodeNumber = 1
                    epi_rango = True
                else:
                    item_local.contentEpisodeNumber = int(episode_num)
            except:
                logger.error('ERROR al extraer Temporada/Episodio: ' + title)
                item_local.contentSeason = 1
                item_local.contentEpisodeNumber = 0

            #Si son episodios múltiples, lo extraemos
            if epi_rango:
                item_local.infoLabels['episodio_titulo'] = 'al 99'
                item_local.title = '%sx%s al 99 - Season Pack' % (
                    str(item_local.contentSeason),
                    str(item_local.contentEpisodeNumber).zfill(2))
            else:
                item_local.title = '%sx%s - ' % (
                    str(item_local.contentSeason),
                    str(item_local.contentEpisodeNumber).zfill(2))

            if season_display > 0:
                if item_local.contentSeason > season_display:
                    continue
                elif item_local.contentSeason < season_display:
                    break

            itemlist.append(item_local.clone())

            #logger.debug(item_local)

    if len(itemlist) > 1:
        itemlist = sorted(itemlist,
                          key=lambda it:
                          (int(it.contentSeason), int(it.contentEpisodeNumber)
                           ))  #clasificamos

    if item.season_colapse and not item.add_videolibrary:  #Si viene de listado, mostramos solo Temporadas
        item, itemlist = generictools.post_tmdb_seasons(item, itemlist)

    if not item.season_colapse:  #Si no es pantalla de Temporadas, pintamos todo
        # Pasada por TMDB y clasificación de lista por temporada y episodio
        tmdb.set_infoLabels(itemlist, True, idioma_busqueda='es,en')

        #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
        item, itemlist = generictools.post_tmdb_episodios(item, itemlist)

    #logger.debug(item)

    return itemlist
Exemple #3
0
def listado(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    curr_page = 1  # Página inicial
    last_page = 99999  # Última página inicial
    last_title = 99999  # Última línea inicial
    cnt_matches = 0  # Contador de líneas insertadas en Itemlist
    if item.curr_page:
        curr_page = int(
            item.curr_page)  # Si viene de una pasada anterior, lo usamos
        del item.curr_page  # ... y lo borramos
    if item.last_page:
        last_page = int(
            item.last_page)  # Si viene de una pasada anterior, lo usamos
        del item.last_page  # ... y lo borramos
    if item.cnt_matches:
        cnt_matches = int(
            item.cnt_matches)  # Si viene de una pasada anterior, lo usamos
    item.cnt_matches = 0
    del item.cnt_matches  # ... y lo borramos

    cnt_tot = 40  # Poner el num. máximo de items por página
    cnt_pct = 0.625  #% de la página a llenar
    cnt_title = 0  # Contador de líneas insertadas en Itemlist
    inicio = time.time(
    )  # Controlaremos que el proceso no exceda de un tiempo razonable
    fin = inicio + 10  # Después de este tiempo pintamos (segundos)
    timeout_search = timeout  # Timeout para descargas
    if item.extra == 'search':
        timeout_search = timeout * 2  # Timeout un poco más largo para las búsquedas
        if timeout_search < 5:
            timeout_search = 5  # Timeout un poco más largo para las búsquedas
    item.tmdb_stat = True  # Este canal no es ambiguo en los títulos

    #Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios
    title_lista = [
    ]  # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas
    if item.title_lista:  # Si viene de una pasada anterior, la lista ya estará guardada
        title_lista.extend(
            item.title_lista)  # Se usa la lista de páginas anteriores en Item
        del item.title_lista  # ... limpiamos

    if not item.extra2:  # Si viene de Catálogo o de Alfabeto
        item.extra2 = ''

    next_page_url = item.url
    #Máximo num. de líneas permitidas por TMDB. Máx de 10 segundos por Itemlist para no degradar el rendimiento
    while cnt_title < cnt_tot * cnt_pct and cnt_matches + 1 < last_title and fin > time.time(
    ):

        # Descarga la página
        data = ''
        try:
            data = httptools.downloadpage(next_page_url,
                                          timeout=timeout_search).data
            data = unicode(data, "utf-8", errors="replace").encode("utf-8")
            pos = data.find('[')
            if pos > 0: data = data[pos:]
        except:
            pass

        if not data:  #Si la web está caída salimos sin dar error
            logger.error(
                "ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: "
                + item.url + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 01: LISTADO:.  La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
                ))
            break  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        matches = jsontools.load(data)  #cargamos lo datos como dict.
        if not matches and data[1] != ']':  #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 " +
                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'
                ))
            return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        last_title = len(matches)  #Tamaño de total matches
        matches = matches[cnt_matches:]  #avanzamos hasta la página actual

        #logger.debug(matches)
        #logger.debug(data)

        if last_page == 99999:  #Si es el valor inicial, cargamos el num. de items
            last_page = int((last_title / (cnt_tot * cnt_pct)))
            curr_page = 1

        #Empezamos el procesado de matches
        for titulo in matches:
            cnt_title += 1  #Sumamos 1 a los títulos tratados
            if cnt_title > cnt_tot * cnt_pct:
                cnt_title += last_title
                break
            cnt_matches += 1  #Sumamos 1 a total títulos tratados

            title = titulo.get("nom", "")  #nombre del título
            title = title.replace("á", "a").replace("é", "e").replace(
                "í", "i").replace("ó", "o").replace("ú", "u").replace(
                    "ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace(
                        "&atilde;", "a").replace("&etilde;", "e").replace(
                            "&itilde;", "i").replace("&otilde;", "o").replace(
                                "&utilde;",
                                "u").replace("&ntilde;",
                                             "ñ").replace("&#8217;", "'")

            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 titulo.get("posterurl", ""):
                item_local.thumbnail = "http://image.tmdb.org/t/p/w342%s" % titulo.get(
                    "posterurl", "")  #thumb
            if titulo.get("backurl", ""):
                item_local.fanart = "http://image.tmdb.org/t/p/w1280%s" % titulo.get(
                    "backurl", "")  #Fanart
            url = titulo.get("magnets", {})  #magnet de diversas calidades
            year = titulo.get("year", "")  #año
            if titulo.get("id", ""):
                item_local.infoLabels["tmdb_id"] = titulo.get("id",
                                                              "")  #TMDB id

            title_subs = []  #creamos una lista para guardar info importante
            item_local.language = []  #iniciamos Lenguaje
            item_local.quality = ''  #inicialmos la calidad
            item_local.context = "['buscar_trailer']"

            item_local.contentType = "movie"  #por defecto, son películas
            item_local.action = "findvideos"

            #Analizamos los formatos de series
            if item_local.extra == 'series':
                item_local.contentType = "tvshow"
                item_local.action = "episodios"
                item_local.season_colapse = True  #Muestra las series agrupadas por temporadas
                item_local.url = "%s?id=%s" % (api_temp, titulo.get(
                    "id", ""))  #Salvamos la url special para series

            #Revisamos para peliculas todos los magnets, extrayendo dirección y calidad
            if item_local.contentType == "movie":
                item_local.url = []  #iniciamos dict. de magnets
                for etiqueta, magnet in titulo.get("magnets", {}).iteritems():
                    if magnet.get("magnet"):  #buscamos los magnets activos
                        url = magnet.get("magnet")  #salvamos el magnet
                        quality = magnet.get(
                            "quality", "")  #salvamos la calidad del magnet
                        item_local.url += [
                            (url, quality)
                        ]  #guardamos todo como url para findvideos

                        item_local.quality += "%s, " % quality.strip(
                        )  #agregamos a la calidad del título
                item_local.quality = re.sub(r', $', '', item_local.quality)
                if not item_local.url:  #si no hay magnets, no seguimos
                    continue

            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 >= 1950 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
            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)

            #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()

            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()

            #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

            #Ahora se filtra por idioma, si procede, y se pinta lo que vale
            if config.get_setting(
                    'filter_languages',
                    channel) > 0:  #Si hay idioma seleccionado, se filtra
                itemlist = filtertools.get_link(itemlist, item_local,
                                                list_language)
            else:
                itemlist.append(item_local.clone())  #Si no, 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 cnt_title >= cnt_tot * cnt_pct:

        title = '%s' % curr_page

        if cnt_matches + 1 >= last_title:  #Si hemos pintado ya todo lo de esta página...
            cnt_matches = 0  #... la próxima pasada leeremos otra página
            next_page_url = re.sub(
                r'page=(\d+)', r'page=' +
                str(int(re.search('\d+', next_page_url).group()) + 1),
                next_page_url)

        itemlist.append(
            Item(channel=item.channel,
                 action="listado",
                 title=">> Página siguiente " + title,
                 url=next_page_url,
                 extra=item.extra,
                 extra2=item.extra2,
                 last_page=str(last_page),
                 curr_page=str(curr_page + 1),
                 cnt_matches=str(cnt_matches)))

    return itemlist
Exemple #4
0
def episodios(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    if item.from_title:
        item.title = item.from_title
    if item.subtitle:
        del item.subtitle

    #Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
    season_display = 0
    if item.contentSeason:
        if item.season_colapse:  #Si viene del menú de Temporadas...
            season_display = item.contentSeason  #... salvamos el num de sesión a pintar
            item.from_num_season_colapse = season_display
            del item.season_colapse
            item.contentType = "tvshow"
            if item.from_title_season_colapse:
                item.title = item.from_title_season_colapse
                del item.from_title_season_colapse
                if item.infoLabels['title']:
                    del item.infoLabels['title']
        del item.infoLabels['season']
    if item.contentEpisodeNumber:
        del item.infoLabels['episode']
    if season_display == 0 and item.from_num_season_colapse:
        season_display = item.from_num_season_colapse

    # 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)

    # Descarga la página
    data = ''  #Inserto en num de página en la url
    try:
        data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                      httptools.downloadpage(item.url, timeout=timeout).data)
        #data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
    except:  #Algún error de proceso, salimos
        pass

    if not data:
        logger.error(
            "ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" +
            item.url)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': 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

    patron = '<td class="capitulonombre"><img src="([^"]+)[^>]+>(?:<a href="[^>]+>)(.*?)<\/a><\/td><td class="capitulodescarga"><a href="([^"]+)[^>]+>.*?(?:<td class="capitulofecha">.*?(\d{4})?.*?<\/td>)?(?:<td class="capitulosubtitulo"><a href="([^"]+)[^>]+>.*?<\/td>)?<td class="capitulodescarga"><\/tr>'
    matches = re.compile(patron, re.DOTALL).findall(data)
    if not matches:  #error
        item = generictools.web_intervenida(
            item, data)  #Verificamos que no haya sido clausurada
        if item.intervencion:  #Sí ha sido clausurada judicialmente
            item, itemlist = generictools.post_tmdb_episodios(
                item, itemlist)  #Llamamos al método para el pintado del error
            return itemlist  #Salimos

        logger.error(
            "ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " +
            " / PATRON: " + patron + " / DATA: " + data)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web.  Reportar el error con el log'
            ))
        return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

    #logger.debug("PATRON: " + patron)
    #logger.debug(matches)
    #logger.debug(data)

    season = max_temp
    #Comprobamos si realmente sabemos el num. máximo de temporadas
    if item.library_playcounts or (item.infoLabels['number_of_seasons']
                                   and item.tmdb_stat):
        num_temporadas_flag = True
    else:
        num_temporadas_flag = False

    # Recorremos todos los episodios generando un Item local por cada uno en Itemlist
    for scrapedlanguage, scrapedtitle, scrapedurl, year, scrapedsubtitle in matches:
        item_local = item.clone()
        item_local.action = "findvideos"
        item_local.contentType = "episode"
        item_local.extra = "episodios"
        if item_local.library_playcounts:
            del item_local.library_playcounts
        if item_local.library_urls:
            del item_local.library_urls
        if item_local.path:
            del item_local.path
        if item_local.update_last:
            del item_local.update_last
        if item_local.update_next:
            del item_local.update_next
        if item_local.channel_host:
            del item_local.channel_host
        if item_local.active:
            del item_local.active
        if item_local.contentTitle:
            del item_local.infoLabels['title']
        if item_local.season_colapse:
            del item_local.season_colapse

        item_local.title = ''
        item_local.context = "['buscar_trailer']"
        item_local.url = scrapedurl.replace('&#038;', '&').replace(
            '.io/', sufix).replace('.com/', sufix)
        if scrapedsubtitle:
            item_local.subtitle = scrapedsubtitle.replace(
                '&#038;', '&').replace('.io/', sufix).replace('.com/', sufix)
        title = scrapedtitle
        item_local.language = []

        if "1.png" in scrapedlanguage: item_local.language += ['CAST']
        if "512.png" in scrapedlanguage or 'latino' in title.lower():
            item_local.language += ['LAT']
        if ("1.png" not in scrapedlanguage and "512.png" not in scrapedlanguage
            ) or "eng" in title.lower() or "sub" in title.lower():
            item_local.language += ['VOSE']

        try:
            item_local.contentEpisodeNumber = 0
            if 'miniserie' in title.lower():
                item_local.contentSeason = 1
                title = title.replace('miniserie', '').replace('MiniSerie', '')
            elif 'completa' in title.lower():
                patron = '[t|T].*?(\d+) [c|C]ompleta'
                if scrapertools.find_single_match(title, patron):
                    item_local.contentSeason = int(
                        scrapertools.find_single_match(title, patron))
            if not item_local.contentSeason:
                #Extraemos los episodios
                patron = '(\d{1,2})[x|X](\d{1,2})'
                item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(
                    title, patron)
                item_local.contentSeason = int(item_local.contentSeason)
                item_local.contentEpisodeNumber = int(
                    item_local.contentEpisodeNumber)
        except:
            logger.error('ERROR al extraer Temporada/Episodio: ' + title)
            item_local.contentSeason = 1
            item_local.contentEpisodeNumber = 0

        #Si son eisodios múltiples, lo extraemos
        patron1 = '\d+[x|X]\d{1,2}.?(?:y|Y|al|Al)?(?:\d+[x|X]\d{1,2})?.?(?:y|Y|al|Al)?.?\d+[x|X](\d{1,2})'
        epi_rango = scrapertools.find_single_match(title, patron1)
        if epi_rango:
            item_local.infoLabels['episodio_titulo'] = 'al %s' % epi_rango
            item_local.title = '%sx%s al %s -' % (str(
                item_local.contentSeason), str(
                    item_local.contentEpisodeNumber).zfill(2),
                                                  str(epi_rango).zfill(2))
        else:
            item_local.title = '%sx%s -' % (str(
                item_local.contentSeason), str(
                    item_local.contentEpisodeNumber).zfill(2))

        if modo_ultima_temp_alt and item.library_playcounts:  #Si solo se actualiza la última temporada de Videoteca
            if item_local.contentSeason < max_temp:
                break  #Sale del bucle actual del FOR

        if season_display > 0:
            if item_local.contentSeason > season_display:
                continue
            elif item_local.contentSeason < season_display:
                break

        itemlist.append(item_local.clone())

        #logger.debug(item_local)

    if len(itemlist) > 1:
        itemlist = sorted(itemlist,
                          key=lambda it:
                          (int(it.contentSeason), int(it.contentEpisodeNumber)
                           ))  #clasificamos

    if item.season_colapse and not item.add_videolibrary:  #Si viene de listado, mostramos solo Temporadas
        item, itemlist = generictools.post_tmdb_seasons(item, itemlist)

    if not item.season_colapse:  #Si no es pantalla de Temporadas, pintamos todo
        # Pasada por TMDB y clasificación de lista por temporada y episodio
        tmdb.set_infoLabels(itemlist, True)

        #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
        item, itemlist = generictools.post_tmdb_episodios(item, itemlist)

    #logger.debug(item)

    return itemlist
Exemple #5
0
def listado(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    curr_page = 1  # Página inicial
    last_page = 99999  # Última página inicial
    if item.curr_page:
        curr_page = int(
            item.curr_page)  # Si viene de una pasada anterior, lo usamos
        del item.curr_page  # ... y lo borramos
    if item.last_page:
        last_page = int(
            item.last_page)  # Si viene de una pasada anterior, lo usamos
        del item.last_page  # ... y lo borramos

    cnt_tot = 40  # Poner el num. máximo de items por página
    cnt_title = 0  # Contador de líneas insertadas en Itemlist
    inicio = time.time(
    )  # Controlaremos que el proceso no exceda de un tiempo razonable
    fin = inicio + 3  # Después de este tiempo pintamos (segundos)
    timeout_search = timeout  # Timeout para descargas
    if item.extra == 'search':
        timeout_search = timeout * 2  # Timeout un poco más largo para las búsquedas
        if timeout_search < 5:
            timeout_search = 5  # Timeout un poco más largo para las búsquedas

    #Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios
    title_lista = [
    ]  # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas
    if item.title_lista:  # Si viene de una pasada anterior, la lista ya estará guardada
        title_lista.extend(
            item.title_lista)  # Se usa la lista de páginas anteriores en Item
        del item.title_lista  # ... limpiamos

    if not item.extra2:  # Si viene de Catálogo o de Alfabeto
        item.extra2 = ''

    next_page_url = item.url
    #Máximo num. de líneas permitidas por TMDB. Máx de 3 segundos por Itemlist para no degradar el rendimiento
    while cnt_title <= cnt_tot * 0.50 and curr_page <= last_page and fin > time.time(
    ):

        # Descarga la página
        data = ''
        try:
            data = re.sub(
                r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                httptools.downloadpage(next_page_url,
                                       timeout=timeout_search).data)
            data = unicode(data, "utf-8", errors="replace").encode("utf-8")
        except:
            pass

        curr_page += 1  #Apunto ya a la página siguiente
        if not data and not item.extra2:  #Si la web está caída salimos sin dar error
            logger.error(
                "ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: "
                + item.url + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 01: LISTADO:.  La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
                ))
            break  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        status, itemlist = check_blocked_IP(
            data, itemlist)  #Comprobamos si la IP ha sido bloqueada
        if status:
            return itemlist  #IP bloqueada

        #Patrón para todo, incluido búsquedas en cualquier caso
        patron = '<tr class="lista2"><td align="(?:[^"]+)?"\s*class="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*style="(?:[^"]+)?"><a href="[^"]+"><img src="([^"]+)?"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*\/><\/a><\/td><td\s*align="(?:[^"]+)?"\s*class="(?:[^"]+)?"><a onmouseover="(?:[^"]+)?"\s*onmouseout="(?:[^"]+)?"\s*href="[^"]+" title="[^"]+">([^<]+)<\/a>\s*<a href="([^"]+)"><img src="[^"]+"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*><\/a>\s*(?:<a href="([^"]+)"><img src="[^"]+"\s*border="(?:[^"]+)?"\s*alt="(?:[^"]+)?"\s*><\/a>)?\s*<br><span.*?<\/span>\s*<\/td><td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">.*?<\/td><td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">([^<]+)?<\/td><td align="(?:[^"]+)?"\s*width="(?:[^"]+)?"\s*class="(?:[^"]+)?">\s*<font color="(?:[^"]+)?">(\d+)?<\/font>'

        matches = re.compile(patron, re.DOTALL).findall(data)
        if not matches and item.extra != 'search':  #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
        if not matches and item.extra == 'search':  #búsqueda vacía
            return itemlist  #Salimos

        #logger.debug("PATRON: " + patron)
        #logger.debug(matches)
        #logger.debug(data)

        #Buscamos la próxima y la última página
        patron_next = '<a href="([^"]+page=(\d+))" title="next page">'
        if item.extra == 'search':
            patron_last = '<a href="[^"]+"\s*title="page\s*\d+">\d+<\/a>\s*<b>(\d+)<\/b><\/div><\/div><\/td>'
        else:
            patron_last = 'title="previous page"[^<]+<\/a>\s*<a href="[^>]+>(\d+)<\/a>'

        try:
            next_page_url, next_page = scrapertools.find_single_match(
                data, patron_next)
            next_page = int(next_page)
            next_page_url = item.url + '&page=' + str(next_page)
        except:  #Si no lo encuentra, lo ponemos a 1
            #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "<ul class=\"pagination\">.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
            next_page = 1
        #logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))

        if last_page == 99999:  #Si es el valor inicial, buscamos
            if item.extra == 'search':
                last_page = 99
            try:
                data_last = ''
                data_last = re.sub(
                    r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                    httptools.downloadpage(item.url + '&page=%s' % last_page,
                                           timeout=timeout_search).data)
                data_last = unicode(data_last, "utf-8",
                                    errors="replace").encode("utf-8")
                last_page = int(
                    scrapertools.find_single_match(
                        data_last, patron_last))  #lo cargamos como entero
            except:  #Si no lo encuentra, lo ponemos a 1
                #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "<ul class=\"pagination\">.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
                last_page = next_page
            #logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))

        #Empezamos el procesado de matches
        for scrapedthumbnail, scrapedtitle, scrapedurl, scrapedepisodes, scrapedsize, scrapedseeds in matches:

            title = scrapedtitle
            if scrapedepisodes:
                url = scrapedepisodes
            else:
                url = scrapedurl
            size = scrapedsize
            title = title.replace("á", "a").replace("é", "e").replace(
                "í", "i").replace("ó", "o").replace("ú", "u").replace(
                    "ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace(
                        "&atilde;", "a").replace("&etilde;", "e").replace(
                            "&itilde;", "i").replace("&otilde;", "o").replace(
                                "&utilde;",
                                "u").replace("&ntilde;",
                                             "ñ").replace("&#8217;", "'")

            if scrapedurl in title_lista:  #Si ya hemos procesado el título, lo ignoramos
                continue
            else:
                title_lista += [scrapedurl]  #la añadimos a la lista de títulos

            #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.intervencion:
                del item_local.intervencion
            if item_local.viewmode:
                del item_local.viewmode
            item_local.extra2 = True
            del item_local.extra2
            item_local.text_bold = True
            del item_local.text_bold
            item_local.text_color = True
            del item_local.text_color

            title_subs = []  #creamos una lista para guardar info importante
            item_local.language = ['VO']  #creamos lista para los idiomas
            item_local.quality = ''  #iniciamos calidad
            item_local.thumbnail = scrapedthumbnail  #iniciamos thumbnail

            if item.extra == 'search':
                if scrapedepisodes:
                    item_local.extra = 'series'
                else:
                    item_local.extra = 'peliculas'

            item_local.url = urlparse.urljoin(host,
                                              url)  #guardamos la url final
            if item_local.extra != 'series':
                item_local.url += '&order=size&by=ASC'  #guardamos la url final
            item_local.context = "['buscar_trailer']"

            item_local.contentType = "movie"  #por defecto, son películas
            item_local.action = "findvideos"

            #Analizamos los formatos de la películas
            if item_local.extra == 'peliculas':
                patron_title = '(.*?)\.([1|2][9|0]\d{2})?\.(.*?)(?:-.*?)?$'
                if not scrapertools.find_single_match(title, patron_title):
                    logger.error('ERROR tratando título PELI: ' + title)
                    continue
                try:
                    title, year, item_local.quality = scrapertools.find_single_match(
                        title, patron_title)
                except:
                    title = scrapedtitle
                    year = ''
                    item_local.quality = ''
                title = title.replace('.', ' ')
                item_local.quality = item_local.quality.replace('.', ' ')

            #Analizamos los formatos de series, temporadas y episodios
            elif item_local.extra == 'series':
                patron_title = '(.*?)(\.[1|2][9|0]\d{2})?\.S\d{2}.*?\.([\d|A-Z]{2}.*?)(?:-.*?)?$'
                if not scrapertools.find_single_match(title, patron_title):
                    patron_title = '(.*?)\.*([1|2][9|0]\d{2})?(?:\.\d{2}\.\d{2}).*?\.([\d|A-Z]{2}.*?)(?:-.*?)?$'
                    if not scrapertools.find_single_match(title, patron_title):
                        logger.error('ERROR tratando título SERIE: ' + title)
                        continue
                try:
                    title, year, item_local.quality = scrapertools.find_single_match(
                        title, patron_title)
                except:
                    title = scrapedtitle
                    year = ''
                    item_local.quality = ''
                title = title.replace('.', ' ')
                item_local.quality = item_local.quality.replace('.', ' ')
                year = '-'

                item_local.contentType = "tvshow"
                item_local.action = "episodios"
                item_local.season_colapse = True  #Muestra las series agrupadas por temporadas

            #Limpiamos el título de la basura innecesaria
            title = re.sub(r'(?i)TV|Online', '', title).strip()
            item_local.quality = re.sub(
                r'(?i)proper|unrated|directors|cut|german|repack|internal|real|korean|extended|masted|docu|oar|super|duper|amzn|uncensored|hulu',
                '', item_local.quality).strip()

            #Analizamos el año.  Si no está claro ponemos '-'
            try:
                year_int = int(year)
                if year_int >= 1940 and year_int <= 2050:
                    item_local.infoLabels["year"] = year_int
                else:
                    item_local.infoLabels["year"] = '-'
            except:
                item_local.infoLabels["year"] = '-'

            #Terminamos de limpiar el título
            title = re.sub(r'[\(|\[]\s+[\)|\]]', '', title)
            title = title.replace('()',
                                  '').replace('[]',
                                              '').strip().lower().title()
            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
            else:
                item_local.contentSerieName = title.strip().lower().title()

            item_local.title = title.strip().lower().title()

            #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

            #Salvamos y borramos el número de temporadas porque TMDB a veces hace tonterias.  Lo pasamos como serie completa
            if item_local.contentSeason and (item_local.contentType == "season"
                                             or item_local.contentType
                                             == "tvshow"):
                item_local.contentSeason_save = item_local.contentSeason
                del item_local.infoLabels['season']

            #Ahora se filtra por idioma, si procede, y se pinta lo que vale
            if config.get_setting(
                    'filter_languages',
                    channel) > 0:  #Si hay idioma seleccionado, se filtra
                itemlist = filtertools.get_link(itemlist, item_local,
                                                list_language)
            else:
                itemlist.append(item_local.clone())  #Si no, pintar pantalla

            cnt_title = len(itemlist)  #Contador de líneas añadidas

            #logger.debug(item_local)

    #Pasamos a TMDB la lista completa Itemlist
    tmdb.set_infoLabels(itemlist, __modo_grafico__, idioma_busqueda='es,en')

    #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:
            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
Exemple #6
0
def listado(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    curr_page = 1  # Página inicial
    last_page = 99999  # Última página inicial
    if item.curr_page:
        curr_page = int(
            item.curr_page)  # Si viene de una pasada anterior, lo usamos
        del item.curr_page  # ... y lo borramos
    if item.last_page:
        last_page = int(
            item.last_page)  # Si viene de una pasada anterior, lo usamos
        del item.last_page  # ... y lo borramos

    cnt_tot = 40  # Poner el num. máximo de items por página
    cnt_title = 0  # Contador de líneas insertadas en Itemlist
    inicio = time.time(
    )  # Controlaremos que el proceso no exceda de un tiempo razonable
    fin = inicio + 5  # Después de este tiempo pintamos (segundos)
    timeout_search = timeout  # Timeout para descargas
    if item.extra == 'search':
        timeout_search = timeout * 2  # Timeout un poco más largo para las búsquedas
        if timeout_search < 5:
            timeout_search = 5  # Timeout un poco más largo para las búsquedas

    #Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios
    title_lista = [
    ]  # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas
    if item.title_lista:  # Si viene de una pasada anterior, la lista ya estará guardada
        title_lista.extend(
            item.title_lista)  # Se usa la lista de páginas anteriores en Item
        del item.title_lista  # ... limpiamos

    if not item.extra2:  # Si viene de Catálogo o de Alfabeto
        item.extra2 = ''

    next_page_url = item.url
    #Máximo num. de líneas permitidas por TMDB. Máx de 10 segundos por Itemlist para no degradar el rendimiento
    while cnt_title < cnt_tot * 0.5 and curr_page <= last_page and fin > time.time(
    ):

        # Descarga la página
        data = ''
        try:
            data = re.sub(
                r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                httptools.downloadpage(next_page_url,
                                       timeout=timeout_search).data)
            #data = unicode(data, "iso-8859-1", errors="replace").encode("utf-8")
        except:
            pass

        curr_page += 1  #Apunto ya a la página siguiente
        if not data:  #Si la web está caída salimos sin dar error
            logger.error(
                "ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: "
                + item.url + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 01: LISTADO:.  La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
                ))
            break  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        #Patrón para todo, menos para Series completas, incluido búsquedas en cualquier caso
        patron = '<td class="vertThseccion"><img src="([^"]+)"[^>]+><a href="([^"]+)"\s*title="([^"]+)"\s*>[^<]+<\/a><\/td><td>.*?(\d+)?<\/td><td>([^<]+)?<\/td><td>([^<]+)?<\/td><\/tr>'

        #Si son series completas, ponemos un patrón especializado
        if item.extra == 'series':
            patron = '<(td)><a href="([^"]+)"\s*title="([^"]+)"\s*><[^>]+src="[^"]+\/(\d{4})[^"]+"[^>]+>(?:(\d+))?\s*(?:(\d+))?<\/a>'

        matches = re.compile(patron, re.DOTALL).findall(data)
        if not matches and not '<p>Lo sentimos, pero que esta buscando algo que no esta aqui. </p>' in data and not item.extra2 and not '<h2>Sin resultados</h2> in data':  #error
            item = generictools.web_intervenida(
                item, data)  #Verificamos que no haya sido clausurada
            if item.intervencion:  #Sí ha sido clausurada judicialmente
                item, itemlist = generictools.post_tmdb_episodios(
                    item,
                    itemlist)  #Llamamos al método para el pintado del error
                return itemlist  #Salimos

            logger.error(
                "ERROR 02: LISTADO: Ha cambiado la estructura de la Web " +
                " / PATRON: " + patron + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web.  Reportar el error con el log'
                ))
            break  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        #logger.debug("PATRON: " + patron)
        #logger.debug(matches)
        #logger.debug(data)

        #Buscamos la próxima y la última página
        patron_last = "<div class='pagination'>.*?<a href='([^']+\/page\/(\d+)[^']+)'\s*>(?:&raquo;)?(?:\d+)?<\/a><\/div>"

        if last_page == 99999:  #Si es el valor inicial, buscamos last page
            try:
                next_page_url, last_page = scrapertools.find_single_match(
                    data, patron_last)  #cargamos la url y la última página
                last_page = int(last_page)
            except:  #Si no lo encuentra, lo ponemos a 1
                last_page = 1
                #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_last + ' / ' + next_page_url + ' / ' + str(last_page))
            #logger.debug('curr_page: ' + str(curr_page) + '/ last_page: ' + str(last_page))

        if last_page > 1:
            next_page_url = re.sub(r'\/page\/\d+\/', '/page/%s/' % curr_page,
                                   next_page_url)
            next_page_url = next_page_url.replace('&#038;', '&')
        else:
            next_page_url = item.url
        #logger.debug('curr_page: ' + str(curr_page) + '/ last_page: ' + str(last_page) + '/ next_page_url: ' + next_page_url)

        #Empezamos el procesado de matches
        for scrapedlanguage, scrapedurl, scrapedtitle, year, scrapedcategory, scrapedquality in matches:
            title = scrapedtitle
            url = scrapedurl.replace('&#038;', '&')
            title = title.replace("á", "a").replace("é", "e").replace(
                "í", "i").replace("ó", "o").replace("ú", "u").replace(
                    "ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace(
                        "&atilde;", "a").replace("&etilde;", "e").replace(
                            "&itilde;", "i").replace("&otilde;", "o").replace(
                                "&utilde;",
                                "u").replace("&ntilde;", "ñ").replace(
                                    "&#8217;", "'").replace('&#038;', '&')

            #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.category:
                del item_local.category
            if item_local.intervencion:
                del item_local.intervencion
            if item_local.viewmode:
                del item_local.viewmode
            item_local.extra2 = True
            del item_local.extra2
            item_local.text_bold = True
            del item_local.text_bold
            item_local.text_color = True
            del item_local.text_color

            title_subs = []  #creamos una lista para guardar info importante
            item_local.language = []  #creamos lista para los idiomas
            item_local.quality = scrapedquality  #iniciamos calidad
            item_local.thumbnail = ''
            item_local.url = url.replace('&#038;', '&').replace(
                '.io/', sufix).replace('.com/', sufix)  #guardamos la url final
            item_local.context = "['buscar_trailer']"

            item_local.contentType = "movie"  #por defecto, son películas
            item_local.action = "findvideos"

            #Analizamos el formato de series
            if '/series' in scrapedurl or item_local.extra == 'series' or 'series' in scrapedcategory:
                item_local.extra = 'series'
                item_local.contentType = "tvshow"
                item_local.action = "episodios"
                item_local.season_colapse = True  #Muestra las series agrupadas por temporadas

            #Detectamos idiomas
            if "1.png" in scrapedlanguage: item_local.language += ['CAST']
            if "512.png" in scrapedlanguage or 'latino' in title.lower():
                item_local.language += ['LAT']
            if ("1.png" not in scrapedlanguage
                    and "512.png" not in scrapedlanguage
                ) or "eng" in title.lower() or "sub" in title.lower():
                item_local.language += ['VOSE']

            if '-3d' in scrapedurl:
                title = title.replace('3D', '').replace('3d', '')
                item_local.quality += ' 3D'

            #Detectamos el año
            item_local.infoLabels['year'] = '-'
            if year:
                try:
                    year = int(year)
                    if year >= 1970 and year <= 2040:
                        item_local.infoLabels["year"] = year
                except:
                    pass

            #Detectamos info importante a guardar para después de TMDB
            if "extendida" in title.lower() or "extended" 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 ", "")
            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"]

            #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)
            title = re.sub(r'\d+[M|m|G|g][B|b]', '', title)

            #Limpiamos el título de la basura innecesaria
            title = re.sub(
                r'(?i)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|\(iso\)|\(dvd.*?\)|(?:\d+\s*)?\d{3,4}p.*?$|extended|(?:\d+\s*)?bdrip.*?$|\(.*?\).*?$|iso$|unrated|\[.*?$|\d{4}$',
                '', title)

            #Obtenemos temporada y episodio si se trata de Episodios
            if item_local.contentType == "episode":
                patron = '(\d+)[x|X](\d+)'
                try:
                    item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(
                        title, patron)
                except:
                    item_local.contentSeason = 1
                    item_local.contentEpisodeNumber = 0

                #Si son eisodios múltiples, lo extraemos
                patron1 = '\d+[x|X]\d+.?(?:y|Y|al|Al)?.?\d+[x|X](\d+)'
                epi_rango = scrapertools.find_single_match(title, patron1)
                if epi_rango:
                    item_local.infoLabels[
                        'episodio_titulo'] = 'al %s' % epi_rango
                    title = re.sub(patron1, '', title)
                else:
                    title = re.sub(patron, '', title)

            #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()
            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
            else:
                item_local.contentSerieName = title.strip().lower().title()
            item_local.title = title.strip().lower().title()
            item_local.quality = item_local.quality.strip()

            #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

            #Salvamos y borramos el número de temporadas porque TMDB a veces hace tonterias.  Lo pasamos como serie completa
            if item_local.contentSeason and (item_local.contentType == "season"
                                             or item_local.contentType
                                             == "tvshow"):
                item_local.contentSeason_save = item_local.contentSeason
                del item_local.infoLabels['season']

            #Ahora se filtra por idioma, si procede, y se pinta lo que vale
            if config.get_setting(
                    'filter_languages',
                    channel) > 0:  #Si hay idioma seleccionado, se filtra
                itemlist = filtertools.get_link(itemlist, item_local,
                                                list_language)
            else:
                itemlist.append(item_local.clone())  #Si no, pintar pantalla

            cnt_title = len(itemlist)  #Contador de líneas añadidas

            #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 and last_page > 1:
        if last_page:
            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
Exemple #7
0
def listado(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    curr_page = 1  # Página inicial
    last_page = 99999  # Última página inicial
    if item.curr_page:
        curr_page = int(
            item.curr_page)  # Si viene de una pasada anterior, lo usamos
        del item.curr_page  # ... y lo borramos
    if item.last_page:
        last_page = int(
            item.last_page)  # Si viene de una pasada anterior, lo usamos
        del item.last_page  # ... y lo borramos

    cnt_tot = 40  # Poner el num. máximo de items por página
    cnt_title = 0  # Contador de líneas insertadas en Itemlist
    inicio = time.time(
    )  # Controlaremos que el proceso no exceda de un tiempo razonable
    fin = inicio + 10  # Después de este tiempo pintamos (segundos)
    timeout_search = timeout  # Timeout para descargas
    if item.extra == 'search':
        timeout_search = timeout * 2  # Timeout un poco más largo para las búsquedas
        if timeout_search < 5:
            timeout_search = 5  # Timeout un poco más largo para las búsquedas

    #Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios
    title_lista = [
    ]  # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas
    if item.title_lista:  # Si viene de una pasada anterior, la lista ya estará guardada
        title_lista.extend(
            item.title_lista)  # Se usa la lista de páginas anteriores en Item
        del item.title_lista  # ... limpiamos

    if not item.extra2:  # Si viene de Catálogo o de Alfabeto
        item.extra2 = ''

    next_page_url = item.url
    #Máximo num. de líneas permitidas por TMDB. Máx de 10 segundos por Itemlist para no degradar el rendimiento
    while cnt_title <= cnt_tot * 0.45 and curr_page <= last_page and fin > time.time(
    ):

        # Descarga la página
        data = ''
        try:
            data = re.sub(
                r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                httptools.downloadpage(next_page_url,
                                       timeout=timeout_search).data)
            data = unicode(data, "utf-8", errors="replace").encode("utf-8")
        except:
            pass

        curr_page += 1  #Apunto ya a la página siguiente
        if not data and not item.extra2:  #Si la web está caída salimos sin dar error
            logger.error(
                "ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: "
                + item.url + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 01: LISTADO:.  La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
                ))
            break  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        #Patrón para todo, menos para Series completas, incluido búsquedas en cualquier caso
        patron = '<tr><td(?: class="[^"]+")?><a href="([^"]+)".?title="([^"]+)".*?<\/a><\/td><td(?: class="[^"]+")?>(?:<a href="[^"]+">)?(.*?)(?:<\/a>)?<\/td><td(?: class="[^"]+")?>.*?<\/td><td(?: class="[^"]+")?>(.*?)<\/td><\/tr>'

        #Si son series completas, ponemos un patrón especializado
        if item.extra == 'series':
            patron = '<div class="[^"]+"><p class="[^"]+"><a href="([^"]+)".?title="([^"]+)"><img src="([^"]+)".*?<a href=\'[^\']+\'.?title="([^"]+)".*?<\/p><\/div>'

        matches = re.compile(patron, re.DOTALL).findall(data)
        if not matches and not '<p>Lo sentimos, pero que esta buscando algo que no esta aqui. </p>' in data and not item.extra2 and not '<h2>Sin resultados</h2> in data':  #error
            item = generictools.web_intervenida(
                item, data)  #Verificamos que no haya sido clausurada
            if item.intervencion:  #Sí ha sido clausurada judicialmente
                item, itemlist = generictools.post_tmdb_episodios(
                    item,
                    itemlist)  #Llamamos al método para el pintado del error
                return itemlist  #Salimos

            logger.error(
                "ERROR 02: LISTADO: Ha cambiado la estructura de la Web " +
                " / PATRON: " + patron + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web.  Reportar el error con el log'
                ))
            break  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        #logger.debug("PATRON: " + patron)
        #logger.debug(matches)
        #logger.debug(data)

        #Buscamos la próxima y la última página
        patron_next = "<ul class=\"pagination\">.*?\(current\).*?href='([^']+)'>(\d+)<\/a><\/li>"
        #patron_last = "<ul class=\"pagination\">.*?\(current\).*?href='[^']+'>\d+<\/a><\/li>.*?href='[^']+\/(\d+)\/(?:\?s=[^']+)?'><span aria-hidden='[^']+'>&\w+;<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"
        patron_last = "<ul class=\"pagination\">.*?\(current\).*?href='[^']+'>\d+<\/a><\/li>.*?href='[^']+\/(\d+)\/(?:\?[^']+)?'>(?:\d+)?(?:<span aria-hidden='[^']+'>&\w+;<\/span>)?<\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"

        try:
            next_page_url, next_page = scrapertools.find_single_match(
                data, patron_next)
            next_page = int(next_page)
        except:  #Si no lo encuentra, lo ponemos a 1
            #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "<ul class=\"pagination\">.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
            next_page = 1
        #logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))

        if last_page == 99999:  #Si es el valor inicial, buscamos
            try:
                last_page = int(
                    scrapertools.find_single_match(
                        data, patron_last))  #lo cargamos como entero
            except:  #Si no lo encuentra, lo ponemos a 1
                #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron_next + ' / ' + patron_last + ' / ' + scrapertools.find_single_match(data, "<ul class=\"pagination\">.*?<\/span><\/a><\/li><\/ul><\/nav><\/div><\/div><\/div>"))
                last_page = next_page
            #logger.debug('curr_page: ' + str(curr_page) + ' / next_page: ' + str(next_page) + ' / last_page: ' + str(last_page))

        #Empezamos el procesado de matches
        for scrapedurl, scrapedtitle, cat_ppal, size in matches:
            if "/programas" in scrapedurl or "/otros" in scrapedurl:
                continue

            title = scrapedtitle
            url = scrapedurl
            title = title.replace("á", "a").replace("é", "e").replace(
                "í", "i").replace("ó", "o").replace("ú", "u").replace(
                    "ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace(
                        "&atilde;", "a").replace("&etilde;", "e").replace(
                            "&itilde;", "i").replace("&otilde;", "o").replace(
                                "&utilde;",
                                "u").replace("&ntilde;",
                                             "ñ").replace("&#8217;", "'")
            extra = item.extra

            #Si es una búsqueda, convierte los episodios en Series completas, aptas para la Videoteca
            if extra == 'search' and '/series' in scrapedurl and not "Temp" in title and not "emporada" in title:
                if scrapedurl in title_lista:  #Si ya hemos procesado la serie, pasamos de los episodios adicionales
                    continue

                # Descarga la página del episodio, buscando el enlace a la serie completa
                data_serie = ''
                try:
                    data_serie = re.sub(
                        r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                        httptools.downloadpage(scrapedurl,
                                               timeout=timeout).data)
                    data = unicode(data, "utf-8",
                                   errors="replace").encode("utf-8")
                except:
                    pass

                if not data_serie:  #Si la web está caída salimos sin dar error. Pintamos el episodio
                    logger.error(
                        "ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: "
                        + scrapedurl + " / SERIE: " + scrapedurl)
                else:
                    patron_serie = '<div id="where_i_am">.*?<a href="[^"]+">.*?<\/a>.*?<a href="([^"]+)">'
                    url = scrapertools.find_single_match(
                        data_serie,
                        patron_serie)  #buscamos la url de la serie completa
                    if url:
                        url = host + url
                        extra = 'series'  #es una serie completa
                        title_lista += [
                            scrapedurl
                        ]  #la añadimos a la lista de series completas procesadas
                        title = scrapedurl  #salvamos el título de la serie completa
                    else:
                        url = scrapedurl  #No se encuentra la Serie, se trata como Episodio suelto

            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.category:
                del item_local.category
            if item_local.intervencion:
                del item_local.intervencion
            if item_local.viewmode:
                del item_local.viewmode
            item_local.extra2 = True
            del item_local.extra2
            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 = []  #creamos lista para los idiomas
            item_local.quality = ''  #iniciamos calidad
            quality_alt = ''
            if 'series' in cat_ppal or extra == 'series':
                item_local.thumbnail = cat_ppal  #si son series, contiene el thumb
            else:
                quality_alt = scrapedurl.lower().strip(
                )  #si no son series, contiene la calidad
                item_local.thumbnail = ''  #guardamos el thumb
            item_local.extra = extra  #guardamos el extra procesado
            item_local.url = url  #guardamos la url final
            item_local.context = "['buscar_trailer']"

            item_local.contentType = "movie"  #por defecto, son películas
            item_local.action = "findvideos"

            #Analizamos los formatos de la películas
            if '/peliculas/' in scrapedurl or item_local.extra == 'Películas':
                item_local.quality = 'HDRip '
            elif '/peliculas-hd' in scrapedurl or item_local.extra == 'Películas HD':
                item_local.quality = 'HD '
            elif '/peliculas-dvdr' in scrapedurl or item_local.extra == 'Películas DVDR':
                item_local.quality = 'DVDR '
            elif 'subtituladas' in cat_ppal or item_local.extra == 'VOSE' or 'vose' in title.lower(
            ):
                item_local.language += ['VOSE']
            elif 'Version Original' in cat_ppal or item_local.extra == 'VO' or 'vo' in title.lower(
            ):
                item_local.language += ['VO']

            #Analizamos los formatos de series, temporadas y episodios
            elif '/series' in scrapedurl or item_local.extra == 'series':
                item_local.contentType = "tvshow"
                item_local.action = "episodios"
                item_local.season_colapse = True  #Muestra las series agrupadas por temporadas
            elif item_local.extra == 'episodios':
                item_local.contentType = "episode"
                item_local.extra = "episodios"
                if "Temp" in title or "emporada" in title:
                    try:
                        item_local.contentSeason = int(
                            scrapertools.find_single_match(
                                title, '[t|T]emp.*?(\d+)'))
                    except:
                        item_local.contentSeason = 1
                    title = re.sub(r'[t|T]emp.*?\d+', '', title)
                    title_subs += ["Temporada"]
                    item_local.contentType = "season"
                    item_local.extra = "season"

            if item_local.contentType == "movie":  #para las peliculas ponemos el mismo extra
                item_local.extra = "peliculas"

            #Detectamos idiomas
            if "latino" in scrapedurl.lower() or "latino" in title.lower():
                item_local.language += ['LAT']
            elif "vose" in scrapedurl.lower() or "vos" in scrapedurl.lower(
            ) or "vose" in title.lower() or "vos" in title.lower():
                item_local.language += ['VOSE']

            if item_local.language == []:
                item_local.language = ['CAST']

            #Detectamos el año
            patron = '(\d{4})\s*?(?:\)|\])?$'
            item_local.infoLabels["year"] = '-'
            year = ''
            year = scrapertools.find_single_match(title, patron)
            if year:
                title_alt = re.sub(patron, "", title)
                title_alt = title_alt.strip()
                if title_alt:
                    title = title_alt
                try:
                    year = int(year)
                    if year >= 1970 and year <= 2040:
                        item_local.infoLabels["year"] = year
                except:
                    pass

            #Detectamos info importante 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"]

            #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)
            title = re.sub(r'\d+[M|m|G|g][B|b]', '', title)

            #Limpiamos el título de la basura innecesaria
            title = title.replace("Dual", "").replace("dual", "").replace(
                "Subtitulada",
                "").replace("subtitulada", "").replace("Subt", "").replace(
                    "subt", "").replace("Sub", "").replace("sub", "").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", "")

            #Obtenemos temporada y episodio si se trata de Episodios
            if item_local.contentType == "episode":
                patron = '(\d+)[x|X](\d+)'
                try:
                    item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(
                        title, patron)
                except:
                    item_local.contentSeason = 1
                    item_local.contentEpisodeNumber = 0

                #Si son eisodios múltiples, lo extraemos
                patron1 = '\d+[x|X]\d+.?(?:y|Y|al|Al)?.?\d+[x|X](\d+)'
                epi_rango = scrapertools.find_single_match(title, patron1)
                if epi_rango:
                    item_local.infoLabels[
                        'episodio_titulo'] = 'al %s' % epi_rango
                    title = re.sub(patron1, '', title)
                else:
                    title = re.sub(patron, '', title)

            #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()
            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
            else:
                item_local.contentSerieName = title.strip().lower().title()

            if item_local.contentType == "episode":
                item_local.title = '%sx%s ' % (
                    str(item_local.contentSeason),
                    str(item_local.contentEpisodeNumber).zfill(2))
                item_local.extra3 = 'completa'
            else:
                item_local.title = title.strip().lower().title()

            if scrapertools.find_single_match(size,
                                              '\d+.\d+\s?[g|G|m|M][b|B]'):
                size = size.replace('b', ' B').replace('B', ' B').replace(
                    'b', 'B').replace('g', 'G').replace('m',
                                                        'M').replace('.', ',')
                item_local.quality += '[%s]' % size

            #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

            #Salvamos y borramos el número de temporadas porque TMDB a veces hace tonterias.  Lo pasamos como serie completa
            if item_local.contentSeason and (item_local.contentType == "season"
                                             or item_local.contentType
                                             == "tvshow"):
                item_local.contentSeason_save = item_local.contentSeason
                del item_local.infoLabels['season']

            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:
            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
Exemple #8
0
def listado(item):
    logger.info()
    itemlist = []
    item.category = categoria

    #logger.debug(item)

    curr_page = 1  # Página inicial
    cnt_title = 0  # Contador de líneas insertadas en Itemlist
    if item.curr_page:
        curr_page = int(
            item.curr_page)  # Si viene de una pasada anterior, lo usamos
        del item.curr_page  # ... y lo borramos
    if item.last_page:
        last_page = int(
            item.last_page)  # Si viene de una pasada anterior, lo usamos
        del item.last_page  # ... y lo borramos

    cnt_tot = 40  # Poner el num. máximo de items por página
    cnt_pct = 0.725  #% de la página a llenar
    inicio = time.time(
    )  # Controlaremos que el proceso no exceda de un tiempo razonable
    fin = inicio + 5  # Después de este tiempo pintamos (segundos)
    timeout_search = timeout  # Timeout para descargas
    if item.extra == 'search':
        timeout_search = timeout * 2  # Timeout un poco más largo para las búsquedas
        if timeout_search < 5:
            timeout_search = 5  # Timeout un poco más largo para las búsquedas

    if not item.extra2:  # Si viene de Catálogo o de Alfabeto
        item.extra2 = ''

    next_page_url = item.url
    #Máximo num. de líneas permitidas por TMDB. Máx de 10 segundos por Itemlist para no degradar el rendimiento
    while cnt_title < cnt_tot * cnt_pct and fin > time.time():

        # Descarga la página
        data = ''
        try:
            data = re.sub(
                r"\n|\r|\t|\s{2}|(<!--.*?-->)|&nbsp;", "",
                httptools.downloadpage(next_page_url,
                                       timeout=timeout_search).data)
            data = unicode(data, "utf-8", errors="replace").encode("utf-8")
        except:
            pass

        if not data:  #Si la web está caída salimos sin dar error
            logger.error(
                "ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: "
                + item.url + " / DATA: " + data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 01: LISTADO:.  La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
                ))
            break  #si no hay más datos, algo no funciona, pintamos lo que tenemos

        #Patrón para todo, menos para Alfabeto
        if item.extra == 'search':
            patron = '<div class="moditemfdb"><a title="([^"]+)"\s+href="([^"]+)"><img.*?class="thumbnailresult" src="([^"]+)"\/><\/a>'
        elif item.extra2 == 'categorias':
            patron = '<div class="blogitem "><a href="([^"]+)".*?src="([^"]+)" alt.*?title="([^"]+)">'
        else:
            patron = '<div class="blogitem "><a title="([^"]+)"\s+href="([^"]+)">.*?src="([^"]+)" onload'

        matches = re.compile(patron, re.DOTALL).findall(data)
        if not matches and not 'Total: 0 resultados encontrados' in data and not 'Total: 0 results found' 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_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
        patron = '<a href="([^"]+=(\d+))" title="Next">Next<\/a>'
        if not scrapertools.find_single_match(data, patron):
            patron = '<a href="([^"]+=(\d+))" title="Siguiente">Siguiente<\/a>'
        try:
            next_page_url, curr_page = scrapertools.find_single_match(
                data, patron)
            curr_page = int(curr_page) / len(matches)
        except:  #Si no lo encuentra, lo ponemos a 1
            #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron + ' / ' + data)
            fin = 0  #Forzamos a salir  del WHILE al final del FOR
            cnt_title = 0  #Evitamos pié de página
            curr_page = 1
            next_page_url = item.url
        next_page_url = urlparse.urljoin(host, next_page_url)
        #logger.debug('curr_page: ' + str(curr_page) + ' / url: ' + next_page_url)

        #Empezamos el procesado de matches
        for scrapedtitle, scrapedurl, scrapedthumb in matches:
            if item.extra2 == 'categorias':  #Cambia el orden de tres parámetros (Categorías)
                title = scrapedthumb
                url = urlparse.urljoin(host, scrapedtitle)
                thumb = scrapedurl
            else:  #lo estándar
                title = scrapedtitle
                url = urlparse.urljoin(host, scrapedurl)
                thumb = scrapedthumb

            quality = scrapertools.find_single_match(
                title, '\[(.*?)\]')  #capturamos quality
            title = re.sub(r'\[.*?\]', '', title)  #y lo borramos de title

            title = title.replace("á", "a").replace("é", "e").replace(
                "í", "i").replace("ó", "o").replace("ú", "u").replace(
                    "ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace(
                        "&atilde;", "a").replace("&etilde;", "e").replace(
                            "&itilde;", "i").replace("&otilde;", "o").replace(
                                "&utilde;",
                                "u").replace("&ntilde;",
                                             "ñ").replace("&#8217;", "'")

            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

            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 = url  #guardamos el thumb
            item_local.thumbnail = thumb  #guardamos el thumb
            item_local.context = "['buscar_trailer']"

            item_local.contentType = "movie"  #por defecto, son películas
            item_local.action = "findvideos"

            #Ajustamos los idiomas
            if ("-latino-" in url.lower() or "(latino)"
                    in title.lower()) and "LAT" not in item_local.language:
                item_local.language += ['LAT']
            elif ('-vos-' in url.lower() or '-vose-' in url.lower()
                  or '(vos)' in title.lower() or '(vose)'
                  in title.lower()) and "VOSE" not in item_local.language:
                item_local.language += ['VOSE']
            elif ('-vo-' in url.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']  #Por defecto

            title = re.sub(r'\(.*?\)', '',
                           title)  #Limpiamos del idioma de title

            #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", "")

            item_local.infoLabels["year"] = '-'  #Reseteamos el año para TMDB

            #Limpiamos el título de la basura innecesaria
            title = re.sub(r'- $', '', title)
            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)

            #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()

            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(
            )  #Guardamos el título

            #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

            #Ahora se filtra por idioma, si procede, y se pinta lo que vale
            if config.get_setting(
                    'filter_languages',
                    channel) > 0:  #Si hay idioma seleccionado, se filtra
                itemlist = filtertools.get_link(itemlist, item_local,
                                                list_language)
            else:
                itemlist.append(item_local.clone())  #Si no, pintar pantalla

            cnt_title = len(itemlist)  #Contador de líneas añadidas

            #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 cnt_title >= cnt_tot * cnt_pct:

        title = '%s' % curr_page

        itemlist.append(
            Item(channel=item.channel,
                 action="listado",
                 title=">> Página siguiente " + title,
                 url=next_page_url,
                 extra=item.extra,
                 extra2=item.extra2))

    return itemlist
Exemple #9
0
def episodios(item):
    logger.info()
    
    itemlist = []
    item.category = categoria
    
    #logger.debug(item)

    if item.from_title:
        item.title = item.from_title
    
    #Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades
    season_display = 0
    if item.contentSeason:
        if item.season_colapse:                                                 #Si viene del menú de Temporadas...
            season_display = item.contentSeason                                 #... salvamos el num de sesión a pintar
            item.from_num_season_colapse = season_display
            del item.season_colapse
            item.contentType = "tvshow"
            if item.from_title_season_colapse:
                item.title = item.from_title_season_colapse
                del item.from_title_season_colapse
                if item.infoLabels['title']:
                    del item.infoLabels['title']
        del item.infoLabels['season']
    if item.contentEpisodeNumber:
        del item.infoLabels['episode']
    if season_display == 0 and item.from_num_season_colapse:
        season_display = item.from_num_season_colapse

    # Obtener la información actualizada de la Serie.  TMDB es imprescindible para Videoteca
    try:
        tmdb.set_infoLabels(item, True, idioma_busqueda='es,en')
    except:
        pass
        
    modo_ultima_temp_alt = modo_ultima_temp
    if item.ow_force == "1":                                                    #Si hay una migración de canal o url, se actualiza todo 
        modo_ultima_temp_alt = False
    
    # Vemos la última temporada de TMDB y del .nfo
    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)

    # Si la series tiene solo una temporada, o se lista solo una temporada, guardamos la url y seguimos normalmente
    list_temp = []
    list_temp.append(item.url)

    # Descarga las páginas
    for url in list_temp:                                                       # Recorre todas las temporadas encontradas
        
        data, success, code, item, itemlist = generictools.downloadpage(url, timeout=timeout, s2=False, 
                                          item=item, itemlist=itemlist)         # Descargamos la página
        
        #Verificamos si se ha cargado una página, y si además tiene la estructura correcta
        if not success:                                                         # Si ERROR o lista de errores ...
            return itemlist                                                     # ... Salimos

        patron = '<tr>(?:\s*<td>[^<]+<\/td>)?\s*<td>([^<]+)<\/td>\s*<td>([^<]+)<\/td>\s*'
        patron += '<td\s*class=[^<]+<\/td>(?:<td>([^<]+)<\/td>)?\s*<td\s*class=[^<]+<\/td>\s*'
        patron += '<td>\s*<a\s*class="[^"]+"\s*(?:data-row="[^"]+"\s*data-post="[^"]+"\s*)?'
        patron += 'href="([^"]+)"\s*(?:data-season="([^"]+)"\s*data-serie="([^"]+)")?'
        
        matches = re.compile(patron, re.DOTALL).findall(data)

        #logger.debug("PATRON: " + patron)
        #logger.debug(matches)
        #logger.debug(data)

        # Recorremos todos los episodios generando un Item local por cada uno en Itemlist
        x = 0
        for scrapedquality, scrapedlanguage, scrapedsize, scrapedurl, season_num, episode_num  in matches:
            item_local = item.clone()
            item_local.action = "findvideos"
            item_local.contentType = "episode"
            if item_local.library_playcounts:
                del item_local.library_playcounts
            if item_local.library_urls:
                del item_local.library_urls
            if item_local.path:
                del item_local.path
            if item_local.update_last:
                del item_local.update_last
            if item_local.update_next:
                del item_local.update_next
            if item_local.channel_host:
                del item_local.channel_host
            if item_local.active:
                del item_local.active
            if item_local.contentTitle:
                del item_local.infoLabels['title']
            if item_local.season_colapse:
                del item_local.season_colapse

            item_local.url = url                                                # Usamos las url de la temporada, no hay de episodio
            item_local.matches = []
            item_local.matches.append(matches[x])                               # Salvado Matches de cada episodio
            x += 1
            item_local.context = "['buscar_trailer']"
            if not item_local.infoLabels['poster_path']:
                item_local.thumbnail = item_local.infoLabels['thumbnail']
            
            # Extraemos números de temporada y episodio
            try:
                item_local.contentSeason = int(season_num)
            except:
                item_local.contentSeason = 1
            try:
                item_local.contentEpisodeNumber = int(episode_num)
            except:
                item_local.contentEpisodeNumber = 0

            item_local.title = '%sx%s - ' % (str(item_local.contentSeason), 
                        str(item_local.contentEpisodeNumber).zfill(2))

            # Procesamos Calidad
            if scrapedquality:
                item_local.quality = scrapertools.remove_htmltags(scrapedquality)   # iniciamos calidad
                if '[720p]' in scrapedquality.lower() or '720p' in scrapedquality.lower():
                    item_local.quality = '720p'
                if '[1080p]' in scrapedquality.lower() or '1080p' in scrapedquality.lower():
                    item_local.quality = '1080p'
                if '4k' in scrapedquality.lower():
                    item_local.quality = '4K'
                if '3d' in scrapedquality.lower() and not '3d' in item_local.quality.lower():
                    item_local.quality += ', 3D'
            if not item_local.quality:
                item_local.quality = '720p'
            
            # Comprobamos si hay más de un enlace por episodio, entonces los agrupamos
            if len(itemlist) > 0 and item_local.contentSeason == itemlist[-1].contentSeason \
                        and item_local.contentEpisodeNumber == itemlist[-1].contentEpisodeNumber \
                        and itemlist[-1].contentEpisodeNumber != 0:             # solo guardamos un episodio ...
                if itemlist[-1].quality:
                    if item_local.quality not in itemlist[-1].quality:
                        itemlist[-1].quality += ", " + item_local.quality       # ... pero acumulamos las calidades
                else:
                    itemlist[-1].quality = item_local.quality
                itemlist[-1].matches.append(item_local.matches[0])              # Salvado Matches en el episodio anterior
                continue                                                        # ignoramos el episodio duplicado
            
            if season_display > 0:                                              # Son de la temporada estos episodios?
                if item_local.contentSeason > season_display:
                    break
                elif item_local.contentSeason < season_display:
                    continue
                    
            if modo_ultima_temp_alt and item.library_playcounts:                # Si solo se actualiza la última temporada de Videoteca
                if item_local.contentSeason < max_temp:
                    continue                                                    # Sale del bucle actual del FOR

            itemlist.append(item_local.clone())

            #logger.debug(item_local)
            
    if len(itemlist) > 1:
        itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber)))       #clasificamos
        
    if item.season_colapse and not item.add_videolibrary:                       #Si viene de listado, mostramos solo Temporadas
        item, itemlist = generictools.post_tmdb_seasons(item, itemlist)

    if not item.season_colapse:                                                 #Si no es pantalla de Temporadas, pintamos todo
        # Pasada por TMDB y clasificación de lista por temporada y episodio
        tmdb.set_infoLabels(itemlist, True, idioma_busqueda='es,en')

        #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
        item, itemlist = generictools.post_tmdb_episodios(item, itemlist)
    
    #logger.debug(item)

    return itemlist
Exemple #10
0
def listado(item):
    logger.info()
    itemlist = []

    # Descarga la página
    data = ''
    try:
        data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "",
                      httptools.downloadpage(item.url).data)
    except:
        pass

    if not data and item.extra != "año":  #Si la web está caída salimos sin dar error
        logger.error(
            "ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " +
            item.url + " / DATA: " + data)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 01: LISTADO:.  La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
            ))
        return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos
    elif not data and item.extra == "año":  #cuando no hay datos para un año, da error.  Tratamos de evitar el error
        return itemlist

    patron = '<div class="browse-movie-wrap col-xs-10 col-sm-4 col-md-5 col-lg-4"><a href="([^"]+)".*?src="([^"]+)".*?alt="([^"]+)".*?rel="tag">([^"]+)<\/a>\s?<\/div><div class="[^"]+">(.*?)<\/div><\/div><\/div>'
    #data = scrapertools.find_single_match(data, patron)
    matches = re.compile(patron, re.DOTALL).findall(data)
    if not matches and not '<ul class="tsc_pagination tsc_pagination' 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'
            ))
        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)

    for scrapedurl, scrapedthumbnail, scrapedtitle, scrapedyear, scrapedqualities in matches:
        item_local = item.clone()  #Creamos copia de Item para trabajar
        title_subs = []

        title = re.sub('\r\n', '', scrapedtitle).decode('utf8').strip()
        item_local.url = scrapedurl
        item_local.thumbnail = scrapedthumbnail

        scrapedtorrent = ''
        if scrapedqualities:
            patron_quality = '<a href="([^"]+)"\s?rel="[^"]+"\s?title="[^"]+">(.*?)<\/a>'
            matches_quality = re.compile(patron_quality,
                                         re.DOTALL).findall(scrapedqualities)
            quality = ''

            for scrapedtorrent, scrapedquality in matches_quality:
                quality_inter = scrapedquality
                quality_inter = re.sub('HDr$', 'HDrip', quality_inter)
                quality_inter = re.sub('720$', '720p', quality_inter)
                quality_inter = re.sub('1080$', '1080p', quality_inter)
                if quality:
                    quality += ', %s' % quality_inter
                else:
                    quality = quality_inter
            if quality:
                item_local.quality = quality

        item_local.language = [
        ]  #Verificamos el idioma por si encontramos algo
        if "latino" in scrapedtorrent.lower(
        ) or "latino" in item.url or "latino" in title.lower():
            item_local.language += ["LAT"]
        if "ingles" in scrapedtorrent.lower(
        ) or "ingles" in item.url or "vose" in scrapedurl or "vose" in item.url:
            if "VOSE" in scrapedtorrent.lower() or "sub" in title.lower(
            ) or "vose" in scrapedurl or "vose" in item.url:
                item_local.language += ["VOS"]
            else:
                item_local.language += ["VO"]
        if "dual" in scrapedtorrent.lower() or "dual" in title.lower():
            item_local.language[0:0] = ["DUAL"]

        #Limpiamos el título de la basura innecesaria
        title = title.replace("Dual", "").replace("dual", "").replace(
            "Subtitulada",
            "").replace("subtitulada", "").replace("Subt", "").replace(
                "subt", "").replace("Sub", "").replace("sub", "").replace(
                    "(Proper)",
                    "").replace("(proper)", "").replace("Proper", "").replace(
                        "proper",
                        "").replace("#", "").replace("(Latino)",
                                                     "").replace("Latino", "")
        title = title.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", "")
        title = re.sub(r'\??\s?\d*?\&.*', '', title).title().strip()
        item_local.from_title = title  #Guardamos esta etiqueta para posible desambiguación de título

        item_local.contentType = "movie"
        item_local.contentTitle = title
        item_local.extra = "peliculas"
        item_local.action = "findvideos"
        item_local.title = title.strip()
        item_local.infoLabels['year'] = "-"

        if scrapedyear >= "1900" and scrapedyear <= "2040":
            title_subs += [scrapedyear]

        itemlist.append(item_local.clone())  #Pintar pantalla

    #if not item.category:       #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, True)

    #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB
    item, itemlist = generictools.post_tmdb_listado(item, itemlist)

    # Extrae el paginador
    patron = '<li><a href="[^"]+">(\d+)<\/a><\/li>'  #total de páginas
    patron += '<li><a href="([^"]+\/page\/(\d+)\/)"\s?rel="[^"]+">Página siguiente[^<]+<\/a><\/li><\/ul><\/div><\/ul>'  #url siguiente
    url_next = ''
    if scrapertools.find_single_match(data, patron):
        last_page, url_next, next_num = scrapertools.find_single_match(
            data, patron)

    if url_next:
        if last_page:
            title = '[COLOR gold]Página siguiente >>[/COLOR] %s de %s' % (
                int(next_num) - 1, last_page)
        else:
            title = '[COLOR gold]Página siguiente >>[/COLOR] %s' % (
                int(next_num) - 1)

        itemlist.append(
            Item(channel=item.channel,
                 action="listado",
                 title=title,
                 url=url_next,
                 extra=item.extra))

    return itemlist