Exemplo n.º 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']:
    try:
        tmdb.set_infoLabels(item, True)  #TMDB de cada Temp
    except:
        pass

    # Descarga la página
    data = ''  #Inserto en num de página en la url
    try:
        data = httptools.downloadpage(item.url, timeout=timeout).data
        if not PY3:
            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
Exemplo n.º 2
0
def check_for_update(overwrite=True):
    logger.info("Actualizando series...")

    from core import filetools
    from core import channeltools, videolibrarytools
    from platformcode import platformtools
    from channels import videolibrary
    from lib import generictools
    if config.is_xbmc():
        from platformcode import xbmc_videolibrary

    p_dialog = None
    serie_actualizada = False
    update_when_finished = False
    hoy = datetime.date.today()
    estado_verify_playcount_series = False

    try:
        if config.get_setting("update", "videolibrary") != 0 or overwrite:
            config.set_setting("updatelibrary_last_check",
                               hoy.strftime('%Y-%m-%d'), "videolibrary")

            heading = config.get_localized_string(60389)
            p_dialog = platformtools.dialog_progress_bg(
                config.get_localized_string(20000), heading)
            p_dialog.update(0, '')
            show_list = []

            for path, folders, files in filetools.walk(
                    videolibrarytools.TVSHOWS_PATH):
                show_list.extend([
                    filetools.join(path, f) for f in files if f == "tvshow.nfo"
                ])

            if show_list:
                t = float(100) / len(show_list)

            for i, tvshow_file in enumerate(show_list):
                try:
                    head_nfo, serie = videolibrarytools.read_nfo(tvshow_file)
                    if not serie:
                        logger.error('.nfo erroneo en ' + str(tvshow_file))
                        continue
                    path = filetools.dirname(tvshow_file)

                    ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial
                    overwrite_forced = False
                    try:
                        serie, serie, overwrite_forced = generictools.redirect_clone_newpct1(
                            serie,
                            head_nfo,
                            serie,
                            path,
                            overwrite,
                            lookup=True)
                    except:
                        logger.error(traceback.format_exc())
                    if overwrite_forced == True:
                        overwrite = True
                        serie.update_next = ''

                    info_status = ''
                    if serie.infoLabels['status']:
                        info_status = serie.infoLabels['status']

                    logger.info("Serie=%s, Activa=%s, Fecha=%s, Status=%s" % (serie.contentSerieName, \
                                str(serie.active), str(serie.update_last), str(info_status)))
                    p_dialog.update(int(math.ceil((i + 1) * t)), heading,
                                    serie.contentSerieName)

                    #Verificamos el estado del serie.library_playcounts de la Serie por si está incompleto
                    try:
                        estado = False
                        #Si no hemos hecho la verificación o no tiene playcount, entramos
                        estado = config.get_setting("verify_playcount",
                                                    "videolibrary")
                        if not estado or estado == False or not serie.library_playcounts:  #Si no se ha pasado antes, lo hacemos ahora
                            serie, estado = videolibrary.verify_playcount_series(
                                serie, path
                            )  #También se pasa si falta un PlayCount por completo
                    except:
                        logger.error(traceback.format_exc())
                    else:
                        if estado:  #Si ha tenido éxito la actualización...
                            estado_verify_playcount_series = True  #... se marca para cambiar la opción de la Videoteca

                    interval = int(serie.active)  # Podria ser del tipo bool

                    if not serie.active:
                        # si la serie no esta activa descartar
                        if overwrite_forced == False:
                            #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa, aunque la serie esté desactivada
                            try:
                                if config.is_xbmc():  #Si es Kodi, lo hacemos
                                    xbmc_videolibrary.mark_content_as_watched_on_alfa(
                                        path + '/tvshow.nfo')
                            except:
                                logger.error(traceback.format_exc())

                            continue

                    # obtenemos las fecha de actualizacion y de la proxima programada para esta serie
                    update_next = serie.update_next
                    if update_next:
                        y, m, d = update_next.split('-')
                        update_next = datetime.date(int(y), int(m), int(d))
                    else:
                        update_next = hoy

                    update_last = serie.update_last
                    if update_last:
                        y, m, d = update_last.split('-')
                        update_last = datetime.date(int(y), int(m), int(d))
                    else:
                        update_last = hoy

                    # si la serie esta activa ...
                    if overwrite or config.get_setting(
                            "updatetvshows_interval", "videolibrary") == 0:
                        # ... forzar actualizacion independientemente del intervalo
                        serie_actualizada = update(path, p_dialog, i, t, serie,
                                                   overwrite)
                        if not serie_actualizada:
                            update_next = hoy + datetime.timedelta(
                                days=interval)

                    elif interval == 1 and update_next <= hoy:
                        # ...actualizacion diaria
                        serie_actualizada = update(path, p_dialog, i, t, serie,
                                                   overwrite)
                        if not serie_actualizada and update_last <= hoy - datetime.timedelta(
                                days=7):
                            # si hace una semana q no se actualiza, pasar el intervalo a semanal
                            interval = 7
                            update_next = hoy + datetime.timedelta(
                                days=interval)

                    elif interval == 7 and update_next <= hoy:
                        # ...actualizacion semanal
                        serie_actualizada = update(path, p_dialog, i, t, serie,
                                                   overwrite)
                        if not serie_actualizada:
                            if update_last <= hoy - datetime.timedelta(
                                    days=14):
                                # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual
                                interval = 30

                            update_next += datetime.timedelta(days=interval)

                    elif interval == 30 and update_next <= hoy:
                        # ...actualizacion mensual
                        serie_actualizada = update(path, p_dialog, i, t, serie,
                                                   overwrite)
                        if not serie_actualizada:
                            update_next += datetime.timedelta(days=interval)

                    if serie_actualizada:
                        update_last = hoy
                        update_next = hoy + datetime.timedelta(days=interval)

                    head_nfo, serie = videolibrarytools.read_nfo(
                        tvshow_file
                    )  #Vuelve a leer el.nfo, que ha sido modificado
                    if interval != int(serie.active) or update_next.strftime(
                            '%Y-%m-%d'
                    ) != serie.update_next or update_last.strftime(
                            '%Y-%m-%d') != serie.update_last:
                        serie.update_last = update_last.strftime('%Y-%m-%d')
                        if update_next > hoy:
                            serie.update_next = update_next.strftime(
                                '%Y-%m-%d')
                        if serie.infoLabels[
                                "status"] != "Ended" and serie.infoLabels[
                                    "status"] != "Canceled":
                            serie.active = interval
                        serie.channel = "videolibrary"
                        serie.action = "get_seasons"
                        filetools.write(tvshow_file, head_nfo + serie.tojson())

                    if serie_actualizada and not config.get_setting(
                            'cleanlibrary', 'videolibrary', default=False):
                        if config.get_setting("search_new_content",
                                              "videolibrary") == 0:
                            # Actualizamos la videoteca de Kodi: Buscar contenido en la carpeta de la serie
                            if config.is_xbmc():
                                xbmc_videolibrary.update(
                                    folder=filetools.basename(path))
                                update_when_finished = True
                        else:
                            update_when_finished = True
                except Exception as ex:
                    logger.error(
                        "Se ha producido un error al actualizar la serie %s" %
                        tvshow_file)
                    template = "An exception of type %s occured. Arguments:\n%r"
                    message = template % (type(ex).__name__, ex.args)
                    logger.error(message)
                    logger.error(traceback.format_exc(1))

            if estado_verify_playcount_series:  #Si se ha cambiado algún playcount, ...
                estado = config.set_setting(
                    "verify_playcount", True, "videolibrary"
                )  #... actualizamos la opción de Videolibrary

            #if config.get_setting("search_new_content", "videolibrary") == 1 and update_when_finished:
            if config.is_xbmc() and config.get_setting(
                    'cleanlibrary', 'videolibrary', default=False):
                while xbmc.getCondVisibility(
                        'Library.IsScanningVideo()'):  # Se espera a que acabe
                    time.sleep(1)
                xbmc.executebuiltin('CleanLibrary(video)')
                while xbmc.getCondVisibility(
                        'Library.IsScanningVideo()'):  # Se espera a que acabe
                    time.sleep(1)
                update_when_finished = True
                config.set_setting('cleanlibrary', False, 'videolibrary')
            if update_when_finished:
                # Actualizamos la videoteca de Kodi: Buscar contenido en todas las series
                if config.is_xbmc():
                    xbmc_videolibrary.update()

            p_dialog.close()

        else:
            logger.info(
                "No actualiza la videoteca, está desactivado en la configuración de alfa"
            )

    except Exception as ex:
        logger.error("Se ha producido un error al actualizar las series")
        template = "An exception of type %s occured. Arguments:\n%r"
        message = template % (type(ex).__name__, ex.args)
        logger.error(message)

        if p_dialog:
            p_dialog.close()

    # Sincroniza los "vistos" de la Videoteca de Películas
    from core.item import Item
    item_dummy = Item()
    videolibrary.list_movies(item_dummy, silent=True)

    # Descarga los últimos episodios disponibles, si el canal lo permite
    from channels import downloads
    downloads.download_auto(item_dummy)
Exemplo n.º 3
0
def find_and_set_infoLabels(item):
    """
        función que se llama para buscar y setear los infolabels
        :param item:
        :return: boleano que indica si se ha podido encontrar el 'code'
    """
    global scraper
    scraper = None
    # logger.debug("item:\n" + item.tostring('\n'))

    list_opciones_cuadro = [config.get_localized_string(60223), config.get_localized_string(60224)]
    # Si se añaden más scrapers hay q declararlos aqui-> "modulo_scraper": "Texto_en_cuadro"
    scrapers_disponibles = {'tmdb': config.get_localized_string(60225),
                            'tvdb': config.get_localized_string(60226)}

    # Obtener el Scraper por defecto de la configuracion segun el tipo de contenido
    if item.contentType == "movie":
        scraper_actual = ['tmdb'][config.get_setting("scraper_movies", "videolibrary")]
        tipo_contenido = config.get_localized_string(70283)
        title = item.contentTitle
        # Completar lista de opciones para este tipo de contenido
        list_opciones_cuadro.append(scrapers_disponibles['tmdb'])

    else:
        scraper_actual = ['tmdb', 'tvdb'][config.get_setting("scraper_tvshows", "videolibrary")]
        tipo_contenido = "serie"
        title = item.contentSerieName
        # Completar lista de opciones para este tipo de contenido
        list_opciones_cuadro.append(scrapers_disponibles['tmdb'])
        list_opciones_cuadro.append(scrapers_disponibles['tvdb'])

    # Importamos el scraper
    try:
        scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual])
    except ImportError:
        exec("import core." + scraper_actual + " as scraper")
    except:
        import traceback
        logger.error(traceback.format_exc())

    while scraper:
        # Llamamos a la funcion find_and_set_infoLabels del scraper seleccionado
        scraper_result = scraper.find_and_set_infoLabels(item)

        # Verificar si existe 'code'
        if scraper_result and item.infoLabels['code']:
            # code correcto
            logger.info("Identificador encontrado: %s" % item.infoLabels['code'])
            scraper.completar_codigos(item)
            return True
        elif scraper_result:
            # Contenido encontrado pero no hay 'code'
            msg = config.get_localized_string(60227) % title
        else:
            # Contenido no encontrado
            msg = config.get_localized_string(60228) % title

        logger.info(msg)
        # Mostrar cuadro con otras opciones:
        if scrapers_disponibles[scraper_actual] in list_opciones_cuadro:
            list_opciones_cuadro.remove(scrapers_disponibles[scraper_actual])
        index = platformtools.dialog_select(msg, list_opciones_cuadro)

        if index < 0:
            logger.debug("Se ha pulsado 'cancelar' en la ventana '%s'" % msg)
            return False

        elif index == 0:
            # Pregunta el titulo
            title = platformtools.dialog_input(title, config.get_localized_string(60229) % tipo_contenido)
            if title:
                if item.contentType == "movie":
                    item.contentTitle = title
                else:
                    item.contentSerieName = title
            else:
                logger.debug("he pulsado 'cancelar' en la ventana 'Introduzca el nombre correcto'")
                return False

        elif index == 1:
            # Hay q crear un cuadro de dialogo para introducir los datos
            logger.info("Completar información")
            if cuadro_completar(item):
                # code correcto
                logger.info("Identificador encontrado: %s" % str(item.infoLabels['code']))
                return True
                # raise

        elif list_opciones_cuadro[index] in list(scrapers_disponibles.values()):
            # Obtener el nombre del modulo del scraper
            for k, v in list(scrapers_disponibles.items()):
                if list_opciones_cuadro[index] == v:
                    if scrapers_disponibles[scraper_actual] not in list_opciones_cuadro:
                        list_opciones_cuadro.append(scrapers_disponibles[scraper_actual])
                    # Importamos el scraper k
                    scraper_actual = k
                    try:
                        scraper = None
                        scraper = __import__('core.%s' % scraper_actual, fromlist=["core.%s" % scraper_actual])
                    except ImportError:
                        exec("import core." + scraper_actual + " as scraper_module")
                    break

    logger.error("Error al importar el modulo scraper %s" % scraper_actual)
Exemplo n.º 4
0
def update_external_addon(addon_name):
    logger.info(addon_name)

    try:
        #Verificamos que el addon está instalado
        if xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' %
                                  addon_name):
            #Path de actualizaciones de Alfa
            alfa_addon_updates_mig = filetools.join(config.get_runtime_path(),
                                                    "lib")
            alfa_addon_updates = filetools.join(alfa_addon_updates_mig,
                                                addon_name)

            #Path de destino en addon externo
            __settings__ = xbmcaddon.Addon(id="plugin.video." + addon_name)
            if addon_name.lower() in ['quasar', 'elementum']:
                addon_path_mig = filetools.join(xbmc.translatePath(__settings__.getAddonInfo('Path')), \
                        filetools.join("resources", "site-packages"))
                addon_path = filetools.join(addon_path_mig, addon_name)
            else:
                addon_path_mig = ''
                addon_path = ''

            #Hay modificaciones en Alfa? Las copiamos al addon, incuidas las carpetas de migración a PY3
            if filetools.exists(alfa_addon_updates) and filetools.exists(
                    addon_path):
                for root, folders, files in filetools.walk(
                        alfa_addon_updates_mig):
                    if ('future' in root
                            or 'past' in root) and not 'concurrent' in root:
                        for file in files:
                            alfa_addon_updates_mig_folder = root.replace(
                                alfa_addon_updates_mig, addon_path_mig)
                            if not filetools.exists(
                                    alfa_addon_updates_mig_folder):
                                filetools.mkdir(alfa_addon_updates_mig_folder)
                            if file.endswith('.pyo') or file.endswith('.pyd'):
                                continue
                            input_file = filetools.join(root, file)
                            output_file = input_file.replace(
                                alfa_addon_updates_mig, addon_path_mig)
                            if not filetools.copy(
                                    input_file, output_file, silent=True):
                                logger.error(
                                    'Error en la copia de MIGRACIÓN: Input: %s o Output: %s'
                                    % (input_file, output_file))
                                return False

                for root, folders, files in filetools.walk(alfa_addon_updates):
                    for file in files:
                        input_file = filetools.join(root, file)
                        output_file = input_file.replace(
                            alfa_addon_updates, addon_path)
                        if not filetools.copy(
                                input_file, output_file, silent=True):
                            logger.error(
                                'Error en la copia: Input: %s o Output: %s' %
                                (input_file, output_file))
                            return False
                return True
            else:
                logger.error('Alguna carpeta no existe: Alfa: %s o %s: %s' %
                             (alfa_addon_updates, addon_name, addon_path))
        # Se ha desinstalado Quasar, reseteamos la opción
        else:
            config.set_setting('addon_quasar_update', False)
            if filetools.exists(
                    filetools.join(config.get_data_path(),
                                   "%s.json" % addon_name)):
                filetools.remove(
                    filetools.join(config.get_data_path(),
                                   "%s.json" % addon_name))
            return True
    except:
        logger.error(traceback.format_exc())

    return False
