Ejemplo n.º 1
0
def mark_content_as_watched_on_alfa(path):
    from channels import videolibrary
    from core import videolibrarytools
    
    """
        marca toda la serie o película como vista o no vista en la Videoteca de Alfa basado en su estado en la Videoteca de Kodi
        @type str: path
        @param path: carpeta de contenido a marcar
        """
    logger.info()
    #logger.debug("path: " + path)
    
    FOLDER_MOVIES = config.get_setting("folder_movies")
    FOLDER_TVSHOWS = config.get_setting("folder_tvshows")
    VIDEOLIBRARY_PATH = config.get_videolibrary_config_path()
    if not VIDEOLIBRARY_PATH:
        return

    # Solo podemos marcar el contenido como vista en la BBDD de Kodi si la BBDD es local,
    # en caso de compartir BBDD esta funcionalidad no funcionara
    #if config.get_setting("db_mode", "videolibrary"):
    #    return
    
    path2 = ''
    if "special://" in VIDEOLIBRARY_PATH:
        if FOLDER_TVSHOWS in path:
            path2 = re. sub(r'.*?%s' % FOLDER_TVSHOWS, VIDEOLIBRARY_PATH + "/" + FOLDER_TVSHOWS, path).replace("\\", "/")
        if FOLDER_MOVIES in path:
            path2 = re. sub(r'.*?%s' % FOLDER_MOVIES, VIDEOLIBRARY_PATH + "/" + FOLDER_MOVIES, path).replace("\\", "/")

    if "\\" in path:
        path = path.replace("/", "\\")
    head_nfo, item = videolibrarytools.read_nfo(path)                   #Leo el .nfo del contenido
    if not item or not isinstance(item.library_playcounts, dict):
        logger.error('.NFO no encontrado o erroneo: ' + path)
        return

    if FOLDER_TVSHOWS in path:                                          #Compruebo si es CINE o SERIE
        contentType = "episode_view"                                    #Marco la tabla de BBDD de Kodi Video
        nfo_name = "tvshow.nfo"                                         #Construyo el nombre del .nfo
        path1 = path.replace("\\\\", "\\").replace(nfo_name, '')        #para la SQL solo necesito la carpeta
        if not path2:
            path2 = path1.replace("\\", "/")                            #Formato no Windows
        else:
            path2 = path2.replace(nfo_name, '')
        
    else:
        contentType = "movie_view"                                      #Marco la tabla de BBDD de Kodi Video
        path1 = path.replace("\\\\", "\\")                              #Formato Windows
        if not path2:
            path2 = path1.replace("\\", "/")                            #Formato no Windows
        nfo_name = scrapertools.find_single_match(path2, '\]\/(.*?)$')  #Construyo el nombre del .nfo
        path1 = path1.replace(nfo_name, '')                             #para la SQL solo necesito la carpeta
        path2 = path2.replace(nfo_name, '')                             #para la SQL solo necesito la carpeta
    path2 = filetools.remove_smb_credential(path2)                      #Si el archivo está en un servidor SMB, quitamos las credenciales
    
    #Ejecutmos la sentencia SQL
    sql = 'select strFileName, playCount from %s where (strPath like "%s" or strPath like "%s")' % (contentType, path1, path2)
    nun_records = 0
    records = None
    nun_records, records = execute_sql_kodi(sql)                        #ejecución de la SQL
    if nun_records == 0:                                                #hay error?
        logger.error("Error en la SQL: " + sql + ": 0 registros")
        return                                                          #salimos: o no está catalogado en Kodi, o hay un error en la SQL
    
    for title, playCount in records:                                    #Ahora recorremos todos los registros obtenidos
        if contentType == "episode_view":
            title_plain = title.replace('.strm', '')                    #Si es Serie, quitamos el sufijo .strm
        else:
            title_plain = scrapertools.find_single_match(item.strm_path, '.(.*?\s\[.*?\])') #si es peli, quitamos el título
        if playCount is None or playCount == 0:                         #todavía no se ha visto, lo ponemos a 0
            playCount_final = 0
        elif playCount >= 1:
            playCount_final = 1

        elif not PY3 and isinstance(title_plain, (str, unicode)):
            title_plain = title_plain.decode("utf-8").encode("utf-8")   #Hacemos esto porque si no genera esto: u'title_plain'
        elif PY3 and isinstance(var, bytes):
            title_plain = title_plain.decode('utf-8')
        item.library_playcounts.update({title_plain: playCount_final})  #actualizamos el playCount del .nfo

    if item.infoLabels['mediatype'] == "tvshow":                        #Actualizamos los playCounts de temporadas y Serie
        for season in item.library_playcounts:
            if "season" in season:                                      #buscamos las etiquetas "season" dentro de playCounts
                season_num = int(scrapertools.find_single_match(season, 'season (\d+)'))    #salvamos el núm, de Temporada
                item = videolibrary.check_season_playcount(item, season_num)    #llamamos al método que actualiza Temps. y Series

    res = videolibrarytools.write_nfo(path, head_nfo, item)
