Example #1
0
def save_download_movie(item):
    logger.info("pelisalacarta.channels.descargas save_download_movie")
    
    progreso = platformtools.dialog_progress("Descargas", "Obteniendo datos de la pelicula")
    tmdb.find_and_set_infoLabels_tmdb(item)
    
    progreso.update(0, "Añadiendo pelicula...")
    
    item.action = "menu"
    item.channel = "descargas"
    item.downloadStatus = 0
    item.downloadProgress = 0
    item.downloadSize = 0
    item.downloadCompleted = 0
    item.downloadFilename = "%s [%s]" % (item.contentTitle.strip(), item.contentChannel)
    if item.text_color: del item.text_color
    if item.text_bold: del item.text_bold
    if item.text_italic: del item.text_italic

    item.path = filetools.encode(os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json"))
    filetools.write(item.path, item.tojson())
    
    progreso.close()
    
    if not platformtools.dialog_yesno(config.get_localized_string(30101), "¿Iniciar la descarga ahora?"):
        platformtools.dialog_ok(config.get_localized_string(30101), item.contentTitle,
                                config.get_localized_string(30109))
    else:
        start_download(item)
Example #2
0
def play(item):
    logger.info()
    itemlist = []

    try:
        from core import filetools
        ficherosubtitulo = filetools.join( config.get_data_path(), 'subtitulo_areadocu.srt' )
        if filetools.exists(ficherosubtitulo):
            try:
                filetools.remove(ficherosubtitulo)
            except IOError:
                logger.info("Error al eliminar el archivo "+ficherosubtitulo)
                raise
        
        data = httptools.downloadpage(item.subtitle, headers={'Referer': item.extra}).data
        filetools.write(ficherosubtitulo, data)
        subtitle = ficherosubtitulo
    except:
        subtitle = ""
        logger.info("Error al descargar el subtítulo")

    extension = item.url.rsplit("|", 1)[0][-4:]
    itemlist.append(['%s %s [directo]' % (extension, item.calidad), item.url, 0, subtitle])
    #itemlist.append(item.clone(subtitle=subtitle))

    return itemlist
Example #3
0
def save_download_tvshow(item):
    logger.info("pelisalacarta.channels.descargas save_download_tvshow")
    logger.info("Tipo: %s" % item.contentType)
    
    progreso = platformtools.dialog_progress("Descargas", "Obteniendo datos de la serie")
    
    tmdb.find_and_set_infoLabels_tmdb(item)

    item.downloadFilename = item.downloadFilename = "%s [%s]" % (item.contentSerieName, item.contentChannel)
    episodes = get_episodes(item)

    progreso.update(0, "Añadiendo capitulos...")

    for x, i in enumerate(episodes):
        progreso.update(x * 100 / len(episodes), os.path.basename(i.downloadFilename))
        i.path = os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json")
        filetools.write(i.path, i.tojson())
        time.sleep(0.1)

    progreso.close()

    if not platformtools.dialog_yesno(config.get_localized_string(30101), "¿Iniciar la descarga ahora?"):
        platformtools.dialog_ok(config.get_localized_string(30101),
                                str(len(episodes)) + " capitulos de: " + item.contentSerieName,
                                config.get_localized_string(30109))
    else:
        for i in episodes:
            res = start_download(i)
            if res == 1:
                break
Example #4
0
def eliminar(item):

    def eliminar_todo(item):
        filetools.rmdirtree(item.path)
        if config.is_xbmc():
            import xbmc
            # esperamos 3 segundos para dar tiempo a borrar los ficheros
            xbmc.sleep(3000)
            # TODO mirar por qué no funciona al limpiar en la biblioteca de Kodi al añadirle un path
            # limpiamos la biblioteca de Kodi
            library.clean()

        logger.info("Eliminados todos los enlaces")
        platformtools.itemlist_refresh()


    logger.info(item.contentTitle)
    #logger.debug(item.tostring('\n'))

    if item.contentType == 'movie':
        heading = "Eliminar película"
    else:
        heading = "Eliminar serie"

    if item.multicanal:
        # Obtener listado de canales
        opciones = ["Eliminar solo los enlaces de %s" % k.capitalize() for k in item.library_urls.keys() if k !="descargas"]
        opciones.insert(0, heading)

        index = platformtools.dialog_select(config.get_localized_string(30163), opciones)

        if index == 0:
            # Seleccionado Eliminar pelicula/serie
            eliminar_todo(item)

        elif index > 0:
            # Seleccionado Eliminar canal X
            canal = opciones[index].replace("Eliminar solo los enlaces de ", "").lower()

            num_enlaces= 0
            for fd in filetools.listdir(item.path):
                if fd.endswith(canal + '].json'):
                    if filetools.remove(filetools.join(item.path, fd)):
                        num_enlaces += 1

            if num_enlaces > 0:
                # Actualizar .nfo
                head_nfo, item_nfo = library.read_nfo(item.nfo)
                del item_nfo.library_urls[canal]
                filetools.write(item.nfo, head_nfo + item_nfo.tojson())

            msg_txt = "Eliminados %s enlaces del canal %s" % (num_enlaces, canal)
            logger.info(msg_txt)
            platformtools.dialog_notification(heading, msg_txt)
            platformtools.itemlist_refresh()

    else:
        if platformtools.dialog_yesno(heading,
                                      "¿Realmente desea eliminar '%s' de su biblioteca?" % item.infoLabels['title']):
            eliminar_todo(item)
Example #5
0
def mark_tvshow_as_updatable(item):
    logger.info()
    head_nfo, it = library.read_nfo(item.nfo)
    it.active = item.active
    filetools.write(item.nfo, head_nfo + it.tojson())

    platformtools.itemlist_refresh()
Example #6
0
def mark_tvshow_as_updatable(item):
    logger.info("pelisalacarta.channels.biblioteca mark_tvshow_as_updatable")
    url_scraper = filetools.read(item.nfo, 0, 1)
    it = Item().fromjson(filetools.read(item.nfo, 1))
    it.active = item.active
    filetools.write(item.nfo, url_scraper + it.tojson())

    platformtools.itemlist_refresh()
Example #7
0
def menu(item):
    logger.info("pelisalacarta.channels.descargas menu")

    # Opciones disponibles para el menu
    op = ["Descargar", "Eliminar de la lista", "Reiniciar descarga"]

    opciones = []

    # Opciones para el menu
    if item.downloadStatus == 0:  # Sin descargar
        opciones.append(op[0])  # Descargar
        opciones.append(op[1])  # Eliminar de la lista

    if item.downloadStatus == 1:  # descarga parcial
        opciones.append(op[0])  # Descargar
        opciones.append(op[2])  # Reiniciar descarga
        opciones.append(op[1])  # Eliminar de la lista

    if item.downloadStatus == 2:  # descarga completada
        opciones.append(op[1])  # Eliminar de la lista
        opciones.append(op[2])  # Reiniciar descarga

    if item.downloadStatus == 3:  # descarga con error
        opciones.append(op[2])  # Reiniciar descarga
        opciones.append(op[1])  # Eliminar de la lista

    # Mostramos el dialogo
    seleccion = platformtools.dialog_select("Elige una opción", opciones)

    # -1 es cancelar
    if seleccion == -1: return

    logger.info("pelisalacarta.channels.descargas menu opcion=%s" % (opciones[seleccion]))
    # Opcion Eliminar
    if opciones[seleccion] == op[1]:
        filetools.remove(item.path)

    # Opcion inicaiar descarga
    if opciones[seleccion] == op[0]:
        start_download(item)

    # Reiniciar descarga
    if opciones[seleccion] == op[2]:
        if filetools.isfile(os.path.join(config.get_setting("downloadpath"), item.downloadFilename)):
            filetools.remove(os.path.join(config.get_setting("downloadpath"), item.downloadFilename))
        JSONItem = Item().fromjson(filetools.read(item.path))
        JSONItem.downloadStatus = 0
        JSONItem.downloadComplete = 0
        JSONItem.downloadProgress = 0
        JSONItem.downloadUrl = ""
        filetools.write(item.path, JSONItem.tojson())

    platformtools.itemlist_refresh()
Example #8
0
def mark_season_as_watched(item):
    logger.info("pelisalacarta.channels.biblioteca mark_season_as_watched")
    # logger.debug("item:\n" + item.tostring('\n'))

    # Obtener el diccionario de episodios marcados
    f = filetools.join(item.path, "tvshow.nfo")
    url_scraper = filetools.read(f, 0, 1)
    it = Item().fromjson(filetools.read(f, 1))
    if not hasattr(it, "library_playcounts"):
        it.library_playcounts = {}

    # Obtenemos los archivos de los episodios
    raiz, carpetas_series, ficheros = filetools.walk(item.path).next()

    # Marcamos cada uno de los episodios encontrados de esta temporada
    episodios_marcados = 0
    for i in ficheros:
        if i.endswith(".strm"):
            season_episode = scrapertools.get_season_and_episode(i)
            if not season_episode:
                # El fichero no incluye el numero de temporada y episodio
                continue
            season, episode = season_episode.split("x")

            if int(item.contentSeason) == -1 or int(season) == int(item.contentSeason):
                name_file = os.path.splitext(os.path.basename(i))[0]
                it.library_playcounts[name_file] = item.playcount
                episodios_marcados += 1

    if episodios_marcados:
        if int(item.contentSeason) == -1:
            # Añadimos todas las temporadas al diccionario item.library_playcounts
            for k in it.library_playcounts.keys():
                if k.startswith("season"):
                    it.library_playcounts[k] = item.playcount
        else:
            # Añadimos la temporada al diccionario item.library_playcounts
            it.library_playcounts["season %s" % item.contentSeason] = item.playcount

            # se comprueba que si todas las temporadas están vistas, se marque la serie como vista
            it = check_tvshow_playcount(it, item.contentSeason)

        # Guardamos los cambios en tvshow.nfo
        filetools.write(f, url_scraper + it.tojson())
        item.infoLabels["playcount"] = item.playcount

        if config.is_xbmc():
            # Actualizamos la BBDD de Kodi
            library.mark_season_as_watched_on_kodi(item, item.playcount)

    platformtools.itemlist_refresh()
Example #9
0
def write_data(channel, show, data):
    # OBTENEMOS LOS DATOS DEL JSON
    dict_series = get_tvshows(channel)
    tvshow = show.strip()
    list_season_episode = dict_series.get(tvshow, {}).get(TAG_SEASON_EPISODE, [])
    logger.debug("data {0}".format(list_season_episode))

    if data:
        # cambiamos el orden para que se vea en orden descendente y usarse bien en el _data.json
        data.sort(key=lambda el: int(el[0]), reverse=True)
        dict_renumerate = {TAG_SEASON_EPISODE: data}

        dict_series[tvshow] = dict_renumerate
    else:
        # hemos borrado todos los elementos, por lo que se borra la serie del fichero
        del dict_series[tvshow]

    fname, json_data = update_json_data(dict_series, channel)
    result = filetools.write(fname, json_data)

    if result:
        if data:
            message = "FILTRO GUARDADO"
        else:
            message = "FILTRO BORRADO"
    else:
        message = "Error al guardar en disco"

    heading = show.strip()
    platformtools.dialog_notification(heading, message)
Example #10
0
def save_favourites(favourites_list):
    raw = '<favourites>' + chr(10)
    for name,thumb,data in favourites_list:
        raw += '    <favourite name="%s" thumb="%s">%s</favourite>' %(name,thumb,data) + chr(10)
    raw += '</favourites>' + chr(10)

    return filetools.write(FAVOURITES_PATH, raw)
def check_json_file(data, fname, dict_data):
    """
    Comprueba que si dict_data(conversion del fichero JSON a dict) no es un diccionario, se genere un fichero con
    data de nombre fname.bk.

    :param data: contenido del fichero fname
    :type data: str
    :param fname: nombre del fichero leido
    :type fname: str
    :param dict_data: nombre del diccionario
    :type dict_data: dict
    """
    logger.info("[filtertools.py] check_json_file")
    if not dict_data:
        logger.info("Error al cargar el json del fichero {0}".format(fname))

        if data != "":
            # se crea un nuevo fichero
            title = filetools.write("{0}.bk".format(fname), data)
            if title != "":
                logger.info("Ha habido un error al guardar el fichero: {0}.bk"
                            .format(fname))
            else:
                logger.info("Se ha guardado una copia con el nombre: {0}.bk"
                            .format(fname))
        else:
            logger.info("Está vacío el fichero: {0}".format(fname))
Example #12
0
def mark_content_as_watched(item):
    logger.info()
    # logger.debug("item:\n" + item.tostring('\n'))

    if filetools.exists(item.nfo):
        head_nfo = filetools.read(item.nfo, 0, 1)
        it = Item().fromjson(filetools.read(item.nfo, 1))

        if item.contentType == 'movie':
            name_file = os.path.splitext(os.path.basename(item.nfo))[0]
        elif item.contentType == 'episode':
            name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2))
        else:
            name_file = item.contentTitle

        if not hasattr(it, 'library_playcounts'):
            it.library_playcounts = {}
        it.library_playcounts.update({name_file: item.playcount})

        # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada
        if item.contentType != 'movie':
            it = check_season_playcount(it, item.contentSeason)

        # Guardamos los cambios en item.nfo
        if filetools.write(item.nfo, head_nfo + it.tojson()):
            item.infoLabels['playcount'] = item.playcount

            if item.contentType == 'tvshow':
                # Actualizar toda la serie
                new_item = item.clone(contentSeason=-1)
                mark_season_as_watched(new_item)

            if config.is_xbmc():
                library.mark_content_as_watched_on_kodi(item, item.playcount)
                platformtools.itemlist_refresh()