Exemplo n.º 5
0
def init():
    logger.info()
    """
    Todo el código añadido al add-on se borra con cada actualización.  Esta función permite restaurarlo automáticamente con cada actualización.  Esto permite al usuario tener su propio código, bajo su responsabilidad, y restaurarlo al add-on cada vez que se actualiza.
    
    El mecanismo funciona copiando el contenido de la carpeta-arbol "./userdata/addon_data/plugin.video.alfa/custom_code/..." sobre
    las carpetas de código del add-on.  No verifica el contenido, solo vuelca(reemplaza) el contenido de "custom_code".
    
    El usuario almacenará en las subcarpetas de "custom_code" su código actualizado y listo para ser copiado en cualquier momento.
    Si no se desea que copie algo, simplemente se borra de "custom_code" y ya no se copiará en la próxima actualización.
    
    Los pasos que sigue esta función, son los siguientes:
    
    1.- La función se llama desde videolibrary_service.py, desde la función inicial:
            # Copia Custom code a las carpetas de Alfa desde la zona de Userdata
            from platformcode import custom_code
            custom_code.init()
            
    2.- En el inicio de Kodi, comprueba si existe la carpeta "custom_code" en "./userdata/addon_data/plugin.video.alfa/".  
        Si no existe, la crea y sale sin más, dando al ususario la posibilidad de copiar sobre esa estructura su código, 
        y que la función la vuelque sobre el add-on en el próximo inicio de Kodi.
        
    3.- En el siguiente inicio de Kodi, comprueba si existe el custom_code.json en la carpeta root del add-on.
        Si no existe, lo crea con el número de versión del add-on vacío, para permitir que se copien los archivos en esta pasada.
        
    4.- Verifica que el número de versión del add-on es diferente de el de custom_code.json.  Si es la misma versión, 
        se sale porque ya se realizo la copia anteriormente.
        Si la versión es distinta, se realiza el volcado de todos los archivos de la carpeta-árbol "custom_code" sobre el add-on.
        Si la carpeta de destino no existe, dará un error y se cancelará la copia.  Se considera que no tienen sentido nuevas carpetas.
        
    5.- Si la copia ha terminado con éxito, se actualiza el custom_code.json con el número de versión del add-on,
        para que en inicios sucesivos de Kodi no se realicen las copias, hasta que el add-on cambie de versión.
        En el número de versión del add-on no se considera el número de fix.
        
    Tiempos:    Copiando 7 archivos de prueba, el proceso ha tardado una décima de segundo.
    """

    try:
        #Borra el .zip de instalación de Alfa de la carpeta Packages, por si está corrupto, y que así se pueda descargar de nuevo
        version = 'plugin.video.alfa-%s.zip' % config.get_addon_version(
            with_fix=False)
        filetools.remove(
            filetools.join(xbmc.translatePath('special://home'), 'addons',
                           'packages', version), True)

        #Verifica si Kodi tiene algún achivo de Base de Datos de Vídeo de versiones anteriores, entonces los borra
        verify_Kodi_video_DB()

        #LIBTORRENT: se descarga el binario de Libtorrent cada vez que se actualiza Alfa
        try:
            threading.Thread(target=update_libtorrent).start(
            )  # Creamos un Thread independiente, hasta el fin de Kodi
            time.sleep(2)  # Dejamos terminar la inicialización...
        except:  # Si hay problemas de threading, nos vamos
            logger.error(traceback.format_exc())

        #QUASAR: Preguntamos si se hacen modificaciones a Quasar
        if not filetools.exists(filetools.join(config.get_data_path(), "quasar.json")) \
                    and not config.get_setting('addon_quasar_update', default=False):
            question_update_external_addon("quasar")

        #QUASAR: Hacemos las modificaciones a Quasar, si está permitido, y si está instalado
        if config.get_setting('addon_quasar_update', default=False) or \
                    (filetools.exists(filetools.join(config.get_data_path(), \
                    "quasar.json")) and not xbmc.getCondVisibility('System.HasAddon("plugin.video.quasar")')):
            if not update_external_addon("quasar"):
                platformtools.dialog_notification(
                    "Actualización Quasar", "Ha fallado. Consulte el log")

        #Existe carpeta "custom_code" ? Si no existe se crea y se sale
        custom_code_dir = filetools.join(config.get_data_path(), 'custom_code')
        if not filetools.exists(custom_code_dir):
            create_folder_structure(custom_code_dir)
            return

        else:
            #Existe "custom_code.json" ? Si no existe se crea
            custom_code_json_path = config.get_runtime_path()
            custom_code_json = filetools.join(custom_code_json_path,
                                              'custom_code.json')
            if not filetools.exists(custom_code_json):
                create_json(custom_code_json_path)

            #Se verifica si la versión del .json y del add-on son iguales.  Si es así se sale.  Si no se copia "custom_code" al add-on
            verify_copy_folders(custom_code_dir, custom_code_json_path)
    except:
        logger.error(traceback.format_exc())
Exemplo n.º 6
0
def update(path, p_dialog, i, t, serie, overwrite):
    logger.info("Actualizando " + path)
    insertados_total = 0
      
    head_nfo, it = videolibrarytools.read_nfo(path + '/tvshow.nfo')

    # logger.debug("%s: %s" %(serie.contentSerieName,str(list_canales) ))
    for channel, url in serie.library_urls.items():
        serie.channel = channel
        serie.url = url
        
        ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial
        try:
            serie, it, overwrite = generictools.redirect_clone_newpct1(serie, head_nfo, it, path, overwrite)
        except:
            pass

        channel_enabled = channeltools.is_enabled(serie.channel)

        if channel_enabled:

            heading = config.get_localized_string(60389)
            p_dialog.update(int(math.ceil((i + 1) * t)), heading, "%s: %s" % (serie.contentSerieName,
                                                                              serie.channel.capitalize()))
            try:
                pathchannels = filetools.join(config.get_runtime_path(), "channels", serie.channel + '.py')
                logger.info("Cargando canal: " + pathchannels + " " +
                            serie.channel)

                if serie.library_filter_show:
                    serie.show = serie.library_filter_show.get(serie.channel, serie.contentSerieName)

                obj = imp.load_source(serie.channel, pathchannels)
                itemlist = obj.episodios(serie)

                try:
                    if int(overwrite) == 3:
                        # Sobrescribir todos los archivos (tvshow.nfo, 1x01.nfo, 1x01 [canal].json, 1x01.strm, etc...)
                        insertados, sobreescritos, fallidos, notusedpath = videolibrarytools.save_tvshow(serie, itemlist)
                        #serie= videolibrary.check_season_playcount(serie, serie.contentSeason)
                        #if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()):
                        #    serie.infoLabels['playcount'] = serie.playcount
                    else:
                        insertados, sobreescritos, fallidos = videolibrarytools.save_episodes(path, itemlist, serie,
                                                                                              silent=True,
                                                                                              overwrite=overwrite)
                        #it = videolibrary.check_season_playcount(it, it.contentSeason)
                        #if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()):
                        #    serie.infoLabels['playcount'] = serie.playcount
                    insertados_total += insertados

                except Exception, ex:
                    logger.error("Error al guardar los capitulos de la serie")
                    template = "An exception of type %s occured. Arguments:\n%r"
                    message = template % (type(ex).__name__, ex.args)
                    logger.error(message)

            except Exception, ex:
                logger.error("Error al obtener los episodios de: %s" % serie.show)
                template = "An exception of type %s occured. Arguments:\n%r"
                message = template % (type(ex).__name__, ex.args)
                logger.error(message)

        else:
            logger.debug("Canal %s no activo no se actualiza" % serie.channel)
Exemplo n.º 7
0
def resolve_video_urls_for_playing(server, url, video_password="", muestra_dialogo=False):
    """
    Función para obtener la url real del vídeo
    @param server: Servidor donde está alojado el vídeo
    @type server: str
    @param url: url del vídeo
    @type url: str
    @param video_password: Password para el vídeo
    @type video_password: str
    @param muestra_dialogo: Muestra el diálogo de progreso
    @type muestra_dialogo: bool

    @return: devuelve la url del video
    @rtype: list
    """
    logger.info("Server: %s, Url: %s" % (server, url))

    server = server.lower()

    video_urls = []
    video_exists = True
    error_messages = []
    opciones = []

    # Si el vídeo es "directo" o "local", no hay que buscar más
    if server=="directo" or server=="local":
        logger.info("Server: %s, la url es la buena" % server)
        video_urls.append([ "%s [%s]" % (urlparse.urlparse(url)[2][-4:], server) , url ])

    # Averigua la URL del vídeo
    else:
        if server:
            server_parameters = get_server_parameters(server)
        else:
            server_parameters = {}

        if server_parameters:
            # Muestra un diágo de progreso
            if muestra_dialogo:
                progreso = platformtools.dialog_progress("streamondemand", "Connessione con %s" % server_parameters["name"])

            #Cuenta las opciones disponibles, para calcular el porcentaje

            orden = [["free"] + [server] + [premium for premium in server_parameters["premium"] if not premium == server],
                     [server] + [premium for premium in server_parameters["premium"] if not premium == server] + ["free"],
                     [premium for premium in server_parameters["premium"] if not premium == server] + [server] + ["free"]
                    ]


            if server_parameters["free"] == "true": opciones.append("free")
            opciones.extend([premium for premium in server_parameters["premium"] if config.get_setting("premium",server=premium)])

            priority = int(config.get_setting("resolve_priority"))
            opciones = sorted(opciones, key=lambda x: orden[priority].index(x))


            logger.info("Opciones disponibles: %s | %s"  % (len(opciones), opciones))
        else:
            logger.error("No existe conector para el servidor %s" % server)
            error_messages.append("Non esiste alcuna connessione per il server %s" % server)
            muestra_dialogo = False

        #Importa el server
        try:
            server_module = __import__('servers.%s' % server, None, None, ["servers.%s" % server])
            logger.info("Servidor importado: %s" % server_module)
        except:
            server_module = None
            logger.error("No se ha podido importar el servidor: %s" % server)
            import traceback
            logger.error(traceback.format_exc())


        # Si tiene una función para ver si el vídeo existe, lo comprueba ahora
        if hasattr(server_module, 'test_video_exists'):
            logger.info("Invocando a %s.test_video_exists" % server)
            try:
                video_exists, message = server_module.test_video_exists(page_url=url)

                if not video_exists:
                    error_messages.append(message)
                    logger.info("test_video_exists dice que el video no existe")
                else:
                    logger.info("test_video_exists dice que el video SI existe")
            except:
                logger.error("No se ha podido comprobar si el video existe")
                import traceback
                logger.error(traceback.format_exc())

        #Si el video existe y el modo free está disponible, obtenemos la url
        if video_exists:
            for opcion in opciones:
                #Opcion free y premium propio usa el mismo server
                if opcion == "free" or opcion == server:
                    serverid = server_module
                    server_name = server_parameters["name"]

                #Resto de opciones premium usa un debrider
                else:
                    serverid = __import__('servers.debriders.%s' % opcion, None, None, ["servers.debriders.%s" % opcion])
                    server_name = get_server_parameters(opcion)["name"]

                #Muestra el progreso
                if muestra_dialogo:
                    progreso.update((100 / len(opciones)) * opciones.index(opcion)  , "Connessione con %s" % server_name)

                #Modo free
                if opcion == "free":
                    try:
                        logger.info("Invocando a %s.get_video_url" % server)
                        response = serverid.get_video_url(page_url=url, video_password=video_password)
                        if response:
                            save_server_stats({server: "sucess"}, "resolve")
                        video_urls.extend(response)
                    except:
                        save_server_stats({server: "error"}, "resolve")
                        logger.error("Error al obrener la url en modo free")
                        error_messages.append("Si è verificato un errore in %s" % server_name)
                        import traceback
                        logger.error(traceback.format_exc())

                #Modo premium
                else:
                    try:
                        logger.info("Invocando a %s.get_video_url" % opcion)
                        response = serverid.get_video_url(page_url=url, premium=True, user=config.get_setting("user", server=opcion), password=config.get_setting("password", server=opcion), video_password=video_password)
                        if response and response[0][1]:
                            if opcion == server:
                                save_server_stats({server: "sucess"}, "resolve")
                            video_urls.extend(response)
                        elif response and response[0][0]:
                            error_messages.append(response[0][0])
                        else:
                            error_messages.append("Si è verificato un errore in %s" % server_name)
                    except:
                        if opcion == server:
                            save_server_stats({server: "error"}, "resolve")
                        logger.error("Error en el servidor: %s" % opcion)
                        error_messages.append("Si è verificato un errore in %s" % server_name)
                        import traceback
                        logger.error(traceback.format_exc())

                #Si ya tenemos URLS, dejamos de buscar
                if video_urls and config.get_setting("resolve_stop") == True:
                    break

            #Cerramos el progreso
            if muestra_dialogo:
                progreso.update( 100 , "Proceso finalizado")
                progreso.close()

            #Si no hay opciones disponibles mostramos el aviso de las cuentas premium
            if video_exists and not opciones and server_parameters.get("premium"):
                listapremium = [get_server_parameters(premium)["name"] for premium in server_parameters["premium"]]
                error_messages.append("Para ver un vídeo en %s necesitas<br/>una cuenta en: %s" % (server, " o ".join(listapremium)))

            #Si no tenemos urls ni mensaje de error, ponemos uno generico
            elif not video_urls and not error_messages:
                error_messages.append("Si è verificato un errore in %s" % get_server_parameters(server)["name"])


    return video_urls, len(video_urls) > 0, "<br/>".join(error_messages)
Exemplo n.º 8
0
def submenu(item):
    logger.info()
    itemlist = []
    item.filter_lang = True

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

    if not data:
        logger.error(
            "ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " +
            item.url)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
            ))
        return itemlist  #Algo no funciona, pintamos lo que tenemos

    patron = '<div class="cab_menu"\s*>.*?<\/div>'  #Menú principal
    data1 = scrapertools.find_single_match(data, patron)
    patron = '<div id="menu_langen"\s*>.*?<\/div>'  #Menú de idiomas
    data1 += scrapertools.find_single_match(data, patron)

    patron = '<a href="(.*?)".*?title="(.*?)"'  #Encontrar todos los apartados
    matches = re.compile(patron, re.DOTALL).findall(data1)
    if not matches:
        item = generictools.web_intervenida(
            item, data)  #Verificamos que no haya sido clausurada
        if item.intervencion:  #Sí ha sido clausurada judicialmente
            for clone_inter, autoridad in item.intervencion:
                thumb_intervenido = get_thumb(autoridad)
                itemlist.append(
                    item.clone(action='',
                               title="[COLOR yellow]" +
                               clone_inter.capitalize() + ': [/COLOR]' +
                               intervenido_judicial +
                               '. Reportar el problema en el foro',
                               thumbnail=thumb_intervenido))
            return itemlist  #Salimos

        logger.error(
            "ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " +
            " / PATRON: " + patron + " / DATA: " + data1)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 02: SUBMENU: 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

    for scrapedurl, scrapedtitle in matches:
        if PY3:
            scrapedtitle = re.sub('\r\n', '', scrapedtitle).strip()
        else:
            scrapedtitle = re.sub('\r\n', '',
                                  scrapedtitle).decode('utf8').strip()
        scrapedtitle = scrapedtitle.replace(" torrent", "").replace(
            " Torrent", "").replace("Series y ", "").title()

        if "castellano" in scrapedtitle.lower(
        ):  #Evita la entrada de peliculas castellano del menú de idiomas
            continue

        if item.extra == "series":  #Tratamos Series
            if not "/serie" in scrapedurl:
                continue
        else:  #Tratamos Películas
            if "/serie" in scrapedurl:
                continue

        if 'subtitulado' in scrapedtitle.lower(
        ) or 'latino' in scrapedtitle.lower(
        ) or 'original' in scrapedtitle.lower():
            item.filter_lang = False

        itemlist.append(
            item.clone(action="listado", title=scrapedtitle, url=scrapedurl))

    if item.extra == "series":  #Añadimos Series VOSE que está fuera del menú principal
        itemlist.append(
            item.clone(action="listado",
                       title="Series VOSE",
                       url=host + "/series-vose/",
                       filter_lang=False))

    return itemlist