Ejemplo n.º 2
0
def sync_trakt_addon(path_folder):
    """
       Actualiza los valores de episodios vistos si
    """
    logger.info()
    # si existe el addon hacemos la busqueda
    if xbmc.getCondVisibility('System.HasAddon("script.trakt")'):
        # importamos dependencias
        paths = ["special://home/addons/script.module.dateutil/lib/", "special://home/addons/script.module.six/lib/",
                 "special://home/addons/script.module.arrow/lib/", "special://home/addons/script.module.trakt/lib/",
                 "special://home/addons/script.trakt/"]

        for path in paths:
            sys.path.append(filetools.translatePath(path))

        # se obtiene las series vistas
        try:
            from resources.lib.traktapi import traktAPI
            traktapi = traktAPI()
        except:
            return

        shows = traktapi.getShowsWatched({})
        shows = list(shows.items())

        # obtenemos el id de la serie para comparar
        _id = re.findall("\[(.*?)\]", path_folder, flags=re.DOTALL)[0]
        logger.debug("el id es %s" % _id)

        if "tt" in _id:
            type_id = "imdb"
        elif "tvdb_" in _id:
            _id = _id.strip("tvdb_")
            type_id = "tvdb"
        elif "tmdb_" in _id:
            type_id = "tmdb"
            _id = _id.strip("tmdb_")
        else:
            logger.error("No hay _id de la serie")
            return

        # obtenemos los valores de la serie
        from core import videolibrarytools
        tvshow_file = filetools.join(path_folder, "tvshow.nfo")
        head_nfo, serie = videolibrarytools.read_nfo(tvshow_file)

        # buscamos en las series de trakt
        for show in shows:
            show_aux = show[1].to_dict()

            try:
                _id_trakt = show_aux['ids'].get(type_id, None)
                # logger.debug("ID ES %s" % _id_trakt)
                if _id_trakt:
                    if _id == _id_trakt:
                        logger.debug("ENCONTRADO!! %s" % show_aux)

                        # creamos el diccionario de trakt para la serie encontrada con el valor que tiene "visto"
                        dict_trakt_show = {}

                        for idx_season, season in enumerate(show_aux['seasons']):
                            for idx_episode, episode in enumerate(show_aux['seasons'][idx_season]['episodes']):
                                sea_epi = "%sx%s" % (show_aux['seasons'][idx_season]['number'],
                                                     str(show_aux['seasons'][idx_season]['episodes'][idx_episode][
                                                             'number']).zfill(2))

                                dict_trakt_show[sea_epi] = show_aux['seasons'][idx_season]['episodes'][idx_episode][
                                    'watched']
                        logger.debug("dict_trakt_show %s " % dict_trakt_show)

                        # obtenemos las keys que son episodios
                        regex_epi = re.compile('\d+x\d+')
                        keys_episodes = [key for key in serie.library_playcounts if regex_epi.match(key)]
                        # obtenemos las keys que son temporadas
                        keys_seasons = [key for key in serie.library_playcounts if 'season ' in key]
                        # obtenemos los numeros de las keys temporadas
                        seasons = [key.strip('season ') for key in keys_seasons]

                        # marcamos los episodios vistos
                        for k in keys_episodes:
                            serie.library_playcounts[k] = dict_trakt_show.get(k, 0)

                        for season in seasons:
                            episodios_temporada = 0
                            episodios_vistos_temporada = 0

                            # obtenemos las keys de los episodios de una determinada temporada
                            keys_season_episodes = [key for key in keys_episodes if key.startswith("%sx" % season)]

                            for k in keys_season_episodes:
                                episodios_temporada += 1
                                if serie.library_playcounts[k] > 0:
                                    episodios_vistos_temporada += 1

                            # se comprueba que si todos los episodios están vistos, se marque la temporada como vista
                            if episodios_temporada == episodios_vistos_temporada:
                                serie.library_playcounts.update({"season %s" % season: 1})

                        temporada = 0
                        temporada_vista = 0

                        for k in keys_seasons:
                            temporada += 1
                            if serie.library_playcounts[k] > 0:
                                temporada_vista += 1

                        # se comprueba que si todas las temporadas están vistas, se marque la serie como vista
                        if temporada == temporada_vista:
                            serie.library_playcounts.update({serie.title: 1})

                        logger.debug("los valores nuevos %s " % serie.library_playcounts)
                        res = videolibrarytools.write_nfo(tvshow_file, head_nfo, serie)

                        break
                    else:
                        continue

                else:
                    logger.error("no se ha podido obtener el id, trakt tiene: %s" % show_aux['ids'])

            except:
                import traceback
                logger.error(traceback.format_exc())
Ejemplo n.º 3
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

                    if serie.active:
                        try:
                            interval = int(
                                serie.active)  # Podria ser del tipo bool
                        except:
                            interval = 1
                    else:
                        interval = 0

                    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"
                        res = videolibrarytools.write_nfo(
                            tvshow_file, head_nfo, serie)

                    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
    if config.get_setting("update", "videolibrary") != 0 or overwrite:
        from channels import downloads
        downloads.download_auto(item_dummy)