Example #13
0
def borrar_filtro(item):
    logger.info()
    if item:
        # OBTENEMOS LOS DATOS DEL JSON
        dict_series = get_tvshows(item.from_channel)
        tvshow = item.show.strip().lower()

        heading = "¿Está seguro que desea eliminar el filtro?"
        line1 = "Pulse 'Si' para eliminar el filtro de [COLOR blue]{0}[/COLOR], pulse 'No' o cierre la ventana para " \
                "no hacer nada.".format(item.show.strip())

        if platformtools.dialog_yesno(heading, line1) == 1:
            lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "")
            dict_series.pop(tvshow, None)

            fname, json_data = update_json_data(dict_series, item.from_channel)
            result = filetools.write(fname, json_data)

            if result:
                message = "FILTRO ELIMINADO"
            else:
                message = "Error al guardar en disco"

            heading = "{0} [{1}]".format(item.show.strip(), lang_selected)
            platformtools.dialog_notification(heading, message)
Example #14
0
def mark_content_as_watched(item):
    logger.info("pelisalacarta.channels.biblioteca mark_content_as_watched")
    # logger.debug("item:\n" + item.tostring('\n'))

    if filetools.exists(item.nfo):
        url_scraper = filetools.read(item.nfo, 0, 1)
        it = Item().fromjson(filetools.read(item.nfo, 1))

        if item.contentType == "movie":
            name_file = os.path.splitext(os.path.basename(item.nfo))[0]
        elif item.contentType == "episode":
            name_file = item.contentSeason + "x" + item.contentEpisodeNumber
        else:
            name_file = item.contentTitle

        if not hasattr(it, "library_playcounts"):
            it.library_playcounts = {}
        it.library_playcounts.update({name_file: item.playcount})

        # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada
        if item.contentType != "movie":
            it = check_season_playcount(it, item.contentSeason)

        # Guardamos los cambios en item.nfo
        if filetools.write(item.nfo, url_scraper + it.tojson()):
            item.infoLabels["playcount"] = item.playcount

            if item.contentType == "tvshow":
                # Actualizar toda la serie
                new_item = item.clone(contentSeason=-1)
                mark_season_as_watched(new_item)

            if config.is_xbmc():
                library.mark_content_as_watched_on_kodi(item, item.playcount)
                platformtools.itemlist_refresh()
Example #15
0
def restart_error(item):
    logger.info("pelisalacarta.channels.descargas restart_error")
    for fichero in sorted(filetools.listdir(item.url)):
        if fichero.endswith(".json"):
            download_item = Item().fromjson(filetools.read(os.path.join(item.url, fichero)))
            serie_name = "%s [%s]" % (download_item.contentSerieName, download_item.contentChannel)
            if not item.serie_name or item.serie_name == serie_name:
              if download_item.downloadStatus == 3:
                  if filetools.isfile(os.path.join(config.get_setting("downloadpath"), download_item.downloadFilename)):
                      filetools.remove(os.path.join(config.get_setting("downloadpath"), download_item.downloadFilename))
                  download_item.downloadStatus = 0
                  download_item.downloadComplete = 0
                  download_item.downloadProgress = 0
                  download_item.downloadUrl = ""
                  filetools.write(os.path.join(item.url, fichero), download_item.tojson())

    platformtools.itemlist_refresh()
def decrypt_subs(iv, data, id):
    from Crypto.Cipher import AES
    data = base64.b64decode(data.encode('utf-8'))
    iv = base64.b64decode(iv.encode('utf-8'))
    id = int(id)

    def obfuscate_key_aux(count, modulo, start):
        output = list(start)
        for _ in range(count):
            output.append(output[-1] + output[-2])
        # cut off start values
        output = output[2:]
        output = list(map(lambda x: x % modulo + 33, output))
        return output

    def obfuscate_key(key):
        from math import pow, sqrt, floor
        num1 = int(floor(pow(2, 25) * sqrt(6.9)))
        num2 = (num1 ^ key) << 5
        num3 = key ^ num1
        num4 = num3 ^ (num3 >> 3) ^ num2
        prefix = obfuscate_key_aux(20, 97, (1, 2))
        prefix = struct.pack('B' * len(prefix), *prefix)
        shaHash = sha1(prefix + str(num4).encode('ascii')).digest()
        decshaHash = []
        for char in shaHash:
            decshaHash.append(ord(char))
        # Extend 160 Bit hash to 256 Bit
        return decshaHash + [0] * 12

    key = obfuscate_key(id)
    key = struct.pack('B' * len(key), *key)

    decryptor = AES.new(key, AES.MODE_CBC, iv)
    decrypted_data = decryptor.decrypt(data)
    data = zlib.decompress(decrypted_data)
    
    import xml.etree.ElementTree as ET
    raiz = ET.fromstring(data)

    ass_sub = convert_to_ass(raiz)
    file_sub = filetools.join(config.get_data_path(), 'crunchyroll_sub.ass')
    filetools.write(file_sub, ass_sub)
    return file_sub
def mark_as_watched_on_strm(item):
    """
    Marca un .strm como "visto" añadiendo el parametro "playcount" a los infoLabels del strm.
    @param item: item que queremos marcar como visto
    @type item: item
    """
    logger.info("streamondemand.platformcode.library mark_as_watched_on_strm")
    if not config.get_setting("mark_as_watched") == "true":
        return

    xbmc.sleep(5000)

    while xbmc.Player().isPlaying():
        tiempo_actual = xbmc.Player().getTime()
        totaltime = xbmc.Player().getTotalTime()
        condicion = int(config.get_setting("watched_setting"))

        if condicion == 0:  # '5 minutos'
            mark_time = 300
        elif condicion == 1:  # '30%'
            mark_time = totaltime * 0.3
        elif condicion == 2:  # '50%'
            mark_time = totaltime * 0.5
        elif condicion == 3:  # '80%'
            mark_time = totaltime * 0.8

        logger.debug(str(mark_time))

        if tiempo_actual > mark_time:
            strm = Item().fromurl(filetools.read(item.path))
            if not type(strm.infoLabels) == dict:
                strm.infoLabels = {}
            strm.infoLabels["playcount"] = 1
            addon_name = sys.argv[0].strip()

            if not addon_name:
                addon_name = "plugin://plugin.video.pelisalacarta/"

            filetools.write(item.path + ".json", strm.tojson())
            filetools.write(item.path, '{addon}?{url}'.format(addon=addon_name, url=strm.tourl()))
            break

        xbmc.sleep(30000)
Example #18
0
def write_json(item):
    logger.info("pelisalacarta.channels.descargas write_json")
  
    item.action = "menu"
    item.channel = "descargas"
    item.downloadStatus = STATUS_CODES.stoped
    item.downloadProgress = 0
    item.downloadSize = 0
    item.downloadCompleted = 0
    if not item.contentThumbnail:
      item.contentThumbnail = item.thumbnail
    
    for name in ["text_bold", "text_color", "text_italic", "context", "totalItems", "viewmode", "title", "fulltitle", "thumbnail"]:
      if item.__dict__.has_key(name):
        item.__dict__.pop(name)

    path = filetools.encode(os.path.join(config.get_setting("downloadlistpath"), str(time.time()) + ".json"))
    filetools.write(path, item.tojson())
    item.path = path
    time.sleep(0.1)
Example #19
0
def check_bookmark(savepath):
    from channels import favoritos
    for fichero in filetools.listdir(savepath):
        # Ficheros antiguos (".txt")
        if fichero.endswith(".txt"):
            # Esperamos 0.1 segundos entre ficheros, para que no se solapen los nombres de archivo
            time.sleep(0.1)

            # Obtenemos el item desde el .txt
            canal, titulo, thumbnail, plot, server, url, fulltitle = favoritos.readbookmark(fichero, savepath)
            item = Item(channel=canal, action="play", url=url, server=server, title=fulltitle, thumbnail=thumbnail,
                        plot=plot, fanart=thumbnail, extra=os.path.join(savepath, fichero), fulltitle=fulltitle,
                        folder=False)

            # Eliminamos el .txt
            os.remove(item.extra)
            item.extra = ""

            # Guardamos el archivo
            filename = os.path.join(savepath, str(time.time()) + ".json")
            filetools.write(filename, item.tojson())