Exemplo n.º 9
0
def listado(item):
    logger.info()
    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

    # Descarga la página
    data = ''
    try:
        data = re.sub(
            r"\n|\r|\t|\s{2}|(<!--.*?-->)", "",
            httptools.downloadpage(item.url, timeout=timeout_search).data)
    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'
            ))
        return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

    patron = '<div id="principal">.*?<\/nav><\/div><\/div>'
    data = scrapertools.find_single_match(data, patron)

    patron = '<li>\s*<div\s*class="[^"]+">\s*<a href="([^"]+)"\s*'  #url
    patron += 'title="([^"]+)"\s*(?:alt="[^"]+")?\s*>\s*'  #título
    patron += '<img (?:class="[^"]+")?\s*src="([^"]+)".*?border="[^"]+"\s*'  #thumb
    patron += 'title="([^"]+)".*?'  #categoría
    patron += '<span class="[^"]+"\s*id="[^"]+">\s*<i>\s*'
    patron += "<img src='[^']+'\s*data-src='[^']+\/(\w+).png'.*?"  #idioma
    patron += '<span class="[^"]+" style="[^"]+"\s*><i>(.*?)?<\/i>'  #calidad
    patron += '(?:<\/span.*?="dig1">(.*?)?)?'  #tamaño
    patron += '(?:<.*?="dig2">(.*?)?)?<\/span><\/div>'  #tipo tamaño

    matches = re.compile(patron, re.DOTALL).findall(data)
    if not matches and not '<title>503 Backend fetch failed</title>' in data and not 'No se han encontrado resultados' in data:  #error
        item = generictools.web_intervenida(
            item, data)  #Verificamos que no haya sido clausurada
        if item.intervencion:  #Sí ha sido clausurada judicialmente
            item, itemlist = generictools.post_tmdb_listado(
                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, scrapedtitle, scrapedthumbnail, scrapedcategory, scrapedlang, \
                            scrapedcalidad, scrapedsize, scrapedsizet in matches:
        item_local = item.clone()  #Creamos copia de Item para trabajar

        if PY3:
            title = re.sub('\r\n', '', scrapedtitle).strip()
        else:
            title = re.sub('\r\n', '', scrapedtitle).decode('utf8').strip()
        title = title.replace(" torrent",
                              "").replace(" Torrent",
                                          "").replace("Series y ", "")
        item_local.url = urlparse.urljoin(host, scrapedurl)
        item_local.thumbnail = urlparse.urljoin(host, scrapedthumbnail)

        if "---" in scrapedcalidad:  #limpiamos calidades
            scrapedcalidad = ''
        if "microhd" in title.lower():
            item_local.quality = "microHD"
        if not "/series-vose/" in item.url and not item_local.quality:
            item_local.quality = scrapedcalidad
        if scrapertools.find_single_match(item_local.quality, r'\d+\.\d+'):
            item_local.quality = ''
        if not item_local.quality and (
                "DVDRip" in title or "HDRip" in title or "BR-LINE" in title
                or "HDTS-SCREENER" in title or "BDRip" in title
                or "BR-Screener" in title or "DVDScreener" in title
                or "TS-Screener" in title):
            item_local.quality = scrapertools.find_single_match(
                title, r'\((.*?)\)')
            item_local.quality = item_local.quality.replace("Latino", "")
        if not scrapedsizet or "---" in scrapedsizet:
            scrapedsize = ''
        else:
            item_local.quality += ' [%s %s]' % (scrapedsize.replace(
                ".", ","), scrapedsizet)

        item_local.language = [
        ]  #Verificamos el idioma por si encontramos algo
        if "latino" in scrapedlang.lower(
        ) or "latino" in item.url or "latino" in title.lower():
            item_local.language += ["LAT"]
        if scrapedlang.lower() in ['vos', 'vose'] or "vose" in item.url or "vos" in item.url \
                        or "vose" in scrapedurl or "vos" in scrapedurl or "subt" in title.lower():
            item_local.language += ["VOSE"]
        elif scrapedlang.lower() in ['ingles', 'inglés', 'english', 'original', 'vo'] or "ingles" in item.url \
                        or "vo" in item.url or "ingles" in scrapedurl or "vo" in scrapedurl:
            item_local.language += ["VO"]
        if item_local.language == []:
            item_local.language = ['CAST']  #Por defecto

        if "dual" in scrapedlang.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", "").replace("temporada", "").replace(
                                    "Temporada",
                                    "").replace("capitulo",
                                                "").replace("Capitulo", "")

        title = re.sub(r'(?:\d+)?x.?\s?\d+', '', title)
        title = re.sub(r'\??\s?\d*?\&.*', '', title).title().strip()

        item_local.from_title = title  #Guardamos esta etiqueta para posible desambiguación de título

        if item_local.extra == "peliculas":  #preparamos Item para películas
            if "/serie" in scrapedurl or "/serie" in item.url:
                continue
        if not "/serie" in scrapedurl and not "/serie" in item.url:
            item_local.contentType = "movie"
            item_local.contentTitle = title
            item_local.extra = "peliculas"

        if item_local.extra == "series":  #preparamos Item para series
            if not "/serie" in scrapedurl and not "/serie" in item.url:
                continue
        if "/serie" in scrapedurl or "/serie" in item.url:
            item_local.contentType = "episode"
            item_local.extra = "series"
            epi_mult = scrapertools.find_single_match(item_local.url,
                                                      r'cap.*?-\d+-al-(\d+)')
            item_local.contentSeason = scrapertools.find_single_match(
                item_local.url, r'temporada-(\d+)')
            item_local.contentEpisodeNumber = scrapertools.find_single_match(
                item_local.url, r'cap.*?-(\d+)')
            if not item_local.contentSeason:
                item_local.contentSeason = scrapertools.find_single_match(
                    item_local.url, r'-(\d+)[x|X]\d+')
            if not item_local.contentEpisodeNumber:
                item_local.contentEpisodeNumber = scrapertools.find_single_match(
                    item_local.url, r'-\d+[x|X](\d+)')
            if not item_local.contentSeason or item_local.contentSeason < 1:
                item_local.contentSeason = 0
            if item_local.contentEpisodeNumber < 1:
                item_local.contentEpisodeNumber = 1

            item_local.contentSerieName = title
            if epi_mult:
                title = "%sx%s al %s -" % (
                    item_local.contentSeason,
                    str(item_local.contentEpisodeNumber).zfill(2),
                    str(epi_mult).zfill(2)
                )  #Creamos un título con el rango de episodios
            else:
                title = '%sx%s ' % (
                    str(item_local.contentSeason),
                    str(item_local.contentEpisodeNumber).zfill(2))

        item_local.action = "findvideos"
        item_local.title = title.strip()
        item_local.infoLabels['year'] = "-"

        #Pasamos a TMDB cada Item, para evitar el efecto memoria de tmdb
        #if item.category:       #Si este campo no existe es que viene de la primera pasada de una búsqueda global, pasamos
        #    tmdb.set_infoLabels(item_local, True)

        #Ahora se filtra por idioma, si procede, y se pinta lo que vale
        if config.get_setting(
                'filter_languages', channel
        ) > 0 and item.filter_lang:  #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

    #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 = '<div class="paginacion">.*?<span class="pagina pag_actual".*?'
    patron += "<a href='([^']+)'.*?"  #url siguiente página
    patron += 'class="pagina">(\d+)<'  #próxima página
    matches = scrapertools.find_single_match(data, patron)

    patron = 'class="pagina pag_sig">Siguiente.*?'
    patron += "<a href='.*?\/page\/(\d+)\/"  #total de páginas
    last_page = scrapertools.find_single_match(data, patron)
    if not last_page:
        patron = '<div class="paginacion">.*?'
        patron += 'class="pagina">(\d+)<\/a><\/div><\/nav><\/div><\/div>'  #total de páginas
        last_page = scrapertools.find_single_match(data, patron)

    if matches:
        scrapedurl = urlparse.urljoin(item.url, matches[0])
        if last_page:
            title = '[COLOR gold]Página siguiente >>[/COLOR] %s de %s' % (
                int(matches[1]) - 1, last_page)
        else:
            title = '[COLOR gold]Página siguiente >>[/COLOR] %s' % (
                int(matches[1]) - 1)

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

    return itemlist
Exemplo n.º 10
0
def findvideos(item):
    logger.info()
    itemlist = []

    #Bajamos los datos de la página
    try:
        data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "",
                      httptools.downloadpage(item.url).data)
    except:
        logger.error(
            "ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " +
            item.url + " / DATA: " + data)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 01: FINDVIDEOS:.  La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log'
            ))
        return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos
    #data = unicode(data, "utf-8", errors="replace")

    #Añadimos el tamaño para todos
    size = scrapertools.find_single_match(item.quality,
                                          '\s\[(\d+,?\d*?\s\w[b|B]s)\]')
    if size:
        item.title = re.sub('\s\[\d+,?\d*?\s\w[b|B]s\]', '',
                            item.title)  #Quitamos size de título, si lo traía
        item.title = '%s [%s]' % (item.title, size
                                  )  #Agregamos size al final del título
        item.quality = re.sub(
            '\s\[\d+,?\d*?\s\w[b|B]s\]', '',
            item.quality)  #Quitamos size de calidad, si lo traía
        item.quality = '%s [%s]' % (item.quality, size
                                    )  #Agregamos size al final de calidad
        item.quality = item.quality.replace("G", "G ").replace(
            "M", "M ")  #Se evita la palabra reservada en Unify

    patron_t = '<div class="enlace_descarga".*?<a href="(.*?\.torrent)"'
    link_torrent = scrapertools.find_single_match(data, patron_t)
    link_torrent = urlparse.urljoin(item.url, link_torrent)
    link_torrent = link_torrent.replace(
        " ", "%20")  #sustituimos espacios por %20, por si acaso
    #logger.info("link Torrent: " + link_torrent)

    patron_m = '<div class="enlace_descarga".*?<a href="(magnet:?.*?)"'
    link_magnet = scrapertools.find_single_match(data, patron_m)
    link_magnet = urlparse.urljoin(item.url, link_magnet)
    #logger.info("link Magnet: " + link_magnet)

    if not link_torrent and not link_magnet:  #error
        logger.error(
            "ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web "
            + " / PATRON: " + patron_t + " / " + patron_m + " / DATA: " + data)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web.  Verificar en la Web y reportar el error con el log'
            ))
        return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

    #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
    item, itemlist = generictools.post_tmdb_findvideos(item, itemlist)

    #Generamos una copia de Item para trabajar sobre ella
    item_local = item.clone()

    #Ahora pintamos el link del Torrent, si lo hay
    if link_torrent:  # Hay Torrent ?
        if item_local.quality:
            item_local.quality += " "
        item_local.quality += "[Torrent]"
        item_local.url = link_torrent
        item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (
            item_local.quality, str(
                item_local.language))  #Preparamos título de Torrent
        item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '',
                                  item_local.title)  #Quitamos etiquetas vacías
        item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '',
                                  item_local.title)  #Quitamos colores vacíos
        item_local.alive = "??"  #Calidad del link sin verificar
        item_local.action = "play"  #Visualizar vídeo
        item_local.server = "torrent"  #Seridor Torrent

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

    #Ahora pintamos el link del Magnet, si lo hay
    if link_magnet:  # Hay Magnet ?
        if item_local.quality:
            item_local.quality += " "
        item_local.quality = item_local.quality.replace("[Torrent]",
                                                        "") + "[Magnet]"
        item_local.url = link_magnet
        item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (
            item_local.quality, str(
                item_local.language))  #Preparamos título de Magnet
        item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '',
                                  item_local.title)  #Quitamos etiquetas vacías
        item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '',
                                  item_local.title)  #Quitamos colores vacíos
        item_local.alive = "??"  #Calidad del link sin verificar
        item_local.action = "play"  #Visualizar vídeo
        item_local.server = "torrent"  #Seridor Torrent

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

    #logger.debug("TORRENT: " + link_torrent + "MAGNET: " + link_magnet + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
    #logger.debug(item_local)

    return itemlist
Exemplo n.º 11
0
def submenu(item):
    logger.info()
    itemlist = []

    try:
        data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "",
                      httptools.downloadpage(item.url).data)
    except:
        logger.error(
            "ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " +
            item.url)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 01: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log'
            ))
        return itemlist  #Algo no funciona, pintamos lo que tenemos

    patron = '<div class="cab_menu">.*?<\/div>'  #Menú principal
    data1 = scrapertools.get_match(data, patron)
    patron = '<div id="menu_langen">.*?<\/div>'  #Menú de idiomas
    data1 += scrapertools.get_match(data, patron)

    patron = '<a href="(.*?)".*?title="(.*?)"'  #Encontrar todos los apartados
    matches = re.compile(patron, re.DOTALL).findall(data1)
    if not matches:
        logger.error(
            "ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " +
            " / PATRON: " + patron + " / DATA: " + data1)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 02: SUBMENU: 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

    for scrapedurl, scrapedtitle in matches:
        scrapedtitle = re.sub('\r\n', '', scrapedtitle).decode('utf8').strip()
        scrapedtitle = scrapedtitle.replace(" torrent", "").replace(
            " Torrent", "").replace("Series y ", "").title()

        if "castellano" in scrapedtitle.lower(
        ):  #Evita la entrada de peliculas castellano del menú de idiomas
            continue

        if item.extra == "series":  #Tratamos Series
            if not "/serie" in scrapedurl:
                continue
        else:  #Tratamos Películas
            if "/serie" in scrapedurl:
                continue

        itemlist.append(
            item.clone(action="listado", title=scrapedtitle, url=scrapedurl))

    if item.extra == "series":  #Añadimos Series VOSE que está fuera del menú principal
        itemlist.append(
            item.clone(action="listado",
                       title="Series VOSE",
                       url=host + "/series-vose/"))

    return itemlist
Exemplo n.º 12
0
def listado(item):
    logger.info()
    itemlist = []

    # Descarga la página
    try:
        data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "",
                      httptools.downloadpage(item.url).data)
    except:
        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
    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'
            ))
        return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

    patron = '<div id="principal">.*?<\/nav><\/div><\/div>'
    data = scrapertools.find_single_match(data, patron)

    patron = '<li>.*?<a href="(.*?)".*?'  #url
    patron += 'title="(.*?)".*?'  #título
    patron += 'src="(.*?)".*?'  #thumb
    patron += "title='(.*?)'.*?"  #categoría, idioma
    patron += '"><i>(.*?)<\/i><\/span.*?'  #calidad
    patron += '="dig1">(.*?)<.*?'  #tamaño
    patron += '="dig2">(.*?)<\/span><\/div>'  #tipo tamaño

    matches = re.compile(patron, re.DOTALL).findall(data)
    if not matches and not '<title>503 Backend fetch failed</title>' in data:  #error
        logger.error(
            "ERROR 02: LISTADO: Ha cambiado la estructura de la Web " +
            " / PATRON: " + patron + " / DATA: " + data)
        itemlist.append(
            item.clone(
                action='',
                title=item.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, scrapedtitle, scrapedthumbnail, scrapedcategory, scrapedcalidad, scrapedsize, scrapedsizet in matches:
        item_local = item.clone()  #Creamos copia de Item para trabajar

        title = re.sub('\r\n', '', scrapedtitle).decode('utf8').strip()
        title = title.replace(" torrent",
                              "").replace(" Torrent",
                                          "").replace("Series y ", "")
        item_local.url = urlparse.urljoin(host, scrapedurl)
        item_local.thumbnail = urlparse.urljoin(host, scrapedthumbnail)

        if "---" in scrapedcalidad:  #limpiamos calidades
            scrapedcalidad = ''
        if "microhd" in title.lower():
            item_local.quality = "microHD"
        if not "/series-vose/" in item.url and not item_local.quality:
            item_local.quality = scrapedcalidad
        if scrapertools.find_single_match(item_local.quality, r'\d+\.\d+'):
            item_local.quality = ''
        if not item_local.quality and (
                "DVDRip" in title or "HDRip" in title or "BR-LINE" in title
                or "HDTS-SCREENER" in title or "BDRip" in title
                or "BR-Screener" in title or "DVDScreener" in title
                or "TS-Screener" in title):
            item_local.quality = scrapertools.find_single_match(
                title, r'\((.*?)\)')
            item_local.quality = item_local.quality.replace("Latino", "")
        if not scrapedsizet:
            scrapedsize = ''
        else:
            item_local.quality += ' [%s %s]' % (scrapedsize.replace(
                ".", ","), scrapedsizet)

        item_local.language = [
        ]  #Verificamos el idioma por si encontramos algo
        if "latino" in scrapedcategory.lower(
        ) or "latino" in item.url or "latino" in title.lower():
            item_local.language += ["LAT"]
        if "ingles" in scrapedcategory.lower(
        ) or "ingles" in item.url or "vose" in scrapedurl or "vose" in item.url:
            if "VOSE" in scrapedcategory.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 scrapedcategory.lower() or "dual" in title.lower():
            item_local.language[0:0] = ["DUAL"]

        #Limpiamos el título de la basuna 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()

        if item_local.extra == "peliculas":  #preparamos Item para películas
            if "/serie" in scrapedurl or "/serie" in item.url:
                continue
        if not "/serie" in scrapedurl and not "/serie" in item.url:
            item_local.contentType = "movie"
            item_local.contentTitle = title
            item_local.extra = "peliculas"

        if item_local.extra == "series":  #preparamos Item para series
            if not "/serie" in scrapedurl and not "/serie" in item.url:
                continue
        if "/serie" in scrapedurl or "/serie" in item.url:
            item_local.contentType = "episode"
            item_local.extra = "series"
            epi_mult = scrapertools.find_single_match(item_local.url,
                                                      r'cap.*?-\d+-al-(\d+)')
            item_local.contentSeason = scrapertools.find_single_match(
                item_local.url, r'temp.*?-(\d+)')
            item_local.contentEpisodeNumber = scrapertools.find_single_match(
                item_local.url, r'cap.*?-(\d+)')
            if not item_local.contentSeason:
                item_local.contentSeason = scrapertools.find_single_match(
                    item_local.url, r'-(\d+)[x|X]\d+')
            if not item_local.contentEpisodeNumber:
                item_local.contentEpisodeNumber = scrapertools.find_single_match(
                    item_local.url, r'-\d+[x|X](\d+)')
            if item_local.contentSeason < 1:
                item_local.contentSeason = 1
            if item_local.contentEpisodeNumber < 1:
                item_local.contentEpisodeNumber = 1
            item_local.contentSerieName = title
            if epi_mult:
                title = "%sx%s al %s -" % (
                    item_local.contentSeason,
                    str(item_local.contentEpisodeNumber).zfill(2),
                    str(epi_mult).zfill(2)
                )  #Creamos un título con el rango de episodios
            else:
                title = '%sx%s ' % (
                    str(item_local.contentSeason),
                    str(item_local.contentEpisodeNumber).zfill(2))

        item_local.action = "findvideos"
        item_local.title = title.strip()
        item_local.infoLabels['year'] = "-"

        #Pasamos a TMDB cada Item, para evitar el efecto memoria de tmdb
        if item.category:  #Si este campo no existe es que viene de la primera pasada de una búsqueda global, pasamos
            tmdb.set_infoLabels(item_local, True)

        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 = '<div class="paginacion">.*?<span class="pagina pag_actual".*?'
    patron += "<a href='([^']+)'.*?"  #url siguiente página
    patron += 'class="pagina">(\d+)<'  #próxima página
    matches = scrapertools.find_single_match(data, patron)

    patron = 'class="pagina pag_sig">Siguiente.*?'
    patron += "<a href='.*?\/page\/(\d+)\/"  #total de páginas
    last_page = scrapertools.find_single_match(data, patron)
    if not last_page:
        patron = '<div class="paginacion">.*?'
        patron += 'class="pagina">(\d+)<\/a><\/div><\/nav><\/div><\/div>'  #total de páginas
        last_page = scrapertools.find_single_match(data, patron)

    if matches:
        scrapedurl = urlparse.urljoin(item.url, matches[0])
        if last_page:
            title = '[COLOR gold]Página siguiente >>[/COLOR] %s de %s' % (
                int(matches[1]) - 1, last_page)
        else:
            title = '[COLOR gold]Página siguiente >>[/COLOR] %s' % (
                int(matches[1]) - 1)

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

    return itemlist
Exemplo n.º 13
0
def get_server_parameters(server):
    """
    Obtiene los datos del servidor
    @param server: Nombre del servidor
    @type server: str

    @return: datos del servidor
    @rtype: dict
    """
    # logger.info("server %s" % server)
    global dict_servers_parameters
    server = server.split('.')[0]
    if not server:
        return {}

    if server not in dict_servers_parameters:
        try:
            # Servers
            if os.path.isfile(os.path.join(config.get_runtime_path(), "servers", server + ".json")):
                path = os.path.join(config.get_runtime_path(), "servers", server + ".json")

            # Debriders
            elif os.path.isfile(os.path.join(config.get_runtime_path(), "servers", "debriders", server + ".json")):
                path = os.path.join(config.get_runtime_path(), "servers", "debriders", server + ".json")

            import filetools
            data = filetools.read(path)
            dict_server = jsontools.load(data)

            # Imagenes: se admiten url y archivos locales dentro de "resources/images"
            if dict_server.get("thumbnail") and "://" not in dict_server["thumbnail"]:
                dict_server["thumbnail"] = os.path.join(config.get_runtime_path(), "resources", "media",
                                                        "servers", dict_server["thumbnail"])
            for k in ['premium', 'id']:
                dict_server[k] = dict_server.get(k, list())

                if type(dict_server[k]) == str:
                    dict_server[k] = [dict_server[k]]

                    # if not dict_server.has_key(k) or dict_server[k] == "":
                    #     dict_server[k] = []
                    # elif type(dict_server[k]) == dict:
                    #     dict_server[k] = dict_server[k]["value"]
                    # if type(dict_server[k]) == str:
                    #     dict_server[k] = [dict_server[k]]

            if "find_videos" in dict_server:
                dict_server['find_videos']["patterns"] = dict_server['find_videos'].get("patterns", list())
                dict_server['find_videos']["ignore_urls"] = dict_server['find_videos'].get("ignore_urls", list())

            if "settings" in dict_server:
                dict_server['has_settings'] = True
            else:
                dict_server['has_settings'] = False

            dict_servers_parameters[server] = dict_server

        except:
            mensaje = "Error al cargar el servidor: %s\n" % server
            import traceback
            logger.error(mensaje + traceback.format_exc())
            return {}

    return dict_servers_parameters[server]
Exemplo n.º 14
0
def do_search(item, categories=None):
    logger.info("blaa categorias %s" % categories)

    if categories is None:
        categories = []

    multithread = config.get_setting("multithread", "search")
    result_mode = config.get_setting("result_mode", "search")

    tecleado = item.extra

    itemlist = []

    channels_path = os.path.join(config.get_runtime_path(), "channels",
                                 '*.json')
    logger.info("channels_path=%s" % channels_path)

    channel_language = config.get_setting("channel_language")
    logger.info("channel_language=%s" % channel_language)
    if channel_language == "":
        channel_language = "all"
        logger.info("channel_language=%s" % channel_language)

    # Para Kodi es necesario esperar antes de cargar el progreso, de lo contrario
    # el cuadro de progreso queda "detras" del cuadro "cargando..." y no se le puede dar a cancelar
    time.sleep(0.5)
    progreso = platformtools.dialog_progress("Buscando '%s'..." % tecleado, "")
    channel_files = sorted(glob.glob(channels_path),
                           key=lambda x: os.path.basename(x))

    import math
    # fix float porque la division se hace mal en python 2.x
    number_of_channels = float(100) / len(channel_files)

    threads = []
    search_results = {}
    start_time = time.time()

    for index, infile in enumerate(channel_files):
        try:
            percentage = int(math.ceil((index + 1) * number_of_channels))

            basename = os.path.basename(infile)
            basename_without_extension = basename[:-5]
            logger.info("%s..." % basename_without_extension)

            channel_parameters = channeltools.get_channel_parameters(
                basename_without_extension)

            # No busca si es un canal inactivo
            if not channel_parameters["active"]:
                logger.info("%s -no activo-" % basename_without_extension)
                continue

            # En caso de búsqueda por categorias
            if categories:

                # Si no se ha seleccionado torrent no se muestra
                if "torrent" not in categories:
                    if "torrent" in channel_parameters["categories"]:
                        logger.info("%s -torrent-" %
                                    basename_without_extension)
                        continue

                for cat in categories:
                    if cat not in channel_parameters["categories"]:
                        logger.info("%s -no en %s-" %
                                    (basename_without_extension, cat))
                        continue

            # No busca si es un canal para adultos, y el modo adulto está desactivado
            if channel_parameters["adult"] and config.get_setting(
                    "adult_mode") == 0:
                logger.info("%s -adulto-" % basename_without_extension)
                continue

            # No busca si el canal es en un idioma filtrado
            if channel_language != "all" and channel_parameters[
                    "language"] != channel_language:
                logger.info("%s -idioma no válido-" %
                            basename_without_extension)
                continue

            # No busca si es un canal excluido de la búsqueda global
            include_in_global_search = channel_parameters[
                "include_in_global_search"]
            if include_in_global_search:
                # Buscar en la configuracion del canal
                include_in_global_search = config.get_setting(
                    "include_in_global_search", basename_without_extension)

            if not include_in_global_search:
                logger.info("%s -no incluido en lista a buscar-" %
                            basename_without_extension)
                continue

            if progreso.iscanceled():
                progreso.close()
                logger.info("Búsqueda cancelada")
                return itemlist

            # Modo Multi Thread
            if multithread:
                t = Thread(target=channel_search,
                           args=[search_results, channel_parameters, tecleado],
                           name=channel_parameters["title"])
                t.setDaemon(True)
                t.start()
                threads.append(t)

            # Modo single Thread
            else:
                logger.info("Intentado búsqueda en %s de %s " %
                            (basename_without_extension, tecleado))
                channel_search(search_results, channel_parameters, tecleado)

            logger.info("%s incluido en la búsqueda" %
                        basename_without_extension)
            progreso.update(percentage,
                            "Buscando en %s..." % channel_parameters["title"])

        except:
            logger.error("No se puede buscar en: %s" %
                         channel_parameters["title"])
            import traceback
            logger.error(traceback.format_exc())
            continue

    # Modo Multi Thread
    # Usando isAlive() no es necesario try-except,
    # ya que esta funcion (a diferencia de is_alive())
    # es compatible tanto con versiones antiguas de python como nuevas
    if multithread:
        pendent = [a for a in threads if a.isAlive()]
        t = float(100) / len(pendent)
        while pendent:
            index = (len(threads) - len(pendent)) + 1
            percentage = int(math.ceil(index * t))

            list_pendent_names = [a.getName() for a in pendent]
            mensaje = "Buscando en %s" % (", ".join(list_pendent_names))
            progreso.update(
                percentage, "Finalizado en %d/%d canales..." %
                (len(threads) - len(pendent), len(threads)), mensaje)
            logger.debug(mensaje)

            if progreso.iscanceled():
                logger.info("Búsqueda cancelada")
                break

            time.sleep(0.5)
            pendent = [a for a in threads if a.isAlive()]

    total = 0

    for channel in sorted(search_results.keys()):
        for element in search_results[channel]:
            total += len(element["itemlist"])
            title = channel

            # resultados agrupados por canales
            if result_mode == 0:
                if len(search_results[channel]) > 1:
                    title += " [%s]" % element["item"].title.strip()
                title += " (%s)" % len(element["itemlist"])

                title = re.sub("\[COLOR [^\]]+\]", "", title)
                title = re.sub("\[/COLOR]", "", title)

                itemlist.append(
                    Item(title=title,
                         channel="search",
                         action="show_result",
                         url=element["item"].url,
                         extra=element["item"].extra,
                         folder=True,
                         adult=element["adult"],
                         from_action="search",
                         from_channel=element["item"].channel,
                         tecleado=tecleado))
            # todos los resultados juntos, en la misma lista
            else:
                title = " [ Resultados del canal %s ] " % channel
                itemlist.append(
                    Item(title=title,
                         channel="search",
                         action="",
                         folder=False,
                         text_bold=True))
                for i in element["itemlist"]:
                    if i.action:
                        title = "    " + i.title
                        itemlist.append(
                            i.clone(title=title,
                                    from_action=i.action,
                                    from_channel=i.channel,
                                    channel="search",
                                    action="show_result",
                                    adult=element["adult"]))

    title = "Buscando: '%s' | Encontrado: %d vídeos | Tiempo: %2.f segundos" % (
        tecleado, total, time.time() - start_time)
    itemlist.insert(0, Item(title=title, text_color='yellow'))

    progreso.close()

    return itemlist
Exemplo n.º 15
0
def add_tvshow(item, channel=None):
    """
        Guarda contenido en la libreria de series. Este contenido puede ser uno de estos dos:
            - La serie con todos los capitulos incluidos en la lista episodelist.
            - Un solo capitulo descargado previamente en local.

        Para añadir episodios descargados en local, el item debe tener exclusivamente:
            - contentSerieName (o show): Titulo de la serie
            - contentTitle: titulo del episodio para extraer season_and_episode ("1x01 Piloto")
            - title: titulo a mostrar junto al listado de enlaces -findvideos- ("Reproducir video local")
            - infoLabels["tmdb_id"] o infoLabels["imdb_id"]
            - contentType != "movie"
            - channel = "downloads"
            - url : ruta local al video

        @type item: item
        @param item: item que representa la serie a guardar
        @type channel: modulo
        @param channel: canal desde el que se guardara la serie.
            Por defecto se importara item.from_channel o item.channel

    """
    logger.info("show=#" + item.show + "#")

    if item.channel == "downloads":
        itemlist = [item.clone()]

    else:
        # Esta marca es porque el item tiene algo más aparte en el atributo "extra"
        item.action = item.extra
        if isinstance(item.extra, str) and "###" in item.extra:
            item.action = item.extra.split("###")[0]
            item.extra = item.extra.split("###")[1]

        if item.from_action:
            item.__dict__["action"] = item.__dict__.pop("from_action")
        if item.from_channel:
            item.__dict__["channel"] = item.__dict__.pop("from_channel")

        if not channel:
            try:
                channel = __import__('channels.%s' % item.channel,
                                     fromlist=["channels.%s" % item.channel])
            except ImportError:
                exec "import channels." + item.channel + " as channel"

        #Para desambiguar títulos, se provoca que TMDB pregunte por el título realmente deseado
        #El usuario puede seleccionar el título entre los ofrecidos en la primera pantalla
        #o puede cancelar e introducir un nuevo título en la segunda pantalla
        #Si lo hace en "Introducir otro nombre", TMDB buscará automáticamente el nuevo título
        #Si lo hace en "Completar Información", cambia parcialmente al nuevo título, pero no busca en TMDB.  Hay que hacerlo
        #Si se cancela la segunda pantalla, la variable "scraper_return" estará en False.  El usuario no quiere seguir

        item = generictools.update_title(
            item
        )  #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels
        #if item.tmdb_stat:
        #    del item.tmdb_stat          #Limpiamos el status para que no se grabe en la Videoteca

        # Obtiene el listado de episodios
        itemlist = getattr(channel, item.action)(item)

    global magnet_caching
    magnet_caching = False
    insertados, sobreescritos, fallidos, path = save_tvshow(item, itemlist)

    if not insertados and not sobreescritos and not fallidos:
        platformtools.dialog_ok(config.get_localized_string(30131),
                                config.get_localized_string(60067))
        logger.error(
            "La serie %s no se ha podido añadir a la videoteca. No se ha podido obtener ningun episodio"
            % item.show)

    elif fallidos == -1:
        platformtools.dialog_ok(config.get_localized_string(30131),
                                config.get_localized_string(60068))
        logger.error("La serie %s no se ha podido añadir a la videoteca" %
                     item.show)

    elif fallidos > 0:
        platformtools.dialog_ok(config.get_localized_string(30131),
                                config.get_localized_string(60069))
        logger.error(
            "No se han podido añadir %s episodios de la serie %s a la videoteca"
            % (fallidos, item.show))

    else:
        platformtools.dialog_ok(config.get_localized_string(30131),
                                config.get_localized_string(60070))
        logger.info(
            "Se han añadido %s episodios de la serie %s a la videoteca" %
            (insertados, item.show))
        if config.is_xbmc():
            if config.get_setting("sync_trakt_new_tvshow", "videolibrary"):
                import xbmc
                from platformcode import xbmc_videolibrary
                if config.get_setting("sync_trakt_new_tvshow_wait",
                                      "videolibrary"):
                    # Comprobar que no se esta buscando contenido en la videoteca de Kodi
                    while xbmc.getCondVisibility('Library.IsScanningVideo()'):
                        xbmc.sleep(1000)
                # Se lanza la sincronizacion para la videoteca de Kodi
                xbmc_videolibrary.sync_trakt_kodi()
                # Se lanza la sincronización para la videoteca del addon
                xbmc_videolibrary.sync_trakt_addon(path)
Exemplo n.º 16
0
def findvideos(item):
    logger.info()
    itemlist = []
    itemlist_t = []  #Itemlist total de enlaces
    itemlist_f = []  #Itemlist de enlaces filtrados
    if not item.language:
        item.language = ['CAST']  #Castellano por defecto

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

    if not data:
        logger.error(
            "ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " +
            item.url + " / DATA: " + data)
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 01: FINDVIDEOS:.  La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log',
                folder=False))
        if item.emergency_urls and not item.videolibray_emergency_urls:  #Hay urls de emergencia?
            link_torrent = item.emergency_urls[0][
                0]  #Guardamos la url del .Torrent
            link_magnet = item.emergency_urls[1][
                0]  #Guardamos la url del .Magnet
            item.armagedon = True  #Marcamos la situación como catastrófica
        else:
            if item.videolibray_emergency_urls:  #Si es llamado desde creación de Videoteca...
                return item  #Devolvemos el Item de la llamada
            else:
                return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos
    #data = unicode(data, "utf-8", errors="replace")

    patron_t = '<div class="enlace_descarga".*?<a href="(.*?\.torrent)"'
    patron_m = '<div class="enlace_descarga".*?<a href="(magnet:?.*?)"'
    if not item.armagedon:  #Si es un proceso normal, seguimos
        link_torrent = scrapertools.find_single_match(data, patron_t)
        link_torrent = urlparse.urljoin(item.url, link_torrent)
        link_torrent = link_torrent.replace(
            " ", "%20")  #sustituimos espacios por %20, por si acaso
        #logger.info("link Torrent: " + link_torrent)

        link_magnet = scrapertools.find_single_match(data, patron_m)
        link_magnet = urlparse.urljoin(item.url, link_magnet)
        #logger.info("link Magnet: " + link_magnet)

    #Si es un lookup para cargar las urls de emergencia en la Videoteca...
    if (link_torrent or link_magnet) and item.videolibray_emergency_urls:
        item.emergency_urls = []
        item.emergency_urls.append([link_torrent
                                    ])  #Salvamos el enlace de .torrent
        item.emergency_urls.append([link_magnet
                                    ])  #Salvamos el enlace de .magnet
        return item  #... y nos vamos

    #Añadimos el tamaño para todos
    size = scrapertools.find_single_match(item.quality,
                                          '\s\[(\d+,?\d*?\s\w\s*[b|B]s*)\]')
    if size:
        item.title = re.sub('\s\[\d+,?\d*?\s\w\s*[b|B]s*\]', '',
                            item.title)  #Quitamos size de título, si lo traía
        item.quality = re.sub(
            '\s\[\d+,?\d*?\s\w\s*[b|B]s*\]', '',
            item.quality)  #Quitamos size de calidad, si lo traía

    if not link_torrent and not link_magnet:  #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_findvideos(
                item, itemlist)  #Llamamos al método para el pintado del error
        else:
            logger.error(
                "ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web "
                + " / PATRON: " + patron_t + " / " + patron_m + " / DATA: " +
                data)
            itemlist.append(
                item.clone(
                    action='',
                    title=item.channel.capitalize() +
                    ': ERROR 02: FINDVIDEOS: El archivo Torrent no existe o ha cambiado la estructura de la Web.  Verificar en la Web y reportar el error con el log',
                    folder=False))
        if item.emergency_urls and not item.videolibray_emergency_urls:  #Hay urls de emergencia?
            link_torrent = item.emergency_urls[0][
                0]  #Guardamos la url del .Torrent
            link_magnet = item.emergency_urls[1][
                0]  #Guardamos la url del .Magnet
            item.armagedon = True  #Marcamos la situación como catastrófica
        else:
            if item.videolibray_emergency_urls:  #Si es llamado desde creación de Videoteca...
                return item  #Devolvemos el Item de la llamada
            else:
                return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

    #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
    item, itemlist = generictools.post_tmdb_findvideos(item, itemlist)

    if not size and not item.armagedon:
        size = generictools.get_torrent_size(
            link_torrent)  #Buscamos el tamaño en el .torrent
    if size:
        size = size.replace('GB', 'G·B').replace('Gb', 'G·b').replace('MB', 'M·B')\
                        .replace('Mb', 'M·b').replace('.', ',')

    #Ahora pintamos el link del Torrent, si lo hay
    if link_torrent:  # Hay Torrent ?
        #Generamos una copia de Item para trabajar sobre ella
        item_local = item.clone()

        item_local.torrent_info = "[Torrent] "
        item_local.torrent_info += '%s' % size  #Agregamos size
        if not item.unify:
            item_local.torrent_info = '[%s]' % item_local.torrent_info.strip(
            ).strip(',')
        if item.armagedon:  #Si es catastrófico, lo marcamos
            item_local.quality = '[/COLOR][COLOR hotpink][E] [COLOR limegreen]%s' % item_local.quality
        item_local.url = link_torrent
        if item_local.url and item.emergency_urls and not item.armagedon:
            item_local.torrent_alt = item.emergency_urls[0][
                0]  #Guardamos la url del .Torrent ALTERNATIVA

        item_local.title = '[[COLOR yellow]?[/COLOR]] [COLOR yellow][Torrent][/COLOR] ' \
                        + '[COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] %s' % \
                        (item_local.quality, str(item_local.language),  \
                        item_local.torrent_info)                                #Preparamos título de Torrent

        #Preparamos título y calidad, quitamos etiquetas vacías
        item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]',
                                  '', item_local.title)
        item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '',
                                  item_local.title)
        item_local.title = item_local.title.replace("--", "").replace(
            "[]", "").replace("()", "").replace("(/)", "").replace("[/]",
                                                                   "").strip()
        item_local.quality = re.sub(
            r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '',
            item_local.quality)
        item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '',
                                    item_local.quality)
        item_local.quality = item_local.quality.replace("--", "").replace(
            "[]", "").replace("()", "").replace("(/)", "").replace("[/]",
                                                                   "").strip()

        item_local.alive = "??"  #Calidad del link sin verificar
        item_local.action = "play"  #Visualizar vídeo
        item_local.server = "torrent"  #Seridor Torrent

        itemlist_t.append(
            item_local.clone())  #Pintar pantalla, si no se filtran idiomas

        # Requerido para FilterTools
        if config.get_setting(
                'filter_languages',
                channel) > 0:  #Si hay idioma seleccionado, se filtra
            itemlist_f = filtertools.get_link(
                itemlist_f, item_local,
                list_language)  #Pintar pantalla, si no está vacío

        if len(itemlist_f) > 0:  #Si hay entradas filtradas...
            itemlist.extend(itemlist_f)  #Pintamos pantalla filtrada
        else:
            if config.get_setting('filter_languages', channel) > 0 and len(
                    itemlist_t) > 0:  #Si no hay entradas filtradas ...
                thumb_separador = get_thumb(
                    "next.png")  #... pintamos todo con aviso
                itemlist.append(
                    Item(
                        channel=item.channel,
                        url=host,
                        title=
                        "[COLOR red][B]NO hay elementos con el idioma seleccionado[/B][/COLOR]",
                        thumbnail=thumb_separador,
                        folder=False))
            itemlist.extend(
                itemlist_t)  #Pintar pantalla con todo si no hay filtrado

    #Ahora pintamos el link del Magnet, si lo hay
    itemlist_t = []  #Itemlist total de enlaces
    itemlist_f = []  #Itemlist de enlaces filtrados
    if link_magnet:  # Hay Magnet ?
        #Generamos una copia de Item para trabajar sobre ella
        item_local = item.clone()

        item_local.torrent_info = "[Magnet] "
        item_local.torrent_info += '%s' % size  #Agregamos size
        if not item.unify:
            item_local.torrent_info = '[%s]' % item_local.torrent_info.strip(
            ).strip(',')
        if item.armagedon:  #Si es catastrófico, lo marcamos
            item_local.quality = '[/COLOR][COLOR hotpink][E] [COLOR limegreen]%s' % item_local.quality
        item_local.url = link_magnet

        item_local.title = '[[COLOR yellow]?[/COLOR]] [COLOR yellow][Torrent][/COLOR] ' \
                        + '[COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] %s' % \
                        (item_local.quality, str(item_local.language),  \
                        item_local.torrent_info)                                #Preparamos título de Magnet

        item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '',
                                  item_local.title)  #Quitamos etiquetas vacías
        item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '',
                                  item_local.title)  #Quitamos colores vacíos
        item_local.alive = "??"  #Calidad del link sin verificar
        item_local.action = "play"  #Visualizar vídeo
        item_local.server = "torrent"  #Seridor Torrent

        itemlist_t.append(
            item_local.clone())  #Pintar pantalla, si no se filtran idiomas

        # Requerido para FilterTools
        if config.get_setting(
                'filter_languages',
                channel) > 0:  #Si hay idioma seleccionado, se filtra
            itemlist_f = filtertools.get_link(
                itemlist_f, item_local,
                list_language)  #Pintar pantalla, si no está vacío

        if len(itemlist_f) > 0:  #Si hay entradas filtradas...
            itemlist.extend(itemlist_f)  #Pintamos pantalla filtrada
        else:
            if config.get_setting('filter_languages', channel) > 0 and len(
                    itemlist_t) > 0:  #Si no hay entradas filtradas ...
                thumb_separador = get_thumb(
                    "next.png")  #... pintamos todo con aviso
                itemlist.append(
                    Item(
                        channel=item.channel,
                        url=host,
                        title=
                        "[COLOR red][B]NO hay elementos con el idioma seleccionado[/B][/COLOR]",
                        thumbnail=thumb_separador,
                        folder=False))
            itemlist.extend(
                itemlist_t)  #Pintar pantalla con todo si no hay filtrado

    #logger.debug("TORRENT: " + link_torrent + "MAGNET: " + link_magnet + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / tamaño: " + size + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)
    #logger.debug(item_local)

    # Requerido para AutoPlay
    autoplay.start(itemlist, item)  #Lanzamos Autoplay

    return itemlist