def create_nfo_file(video_id, path, type_video):
    """
    crea el fichero nfo con la información para scrapear la pelicula o serie
    @type video_id: str
    @param video_id: codigo identificativo del video
    @type path: str
    @param path: ruta donde se creará el fichero
    @type type_video: str
    @param type_video: tipo de video "serie" o "pelicula"
    """
    # TODO meter un parametro más "scraper" para elegir entre una lista: imdb, tvdb, etc... y con el video_id pasado de
    # esa pagina se genere el nfo especifico
    logger.info("streamondemand.platformcode.library create_nfo_file")

    if type_video == "serie":
        data = "https://www.themoviedb.org/tv/{0}".format(video_id)
        nfo_file = filetools.join(path, "tvshow.nfo")
    else:
        data = "https://www.themoviedb.org/movie/{0}".format(video_id)
        nfo_file = path + ".nfo"

    filetools.write(nfo_file, data)
Example #21
0
def write_json(item):
    logger.info("pelisalacarta.channels.descargas write_json")

    item.action = "menu"
    item.channel = "descargas"
    item.downloadStatus = STATUS_CODES.stoped
    item.downloadProgress = 0
    item.downloadSize = 0
    item.downloadCompleted = 0
    if not item.contentThumbnail:
        item.contentThumbnail = item.thumbnail

    for name in [
            "text_bold", "text_color", "text_italic", "context", "totalItems",
            "viewmode", "title", "fulltitle", "thumbnail"
    ]:
        if item.__dict__.has_key(name):
            item.__dict__.pop(name)

    path = os.path.join(config.get_setting("downloadlistpath"),
                        str(time.time()) + ".json")
    filetools.write(path, item.tojson())
    item.path = path
    time.sleep(0.1)
Example #22
0
def obtener_data(url, referer=''):
    headers = {}
    if referer != '': headers['Referer'] = referer
    data = httptools.downloadpage(url, headers=headers).data
    if "Javascript is required" in data:
        ck = decodificar_cookie(data)
        logger.info("Javascript is required. Cookie necesaria %s" % ck)

        headers['Cookie'] = ck
        data = httptools.downloadpage(url, headers=headers).data

        # Guardar la cookie y eliminar la que pudiera haber anterior
        cks = ck.split("=")
        cookie_file = filetools.join(config.get_data_path(), 'cookies.dat')
        cookie_data = filetools.read(cookie_file)
        cookie_data = re.sub(
            r"www\.pelispedia\.tv\tFALSE\t/\tFALSE\t\tsucuri_(.*)\n", "",
            cookie_data)
        cookie_data += "www.pelispedia.tv\tFALSE\t/\tFALSE\t\t%s\t%s\n" % (
            cks[0], cks[1])
        filetools.write(cookie_file, cookie_data)
        logger.info("Añadida cookie %s con valor %s" % (cks[0], cks[1]))

    return data
Example #23
0
def update_tvshow(item):
    logger.debug()
    # logger.debug("item:\n" + item.tostring('\n'))

    heading = config.get_localized_string(60037)
    p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), heading)
    p_dialog.update(0, heading, item.contentSerieName)

    import service
    if service.update(item.path, p_dialog, 0, 100, item, False) and config.is_xbmc() and config.get_setting("videolibrary_kodi"):
        from platformcode import xbmc_videolibrary
        xbmc_videolibrary.update(folder=filetools.basename(item.path))

    p_dialog.close()

    # check if the TV show is ended or has been canceled and ask the user to remove it from the video library update
    nfo_path = filetools.join(item.path, "tvshow.nfo")
    head_nfo, item_nfo = videolibrarytools.read_nfo(nfo_path)
    if item.active and not item_nfo.active:
        # if not platformtools.dialog_yesno(config.get_localized_string(60037).replace('...',''), config.get_localized_string(70268) % item.contentSerieName):
        item_nfo.active = 1
        filetools.write(nfo_path, head_nfo + item_nfo.tojson())

    platformtools.itemlist_refresh()
Example #24
0
def get_from_subdivx(sub_url):
    """
    :param sub_url: Url de descarga del subtitulo alojado en suvdivx.com
           Por Ejemplo: http://www.subdivx.com/bajar.php?id=573942&u=8

    :return: La ruta al subtitulo descomprimido
    """

    logger.info()

    sub = ''
    sub_dir = os.path.join(config.get_data_path(), 'temp_subs')

    if os.path.exists(sub_dir):
        for sub_file in os.listdir(sub_dir):
            old_sub = os.path.join(sub_dir, sub_file)
            os.remove(old_sub)
    else:
        os.mkdir(sub_dir)

    sub_url = sub_url.replace("&amp;", "&")
    sub_data = httptools.downloadpage(sub_url, follow_redirects=False)
    if 'x-frame-options' not in sub_data.headers:
        sub_url = '%s' % sub_data.headers['location']
        ext = sub_url[-4::]
        file_id = "subtitle%s" % ext
        filename = os.path.join(sub_dir, file_id)
        try:
            data_dl = httptools.downloadpage(sub_url).data
            filetools.write(filename, data_dl)
            sub = extract_file_online(sub_dir, filename)
        except:
            logger.info('sub no valido')
    else:
        logger.info('sub no valido')
    return sub
Example #25
0
def verify_copy_folders(custom_code_dir, custom_code_json_path):
    logger.info()

    #verificamos si es una nueva versión de Alfa instalada o era la existente.  Si es la existente, nos vamos sin hacer nada
    json_data_file = filetools.join(custom_code_json_path, json_data_file_name)
    json_data = jsontools.load(filetools.read(json_data_file))
    current_version = config.get_addon_version(with_fix=False)
    if current_version == json_data['addon_version']:
        return

    #Ahora copiamos los archivos desde el área de Userdata, Custom_code, sobre las carpetas del add-on
    for root, folders, files in os.walk(custom_code_dir):
        for file in files:
            input_file = filetools.join(root, file)
            output_file = input_file.replace(custom_code_dir,
                                             custom_code_json_path)
            if filetools.copy(input_file, output_file, silent=True) == False:
                return

    #Guardamaos el json con la versión actual de Alfa, para no volver a hacer la copia hasta la nueva versión
    json_data['addon_version'] = current_version
    filetools.write(json_data_file, jsontools.dump(json_data))

    return
Example #26
0
def check_blacklist(domain, expiration=0):
    res = True
    if not filetools.exists(PATH_BL):
        return res

    try:
        expiration_default = 30
        bl_data = jsontools.load(filetools.read(PATH_BL))
        bl_data_clean = bl_data.copy()
        if not expiration:
            expiration = config.get_setting('cf_assistant_bl_expiration',
                                            default=expiration_default) * 60
            config.set_setting('cf_assistant_bl_expiration',
                               expiration_default)
            expiration = expiration_default * 60
        else:
            expiration = expiration * 60
        time_today = time.time()

        if bl_data:
            for domain_reg, time_rec in list(bl_data_clean.items()):
                if time_today > time_rec + expiration:
                    del bl_data[domain_reg]
            filetools.write(PATH_BL, jsontools.dump(bl_data))
            for domain_reg, time_rec in list(bl_data.items()):
                if domain in domain_reg:
                    res = False
                    break
            else:
                res = True
    except:
        logger.error(traceback.format_exc())
        filetools.remove(PATH_BL)
        res = True

    return res
Example #27
0
def save_download_tvshow(item):
    logger.info("pelisalacarta.channels.descargas save_download_tvshow")
    logger.info("Tipo: %s" % item.contentType)

    progreso = platformtools.dialog_progress("Descargas",
                                             "Obteniendo datos de la serie")

    tmdb.find_and_set_infoLabels_tmdb(item)

    item.downloadFilename = item.downloadFilename = "%s [%s]" % (
        item.contentSerieName, item.contentChannel)
    episodes = get_episodes(item)

    progreso.update(0, "Añadiendo capitulos...")

    for x, i in enumerate(episodes):
        progreso.update(x * 100 / len(episodes),
                        os.path.basename(i.downloadFilename))
        i.path = os.path.join(config.get_setting("downloadlistpath"),
                              str(time.time()) + ".json")
        filetools.write(i.path, i.tojson())
        time.sleep(0.1)

    progreso.close()

    if not platformtools.dialog_yesno(config.get_localized_string(30101),
                                      "¿Iniciar la descarga ahora?"):
        platformtools.dialog_ok(
            config.get_localized_string(30101),
            str(len(episodes)) + " capitulos de: " + item.contentSerieName,
            config.get_localized_string(30109))
    else:
        for i in episodes:
            res = start_download(i)
            if res == 1:
                break
Example #28
0
def restart_error(item):
    logger.info("pelisalacarta.channels.descargas restart_error")
    for fichero in sorted(filetools.listdir(item.url)):
        if fichero.endswith(".json"):
            download_item = Item().fromjson(
                filetools.read(os.path.join(item.url, fichero)))
            serie_name = "%s [%s]" % (download_item.contentSerieName,
                                      download_item.contentChannel)
            if not item.serie_name or item.serie_name == serie_name:
                if download_item.downloadStatus == 3:
                    if filetools.isfile(
                            os.path.join(config.get_setting("downloadpath"),
                                         download_item.downloadFilename)):
                        filetools.remove(
                            os.path.join(config.get_setting("downloadpath"),
                                         download_item.downloadFilename))
                    download_item.downloadStatus = 0
                    download_item.downloadComplete = 0
                    download_item.downloadProgress = 0
                    download_item.downloadUrl = ""
                    filetools.write(os.path.join(item.url, fichero),
                                    download_item.tojson())

    platformtools.itemlist_refresh()