Exemplo n.º 17
0
def emergency_urls(item, channel=None, path=None, headers={}):
    logger.info()
    import re
    from servers import torrent
    try:
        magnet_caching_e = magnet_caching
    except:
        magnet_caching_e = True
    """ 
    Llamamos a Findvideos del canal con la variable "item.videolibray_emergency_urls = True" para obtener la variable
    "item.emergency_urls" con la lista de listas de tuplas de los enlaces torrent y de servidores directos para ese episodio o película
    En la lista [0] siempre deben ir los enlaces torrents, si los hay.  Si se desea cachear los .torrents, la búsqueda va contra esa lista.
    En la lista dos irán los enlaces de servidores directos, pero también pueden ir enlaces magnet (que no son cacheables)
    """
    #lanazamos un "lookup" en el "findvideos" del canal para obtener los enlaces de emergencia
    try:
        if channel == None:  #Si el llamador no ha aportado la estructura de channel, se crea
            channel = generictools.verify_channel(
                item.channel
            )  #Se verifica si es un clon, que devuelva "newpct1"
            channel = __import__('channels.%s' % channel,
                                 fromlist=["channels.%s" % channel])
        if hasattr(channel, 'findvideos'):  #Si el canal tiene "findvideos"...
            item.videolibray_emergency_urls = True  #... se marca como "lookup"
            channel_save = item.channel  #... guarda el canal original por si hay fail-over en Newpct1
            category_save = item.category  #... guarda la categoría original por si hay fail-over o redirección en Newpct1
            if item.channel_redir:  #... si hay un redir, se restaura temporamente el canal alternativo
                item.channel = scrapertools.find_single_match(
                    item.url, 'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').lower()
                item.category = scrapertools.find_single_match(
                    item.url,
                    'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').capitalize()
            item_res = getattr(channel,
                               'findvideos')(item)  #... se procesa Findvideos
            item_res.channel = channel_save  #... restaura el canal original por si hay fail-over en Newpct1
            item_res.category = category_save  #... restaura la categoría original por si hay fail-over o redirección en Newpct1
            item.category = category_save  #... restaura la categoría original por si hay fail-over o redirección en Newpct1
            del item_res.videolibray_emergency_urls  #... y se borra la marca de lookup
            if item.videolibray_emergency_urls:
                del item.videolibray_emergency_urls  #... y se borra la marca de lookup original
    except:
        logger.error('ERROR al procesar el título en Findvideos del Canal: ' +
                     item.channel + ' / ' + item.title)
        logger.error(traceback.format_exc())
        item.channel = channel_save  #... restaura el canal original por si hay fail-over o redirección en Newpct1
        item.category = category_save  #... restaura la categoría original por si hay fail-over o redirección en Newpct1
        item_res = item.clone(
        )  #Si ha habido un error, se devuelve el Item original
        if item_res.videolibray_emergency_urls:
            del item_res.videolibray_emergency_urls  #... y se borra la marca de lookup
        if item.videolibray_emergency_urls:
            del item.videolibray_emergency_urls  #... y se borra la marca de lookup original

    #Si el usuario ha activado la opción "emergency_urls_torrents", se descargarán los archivos .torrent de cada título
    else:  #Si se han cacheado con éxito los enlaces...
        try:
            referer = None
            post = None
            channel_bis = generictools.verify_channel(item.channel)
            if config.get_setting(
                    "emergency_urls_torrents",
                    channel_bis) and item_res.emergency_urls and path != None:
                videolibrary_path = config.get_videolibrary_path(
                )  #detectamos el path absoluto del título
                movies = config.get_setting("folder_movies")
                series = config.get_setting("folder_tvshows")
                if movies in path:
                    folder = movies
                else:
                    folder = series
                videolibrary_path = filetools.join(videolibrary_path, folder)
                i = 1
                if item_res.referer: referer = item_res.referer
                if item_res.post: post = item_res.post
                for url in item_res.emergency_urls[
                        0]:  #Recorremos las urls de emergencia...
                    torrents_path = re.sub(r'(?:\.\w+$)',
                                           '_%s.torrent' % str(i).zfill(2),
                                           path)
                    path_real = ''
                    if magnet_caching_e or not url.startswith('magnet'):
                        path_real = torrent.caching_torrents(
                            url,
                            referer,
                            post,
                            torrents_path=torrents_path,
                            headers=headers
                        )  #...  para descargar los .torrents
                    if path_real:  #Si ha tenido éxito...
                        item_res.emergency_urls[0][i - 1] = path_real.replace(
                            videolibrary_path,
                            '')  #se guarda el "path" relativo
                    i += 1

                #Restauramos variables originales
                if item.referer:
                    item_res.referer = item.referer
                elif item_res.referer:
                    del item_res.referer
                if item.referer:
                    item_res.referer = item.referer
                elif item_res.referer:
                    del item_res.referer
                item_res.url = item.url

        except:
            logger.error('ERROR al cachear el .torrent de: ' + item.channel +
                         ' / ' + item.title)
            logger.error(traceback.format_exc())
            item_res = item.clone(
            )  #Si ha habido un error, se devuelve el Item original

    #logger.debug(item_res.emergency_urls)
    return item_res  #Devolvemos el Item actualizado con los enlaces de emergencia
Exemplo n.º 18
0
def get_video_url(page_url,
                  premium=False,
                  user="",
                  password="",
                  video_password=""):
    logger.info("url=" + page_url)
    video_urls = []
    if "crunchyroll.com" in page_url:
        media_id = page_url.rsplit("-", 1)[1]
    else:
        media_id = scrapertools.find_single_match(page_url, 'media_id=(\d+)')
    url = "https://www.crunchyroll.com/xml/?req=RpcApiVideoPlayer_GetStandardConfig&media_id=%s" \
          "&video_format=0&video_quality=0&auto_play=0&aff=af-12299-plwa" % media_id
    post = "current_page=%s" % page_url
    data = httptools.downloadpage(url, post, headers=GLOBAL_HEADER).data
    if "<msg>Media not available</msg>" in data or "flash_block.png" in data:
        data = httptools.downloadpage(proxy + url,
                                      post,
                                      headers=GLOBAL_HEADER,
                                      cookies=False).data
    media_url = scrapertools.find_single_match(data,
                                               '<file>(.*?)</file>').replace(
                                                   "&amp;", "&")
    if not media_url:
        return video_urls
    elif not media_url.startswith("http"):
        rtmp = scrapertools.find_single_match(data,
                                              '<host>(.*?)</host>').replace(
                                                  "&amp;", "&")
        media_url = rtmp + " playpath=%s" % media_url
        filename = "RTMP"
    else:
        filename = scrapertools.get_filename_from_url(media_url)[-4:]
    quality = scrapertools.find_single_match(data, '<height>(.*?)</height>')
    try:
        idiomas = [
            'Español \(España\)', 'Español\]', 'English', 'Italiano',
            'Français', 'Português', 'Deutsch'
        ]
        index_sub = int(config.get_setting("sub", server="crunchyroll"))
        idioma_sub = idiomas[index_sub]
        link_sub = scrapertools.find_single_match(
            data, "link='([^']+)' title='\[%s" % idioma_sub)
        if not link_sub and index_sub == 0:
            link_sub = scrapertools.find_single_match(
                data, "link='([^']+)' title='\[Español\]")
        elif not link_sub and index_sub == 1:
            link_sub = scrapertools.find_single_match(
                data, "link='([^']+)' title='\[Español \(España\)")
        if not link_sub:
            link_sub = scrapertools.find_single_match(
                data, "link='([^']+)' title='\[English")
        data_sub = httptools.downloadpage(link_sub.replace("&amp;", "&"),
                                          headers=GLOBAL_HEADER).data
        id_sub = scrapertools.find_single_match(data_sub,
                                                "subtitle id='([^']+)'")
        iv = scrapertools.find_single_match(data_sub, '<iv>(.*?)</iv>')
        data_sub = scrapertools.find_single_match(data_sub,
                                                  '<data>(.*?)</data>')
        file_sub = decrypt_subs(iv, data_sub, id_sub)
    except:
        import traceback
        logger.error(traceback.format_exc())
        file_sub = ""
    video_urls.append([
        "%s  %sp [crunchyroll]" % (filename, quality), media_url, 0, file_sub
    ])
    for video_url in video_urls:
        logger.info("%s - %s" % (video_url[0], video_url[1]))
    return video_urls
Exemplo n.º 19
0
def check_for_update(overwrite=True):
    logger.info("Actualizando series...")

    p_dialog = None
    serie_actualizada = False
    update_when_finished = False
    hoy = datetime.date.today()
    estado_verify_playcount_series = False
    
    try:
        if config.get_setting("update", "videolibrary") != 0 or overwrite:
            config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "videolibrary")

            heading = config.get_localized_string(60389)
            p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), heading)
            p_dialog.update(0, '')
            show_list = []

            for path, folders, files in filetools.walk(videolibrarytools.TVSHOWS_PATH):
                show_list.extend([filetools.join(path, f) for f in files if f == "tvshow.nfo"])

            if show_list:
                t = float(100) / len(show_list)

            for i, tvshow_file in enumerate(show_list):
                head_nfo, serie = videolibrarytools.read_nfo(tvshow_file)
                path = filetools.dirname(tvshow_file)
                
                ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial
                overwrite_forced = False
                try:
                    serie, serie, overwrite_forced = generictools.redirect_clone_newpct1(serie, head_nfo, serie, path, overwrite, lookup=True)
                except:
                    pass
                if overwrite_forced == True:
                    overwrite = True
                    serie.update_next = ''
                    
                logger.info("serie=" + serie.contentSerieName)
                p_dialog.update(int(math.ceil((i + 1) * t)), heading, serie.contentSerieName)
                
                #Verificamos el estado del serie.library_playcounts de la Serie por si está incompleto
                try:
                    estado = False
                    #Si no hemos hecho la verificación o no tiene playcount, entramos
                    estado = config.get_setting("verify_playcount", "videolibrary")
                    if not estado or estado == False or not serie.library_playcounts:               #Si no se ha pasado antes, lo hacemos ahora
                        serie, estado = videolibrary.verify_playcount_series(serie, path)           #También se pasa si falta un PlayCount por completo
                except:
                    pass
                else:
                    if estado:                                                                      #Si ha tenido éxito la actualización...
                        estado_verify_playcount_series = True                                       #... se marca para cambiar la opción de la Videoteca

                interval = int(serie.active)  # Podria ser del tipo bool

                if not serie.active:
                    # si la serie no esta activa descartar
                    if overwrite_forced == False:
                        #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa, aunque la serie esté desactivada
                        try:
                            if config.is_xbmc():                #Si es Kodi, lo hacemos
                                from platformcode import xbmc_videolibrary
                                xbmc_videolibrary.mark_content_as_watched_on_alfa(path + '/tvshow.nfo')
                        except:
                            pass
                    
                        continue

                # obtenemos las fecha de actualizacion y de la proxima programada para esta serie
                update_next = serie.update_next
                if update_next:
                    y, m, d = update_next.split('-')
                    update_next = datetime.date(int(y), int(m), int(d))
                else:
                    update_next = hoy

                update_last = serie.update_last
                if update_last:
                    y, m, d = update_last.split('-')
                    update_last = datetime.date(int(y), int(m), int(d))
                else:
                    update_last = hoy

                # si la serie esta activa ...
                if overwrite or config.get_setting("updatetvshows_interval", "videolibrary") == 0:
                    # ... forzar actualizacion independientemente del intervalo
                    serie_actualizada = update(path, p_dialog, i, t, serie, overwrite)

                elif interval == 1 and update_next <= hoy:
                    # ...actualizacion diaria
                    serie_actualizada = update(path, p_dialog, i, t, serie, overwrite)
                    if not serie_actualizada and update_last <= hoy - datetime.timedelta(days=7):
                        # si hace una semana q no se actualiza, pasar el intervalo a semanal
                        interval = 7
                        update_next = hoy + datetime.timedelta(days=interval)

                elif interval == 7 and update_next <= hoy:
                    # ...actualizacion semanal
                    serie_actualizada = update(path, p_dialog, i, t, serie, overwrite)
                    if not serie_actualizada:
                        if update_last <= hoy - datetime.timedelta(days=14):
                            # si hace 2 semanas q no se actualiza, pasar el intervalo a mensual
                            interval = 30

                        update_next += datetime.timedelta(days=interval)

                elif interval == 30 and update_next <= hoy:
                    # ...actualizacion mensual
                    serie_actualizada = update(path, p_dialog, i, t, serie, overwrite)
                    if not serie_actualizada:
                        update_next += datetime.timedelta(days=interval)

                head_nfo, serie = videolibrarytools.read_nfo(tvshow_file)                       #Vuelve a leer el.nfo, que ha sido modificado
                if interval != int(serie.active) or update_next.strftime('%Y-%m-%d') != serie.update_next:
                    if update_next > hoy:
                        serie.update_next = update_next.strftime('%Y-%m-%d')
                    serie.active = interval
                    serie.channel = "videolibrary"
                    serie.action = "get_seasons"
                    filetools.write(tvshow_file, head_nfo + serie.tojson())

                if serie_actualizada:
                    if config.get_setting("search_new_content", "videolibrary") == 0:
                        # Actualizamos la videoteca de Kodi: Buscar contenido en la carpeta de la serie
                        if config.is_xbmc():
                            from platformcode import xbmc_videolibrary
                            xbmc_videolibrary.update(folder=filetools.basename(path))
                    else:
                        update_when_finished = True

            if estado_verify_playcount_series:                                                  #Si se ha cambiado algún playcount, ...
                estado = config.set_setting("verify_playcount", True, "videolibrary")           #... actualizamos la opción de Videolibrary
            
            if config.get_setting("search_new_content", "videolibrary") == 1 and update_when_finished:
                # Actualizamos la videoteca de Kodi: Buscar contenido en todas las series
                if config.is_xbmc():
                    from platformcode import xbmc_videolibrary
                    xbmc_videolibrary.update()

            p_dialog.close()

        else:
            logger.info("No actualiza la videoteca, está desactivado en la configuración de alfa")

    except Exception, ex:
        logger.error("Se ha producido un error al actualizar las series")
        template = "An exception of type %s occured. Arguments:\n%r"
        message = template % (type(ex).__name__, ex.args)
        logger.error(message)

        if p_dialog:
            p_dialog.close()
Exemplo n.º 20
0
def findvideos(item):
    logger.info()
    itemlist = []
    data = httptools.downloadpage(item.url).data
    _sa = scrapertools.find_single_match(data, 'var _sa = (true|false);')
    _sl = scrapertools.find_single_match(data, 'var _sl = ([^;]+);')
    sl = eval(_sl)
    buttons = scrapertools.find_multiple_matches(
        data, '<button.*?class="selop" sl="([^"]+)">')
    if not buttons:
        buttons = [0, 1, 2]
    for id in buttons:
        title = '%s'
        new_url = golink(int(id), _sa, sl)
        data_new = httptools.downloadpage(new_url).data
        matches = scrapertools.find_multiple_matches(
            data_new, 'javascript">(.*?)</script>')
        js = ""
        for part in matches:
            js += part
        #logger.info("test before:" + js)

        try:
            matches = scrapertools.find_multiple_matches(
                data_new, '" id="(.*?)" val="(.*?)"')
            for zanga, val in matches:
                js = js.replace(
                    'var %s = document.getElementById("%s");' % (zanga, zanga),
                    "")
                js = js.replace('%s.getAttribute("val")' % zanga, '"%s"' % val)
            #logger.info("test1 after:" +js)
        except:
            pass

        #v1
        js = re.sub('(document\[.*?)=', 'prem=', js)

        #Parcheando a lo bruto v2
        video = scrapertools.find_single_match(js,
                                               "sources: \[\{src:(.*?), type")
        js = re.sub(' videojs\((.*?)\);', video + ";", js)

        from lib import js2py
        js2py.disable_pyimport()
        context = js2py.EvalJs({'atob': atob})

        try:
            result = context.eval(js)
        except:
            logger.error("Js2Py no puede desofuscar el codigo, ¿cambió?")
            continue

        url = scrapertools.find_single_match(result, 'src="(.*?)"')
        #v2
        if not url:
            url = result.strip()

        itemlist.append(
            Item(channel=item.channel,
                 title=title,
                 url=url,
                 action='play',
                 language='latino',
                 infoLabels=item.infoLabels))
    itemlist = servertools.get_servers_itemlist(
        itemlist, lambda i: i.title % i.server.capitalize())
    # Requerido para FilterTools
    itemlist = filtertools.get_links(itemlist, item, list_language)

    # Requerido para AutoPlay

    autoplay.start(itemlist, item)

    return itemlist
Exemplo n.º 21
0
def get_server_parameters(server):
    """
    Obtiene los datos del servidor
    @param server: Nombre del servidor
    @type server: str

    @return: datos del servidor
    @rtype: dict
    """
    global dict_servers_parameters
    server = server.split('.')[0]
    if not server:
        return {}

    if not server in dict_servers_parameters:
        try:
            #Servers
            if os.path.isfile(os.path.join(config.get_runtime_path(),"servers", server + ".xml")):
                JSONFile =  xml2dict(os.path.join(config.get_runtime_path(),"servers", server + ".xml"))["server"]
            #Debriders
            elif os.path.isfile(os.path.join(config.get_runtime_path(),"servers", "debriders", server + ".xml")):
                JSONFile =  xml2dict(os.path.join(config.get_runtime_path(),"servers", "debriders", server + ".xml"))["server"]


            for k in ['premium', 'id']:
                if not JSONFile.has_key(k) or JSONFile[k] == "":
                    JSONFile[k] = []
                elif type(JSONFile[k]) == dict:
                    JSONFile[k] = JSONFile[k]["value"]
                if type(JSONFile[k]) == str:
                    JSONFile[k] = [JSONFile[k]]

            if JSONFile.has_key('find_videos'):
                if type(JSONFile['find_videos']['patterns']) == dict:
                    JSONFile['find_videos']['patterns'] = [JSONFile['find_videos']['patterns']]

                if not JSONFile['find_videos'].get("ignore_urls", ""):
                    JSONFile['find_videos']["ignore_urls"] = []
                elif type(JSONFile['find_videos']["ignore_urls"] == dict):
                    JSONFile['find_videos']["ignore_urls"] = JSONFile['find_videos']["ignore_urls"]["value"]
                if type(JSONFile['find_videos']["ignore_urls"]) == str:
                    JSONFile['find_videos']["ignore_urls"] = [JSONFile['find_videos']["ignore_urls"]]

            if JSONFile.has_key('settings'):
                if type(JSONFile['settings']) == dict:
                    JSONFile['settings'] = [JSONFile['settings']]

                if len(JSONFile['settings']):
                    JSONFile['has_settings'] = True
                else:
                    JSONFile['has_settings'] = False
            else:
                JSONFile['has_settings'] = False

            dict_servers_parameters[server] = JSONFile

        except:
            mensaje = "Error al cargar el servidor: %s\n" % server
            import traceback
            logger.error(mensaje + traceback.format_exc())
            return {}

    return dict_servers_parameters[server]
Exemplo n.º 22
0
def token_trakt(item):
    from platformcode import platformtools

    headers = {
        'Content-Type': 'application/json',
        'trakt-api-key': client_id,
        'trakt-api-version': '2'
    }
    try:
        if item.extra == "renew":
            refresh = config.get_setting("refresh_token_trakt", "trakt")
            url = "http://api-v2launch.trakt.tv/oauth/device/token"
            post = {
                'refresh_token': refresh,
                'client_id': client_id,
                'client_secret': client_secret,
                'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
                'grant_type': 'refresh_token'
            }
            post = jsontools.dump(post)
            data = httptools.downloadpage(url, post=post, headers=headers).data
            data = jsontools.load(data)
        elif item.action == "token_trakt":
            url = "http://api-v2launch.trakt.tv/oauth/device/token"
            post = "code=%s&client_id=%s&client_secret=%s" % (
                item.device_code, client_id, client_secret)
            data = httptools.downloadpage(url, post=post, headers=headers).data
            data = jsontools.load(data)
        else:
            import time
            dialog_auth = platformtools.dialog_progress(
                config.get_localized_string(60251),
                config.get_localized_string(60252) % item.verify_url,
                config.get_localized_string(60253) % item.user_code,
                config.get_localized_string(60254))

            # Generalmente cada 5 segundos se intenta comprobar si el usuario ha introducido el código
            while True:
                time.sleep(item.intervalo)
                try:
                    if dialog_auth.iscanceled():
                        config.set_setting("trakt_sync", False)
                        return

                    url = "http://api-v2launch.trakt.tv/oauth/device/token"
                    post = {
                        'code': item.device_code,
                        'client_id': client_id,
                        'client_secret': client_secret
                    }
                    post = jsontools.dump(post)
                    data = httptools.downloadpage(url,
                                                  post=post,
                                                  headers=headers).data
                    data = jsontools.load(data)
                    if "access_token" in data:
                        # Código introducido, salimos del bucle
                        break
                except:
                    pass

            try:
                dialog_auth.close()
            except:
                pass

        token = data["access_token"]
        refresh = data["refresh_token"]

        config.set_setting("token_trakt", token, "trakt")
        config.set_setting("refresh_token_trakt", refresh, "trakt")
        if not item.folder:
            platformtools.dialog_notification(
                config.get_localized_string(60255),
                config.get_localized_string(60256))
            if config.is_xbmc():
                import xbmc
                xbmc.executebuiltin("Container.Refresh")
            return

    except:
        import traceback
        logger.error(traceback.format_exc())
        if not item.folder:
            return platformtools.dialog_notification(
                config.get_localized_string(60527),
                config.get_localized_string(60258))
        token = ""

    itemlist = []
    if token:
        itemlist.append(
            item.clone(config.get_localized_string(60256), action=""))
    else:
        itemlist.append(
            item.clone(config.get_localized_string(60260), action=""))

    return itemlist
Exemplo n.º 23
0
def update_libtorrent():
    logger.info()

    if not config.get_setting("mct_buffer", server="torrent", default=""):
        default = config.get_setting("torrent_client",
                                     server="torrent",
                                     default=0)
        config.set_setting("torrent_client", default, server="torrent")
        config.set_setting("mct_buffer", "50", server="torrent")
        if config.get_setting("mct_download_path",
                              server="torrent",
                              default=config.get_setting("downloadpath")):
            config.set_setting("mct_download_path",
                               config.get_setting("downloadpath"),
                               server="torrent")
        config.set_setting("mct_background_download", True, server="torrent")
        config.set_setting("mct_rar_unpack", True, server="torrent")
        config.set_setting("bt_buffer", "50", server="torrent")
        if config.get_setting("bt_download_path",
                              server="torrent",
                              default=config.get_setting("downloadpath")):
            config.set_setting("bt_download_path",
                               config.get_setting("downloadpath"),
                               server="torrent")
        config.set_setting("mct_download_limit", "", server="torrent")
        config.set_setting("magnet2torrent", False, server="torrent")

    if not filetools.exists(filetools.join(config.get_runtime_path(), "custom_code.json")) or not \
                    config.get_setting("unrar_path", server="torrent", default=""):

        path = filetools.join(config.get_runtime_path(), 'lib', 'rarfiles')
        creationflags = ''
        sufix = ''
        unrar = ''
        for device in filetools.listdir(path):
            if xbmc.getCondVisibility(
                    "system.platform.android") and 'android' not in device:
                continue
            if xbmc.getCondVisibility(
                    "system.platform.windows") and 'windows' not in device:
                continue
            if not xbmc.getCondVisibility("system.platform.windows") and not  xbmc.getCondVisibility("system.platform.android") \
                        and ('android' in device or 'windows' in device):
                continue
            if 'windows' in device:
                creationflags = 0x08000000
                sufix = '.exe'
            else:
                creationflags = ''
                sufix = ''
            unrar = filetools.join(path, device, 'unrar%s') % sufix
            if not filetools.exists(unrar): unrar = ''
            if unrar:
                if not xbmc.getCondVisibility("system.platform.windows"):
                    try:
                        if xbmc.getCondVisibility("system.platform.android"):
                            # Para Android copiamos el binario a la partición del sistema
                            unrar_org = unrar
                            unrar = filetools.join(
                                xbmc.translatePath('special://xbmc/'),
                                'files').replace('/cache/apk/assets', '')
                            if not filetools.exists(unrar):
                                filetools.mkdir(unrar)
                            unrar = filetools.join(unrar, 'unrar')
                            filetools.copy(unrar_org, unrar, silent=True)

                        command = ['chmod', '777', '%s' % unrar]
                        p = subprocess.Popen(command,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)
                        output_cmd, error_cmd = p.communicate()
                        command = ['ls', '-l', unrar]
                        p = subprocess.Popen(command,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)
                        output_cmd, error_cmd = p.communicate()
                        xbmc.log('######## UnRAR file: %s' % str(output_cmd),
                                 xbmc.LOGNOTICE)
                    except:
                        xbmc.log(
                            '######## UnRAR ERROR in path: %s' % str(unrar),
                            xbmc.LOGNOTICE)
                        logger.error(traceback.format_exc(1))

                try:
                    if xbmc.getCondVisibility("system.platform.windows"):
                        p = subprocess.Popen(unrar,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE,
                                             creationflags=creationflags)
                    else:
                        p = subprocess.Popen(unrar,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)
                    output_cmd, error_cmd = p.communicate()
                    if p.returncode != 0 or error_cmd:
                        xbmc.log('######## UnRAR returncode in module %s: %s, %s in %s' % \
                                (device, str(p.returncode), str(error_cmd), unrar), xbmc.LOGNOTICE)
                        unrar = ''
                    else:
                        xbmc.log(
                            '######## UnRAR OK in %s: %s' % (device, unrar),
                            xbmc.LOGNOTICE)
                        break
                except:
                    xbmc.log(
                        '######## UnRAR ERROR in module %s: %s' %
                        (device, unrar), xbmc.LOGNOTICE)
                    logger.error(traceback.format_exc(1))
                    unrar = ''

        if unrar: config.set_setting("unrar_path", unrar, server="torrent")

    if filetools.exists(filetools.join(config.get_runtime_path(), "custom_code.json")) and \
                    config.get_setting("libtorrent_path", server="torrent", default="") :
        return

    try:
        from lib.python_libtorrent.python_libtorrent import get_libtorrent
    except Exception as e:
        logger.error(traceback.format_exc(1))
        if not PY3:
            e = unicode(str(e), "utf8", errors="replace").encode("utf8")
        config.set_setting("libtorrent_path", "", server="torrent")
        if not config.get_setting(
                "libtorrent_error", server="torrent", default=''):
            config.set_setting("libtorrent_error", str(e), server="torrent")

    return
Exemplo n.º 24
0
def save_tvshow(item, episodelist):
    """
    guarda en la libreria de series la serie con todos los capitulos incluidos en la lista episodelist
    @type item: item
    @param item: item que representa la serie a guardar
    @type episodelist: list
    @param episodelist: listado de items que representan los episodios que se van a guardar.
    @rtype insertados: int
    @return:  el número de episodios insertados
    @rtype sobreescritos: int
    @return:  el número de episodios sobreescritos
    @rtype fallidos: int
    @return:  el número de episodios fallidos o -1 si ha fallado toda la serie
    @rtype path: str
    @return:  directorio serie
    """
    logger.info()
    # logger.debug(item.tostring('\n'))
    path = ""

    # Si llegados a este punto no tenemos titulo o code, salimos
    if not (item.contentSerieName
            or item.infoLabels['code']) or not item.channel:
        logger.error("NO ENCONTRADO contentSerieName NI code: " + item.url)
        return 0, 0, -1, path  # Salimos sin guardar

    scraper_return = scraper.find_and_set_infoLabels(item)
    # Llegados a este punto podemos tener:
    #  scraper_return = True: Un item con infoLabels con la información actualizada de la serie
    #  scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana)
    #  item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos
    if not scraper_return or not item.infoLabels['code']:
        # TODO de momento si no hay resultado no añadimos nada,
        # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano
        logger.error("NO ENCONTRADO EN SCRAPER O NO TIENE code: " + item.url)
        return 0, 0, -1, path

    _id = item.infoLabels['code'][0]
    if not item.infoLabels['code'][0] or item.infoLabels['code'][0] == 'None':
        if item.infoLabels['code'][1] and item.infoLabels['code'][1] != 'None':
            _id = item.infoLabels['code'][1]
        elif item.infoLabels['code'][
                2] and item.infoLabels['code'][2] != 'None':
            _id = item.infoLabels['code'][2]
        else:
            logger.error("NO ENCONTRADO EN SCRAPER O NO TIENE code: " +
                         item.url + ' / ' + item.infoLabels['code'])
            return 0, 0, -1, path

    if config.get_setting(
            "original_title_folder",
            "videolibrary") == 1 and item.infoLabels['originaltitle']:
        base_name = item.infoLabels['originaltitle']
    elif item.infoLabels['tvshowtitle']:
        base_name = item.infoLabels['tvshowtitle']
    elif item.infoLabels['title']:
        base_name = item.infoLabels['title']
    else:
        base_name = item.contentSerieName

    base_name = unicode(filetools.validate_path(base_name.replace('/', '-')),
                        "utf8").encode("utf8")

    if config.get_setting("lowerize_title", "videolibrary") == 0:
        base_name = base_name.lower()

    for raiz, subcarpetas, ficheros in filetools.walk(TVSHOWS_PATH):
        for c in subcarpetas:
            code = scrapertools.find_single_match(c, '\[(.*?)\]')
            if code and code != 'None' and code in item.infoLabels['code']:
                path = filetools.join(raiz, c)
                _id = code
                break

    if not path:
        path = filetools.join(TVSHOWS_PATH,
                              ("%s [%s]" % (base_name, _id)).strip())
        logger.info("Creando directorio serie: " + path)
        try:
            filetools.mkdir(path)
        except OSError, exception:
            if exception.errno != errno.EEXIST:
                raise