def save_filter(item):
    """
    salva el filtro a través del menú contextual

    :param item: item
    :type item: item
    """
    logger.info("[filtertools.py] save_filter")

    dict_series = get_filtered_tvshows(item.from_channel)

    name = item.show.lower().strip()
    logger.info("[filtertools.py] config_filter name {0}".format(name))

    open_tag_idioma = (0, item.title.find("[")+1)[item.title.find("[") >= 0]
    close_tag_idioma = (0, item.title.find("]"))[item.title.find("]") >= 0]
    idioma = item.title[open_tag_idioma: close_tag_idioma]

    open_tag_calidad = (0, item.title.find("[", item.title.find("[") + 1)+1)[item.title.find("[", item.title.find("[") + 1) >= 0]
    close_tag_calidad = (0, item.title.find("]", item.title.find("]") + 1))[item.title.find("]", item.title.find("]") + 1) >= 0]
    calidad_no_permitida = ""  # item.title[open_tag_calidad: close_tag_calidad]

    # filter_idioma = ""
    # logger.info("idioma {0}".format(idioma))
    # if idioma != "":
    #     filter_idioma = [key for key, value in dict_idiomas.iteritems() if value == idioma][0]

    list_calidad = list()

    dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: True, TAG_LANGUAGE: idioma, TAG_QUALITY_NOT_ALLOWED: list_calidad}
    dict_series[name] = dict_filter

    # filter_list = item.extra.split("##")
    # dict_series = eval(filter_list[0])
    # dict_filter = eval(filter_list[2])
    # dict_series[filter_list[1].strip().lower()] = dict_filter
    # logger.info("categoria {0}".format(item.from_channel))

    fname, json_data = update_json_data(dict_series, item.from_channel)
    result = filetools.write(fname, json_data)

    if result:
        message = "FILTRO GUARDADO"
    else:
        message = "Error al guardar en disco"

    heading = "{0} [1]".format(item.show.strip(), idioma)
    platformtools.dialog_notification(heading, message)
Example #30
0
    def tojson(self, path=""):
        from core import filetools
        """
        Create a JSON from the item, to save favorite files, download list, etc....
        If a path is specified, it saves it in the specified path, if not, it returns the string json
        Applications: item.tojson(path="path\archivo\json.json")
                      file.write(item.tojson())

        @param path: path
        @type path: str
        """
        if path:
            #open(path, "wb").write(json.dump(self.__dict__))
            res = filetools.write(path, json.dump(self.__dict__))
        else:
            return json.dump(self.__dict__)
Example #31
0
    def tojson(self, path=""):
        from core import filetools
        """
        Crea un JSON a partir del item, para guardar archivos de favoritos, lista de descargas, etc...
        Si se especifica un path, te lo guarda en la ruta especificada, si no, devuelve la cadena json
        Usos: item.tojson(path="ruta\archivo\json.json")
              file.write(item.tojson())

        @param path: ruta
        @type path: str
        """
        if path:
            #open(path, "wb").write(json.dump(self.__dict__))
            res = filetools.write(path, json.dump(self.__dict__))
        else:
            return json.dump(self.__dict__)
Example #32
0
def guardar_valores(item, dict_data_saved):
    """
    Guarda los valores configurados en la ventana

    :param item: item
    :type item: Item
    :param dict_data_saved: diccionario con los datos salvados
    :type dict_data_saved: dict
    """
    logger.info()
    # Aqui tienes q gestionar los datos obtenidos del cuadro de dialogo
    if item and dict_data_saved:
        logger.debug('item: {0}\ndatos: {1}'.format(item.tostring(),
                                                    dict_data_saved))

        # OBTENEMOS LOS DATOS DEL JSON
        if item.from_channel == "biblioteca":
            item.from_channel = item.contentChannel
        dict_series = get_tvshows(item.from_channel)
        tvshow = item.show.strip().lower()

        logger.info("Se actualiza los datos")

        list_quality = []
        for _id, value in dict_data_saved.items():
            if _id in item.list_calidad and value:
                list_quality.append(_id.lower())

        lang_selected = item.list_idiomas[dict_data_saved[TAG_LANGUAGE]]
        dict_filter = {
            TAG_NAME: item.show,
            TAG_ACTIVE: dict_data_saved.get(TAG_ACTIVE, True),
            TAG_LANGUAGE: lang_selected,
            TAG_QUALITY_NOT_ALLOWED: list_quality
        }
        dict_series[tvshow] = dict_filter

        fname, json_data = update_json_data(dict_series, item.from_channel)
        result = filetools.write(fname, json_data)

        if result:
            message = "FILTRO GUARDADO"
        else:
            message = "Error al guardar en disco"

        heading = "{0} [{1}]".format(item.show.strip(), lang_selected)
        platformtools.dialog_notification(heading, message)
Example #33
0
def remove_channel(item):
    logger.info()
    import xbmc
    import xbmcgui
    path = filetools.join(config.get_data_path(), 'community_channels.json')

    community_json = open(path, "r")
    community_json = jsontools.load(community_json.read())

    id = item.channel_id
    to_delete = community_json['channels'][id]['channel_name']
    del community_json['channels'][id]
    res = filetools.write(path, jsontools.dump(community_json), silent=True)

    platformtools.dialog_notification('Alfa', '%s ha sido eliminado' % to_delete)
    platformtools.itemlist_refresh()
    return
Example #34
0
def save(item, dict_data_saved):
    """
    Guarda los valores configurados en la ventana

    @param item: item
    @type item: Item
    @param dict_data_saved: diccionario con los datos salvados
    @type dict_data_saved: dict
    """
    logger.info()

    if item and dict_data_saved:
        logger.debug('item: %s\ndatos: %s' % (item.tostring(), dict_data_saved))

        if item.from_channel == "biblioteca":
            item.from_channel = item.contentChannel
        dict_series = filetools.get_node_from_data_json(item.from_channel, TAG_TVSHOW_FILTER)
        tvshow = item.show.strip().lower()

        logger.info("Se actualiza los datos")

        list_quality = []
        for _id, value in dict_data_saved.items():
            if _id in item.list_quality and value:
                    list_quality.append(_id.lower())

        lang_selected = item.list_language[dict_data_saved[TAG_LANGUAGE]]
        dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: dict_data_saved.get(TAG_ACTIVE, True),
                       TAG_LANGUAGE: lang_selected, TAG_QUALITY_ALLOWED: list_quality}
        dict_series[tvshow] = dict_filter

        fname, json_data = filetools.update_json_data(dict_series, item.from_channel, TAG_TVSHOW_FILTER)
        result = filetools.write(fname, json_data)

        sound = False
        if result:
            message = "FILTRO GUARDADO"
        else:
            message = "Error al guardar en disco"
            sound = True

        heading = "%s [%s]" % (item.show.strip(), lang_selected)
        platformtools.dialog_notification(heading, message, sound=sound)

        if item.from_action in ["findvideos", "play"]:
            platformtools.itemlist_refresh()
def guardar_valores(item, dict_data_saved):
    """
    Guarda los valores configurados en la ventana

    :param item: item
    :type item: Item
    :param dict_data_saved: diccionario con los datos salvados
    :type dict_data_saved: dict
    """
    logger.info()
    # Aqui tienes q gestionar los datos obtenidos del cuadro de dialogo
    if item and dict_data_saved:
        logger.debug('item: {0}\ndatos: {1}'.format(item.tostring(), dict_data_saved))

        # OBTENEMOS LOS DATOS DEL JSON
        if item.from_channel == "biblioteca":
            item.from_channel = item.contentChannel
        dict_series = get_tvshows(item.from_channel)
        tvshow = item.show.strip().lower()

        logger.info("Se actualiza los datos")

        list_quality = []
        for _id, value in dict_data_saved.items():
            if _id in item.list_calidad and value:
                    list_quality.append(_id.lower())

        lang_selected = item.list_idiomas[dict_data_saved[TAG_LANGUAGE]]
        dict_filter = {TAG_NAME: item.show, TAG_ACTIVE: dict_data_saved.get(TAG_ACTIVE, True),
                       TAG_LANGUAGE: lang_selected, TAG_QUALITY_NOT_ALLOWED: list_quality}
        dict_series[tvshow] = dict_filter

        fname, json_data = update_json_data(dict_series, item.from_channel)
        result = filetools.write(fname, json_data)

        if result:
            message = "FILTRO GUARDADO"
        else:
            message = "Error al guardar en disco"

        heading = "{0} [{1}]".format(item.show.strip(), lang_selected)
        platformtools.dialog_notification(heading, message)

        if config.get_platform() == "mediaserver":
            platformtools.itemlist_refresh()
Example #36
0
def add_channel(item):
    logger.info()
    import xbmc
    import xbmcgui
    channel_to_add = {}
    json_file = ''
    result = platformtools.dialog_select('Agregar un canal', ['Desde archivo local', 'Desde URL'])
    if result == -1:
        return
    if result==0:
        file_path = xbmcgui.Dialog().browseSingle(1, 'Alfa - (Comunidad)', 'files')
        try:
            channel_to_add['path'] = file_path
            json_file = jsontools.load(filetools.read(file_path))
            channel_to_add['channel_name'] = json_file['channel_name']
            if "poster" in json_file:
                channel_to_add['poster'] = json_file['poster']
        except:
            pass

    elif result==1:
        url = platformtools.dialog_input("", 'Ingresa la URL del canal', False)
        try:
            channel_to_add['path'] = url
            json_file = jsontools.load(httptools.downloadpage(url).data)
        except:
            pass

    if len(json_file) == 0:
        return
    if "episodes_list" in json_file:
        platformtools.dialog_ok('Alfa', 'No es posible agregar este tipo de canal')
        return
    channel_to_add['channel_name'] = json_file['channel_name']
    path = filetools.join(config.get_data_path(), 'community_channels.json')

    community_json = jsontools.load(filetools.read(path))
    id = len(community_json['channels']) + 1
    community_json['channels'][id]=(channel_to_add)

    res = filetools.write(path, jsontools.dump(community_json), silent=True)

    platformtools.dialog_notification('Alfa', '%s se ha agregado' % json_file['channel_name'])
    platformtools.itemlist_refresh()
    return
Example #37
0
def search_for_unrar_in_error(download_paths, init=False):
    logger.info(download_paths)
    
    for torrent_client, path in download_paths:
        list_dir = filetools.listdir(path)
        for folder_w in list_dir:
            folder = filetools.join(path, folder_w)
            if filetools.isdir(folder):
                if not filetools.exists(filetools.join(folder, '_rar_control.json')):
                    continue
            else:
                if not '_rar_control.json' in folder:
                    continue

            rar_control = jsontools.load(filetools.read(filetools.join(folder, '_rar_control.json')))
            rar_control['status'] += ': Recovery'
            if ('UnRARing' in rar_control['status'] or 'RECOVERY' in rar_control['status']) and not init:
                continue
            if 'UnRARing' in rar_control['status'] or 'ERROR' in rar_control['status']:
                rar_control['status'] = 'RECOVERY: ' + rar_control['status']
            rar_control['download_path'] = folder
            rar_control['torr_client'] = torrent_client
            if 'ERROR' in rar_control['status'] or 'UnRARing' in rar_control['status'] \
                        or 'RECOVERY' in rar_control['status']:
                rar_control['error'] += 1
            ret = filetools.write(filetools.join(rar_control['download_path'], '_rar_control.json'), jsontools.dump(rar_control))
            logger.debug('%s, %s, %s, %s, %s, %s' % (rar_control['download_path'], \
                        rar_control['rar_names'][0], rar_control['password'], \
                        str(rar_control['error']), rar_control['error_msg'], rar_control['status']))
            if ('ERROR' in rar_control['status'] and rar_control['error'] > 2) \
                        or ('UnRARing' in rar_control['status'] and rar_control['error'] > 3) \
                        or ('RECOVERY' in rar_control['status'] and rar_control['error'] > 3)  \
                        or 'DONE' in rar_control['status']:
                continue
            
            if ret:
                try:
                    threading.Thread(target=call_unrar, args=(rar_control,)).start()    # Creamos un Thread independiente por UnRAR
                    time.sleep(1)                                               # Dejamos terminar la inicialización...
                except:                                                         # Si hay problemas de threading, pasamos al siguiente
                    logger.error(traceback.format_exc())

    if not init:
        sys.exit(0)