Exemplo n.º 25
0
def verify_Kodi_video_DB():
    logger.info()
    import random

    platform = {}
    path = ''
    db_files = []

    try:
        path = filetools.join(xbmc.translatePath("special://masterprofile/"),
                              "Database")
        if filetools.exists(path):
            platform = config.get_platform(full_version=True)
            if platform and platform['num_version'] <= 19:
                db_files = filetools.walk(path)
                if filetools.exists(filetools.join(path,
                                                   platform['video_db'])):
                    for root, folders, files in db_files:
                        for file in files:
                            if platform['video_db'] not in file:
                                if file.startswith('MyVideos'):
                                    randnum = str(random.randrange(1, 999999))
                                    filetools.rename(
                                        filetools.join(path, file),
                                        'OLD_' + randnum + '_' + file)
                                    logger.error('BD obsoleta: ' + file)

                else:
                    logger.error('Video_DB: ' + str(platform['video_db']) +
                                 ' para versión Kodi ' +
                                 str(platform['num_version']) +
                                 ' NO EXISTE. Analizar carpeta: ' +
                                 str(db_files))
            else:
                logger.error(
                    'Estructura de get_platform(full_version=True) incorrecta')
        else:
            logger.error('Path a Userdata/Database (' + path +
                         ') no encontrado')

    except:
        logger.error('Platform: ' + str(platform) + ' / Path: ' + str(path) +
                     ' / Files: ' + str(db_files))
        logger.error(traceback.format_exc())

    return
Exemplo n.º 26
0
def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
    """
    guarda en la ruta indicada todos los capitulos incluidos en la lista episodelist
    @type path: str
    @param path: ruta donde guardar los episodios
    @type episodelist: list
    @param episodelist: listado de items que representan los episodios que se van a guardar.
    @type serie: item
    @param serie: serie de la que se van a guardar los episodios
    @type silent: bool
    @param silent: establece si se muestra la notificación
    @param overwrite: permite sobreescribir los ficheros existentes
    @type overwrite: bool
    @rtype insertados: int
    @return:  el número de episodios insertados
    @rtype sobreescritos: int
    @return:  el número de episodios sobreescritos
    @rtype fallidos: int
    @return:  el número de episodios fallidos
    """
    logger.info()

    # No hay lista de episodios, no hay nada que guardar
    if not len(episodelist):
        logger.info("No hay lista de episodios, salimos sin crear strm")
        return 0, 0, 0

    insertados = 0
    sobreescritos = 0
    fallidos = 0
    news_in_playcounts = {}

    # Listamos todos los ficheros de la serie, asi evitamos tener que comprobar si existe uno por uno
    raiz, carpetas_series, ficheros = filetools.walk(path).next()
    ficheros = [filetools.join(path, f) for f in ficheros]

    nostrm_episodelist = []
    for root, folders, files in filetools.walk(path):
        for file in files:
            season_episode = scrapertools.get_season_and_episode(file)
            if season_episode == "" or filetools.exists(
                    filetools.join(path, "%s.strm" % season_episode)):
                continue
            nostrm_episodelist.append(season_episode)
    nostrm_episodelist = sorted(set(nostrm_episodelist))

    # Silent es para no mostrar progreso (para videolibrary_service)
    if not silent:
        # progress dialog
        p_dialog = platformtools.dialog_progress(
            config.get_localized_string(20000),
            config.get_localized_string(60064))
        p_dialog.update(0, config.get_localized_string(60065))

    channel_alt = generictools.verify_channel(
        serie.channel)  #Preparamos para añadir las urls de emergencia
    emergency_urls_stat = config.get_setting(
        "emergency_urls", channel_alt)  #El canal quiere urls de emergencia?
    emergency_urls_succ = False
    channel = __import__('channels.%s' % channel_alt,
                         fromlist=["channels.%s" % channel_alt])
    if serie.torrent_caching_fail:  #Si el proceso de conversión ha fallado, no se cachean
        emergency_urls_stat = 0
        del serie.torrent_caching_fail

    new_episodelist = []
    # Obtenemos el numero de temporada y episodio y descartamos los q no lo sean
    tags = []
    if config.get_setting("enable_filter", "videolibrary"):
        tags = [
            x.strip() for x in config.get_setting(
                "filters", "videolibrary").lower().split(",")
        ]

    for e in episodelist:
        headers = {}
        if e.headers:
            headers = e.headers
        if tags != [] and tags != None and any(tag in e.title.lower()
                                               for tag in tags):
            continue

        try:
            season_episode = scrapertools.get_season_and_episode(e.title)

            # Si se ha marcado la opción de url de emergencia, se añade ésta a cada episodio después de haber ejecutado Findvideos del canal
            if e.emergency_urls and isinstance(e.emergency_urls, dict):
                del e.emergency_urls  #Borramos trazas anteriores
            json_path = filetools.join(
                path, ("%s [%s].json" % (season_episode, e.channel)
                       ).lower())  #Path del .json del episodio
            if emergency_urls_stat == 1 and not e.emergency_urls and e.contentType == 'episode':  #Guardamos urls de emergencia?
                if not silent:
                    p_dialog.update(0,
                                    'Cacheando enlaces y archivos .torrent...',
                                    e.title)  #progress dialog
                if json_path in ficheros:  #Si existe el .json sacamos de ahí las urls
                    if overwrite:  #pero solo si se se sobrescriben los .json
                        json_epi = Item().fromjson(
                            filetools.read(json_path))  #Leemos el .json
                        if json_epi.emergency_urls:  #si existen las urls de emergencia...
                            e.emergency_urls = json_epi.emergency_urls  #... las copiamos
                        else:  #y si no...
                            e = emergency_urls(
                                e, channel, json_path,
                                headers=headers)  #... las generamos
                else:
                    e = emergency_urls(
                        e, channel, json_path, headers=headers
                    )  #Si el episodio no existe, generamos las urls
                if e.emergency_urls:  #Si ya tenemos urls...
                    emergency_urls_succ = True  #... es un éxito y vamos a marcar el .nfo
            elif emergency_urls_stat == 2 and e.contentType == 'episode':  #Borramos urls de emergencia?
                if e.emergency_urls: del e.emergency_urls
                emergency_urls_succ = True  #... es un éxito y vamos a marcar el .nfo
            elif emergency_urls_stat == 3 and e.contentType == 'episode':  #Actualizamos urls de emergencia?
                if not silent:
                    p_dialog.update(0,
                                    'Cacheando enlaces y archivos .torrent...',
                                    e.title)  #progress dialog
                e = emergency_urls(e, channel, json_path,
                                   headers=headers)  #generamos las urls
                if e.emergency_urls:  #Si ya tenemos urls...
                    emergency_urls_succ = True  #... es un éxito y vamos a marcar el .nfo

            if not e.infoLabels["tmdb_id"] or (
                    serie.infoLabels["tmdb_id"]
                    and e.infoLabels["tmdb_id"] != serie.infoLabels["tmdb_id"]
            ):  #en series multicanal, prevalece el infolabels...
                e.infoLabels = serie.infoLabels  #... del canal actual y no el del original
            e.contentSeason, e.contentEpisodeNumber = season_episode.split("x")
            if e.videolibray_emergency_urls:
                del e.videolibray_emergency_urls
            if e.channel_redir:
                del e.channel_redir  #... y se borran las marcas de redirecciones
            new_episodelist.append(e)
        except:
            if e.contentType == 'episode':
                logger.error(
                    "No se ha podido guardar las urls de emergencia de %s en la videoteca"
                    % e.contentTitle)
                logger.error(traceback.format_exc())
            continue

    # No hay lista de episodios, no hay nada que guardar
    if not len(new_episodelist):
        logger.info("No hay lista de episodios, salimos sin crear strm")
        return 0, 0, 0

    # fix float porque la division se hace mal en python 2.x
    try:
        t = float(100) / len(new_episodelist)
    except:
        t = 0

    last_season_episode = ''
    for i, e in enumerate(scraper.sort_episode_list(new_episodelist)):
        if not silent:
            p_dialog.update(int(math.ceil((i + 1) * t)),
                            config.get_localized_string(60064), e.title)

        high_sea = e.contentSeason
        high_epi = e.contentEpisodeNumber
        if scrapertools.find_single_match(e.title, '[a|A][l|L]\s*(\d+)'):
            high_epi = int(
                scrapertools.find_single_match(e.title, 'al\s*(\d+)'))
        max_sea = e.infoLabels["number_of_seasons"]
        max_epi = 0
        if e.infoLabels["number_of_seasons"] and (
                e.infoLabels["temporada_num_episodios"]
                or e.infoLabels["number_of_seasons"] == 1):
            if e.infoLabels["number_of_seasons"] == 1 and e.infoLabels[
                    "number_of_episodes"]:
                max_epi = e.infoLabels["number_of_episodes"]
            else:
                max_epi = e.infoLabels["temporada_num_episodios"]

        season_episode = "%sx%s" % (e.contentSeason, str(
            e.contentEpisodeNumber).zfill(2))
        strm_path = filetools.join(path, "%s.strm" % season_episode)
        nfo_path = filetools.join(path, "%s.nfo" % season_episode)
        json_path = filetools.join(path, ("%s [%s].json" %
                                          (season_episode, e.channel)).lower())

        if season_episode in nostrm_episodelist:
            logger.error('Error en la estructura de la Videoteca: Serie ' +
                         serie.contentSerieName + ' ' + season_episode)
            continue
        strm_exists = strm_path in ficheros
        nfo_exists = nfo_path in ficheros
        json_exists = json_path in ficheros

        if not strm_exists:
            # Si no existe season_episode.strm añadirlo
            item_strm = Item(action='play_from_library',
                             channel='videolibrary',
                             strm_path=strm_path.replace(TVSHOWS_PATH, ""),
                             infoLabels={})
            item_strm.contentSeason = e.contentSeason
            item_strm.contentEpisodeNumber = e.contentEpisodeNumber
            item_strm.contentType = e.contentType
            item_strm.contentTitle = season_episode

            # FILTERTOOLS
            if item_strm.list_language:
                # si tvshow.nfo tiene filtro se le pasa al item_strm que se va a generar
                if "library_filter_show" in serie:
                    item_strm.library_filter_show = serie.library_filter_show

                if item_strm.library_filter_show == "":
                    logger.error(
                        "Se ha producido un error al obtener el nombre de la serie a filtrar"
                    )

            # logger.debug("item_strm" + item_strm.tostring('\n'))
            # logger.debug("serie " + serie.tostring('\n'))
            strm_exists = filetools.write(
                strm_path, '%s?%s' % (addon_name, item_strm.tourl()))

        item_nfo = None
        if not nfo_exists and e.infoLabels["code"]:
            # Si no existe season_episode.nfo añadirlo
            scraper.find_and_set_infoLabels(e)
            head_nfo = scraper.get_nfo(e)

            item_nfo = e.clone(channel="videolibrary",
                               url="",
                               action='findvideos',
                               strm_path=strm_path.replace(TVSHOWS_PATH, ""))
            if item_nfo.emergency_urls:
                del item_nfo.emergency_urls  #Solo se mantiene en el .json del episodio

            nfo_exists = filetools.write(nfo_path,
                                         head_nfo + item_nfo.tojson())

        # Solo si existen season_episode.nfo y season_episode.strm continuamos
        if nfo_exists and strm_exists:
            if not json_exists or overwrite:
                # Obtenemos infoLabel del episodio
                if not item_nfo:
                    head_nfo, item_nfo = read_nfo(nfo_path)

                # En series multicanal, prevalece el infolabels del canal actual y no el del original
                if not e.infoLabels["tmdb_id"] or (item_nfo.infoLabels["tmdb_id"] \
                            and e.infoLabels["tmdb_id"] != item_nfo.infoLabels["tmdb_id"]):
                    e.infoLabels = item_nfo.infoLabels

                if filetools.write(json_path, e.tojson()):
                    if not json_exists:
                        logger.info("Insertado: %s" % json_path)
                        insertados += 1
                        # Marcamos episodio como no visto
                        news_in_playcounts[season_episode] = 0
                        # Marcamos la temporada como no vista
                        news_in_playcounts["season %s" % e.contentSeason] = 0
                        # Marcamos la serie como no vista
                        # logger.debug("serie " + serie.tostring('\n'))
                        news_in_playcounts[serie.contentSerieName] = 0

                    else:
                        logger.info("Sobreescrito: %s" % json_path)
                        sobreescritos += 1
                else:
                    logger.info("Fallido: %s" % json_path)
                    fallidos += 1

        else:
            logger.info("Fallido: %s" % json_path)
            fallidos += 1

        if not silent and p_dialog.iscanceled():
            break

    #logger.debug('high_sea x high_epi: %sx%s' % (str(high_sea), str(high_epi)))
    #logger.debug('max_sea x max_epi: %sx%s' % (str(max_sea), str(max_epi)))
    if not silent:
        p_dialog.close()

    if news_in_playcounts or emergency_urls_succ or serie.infoLabels[
            "status"] == "Ended" or serie.infoLabels["status"] == "Canceled":
        # Si hay nuevos episodios los marcamos como no vistos en tvshow.nfo ...
        tvshow_path = filetools.join(path, "tvshow.nfo")
        try:
            import datetime
            head_nfo, tvshow_item = read_nfo(tvshow_path)
            tvshow_item.library_playcounts.update(news_in_playcounts)

            #Si la operación de insertar/borrar urls de emergencia en los .jsons de los episodios ha tenido éxito, se marca el .nfo
            if emergency_urls_succ:
                if tvshow_item.emergency_urls and not isinstance(
                        tvshow_item.emergency_urls, dict):
                    del tvshow_item.emergency_urls
                if emergency_urls_stat in [
                        1, 3
                ]:  #Operación de guardar/actualizar enlaces
                    if not tvshow_item.emergency_urls:
                        tvshow_item.emergency_urls = dict()
                    if tvshow_item.library_urls.get(serie.channel, False):
                        tvshow_item.emergency_urls.update(
                            {serie.channel: True})
                elif emergency_urls_stat == 2:  #Operación de Borrar enlaces
                    if tvshow_item.emergency_urls and tvshow_item.emergency_urls.get(
                            serie.channel, False):
                        tvshow_item.emergency_urls.pop(
                            serie.channel, None)  #borramos la entrada del .nfo

            if tvshow_item.active == 30:
                tvshow_item.active = 1
            if tvshow_item.infoLabels["tmdb_id"] == serie.infoLabels[
                    "tmdb_id"]:
                tvshow_item.infoLabels = serie.infoLabels
                tvshow_item.infoLabels["title"] = tvshow_item.infoLabels[
                    "tvshowtitle"]

            if max_sea == high_sea and max_epi == high_epi and (
                    tvshow_item.infoLabels["status"] == "Ended"
                    or tvshow_item.infoLabels["status"]
                    == "Canceled") and insertados == 0 and fallidos == 0:
                tvshow_item.active = 0  # ... no la actualizaremos más
                logger.debug("%s [%s]: serie 'Terminada' o 'Cancelada'.  Se desactiva la actualización periódica" % \
                            (serie.contentSerieName, serie.channel))

            update_last = datetime.date.today()
            tvshow_item.update_last = update_last.strftime('%Y-%m-%d')
            update_next = datetime.date.today() + datetime.timedelta(
                days=int(tvshow_item.active))
            tvshow_item.update_next = update_next.strftime('%Y-%m-%d')

            filetools.write(tvshow_path, head_nfo + tvshow_item.tojson())
        except:
            logger.error("Error al actualizar tvshow.nfo")
            logger.error(
                "No se ha podido guardar las urls de emergencia de %s en la videoteca"
                % tvshow_item.contentSerieName)
            logger.error(traceback.format_exc())
            fallidos = -1
        else:
            # ... si ha sido correcto actualizamos la videoteca de Kodi
            if config.is_xbmc() and not silent:
                from platformcode import xbmc_videolibrary
                xbmc_videolibrary.update(FOLDER_TVSHOWS,
                                         filetools.basename(path))

    if fallidos == len(episodelist):
        fallidos = -1

    logger.debug("%s [%s]: insertados= %s, sobreescritos= %s, fallidos= %s" %
                 (serie.contentSerieName, serie.channel, insertados,
                  sobreescritos, fallidos))
    return insertados, sobreescritos, fallidos