Example #38
0
def borrar(channel, show):
    logger.info()
    heading = "¿Está seguro que desea eliminar renumeración?"
    line1 = "Pulse 'Si' para eliminar la renumeración de [COLOR blue]{0}[/COLOR], pulse 'No' o cierre la ventana " \
            "para no hacer nada.".format(show.strip())

    if platformtools.dialog_yesno(heading, line1) == 1:
        dict_series = get_tvshows(channel)
        dict_series.pop(show, None)

        fname, json_data = update_json_data(dict_series, channel)
        result = filetools.write(fname, json_data)

        if result:
            message = "FILTRO ELIMINADO"
        else:
            message = "Error al guardar en disco"

        heading = show.strip()
        platformtools.dialog_notification(heading, message)
Example #39
0
def borrar(channel, show):
    logger.info()
    heading = "¿Está seguro que desea eliminar renumeración?"
    line1 = "Pulse 'Si' para eliminar la renumeración de [COLOR blue]{0}[/COLOR], pulse 'No' o cierre la ventana " \
            "para no hacer nada.".format(show.strip())

    if platformtools.dialog_yesno(heading, line1) == 1:
        dict_series = get_tvshows(channel)
        dict_series.pop(show, None)

        fname, json_data = update_json_data(dict_series, channel)
        result = filetools.write(fname, json_data)

        if result:
            message = "FILTRO ELIMINADO"
        else:
            message = "Error al guardar en disco"

        heading = show.strip()
        platformtools.dialog_notification(heading, message)
def del_filter(item):
    """
    elimina el filtro a través del menú contextual

    :param item: item
    :type item: item
    """
    logger.info("[filtertools.py] del_filter")

    dict_series = get_filtered_tvshows(item.from_channel)
    dict_series.pop(item.show.lower().strip(), None)

    fname, json_data = update_json_data(dict_series, item.from_channel)
    result = filetools.write(fname, json_data)

    if result:
        message = "FILTRO ELIMINADO"
    else:
        message = "Error al guardar en disco"

    heading = "{0}".format(item.show.strip())
    platformtools.dialog_notification(heading, message)
Example #41
0
def del_filter(item):
    """
    elimina el filtro a través del menú contextual

    :param item: item
    :type item: item
    """
    logger.info("[filtertools.py] del_filter")

    dict_series = get_filtered_tvshows(item.from_channel)
    dict_series.pop(item.show.lower().strip(), None)

    fname, json_data = update_json_data(dict_series, item.from_channel)
    result = filetools.write(fname, json_data)

    if result:
        message = "FILTRO ELIMINADO"
    else:
        message = "Error al guardar en disco"

    heading = "{0}".format(item.show.strip())
    platformtools.dialog_notification(heading, message)
Example #42
0
def save_from_context(item):
    """
    Salva el filtro a través del menú contextual

    @param item: item
    @type item: item
    """
    logger.info()

    dict_series = filetools.get_node_from_data_json(item.from_channel,
                                                    TAG_TVSHOW_FILTER)
    tvshow = item.show.strip().lower()

    dict_filter = {
        TAG_NAME: item.show,
        TAG_ACTIVE: True,
        TAG_LANGUAGE: item.language,
        TAG_QUALITY_ALLOWED: []
    }
    dict_series[tvshow] = dict_filter

    fname, json_data = filetools.update_json_data(dict_series,
                                                  item.from_channel,
                                                  TAG_TVSHOW_FILTER)
    result = filetools.write(fname, json_data)

    sound = False
    if result:
        message = "FILTRO GUARDADO"
    else:
        message = "Error al guardar en disco"
        sound = True

    heading = "%s [%s]" % (item.show.strip(), item.language)
    platformtools.dialog_notification(heading, message, sound=sound)

    if item.from_action in ["findvideos", "play"]:
        platformtools.itemlist_refresh()
Example #43
0
def delete_from_context(item):
    """
    Elimina el filtro a través del menú contextual

    @param item: item
    @type item: item
    """
    logger.info()

    # venimos desde get_links y no se ha obtenido ningún resultado, en menu contextual y damos a borrar
    if item.to_channel != "":
        item.from_channel = item.to_channel

    dict_series = filetools.get_node_from_data_json(item.from_channel,
                                                    TAG_TVSHOW_FILTER)
    tvshow = item.show.strip().lower()

    lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "")
    dict_series.pop(tvshow, None)

    fname, json_data = filetools.update_json_data(dict_series,
                                                  item.from_channel,
                                                  TAG_TVSHOW_FILTER)
    result = filetools.write(fname, json_data)

    sound = False
    if result:
        message = "FILTRO ELIMINADO"
    else:
        message = "Error al guardar en disco"
        sound = True

    heading = "%s [%s]" % (item.show.strip(), lang_selected)
    platformtools.dialog_notification(heading, message, sound=sound)

    if item.from_action in ["findvideos", "play", "no_filter"
                            ]:  # 'no_filter' es el mismo caso que L#601
        platformtools.itemlist_refresh()
Example #44
0
def mark_content_as_watched(item):
    logger.info()
    # logger.debug("item:\n" + item.tostring('\n'))

    if filetools.exists(item.nfo):
        head_nfo, it = videolibrarytools.read_nfo(item.nfo)

        if item.contentType == 'movie':
            name_file = os.path.splitext(os.path.basename(item.nfo))[0]
        elif item.contentType == 'episode':
            name_file = "%sx%s" % (item.contentSeason,
                                   str(item.contentEpisodeNumber).zfill(2))
        else:
            name_file = item.contentTitle

        if not hasattr(it, 'library_playcounts'):
            it.library_playcounts = {}
        it.library_playcounts.update({name_file: item.playcount})

        # se comprueba que si todos los episodios de una temporada están marcados, se marque tb la temporada
        if item.contentType != 'movie':
            it = check_season_playcount(it, item.contentSeason)

        # Guardamos los cambios en item.nfo
        if filetools.write(item.nfo, head_nfo + it.tojson()):
            item.infoLabels['playcount'] = item.playcount

            if item.contentType == 'tvshow':
                # Actualizar toda la serie
                new_item = item.clone(contentSeason=-1)
                mark_season_as_watched(new_item)

            if config.is_xbmc() and item.contentType == 'episode':
                from platformcode import xbmc_videolibrary
                xbmc_videolibrary.mark_content_as_watched_on_kodi(
                    item, item.playcount)

            platformtools.itemlist_refresh()
Example #45
0
def borrar_filtro(item):
    logger.info("[filtertools.py] borrar_filtro")
    if item:
        # OBTENEMOS LOS DATOS DEL JSON
        dict_series = get_filtered_tvshows(item.from_channel)
        tvshow = item.show.strip().lower()

        heading = "¿Está seguro que desea eliminar el filtro?"
        line1 = "Pulse 'Si' para eliminar el filtro de [COLOR blue]{0}[/COLOR], pulse 'No' o cierre la ventana para " \
                "no hacer nada.".format(item.show.strip())

        if platformtools.dialog_yesno(heading, line1) == 1:
            lang_selected = dict_series.get(tvshow, {}).get(TAG_LANGUAGE, "")
            dict_series.pop(tvshow, None)
            fname, json_data = update_json_data(dict_series, item.from_channel)
            result = filetools.write(fname, json_data)

            if result:
                message = "FILTRO ELIMINADO"
            else:
                message = "Error al guardar en disco"
            heading = "{0} [{1}]".format(item.show.strip(), lang_selected)
            platformtools.dialog_notification(heading, message)
Example #46
0
def mark_content_as_watched(item):
    logger.info()
    #logger.debug("item:\n" + item.tostring('\n'))

    if filetools.exists(item.nfo):
        head_nfo, it = videolibrarytools.read_nfo(item.nfo)

        if item.contentType == 'movie':
            name_file = os.path.splitext(filetools.basename(item.nfo))[0]
        elif item.contentType == 'episode':
            name_file = "%sx%s" % (item.contentSeason, str(item.contentEpisodeNumber).zfill(2))
        else:
            name_file = item.contentTitle

        if not hasattr(it, 'library_playcounts'):
            it.library_playcounts = {}
        it.library_playcounts.update({name_file: item.playcount})

        # it is verified that if all the episodes of a season are marked, tb the season is marked
        if item.contentType != 'movie':
            it = check_season_playcount(it, item.contentSeason)

        # We save the changes to item.nfo
        if filetools.write(item.nfo, head_nfo + it.tojson()):
            item.infoLabels['playcount'] = item.playcount

            if item.contentType == 'tvshow' and item.type != 'episode' :
                # Update entire series
                new_item = item.clone(contentSeason=-1)
                mark_season_as_watched(new_item)

            if config.is_xbmc():
                from platformcode import xbmc_videolibrary
                xbmc_videolibrary.mark_content_as_watched_on_kodi(item, item.playcount)

            platformtools.itemlist_refresh()
Example #47
0
def mark_content_as_watched2(item):
    logger.info()
    # logger.debug("item:\n" + item.tostring('\n'))
    if filetools.isfile(item.nfo):
        head_nfo, it = videolibrarytools.read_nfo(item.nfo)
        name_file = ""
        if item.contentType == 'movie' or item.contentType == 'tvshow':
            name_file = os.path.splitext(filetools.basename(item.nfo))[0]

            if name_file != 'tvshow' :
                it.library_playcounts.update({name_file: item.playcount})

        if item.contentType == 'episode' or item.contentType == 'tvshow' or item.contentType == 'list' or name_file == 'tvshow':
            name_file = os.path.splitext(filetools.basename(item.strm_path))[0]
            num_season = name_file [0]
            item.__setattr__('contentType', 'episode')
            item.__setattr__('contentSeason', num_season)

        else:
            name_file = item.contentTitle

        if not hasattr(it, 'library_playcounts'):
            it.library_playcounts = {}
        it.library_playcounts.update({name_file: item.playcount})

        # it is verified that if all the episodes of a season are marked, tb the season is marked
        if item.contentType != 'movie':
            it = check_season_playcount(it, item.contentSeason)

        # We save the changes to item.nfo
        if filetools.write(item.nfo, head_nfo + it.tojson()):
            item.infoLabels['playcount'] = item.playcount

            if config.is_xbmc():
                from platformcode import xbmc_videolibrary
                xbmc_videolibrary.mark_content_as_watched_on_kodi(item , item.playcount)