Exemplo n.º 27
0
def update(path, p_dialog, i, t, serie, overwrite):
    logger.info("Actualizando " + path)

    from core import filetools
    from core import channeltools, videolibrarytools
    from platformcode import platformtools
    from channels import videolibrary
    from lib import generictools
    if config.is_xbmc():
        from platformcode import xbmc_videolibrary

    insertados_total = 0

    head_nfo, it = videolibrarytools.read_nfo(path + '/tvshow.nfo')
    category = serie.category

    # logger.debug("%s: %s" %(serie.contentSerieName,str(list_canales) ))
    for channel, url in list(serie.library_urls.items()):
        serie.channel = channel
        serie.url = url

        ###### Redirección al canal NewPct1.py si es un clone, o a otro canal y url si ha intervención judicial
        try:
            head_nfo, it = videolibrarytools.read_nfo(
                path +
                '/tvshow.nfo')  #Refresca el .nfo para recoger actualizaciones
            if not it:
                logger.error('.nfo erroneo en ' + str(path))
                continue
            if it.emergency_urls:
                serie.emergency_urls = it.emergency_urls
            serie.category = category
            serie, it, overwrite = generictools.redirect_clone_newpct1(
                serie, head_nfo, it, path, overwrite)
        except:
            logger.error(traceback.format_exc())

        channel_enabled = channeltools.is_enabled(serie.channel)

        if channel_enabled:

            heading = config.get_localized_string(60389)
            p_dialog.update(
                int(math.ceil((i + 1) * t)), heading, "%s: %s" %
                (serie.contentSerieName, serie.channel.capitalize()))
            try:
                pathchannels = filetools.join(config.get_runtime_path(),
                                              "channels",
                                              serie.channel + '.py')
                logger.info("Cargando canal: " + pathchannels)

                if serie.library_filter_show:
                    serie.show = serie.library_filter_show.get(
                        serie.channel, serie.contentSerieName)

                obj = __import__('channels.%s' % serie.channel,
                                 fromlist=["channels.%s" % serie.channel])
                itemlist = getattr(obj, 'episodios')(
                    serie)  #... se procesa Episodios para ese canal

                try:
                    if int(overwrite) == 3:
                        # Sobrescribir todos los archivos (tvshow.nfo, 1x01.nfo, 1x01 [canal].json, 1x01.strm, etc...)
                        insertados, sobreescritos, fallidos, notusedpath = videolibrarytools.save_tvshow(
                            serie, itemlist)
                        #serie= videolibrary.check_season_playcount(serie, serie.contentSeason)
                        #if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()):
                        #    serie.infoLabels['playcount'] = serie.playcount
                    else:
                        insertados, sobreescritos, fallidos = videolibrarytools.save_episodes(
                            path,
                            itemlist,
                            serie,
                            silent=True,
                            overwrite=overwrite)
                        #it = videolibrary.check_season_playcount(it, it.contentSeason)
                        #if filetools.write(path + '/tvshow.nfo', head_nfo + it.tojson()):
                        #    serie.infoLabels['playcount'] = serie.playcount
                    insertados_total += insertados

                except Exception as ex:
                    logger.error("Error al guardar los capitulos de la serie")
                    template = "An exception of type %s occured. Arguments:\n%r"
                    message = template % (type(ex).__name__, ex.args)
                    logger.error(message)
                    logger.error(traceback.format_exc())

            except Exception as ex:
                logger.error("Error al obtener los episodios de: %s" %
                             serie.show)
                template = "An exception of type %s occured. Arguments:\n%r"
                message = template % (type(ex).__name__, ex.args)
                logger.error(message)
                logger.error(traceback.format_exc())

            #Si el canal lo permite, se comienza el proceso de descarga de los nuevos episodios descargados
            serie.channel = generictools.verify_channel(serie.channel)
            if insertados > 0 and config.get_setting(
                    'auto_download_new', serie.channel, default=False):
                config.set_setting(
                    "search_new_content", 1,
                    "videolibrary")  # Escaneamos a final todas la series
                serie.sub_action = 'auto'
                serie.category = itemlist[0].category
                from channels import downloads
                downloads.save_download(serie, silent=True)
                if serie.sub_action: del serie.sub_action

        else:
            logger.debug("Canal %s no activo no se actualiza" % serie.channel)

    #Sincronizamos los episodios vistos desde la videoteca de Kodi con la de Alfa
    try:
        if config.is_xbmc() and not config.get_setting(
                'cleanlibrary', 'videolibrary',
                default=False):  #Si es Kodi, lo hacemos
            xbmc_videolibrary.mark_content_as_watched_on_alfa(path +
                                                              '/tvshow.nfo')
    except:
        logger.error(traceback.format_exc())

    return insertados_total > 0
Exemplo n.º 28
0
def save_movie(item):
    """
    guarda en la libreria de peliculas el elemento item, con los valores que contiene.
    @type item: item
    @param item: elemento que se va a guardar.
    @rtype insertados: int
    @return:  el número de elementos insertados
    @rtype sobreescritos: int
    @return:  el número de elementos sobreescritos
    @rtype fallidos: int
    @return:  el número de elementos fallidos o -1 si ha fallado todo
    """
    logger.info()
    # logger.debug(item.tostring('\n'))
    insertados = 0
    sobreescritos = 0
    fallidos = 0
    path = ""

    # Itentamos obtener el titulo correcto:
    # 1. contentTitle: Este deberia ser el sitio correcto, ya que title suele contener "Añadir a la videoteca..."
    # 2. fulltitle
    # 3. title
    if not item.contentTitle:
        # Colocamos el titulo correcto en su sitio para que scraper lo localize
        if item.fulltitle:
            item.contentTitle = item.fulltitle
        else:
            item.contentTitle = item.title

    # Si llegados a este punto no tenemos titulo, salimos
    if not item.contentTitle or not item.channel:
        logger.debug("NO ENCONTRADO contentTitle")
        return 0, 0, -1  # Salimos sin guardar

    scraper_return = scraper.find_and_set_infoLabels(item)

    # Llegados a este punto podemos tener:
    #  scraper_return = True: Un item con infoLabels con la información actualizada de la peli
    #  scraper_return = False: Un item sin información de la peli (se ha dado a cancelar en la ventana)
    #  item.infoLabels['code'] == "" : No se ha encontrado el identificador de IMDB necesario para continuar, salimos
    if not scraper_return or not item.infoLabels['code']:
        # TODO de momento si no hay resultado no añadimos nada,
        # aunq podriamos abrir un cuadro para introducir el identificador/nombre a mano
        logger.debug("NO ENCONTRADO EN SCRAPER O NO TIENE code")
        return 0, 0, -1

    _id = item.infoLabels['code'][0]

    # progress dialog
    p_dialog = platformtools.dialog_progress(
        config.get_localized_string(20000), config.get_localized_string(60062))

    if config.get_setting(
            "original_title_folder",
            "videolibrary") == 1 and item.infoLabels['originaltitle']:
        base_name = item.infoLabels['originaltitle']
    else:
        base_name = item.contentTitle

    base_name = unicode(filetools.validate_path(base_name.replace('/', '-')),
                        "utf8").encode("utf8")

    if config.get_setting("lowerize_title", "videolibrary") == 0:
        base_name = base_name.lower()

    for raiz, subcarpetas, ficheros in filetools.walk(MOVIES_PATH):
        for c in subcarpetas:
            code = scrapertools.find_single_match(c, '\[(.*?)\]')
            if code and code in item.infoLabels['code']:
                path = filetools.join(raiz, c)
                _id = code
                break

    if not path:
        # Crear carpeta
        path = filetools.join(MOVIES_PATH,
                              ("%s [%s]" % (base_name, _id)).strip())
        logger.info("Creando directorio pelicula:" + path)
        if not filetools.mkdir(path):
            logger.debug("No se ha podido crear el directorio")
            return 0, 0, -1

    nfo_path = filetools.join(path, "%s [%s].nfo" % (base_name, _id))
    strm_path = filetools.join(path, "%s.strm" % base_name)
    json_path = filetools.join(path, ("%s [%s].json" %
                                      (base_name, item.channel.lower())))

    nfo_exists = filetools.exists(nfo_path)
    strm_exists = filetools.exists(strm_path)
    json_exists = filetools.exists(json_path)

    if not nfo_exists:
        # Creamos .nfo si no existe
        logger.info("Creando .nfo: " + nfo_path)
        head_nfo = scraper.get_nfo(item)

        item_nfo = Item(title=item.contentTitle,
                        channel="videolibrary",
                        action='findvideos',
                        library_playcounts={"%s [%s]" % (base_name, _id): 0},
                        infoLabels=item.infoLabels,
                        library_urls={})

    else:
        # Si existe .nfo, pero estamos añadiendo un nuevo canal lo abrimos
        head_nfo, item_nfo = read_nfo(nfo_path)

    if not strm_exists:
        # Crear base_name.strm si no existe
        item_strm = Item(channel='videolibrary',
                         action='play_from_library',
                         strm_path=strm_path.replace(MOVIES_PATH, ""),
                         contentType='movie',
                         contentTitle=item.contentTitle)
        strm_exists = filetools.write(
            strm_path, '%s?%s' % (addon_name, item_strm.tourl()))
        item_nfo.strm_path = strm_path.replace(MOVIES_PATH, "")

    # Solo si existen item_nfo y .strm continuamos
    if item_nfo and strm_exists:

        if json_exists:
            logger.info("El fichero existe. Se sobreescribe")
            sobreescritos += 1
        else:
            insertados += 1

        # Si se ha marcado la opción de url de emergencia, se añade ésta a la película después de haber ejecutado Findvideos del canal
        try:
            headers = {}
            if item.headers:
                headers = item.headers
            channel = generictools.verify_channel(item.channel)
            if config.get_setting("emergency_urls", channel) in [1, 3]:
                item = emergency_urls(item, None, json_path, headers=headers)
                if item_nfo.emergency_urls and not isinstance(
                        item_nfo.emergency_urls, dict):
                    del item_nfo.emergency_urls
                if not item_nfo.emergency_urls:
                    item_nfo.emergency_urls = dict()
                item_nfo.emergency_urls.update({item.channel: True})
        except:
            logger.error(
                "No se ha podido guardar las urls de emergencia de %s en la videoteca"
                % item.contentTitle)
            logger.error(traceback.format_exc())

        if filetools.write(json_path, item.tojson()):
            p_dialog.update(100, 'Añadiendo película...', item.contentTitle)
            item_nfo.library_urls[item.channel] = item.url

            if filetools.write(nfo_path, head_nfo + item_nfo.tojson()):
                # actualizamos la videoteca de Kodi con la pelicula
                if config.is_xbmc():
                    from platformcode import xbmc_videolibrary
                    xbmc_videolibrary.update(FOLDER_MOVIES,
                                             filetools.basename(path) + "/")

                p_dialog.close()
                return insertados, sobreescritos, fallidos

    # Si llegamos a este punto es por q algo ha fallado
    logger.error("No se ha podido guardar %s en la videoteca" %
                 item.contentTitle)
    p_dialog.update(100, config.get_localized_string(60063), item.contentTitle)
    p_dialog.close()
    return 0, 0, -1
Exemplo n.º 29
0
    except:
        if url.startswith("rtmp"):
            error = downloadfileRTMP(url, nombrefichero, silent)
            if error and not silent:
                from platformcode import platformtools
                platformtools.dialog_ok("Download non consentito",
                                        "Il formato RTMP non", "è supportato")
        else:
            import traceback
            from pprint import pprint
            exc_type, exc_value, exc_tb = sys.exc_info()
            lines = traceback.format_exception(exc_type, exc_value, exc_tb)
            for line in lines:
                line_splits = line.split("\n")
                for line_split in line_splits:
                    logger.error(line_split)

    try:
        f.close()
    except:
        pass

    if not silent:
        try:
            progreso.close()
        except:
            pass

    logger.info("Fin descarga del fichero")

Exemplo n.º 30
0
def findvideos(item):
    logger.info()
    itemlist = []
    itemlist_t = []  #Itemlist total de enlaces
    itemlist_f = []  #Itemlist de enlaces filtrados
    if not item.language:
        item.language = ['CAST']  #Castellano por defecto
    matches = []
    item.category = categoria

    item.extra2 = 'xyz'
    del item.extra2

    #logger.debug(item)

    matches = item.url
    if not matches:  #error
        logger.error(
            "ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web: "
            + str(item))
        itemlist.append(
            item.clone(
                action='',
                title=item.channel.capitalize() +
                ': ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web.  Verificar en la Web esto último y reportar el error con el log',
                folder=False))

        if item.emergency_urls and not item.videolibray_emergency_urls:  #Hay urls de emergencia?
            item.url = item.emergency_urls[0][
                0]  #Guardamos la url del .Torrent
            matches = item.emergency_urls[1]  #Restauramos matches
            item.armagedon = True  #Marcamos la situación como catastrófica
        else:
            if item.videolibray_emergency_urls:  #Si es llamado desde creación de Videoteca...
                return item  #Devolvemos el Item de la llamada
            else:
                return itemlist  #si no hay más datos, algo no funciona, pintamos lo que tenemos

    #logger.debug(matches)

    #Si es un lookup para cargar las urls de emergencia en la Videoteca...
    if item.videolibray_emergency_urls:
        item.emergency_urls = []  #Iniciamos emergency_urls
        item.emergency_urls.append(
            [])  #Reservamos el espacio para los .torrents locales
        item.emergency_urls.append(matches)  #Salvamnos matches...

    #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB
    if not item.videolibray_emergency_urls:
        item, itemlist = generictools.post_tmdb_findvideos(item, itemlist)

    #Ahora tratamos los enlaces .torrent
    for scrapedurl, quality in matches:  #leemos los magnets con la diferentes calidades
        #Generamos una copia de Item para trabajar sobre ella
        item_local = item.clone()

        item_local.url = scrapedurl
        if item.videolibray_emergency_urls:
            item.emergency_urls[0].append(
                scrapedurl)  #guardamos la url y pasamos a la siguiente
            continue
        if item.emergency_urls and not item.videolibray_emergency_urls:
            item_local.torrent_alt = item.emergency_urls[0][
                0]  #Guardamos la url del .Torrent ALTERNATIVA
            if item.armagedon:
                item_local.url = item.emergency_urls[0][
                    0]  #... ponemos la emergencia como primaria
            del item.emergency_urls[0][0]  #Una vez tratado lo limpiamos

        size = ''
        if not item.armagedon:
            size = generictools.get_torrent_size(
                item_local.url)  #Buscamos el tamaño en el .torrent
        if size:
            size = size.replace('GB', 'G·B').replace('Gb', 'G·b').replace('MB', 'M·B')\
                        .replace('Mb', 'M·b').replace('.', ',')
        item_local.torrent_info = '%s' % size  #Agregamos size
        if not item.unify:
            item_local.torrent_info = '[%s]' % item_local.torrent_info.strip(
            ).strip(',')
        if item.armagedon:  #Si es catastrófico, lo marcamos
            quality = '[/COLOR][COLOR hotpink][E] [COLOR limegreen]%s' % quality

        #Añadimos la calidad y copiamos la duración
        item_local.quality = quality
        if scrapertools.find_single_match(item.quality, '(\[\d+:\d+\ h])'):
            item_local.quality += ' [/COLOR][COLOR white]%s' % scrapertools.find_single_match(
                item.quality, '(\[\d+:\d+\ h])')

        #Ahora pintamos el link del Torrent
        item_local.title = '[[COLOR yellow]?[/COLOR]] [COLOR yellow][Torrent][/COLOR] ' \
                        + '[COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR] %s' % \
                        (item_local.quality, str(item_local.language),  \
                        item_local.torrent_info)                                #Preparamos título de Torrent

        #Preparamos título y calidad, quitamos etiquetas vacías
        item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]',
                                  '', item_local.title)
        item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '',
                                  item_local.title)
        item_local.title = item_local.title.replace("--", "").replace(
            "[]", "").replace("()", "").replace("(/)", "").replace("[/]",
                                                                   "").strip()
        item_local.quality = re.sub(
            r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '',
            item_local.quality)
        item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '',
                                    item_local.quality).strip()
        item_local.quality = item_local.quality.replace("--", "").replace(
            "[]", "").replace("()", "").replace("(/)", "").replace("[/]",
                                                                   "").strip()

        item_local.alive = "??"  #Calidad del link sin verificar
        item_local.action = "play"  #Visualizar vídeo
        item_local.server = "torrent"  #Servidor Torrent

        itemlist_t.append(
            item_local.clone())  #Pintar pantalla, si no se filtran idiomas

        # Requerido para FilterTools
        if config.get_setting(
                'filter_languages',
                channel) > 0:  #Si hay idioma seleccionado, se filtra
            itemlist_f = filtertools.get_link(
                itemlist_f, item_local,
                list_language)  #Pintar pantalla, si no está vacío

        #logger.debug("TORRENT: " + scrapedurl + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName)

        #logger.debug(item_local)

    if item.videolibray_emergency_urls:  #Si ya hemos guardado todas las urls...
        return item  #... nos vamos

    if len(itemlist_f) > 0:  #Si hay entradas filtradas...
        itemlist.extend(itemlist_f)  #Pintamos pantalla filtrada
    else:
        if config.get_setting('filter_languages', channel) > 0 and len(
                itemlist_t) > 0:  #Si no hay entradas filtradas ...
            thumb_separador = get_thumb(
                "next.png")  #... pintamos todo con aviso
            itemlist.append(
                Item(
                    channel=item.channel,
                    url=host,
                    title=
                    "[COLOR red][B]NO hay elementos con el idioma seleccionado[/B][/COLOR]",
                    thumbnail=thumb_separador,
                    folder=False))
        itemlist.extend(
            itemlist_t)  #Pintar pantalla con todo si no hay filtrado

    # Requerido para AutoPlay
    autoplay.start(itemlist, item)  #Lanzamos Autoplay

    return itemlist