Example #48
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 = next(filetools.walk(path))
    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)
            if not season_episode:
                continue
        
            # 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
Example #49
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

    if not PY3:
        base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8")
    else:
        base_name = filetools.validate_path(base_name.replace('/', '-'))

    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 as exception:
            if exception.errno != errno.EEXIST:
                raise

    tvshow_path = filetools.join(path, "tvshow.nfo")
    if not filetools.exists(tvshow_path):
        # Creamos tvshow.nfo, si no existe, con la head_nfo, info de la serie y marcas de episodios vistos
        logger.info("Creando tvshow.nfo: " + tvshow_path)
        head_nfo = scraper.get_nfo(item)
        item.infoLabels['mediatype'] = "tvshow"
        item.infoLabels['title'] = item.contentSerieName
        item_tvshow = Item(title=item.contentSerieName, channel="videolibrary", action="get_seasons",
                           fanart=item.infoLabels['fanart'], thumbnail=item.infoLabels['thumbnail'],
                           infoLabels=item.infoLabels, path=path.replace(TVSHOWS_PATH, ""))
        item_tvshow.library_playcounts = {}
        item_tvshow.library_urls = {item.channel: item.url}

    else:
        # Si existe tvshow.nfo, pero estamos añadiendo un nuevo canal actualizamos el listado de urls
        head_nfo, item_tvshow = read_nfo(tvshow_path)
        item_tvshow.channel = "videolibrary"
        item_tvshow.action = "get_seasons"
        item_tvshow.library_urls[item.channel] = item.url

    # FILTERTOOLS
    # si el canal tiene filtro de idiomas, añadimos el canal y el show
    if episodelist and "list_language" in episodelist[0]:
        # si ya hemos añadido un canal previamente con filtro, añadimos o actualizamos el canal y show
        if "library_filter_show" in item_tvshow:
            if item.title_from_channel:
                item_tvshow.library_filter_show[item.channel] = item.title_from_channel
            else:
                item_tvshow.library_filter_show[item.channel] = item.show
        # no habia ningún canal con filtro y lo generamos por primera vez
        else:
            if item.title_from_channel:
                item_tvshow.library_filter_show = {item.channel: item.title_from_channel}
            else:
                item_tvshow.library_filter_show = {item.channel: item.show}

    if item.channel != "downloads":
        item_tvshow.active = 1  # para que se actualice a diario cuando se llame a videolibrary_service

    filetools.write(tvshow_path, head_nfo + item_tvshow.tojson())

    if not episodelist:
        # La lista de episodios esta vacia
        return 0, 0, 0, path

    # Guardar los episodios
    '''import time
    start_time = time.time()'''
    insertados, sobreescritos, fallidos = save_episodes(path, episodelist, item)
    '''msg = "Insertados: %d | Sobreescritos: %d | Fallidos: %d | Tiempo: %2.2f segundos" % \
          (insertados, sobreescritos, fallidos, time.time() - start_time)
    logger.debug(msg)'''

    return insertados, sobreescritos, fallidos, path
Example #50
0
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
    logger.info("url=" + page_url)

    # Lo pide una vez
    data = httptools.downloadpage(page_url, cookies=False).data
    # Si salta aviso, se carga la pagina de comprobacion y luego la inicial
    if "You try to access this video with Kodi" in data:
        url_reload = scrapertools.find_single_match(data, 'try to reload the page.*?href="([^"]+)"')
        url_reload = "http://www.flashx.tv" + url_reload[1:]
        try:
            data = httptools.downloadpage(url_reload, cookies=False).data
            data = httptools.downloadpage(page_url, cookies=False).data
        except:
            pass

    matches = scrapertools.find_multiple_matches(data, "<script type='text/javascript'>(.*?)</script>")
    for n, m in enumerate(matches):
        if m.startswith("eval"):
            try:
                m = jsunpack.unpack(m)
                fake = (scrapertools.find_single_match(m, "(\w{40,})") == "")
                if fake:
                    m = ""
                else:
                    break
            except:
                m = ""
    match = m
    if "sources:[{file:" not in match:
        page_url = page_url.replace("playvid-", "")

        headers = {'Host': 'www.flashx.tv',
                   'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36',
                   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                   'Accept-Language': 'en-US,en;q=0.5',
                   'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1',
                   'Cookie': ''}
        data = httptools.downloadpage(page_url, headers=headers, replace_headers=True).data
        flashx_id = scrapertools.find_single_match(data, 'name="id" value="([^"]+)"')
        fname = scrapertools.find_single_match(data, 'name="fname" value="([^"]+)"')
        hash_f = scrapertools.find_single_match(data, 'name="hash" value="([^"]+)"')
        post = 'op=download1&usr_login=&id=%s&fname=%s&referer=&hash=%s&imhuman=Proceed+to+video' % (
        flashx_id, urllib.quote(fname), hash_f)
        wait_time = scrapertools.find_single_match(data, "<span id='xxc2'>(\d+)")

        file_id = scrapertools.find_single_match(data, "'file_id', '([^']+)'")
        #coding_url = 'https://files.fx.fastcontentdelivery.com/jquery2.js?fx=%s' % base64.encodestring(file_id)
        #headers['Host'] = "files.fx.fastcontentdelivery.com"
        headers['Referer'] = "https://www.flashx.tv/"
        headers['Accept'] = "*/*"
        #coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data
        coding_url = 'https://www.flashx.tv/counter.cgi?fx=%s' % base64.encodestring(file_id)
        headers['Host'] = "www.flashx.tv"
        #coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data

        coding_url = 'https://www.flashx.tv/flashx.php?fxfx=3'
        headers['X-Requested-With'] = 'XMLHttpRequest'
        coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data

        try:
            time.sleep(int(wait_time) + 1)
        except:
            time.sleep(6)

        headers.pop('X-Requested-With')
        headers['Content-Type'] = 'application/x-www-form-urlencoded'
        data = httptools.downloadpage('https://www.flashx.tv/dl?playthis', post, headers, replace_headers=True).data
        matches = scrapertools.find_multiple_matches(data, "(eval\(function\(p,a,c,k.*?)\s+</script>")
        for match in matches:
            if match.startswith("eval"):
                try:
                    match = jsunpack.unpack(match)
                    fake = (scrapertools.find_single_match(match, "(\w{40,})") == "")
                    if fake:
                        match = ""
                    else:
                        break
                except:
                    match = ""

        if not match:
            match = data

    # Extrae la URL
    # {file:"http://f11-play.flashx.tv/luq4gfc7gxixexzw6v4lhz4xqslgqmqku7gxjf4bk43u4qvwzsadrjsozxoa/video1.mp4"}
    video_urls = []
    match = match.replace("\\","").replace('\"',"\'")
    media_urls = scrapertools.find_multiple_matches(match, "{src:'([^']+)'.*?,label:'([^']+)'")
    subtitle = ""
    for media_url, label in media_urls:
        if media_url.endswith(".srt") and label == "Spanish":
            try:
                from core import filetools
                data = scrapertools.downloadpage(media_url)
                subtitle = os.path.join(config.get_data_path(), 'sub_flashx.srt')
                filetools.write(subtitle, data)
            except:
                import traceback
                logger.info("Error al descargar el subtítulo: " + traceback.format_exc())

    for media_url, label in media_urls:
        if not media_url.endswith("png") and not media_url.endswith(".srt"):
            video_urls.append(["." + media_url.rsplit('.', 1)[1] + " [flashx]", media_url, 0, subtitle])

    for video_url in video_urls:
        logger.info("%s - %s" % (video_url[0], video_url[1]))

    return video_urls
def check_for_update(overwrite=True):
    logger.info("Actualizando series...")
    p_dialog = None
    serie_actualizada = False
    update_when_finished = False
    hoy = datetime.date.today()

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

            heading = 'Actualizando biblioteca....'
            p_dialog = platformtools.dialog_progress_bg('pelisalacarta', heading)
            p_dialog.update(0, '')
            show_list = []

            for path, folders, files in filetools.walk(library.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 = library.read_nfo(tvshow_file)
                path = filetools.dirname(tvshow_file)

                logger.info("serie=" + serie.contentSerieName)
                p_dialog.update(int(math.ceil((i+1) * t)), heading, serie.contentSerieName)

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

                if not serie.active:
                    # si la serie no esta activa descartar
                    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", "biblioteca") == 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)

                if interval != int(serie.active) or update_next.strftime('%Y-%m-%d') != serie.update_next:
                    serie.active = interval
                    serie.update_next = update_next.strftime('%Y-%m-%d')
                    serie.channel = "biblioteca"
                    serie.action = "get_temporadas"
                    filetools.write(tvshow_file, head_nfo + serie.tojson())

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

            if config.get_setting("search_new_content", "biblioteca") == 1 and update_when_finished:
                    # Actualizamos la biblioteca de Kodi: Buscar contenido en todas las series
                    if config.is_xbmc():
                        from platformcode import xbmc_library
                        xbmc_library.update()

            p_dialog.close()

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

    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()
Example #52
0
def save_library_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("pelisalacarta.platformcode.library save_library_episodes")

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

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

    # Silent es para no mostrar progreso (para library_service)
    if not silent:
        # progress dialog
        p_dialog = platformtools.dialog_progress('pelisalacarta', 'Añadiendo episodios...')
        p_dialog.update(0, 'Añadiendo episodio...')

    # fix float porque la division se hace mal en python 2.x
    t = float(100) / len(episodelist)

    for i, e in enumerate(episodelist):
        if not silent:
            p_dialog.update(int(math.ceil((i + 1) * t)), 'Añadiendo episodio...', e.title)

        # Añade todos menos el que dice "Añadir esta serie..." o "Descargar esta serie..."
        if e.action == "add_serie_to_library" or e.action == "download_all_episodes":
            continue

        try:
            if e.channel == "descargas":
                season_episode = scrapertools.get_season_and_episode(e.contentTitle.lower())
            else:
                season_episode = scrapertools.get_season_and_episode(e.title.lower())

            e.infoLabels = serie.infoLabels
            e.contentSeason, e.contentEpisodeNumber = season_episode.split("x")
            season_episode = "%sx%s" % (e.contentSeason, str(e.contentEpisodeNumber).zfill(2))
        except:
            continue

        strm_path = filetools.join(path, "%s.strm" % season_episode)
        if not filetools.exists(strm_path):
            # Si no existe season_episode.strm añadirlo
            item_strm = e.clone(action='play_from_library', channel='biblioteca',
                                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

            # si el canal tiene filtro se le pasa el nombre que tiene guardado para que filtre correctamente,
            if item_strm.list_idiomas:
                # si viene de library_service se obtiene del fichero tvshow.nfo, propiedad "library_filter_show"
                if "library_filter_show" in serie:
                    item_strm.library_filter_show = serie.library_filter_show.get(serie.channel, "")
                # si se ha agregado la serie lo obtenemos del titulo.
                else:
                    item_strm.library_filter_show = serie.title

                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'))
            filetools.write(strm_path, '%s?%s' % (addon_name, item_strm.tourl()))

        nfo_path = filetools.join(path, "%s.nfo" % season_episode)
        item_nfo = None
        if not filetools.exists(nfo_path) and e.infoLabels.get("tmdb_id"):
            # Si no existe season_episode.nfo añadirlo
            tmdb.find_and_set_infoLabels_tmdb(e)
            item_nfo = e.clone(channel="biblioteca", url="", action='findvideos',
                               strm_path=strm_path.replace(TVSHOWS_PATH, ""))
            url_scraper = "https://www.themoviedb.org/tv/%s/season/%s/episode/%s\n" % (item_nfo.infoLabels['tmdb_id'],
                                                                                       item_nfo.contentSeason,
                                                                                       item_nfo.contentEpisodeNumber)
            filetools.write(nfo_path, url_scraper + item_nfo.tojson())

        # Solo si existen season_episode.nfo y season_episode.strm continuamos
        json_path = filetools.join(path, ("%s [%s].json" % (season_episode, e.channel)).lower())
        if filetools.exists(nfo_path) and filetools.exists(strm_path):
            nuevo = not filetools.exists(json_path)

            if nuevo or overwrite:
                # Obtenemos infoLabel del episodio
                if not item_nfo:
                    item_nfo = Item().fromjson(filetools.read(nfo_path, 1))

                e.infoLabels = item_nfo.infoLabels

                if filetools.write(json_path, e.tojson()):
                    if nuevo:
                        logger.info("pelisalacarta.platformcode.library savelibrary 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.contentTitle] = 0
                    else:
                        logger.info("pelisalacarta.platformcode.library savelibrary Sobreescrito: %s" % json_path)
                        sobreescritos += 1
                else:
                    logger.info("pelisalacarta.platformcode.library savelibrary Fallido: %s" % json_path)
                    fallidos += 1

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

        if not silent and p_dialog.iscanceled():
            break

    if not silent:
        p_dialog.close()

    if news_in_playcounts:
        # Si hay nuevos episodios los marcamos como no vistos en tvshow.nfo ...
        tvshow_path = filetools.join(path, "tvshow.nfo")
        try:
            url_scraper = filetools.read(tvshow_path, 0, 1)
            tvshow_item = Item().fromjson(filetools.read(tvshow_path, 1))
            tvshow_item.library_playcounts.update(news_in_playcounts)

            filetools.write(tvshow_path, url_scraper + tvshow_item.tojson())
        except:
            logger.error("Error al actualizar tvshow.nfo")
            fallidos = -1

        # ... y actualizamos la biblioteca de Kodi
        if config.is_xbmc():
            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
Example #53
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(xbmc.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)
                        filetools.write(tvshow_file, head_nfo + serie.tojson())

                        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())
Example #54
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. title
    if not item.contentTitle:
        # Colocamos el titulo correcto en su sitio para que scraper lo localize
        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

    if not PY3:
        base_name = unicode(filetools.validate_path(base_name.replace('/', '-')), "utf8").encode("utf8")
    else:
        base_name = filetools.validate_path(base_name.replace('/', '-'))

    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
def set_content(content_type, silent=False):
    """
    Procedimiento para auto-configurar la biblioteca de kodi con los valores por defecto
    @type content_type: str ('CINE' o 'SERIES')
    @param content_type: tipo de contenido para configurar, series o peliculas
    """
    if config.is_xbmc():
        continuar = True
        msg_text = ""
        librarypath = config.get_setting("librarypath")

        if content_type == 'CINE':
            if not xbmc.getCondVisibility('System.HasAddon(metadata.themoviedb.org)'):
                if not silent:
                    # Preguntar si queremos instalar metadata.themoviedb.org
                    install = platformtools.dialog_yesno("The Movie Database",
                                                         "TheMovieDB non presente.",
                                                         "Installare ora?")
                else:
                    install = True

                if install:
                    try:
                        # Instalar metadata.themoviedb.org
                        xbmc.executebuiltin('xbmc.installaddon(metadata.themoviedb.org)', True)
                        logger.info("Instalado el Scraper de películas de TheMovieDB")
                    except:
                        pass

                continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.themoviedb.org)'))
                if not continuar:
                    msg_text = "The Movie Database no instalado."

        else: # SERIES
            # Instalar The TVDB
            if not xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'):
                if not silent:
                    # Preguntar si queremos instalar metadata.tvdb.com
                    install = platformtools.dialog_yesno("The TVDB",
                                                         "The TVDB non presente.",
                                                         "Installare ora?")
                else:
                    install = True

                if install:
                    try:
                        # Instalar metadata.tvdb.com
                        xbmc.executebuiltin('xbmc.installaddon(metadata.tvdb.com)', True)
                        logger.info("Instalado el Scraper de series de The TVDB")
                    except:
                        pass

                continuar = (install and xbmc.getCondVisibility('System.HasAddon(metadata.tvdb.com)'))
                if not continuar:
                    msg_text = "The TVDB no instalado."

            # Instalar TheMovieDB
            if continuar and not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'):
                continuar = False
                if not silent:
                    # Preguntar si queremos instalar metadata.tvshows.themoviedb.org
                    install = platformtools.dialog_yesno("The Movie Database",
                                                         "TheMovieDB non presente.",
                                                         "Installare ora?")
                else:
                    install = True

                if install:
                    try:
                        # Instalar metadata.tvshows.themoviedb.org
                        # 1º Probar desde el repositorio ...
                        xbmc.executebuiltin('xbmc.installaddon(metadata.tvshows.themoviedb.org)', True)
                        if not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'):
                                # ...si no funciona descargar e instalar desde la web
                                url = "http://mirrors.kodi.tv/addons/jarvis/metadata.tvshows.themoviedb.org/metadata.tvshows.themoviedb.org-1.3.1.zip"
                                path_down = xbmc.translatePath(
                                    "special://home/addons/packages/metadata.tvshows.themoviedb.org-1.3.1.zip")
                                path_unzip = xbmc.translatePath("special://home/addons/")
                                header = ("User-Agent",
                                          "Kodi/15.2 (Windows NT 10.0; WOW64) App_Bitness/32 Version/15.2-Git:20151019-02e7013")

                                from core import downloadtools
                                from core import ziptools

                                downloadtools.downloadfile(url, path_down, continuar=True, headers=[header])
                                unzipper = ziptools.ziptools()
                                unzipper.extract(path_down, path_unzip)
                                xbmc.executebuiltin('UpdateLocalAddons')

                        strSettings = '<settings>\n' \
                                      '    <setting id="fanart" value="true" />\n' \
                                      '    <setting id="keeporiginaltitle" value="false" />\n' \
                                      '    <setting id="language" value="it" />\n' \
                                      '</settings>'
                        path_settings = xbmc.translatePath("special://profile/addon_data/metadata.tvshows.themoviedb.org/settings.xml")
                        tv_themoviedb_addon_path = filetools.dirname(path_settings)
                        if not filetools.exists(tv_themoviedb_addon_path):
                            filetools.mkdir(tv_themoviedb_addon_path)
                        if filetools.write(path_settings,strSettings):
                            continuar = True

                    except:
                        pass

                continuar = (install and continuar)
                if not continuar:
                    msg_text = "The Movie Database non installato."

        idPath = 0
        idParentPath = 0
        strPath = ""
        if continuar:
            continuar = False

            # Buscamos el idPath
            sql = 'SELECT MAX(idPath) FROM path'
            nun_records, records = execute_sql_kodi(sql)
            if nun_records == 1:
                idPath = records[0][0] + 1

            sql_librarypath = librarypath
            if sql_librarypath.startswith("special://"):
                sql_librarypath = sql_librarypath.replace('/profile/', '/%/').replace('/home/userdata/', '/%/')
                sep = '/'
            elif sql_librarypath.startswith("smb://"):
                sep = '/'
            else:
                sep = os.sep

            if not sql_librarypath.endswith(sep):
                sql_librarypath += sep

            # Buscamos el idParentPath
            sql = 'SELECT idPath, strPath FROM path where strPath LIKE "%s"' % sql_librarypath
            nun_records, records = execute_sql_kodi(sql)
            if nun_records == 1:
                idParentPath = records[0][0]
                librarypath = records[0][1][:-1]
                continuar = True
            else:
                # No existe librarypath en la BD: la insertamos
                sql_librarypath = librarypath
                if not sql_librarypath.endswith(sep):
                    sql_librarypath += sep

                sql = 'INSERT INTO path (idPath, strPath,  scanRecursive, useFolderNames, noUpdate, exclude) VALUES ' \
                      '(%s, "%s", 0, 0, 0, 0)' % (idPath, sql_librarypath)
                nun_records, records = execute_sql_kodi(sql)
                if nun_records == 1:
                    continuar = True
                    idParentPath = idPath
                    idPath += 1
                else:
                    msg_text = "Omesso di impostare LibraryPath in BD"

        if continuar:
            continuar = False

            # Fijamos strContent, strScraper, scanRecursive y strSettings
            if content_type == 'CINE':
                strContent = 'movies'
                strScraper = 'metadata.themoviedb.org'
                scanRecursive = 2147483647
                strSettings = "<settings><setting id='RatingS' value='TMDb' /><setting id='certprefix' value='Rated ' />" \
                              "<setting id='fanart' value='true' /><setting id='keeporiginaltitle' value='false' />" \
                              "<setting id='language' value='it' /><setting id='tmdbcertcountry' value='us' />" \
                              "<setting id='trailer' value='true' /></settings>"
                strActualizar = "Si desidera configurare questo scraper in italiano come opzione predefinita per i film ?"
                if not librarypath.endswith(sep):
                    librarypath += sep
                strPath = librarypath + config.get_setting("folder_movies") + sep
            else:
                strContent = 'tvshows'
                strScraper = 'metadata.tvdb.com'
                scanRecursive = 0
                strSettings = "<settings><setting id='RatingS' value='TheTVDB' />" \
                              "<setting id='absolutenumber' value='false' />" \
                              "<setting id='dvdorder' value='false' />" \
                              "<setting id='fallback' value='true' />" \
                              "<setting id='fanart' value='true' />" \
                              "<setting id='language' value='it' /></settings>"
                strActualizar = "Si desidera configurare questo scraper in italiano come opzione predefinita per le serie ?"
                if not librarypath.endswith(sep):
                    librarypath += sep
                strPath = librarypath + config.get_setting("folder_tvshows") + sep

            logger.info("%s: %s" % (content_type, strPath))
            # Comprobamos si ya existe strPath en la BD para evitar duplicados
            sql = 'SELECT idPath FROM path where strPath="%s"' % strPath
            nun_records, records = execute_sql_kodi(sql)
            sql = ""
            if nun_records == 0:
                # Insertamos el scraper
                sql = 'INSERT INTO path (idPath, strPath, strContent, strScraper, scanRecursive, useFolderNames, ' \
                      'strSettings, noUpdate, exclude, idParentPath) VALUES (%s, "%s", "%s", "%s", %s, 0, ' \
                      '"%s", 0, 0, %s)' % (
                      idPath, strPath, strContent, strScraper, scanRecursive, strSettings, idParentPath)
            else:
                if not silent:
                    # Preguntar si queremos configurar themoviedb.org como opcion por defecto
                    actualizar = platformtools.dialog_yesno("The TVDB", strActualizar)
                else:
                    actualizar = True

                if actualizar:
                    # Actualizamos el scraper
                    idPath = records[0][0]
                    sql = 'UPDATE path SET strContent="%s", strScraper="%s", scanRecursive=%s, strSettings="%s" ' \
                          'WHERE idPath=%s' % (strContent, strScraper, scanRecursive, strSettings, idPath)

            if sql:
                nun_records, records = execute_sql_kodi(sql)
                if nun_records == 1:
                    continuar = True

            if not continuar:
                msg_text = "Omesso impostare LibraryPath in BD"


        if not continuar:
            heading = "Biblioteca %s no configurada" % content_type
        elif content_type == 'SERIES' and not xbmc.getCondVisibility('System.HasAddon(metadata.tvshows.themoviedb.org)'):
            heading = "Biblioteca %s configurata" % content_type
            msg_text = "Riavviare Kodi per attuare le modifiche."
        else:
            heading = "Biblioteca %s configurata" % content_type
            msg_text = "Libreria di Kodi configurata correttamente."
        platformtools.dialog_notification(heading, msg_text, icon=1, time=10000)
        logger.info("%s: %s" % (heading,msg_text))
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
    logger.info("url=" + page_url)

    # Lo pide una vez
    data = httptools.downloadpage(page_url, cookies=False).data
    # Si salta aviso, se carga la pagina de comprobacion y luego la inicial
    if "You try to access this video with Kodi" in data:
        url_reload = scrapertools.find_single_match(data, 'try to reload the page.*?href="([^"]+)"')
        url_reload = "http://www.flashx.tv" + url_reload[1:]
        try:
            data = httptools.downloadpage(url_reload, cookies=False).data
            data = httptools.downloadpage(page_url, cookies=False).data
        except:
            pass

    matches = scrapertools.find_multiple_matches(data, "<script type='text/javascript'>(.*?)</script>")
    for n, m in enumerate(matches):
        if m.startswith("eval"):
            try:
                m = jsunpack.unpack(m)
                fake = (scrapertools.find_single_match(m, "(\w{40,})") == "")
                if fake:
                    m = ""
                else:
                    break
            except:
                m = ""
    match = m
    if "sources:[{file:" not in match:
        page_url = page_url.replace("playvid-", "")

        headers = {'Host': 'www.flashx.tv', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36',
                  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5',
                  'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1',
                  'Cookie': ''}
        data = httptools.downloadpage(page_url, headers=headers, replace_headers=True).data
        flashx_id = scrapertools.find_single_match(data, 'name="id" value="([^"]+)"')
        fname = scrapertools.find_single_match(data, 'name="fname" value="([^"]+)"')
        hash_f = scrapertools.find_single_match(data, 'name="hash" value="([^"]+)"')
        post = 'op=download1&usr_login=&id=%s&fname=%s&referer=&hash=%s&imhuman=Proceed+to+video' % (flashx_id, urllib.quote(fname), hash_f)
        wait_time = scrapertools.find_single_match(data, "<span id='xxc2'>(\d+)")

        file_id = scrapertools.find_single_match(data, "'file_id', '([^']+)'")
        coding_url = 'https://files.fx.fastcontentdelivery.com/jquery2.js?fx=%s' % base64.encodestring(file_id)
        headers['Host'] = "files.fx.fastcontentdelivery.com"
        headers['Referer'] = "https://www.flashx.tv/"
        headers['Accept'] = "*/*"
        coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data
        
        coding_url = 'https://www.flashx.tv/counter.cgi?fx=%s' % base64.encodestring(file_id)
        headers['Host'] = "www.flashx.tv"
        coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data

        coding_url = 'https://www.flashx.tv/flashx.php?fxfx=3'
        headers['X-Requested-With'] = 'XMLHttpRequest'
        coding = httptools.downloadpage(coding_url, headers=headers, replace_headers=True).data

        try:
            time.sleep(int(wait_time) + 1)
        except:
            time.sleep(6)

        headers.pop('X-Requested-With')
        headers['Content-Type'] = 'application/x-www-form-urlencoded'
        data = httptools.downloadpage('https://www.flashx.tv/dl?playthis', post, headers, replace_headers=True).data

        matches = scrapertools.find_multiple_matches(data, "(eval\(function\(p,a,c,k.*?)\s+</script>")
        for match in matches:
            if match.startswith("eval"):
                try:
                    match = jsunpack.unpack(match)
                    fake = (scrapertools.find_single_match(match, "(\w{40,})") == "")
                    if fake:
                        match = ""
                    else:
                        break
                except:
                    match = ""

        if not match:
            match = data

    # Extrae la URL
    # {file:"http://f11-play.flashx.tv/luq4gfc7gxixexzw6v4lhz4xqslgqmqku7gxjf4bk43u4qvwzsadrjsozxoa/video1.mp4"}
    video_urls = []
    media_urls = scrapertools.find_multiple_matches(match, '\{file\:"([^"]+)",label:"([^"]+)"')
    subtitle = ""
    for media_url, label in media_urls:
        if media_url.endswith(".srt") and label == "Italian":
            try:
                from core import filetools
                data = scrapertools.downloadpage(media_url)
                subtitle = os.path.join(config.get_data_path(), 'sub_flashx.srt')
                filetools.write(subtitle, data)
            except:
                import traceback
                logger.info("streamondemand.servers.flashx Error al descargar el subtítulo: "+traceback.format_exc())
            
    for media_url, label in media_urls:
        if not media_url.endswith("png") and not media_url.endswith(".srt"):
            video_urls.append(["." + media_url.rsplit('.', 1)[1] + " [flashx]", media_url, 0, subtitle])

    for video_url in video_urls:
        logger.info("%s - %s" % (video_url[0], video_url[1]))

    return video_urls
Example #57
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:
        logger.error('.NFO no encontrado: ' + 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

    filetools.write(path, head_nfo + item.tojson())
Example #58
0
def update_json(path, params):
    item = Item().fromjson(filetools.read(path))
    item.__dict__.update(params)
    filetools.write(path, item.tojson())
Example #59
0
def add_sources(path):
    logger.info()
    from xml.dom import minidom

    SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml")

    if os.path.exists(SOURCES_PATH):
        xmldoc = minidom.parse(SOURCES_PATH)
    else:
        # Crear documento
        xmldoc = minidom.Document()
        nodo_sources = xmldoc.createElement("sources")

        for type in ['programs', 'video', 'music', 'picture', 'files']:
            nodo_type = xmldoc.createElement(type)
            element_default = xmldoc.createElement("default")
            element_default.setAttribute("pathversion", "1")
            nodo_type.appendChild(element_default)
            nodo_sources.appendChild(nodo_type)
        xmldoc.appendChild(nodo_sources)

    # Buscamos el nodo video
    nodo_video = xmldoc.childNodes[0].getElementsByTagName("video")[0]

    # Buscamos el path dentro de los nodos_path incluidos en el nodo_video
    nodos_paths = nodo_video.getElementsByTagName("path")
    list_path = [p.firstChild.data for p in nodos_paths]
    logger.debug(list_path)
    if path in list_path:
        logger.debug("La ruta %s ya esta en sources.xml" % path)
        return
    logger.debug("La ruta %s NO esta en sources.xml" % path)

    # Si llegamos aqui es por q el path no esta en sources.xml, asi q lo incluimos
    nodo_source = xmldoc.createElement("source")

    # Nodo <name>
    nodo_name = xmldoc.createElement("name")
    sep = os.sep
    if path.startswith("special://") or scrapertools.find_single_match(path, '(^\w+:\/\/)'):
        sep = "/"
    name = path
    if path.endswith(sep):
        name = path[:-1]
    nodo_name.appendChild(xmldoc.createTextNode(name.rsplit(sep)[-1]))
    nodo_source.appendChild(nodo_name)

    # Nodo <path>
    nodo_path = xmldoc.createElement("path")
    nodo_path.setAttribute("pathversion", "1")
    nodo_path.appendChild(xmldoc.createTextNode(path))
    nodo_source.appendChild(nodo_path)

    # Nodo <allowsharing>
    nodo_allowsharing = xmldoc.createElement("allowsharing")
    nodo_allowsharing.appendChild(xmldoc.createTextNode('true'))
    nodo_source.appendChild(nodo_allowsharing)

    # Añadimos <source>  a <video>
    nodo_video.appendChild(nodo_source)

    # Guardamos los cambios
    filetools.write(SOURCES_PATH,
                    '\n'.join([x for x in xmldoc.toprettyxml().encode("utf-8").splitlines() if x.strip()]))
Example #60
0
        item_nfo = Item(title=item.contentTitle, channel="biblioteca", 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
        url_scraper = filetools.read(nfo_path, 0, 1)
        item_nfo = Item().fromjson(filetools.read(nfo_path, 1))

    strm_path = filetools.join(path, "%s.strm" % base_name)
    if not filetools.exists(strm_path):
        # Crear base_name.strm si no existe
        item_strm = item.clone(channel='biblioteca', action='play_from_library',
                               strm_path=strm_path.replace(MOVIES_PATH, ""), contentType='movie',
                               infoLabels={'title': item.contentTitle})
        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 filetools.exists(strm_path):
        json_path = filetools.join(path, ("%s [%s].json" % (base_name, item.channel)).lower())
        if filetools.exists(json_path):
            logger.info("pelisalacarta.platformcode.library savelibrary el fichero existe. Se sobreescribe")
            sobreescritos += 1
        else:
            insertados += 1

        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