def removeTree(dir):
    if os.path.isdir(dir):
        try:
            shutil.rmtree(dir, ignore_errors=False, onerror=onerror)
        except Exception as e:
            logger.info('Cartella ' + dir + ' NON eliminata')
            logger.error(e)
def update(folder_content=config.get_setting("folder_tvshows"), folder=""):
    """
    Actualiza la libreria dependiendo del tipo de contenido y la ruta que se le pase.

    @type folder_content: str
    @param folder_content: tipo de contenido para actualizar, series o peliculas
    @type folder: str
    @param folder: nombre de la carpeta a escanear.
    """
    logger.info(folder)

    payload = {"jsonrpc": "2.0", "method": "VideoLibrary.Scan", "id": 1}

    if folder:
        folder = str(folder)
        videolibrarypath = config.get_videolibrary_config_path()

        if folder.endswith('/') or folder.endswith('\\'):
            folder = folder[:-1]

        update_path = None

        if videolibrarypath.startswith("special:"):
            if videolibrarypath.endswith('/'):
                videolibrarypath = videolibrarypath[:-1]
            update_path = videolibrarypath + "/" + folder_content + "/" + folder + "/"
        else:
            #update_path = filetools.join(videolibrarypath, folder_content, folder) + "/"   # Problemas de encode en "folder"
            update_path = filetools.join(videolibrarypath, folder_content,
                                         ' ').rstrip()

        if not scrapertools.find_single_match(update_path, '(^\w+:\/\/)'):
            payload["params"] = {"directory": update_path}
    """while xbmc.getCondVisibility('Library.IsScanningVideo()'):
def check_sources(new_movies_path='', new_tvshows_path=''):
    def format_path(path):
        if path.startswith("special://") or '://' in path: sep = '/'
        else: sep = os.sep
        if not path.endswith(sep): path += sep
        return path

    logger.info()

    new_movies_path = format_path(new_movies_path)
    new_tvshows_path = format_path(new_tvshows_path)

    SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml")
    if filetools.isfile(SOURCES_PATH):
        xmldoc = minidom.parse(SOURCES_PATH)

        video_node = xmldoc.childNodes[0].getElementsByTagName("video")[0]
        paths_node = video_node.getElementsByTagName("path")
        list_path = [p.firstChild.data for p in paths_node]

        return new_movies_path in list_path, new_tvshows_path in list_path
    else:
        xmldoc = minidom.Document()
        source_nodes = 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)
            source_nodes.appendChild(nodo_type)
        xmldoc.appendChild(source_nodes)

        return False, False
def fOpen(file, mode = 'r'):
    # per android è necessario, su kodi 18, usare FileIO
    # https://forum.kodi.tv/showthread.php?tid=330124
    # per xbox invece, è necessario usare open perchè _io è rotto :(
    # https://github.com/jellyfin/jellyfin-kodi/issues/115#issuecomment-538811017
    if xbmc.getCondVisibility('system.platform.linux') and xbmc.getCondVisibility('system.platform.android'):
        logger.info('android, uso FileIO per leggere')
        return io.FileIO(file, mode)
    else:
        return open(file, mode)
Exemple #5
0
def remove_tags(title):
    """
    devuelve el titulo sin tags como color
    @type title: str
    @param title: title
    @rtype: str
    @return: cadena sin tags
    """
    logger.info()

    title_without_tags = scrapertools.find_single_match(
        title, '\[color .+?\](.+)\[\/color\]')

    if title_without_tags:
        return title_without_tags
    else:
        return title
def chooseBranch():
    global branch
    apiLink = 'https://api.github.com/repos/' + user + '/' + repo + '/branches'
    try:
        branches = urllib.urlopen(apiLink).read()
    except Exception as e:
        platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(80031))
        logger.info(e)
        return False
    branches = json.loads(branches)
    chDesc = [config.get_localized_string(80034), config.get_localized_string(80035)]
    chDesc.extend([b['name'] for b in branches if b['name'] not in ['stable', 'master']])
    chName = ['stable', 'master']
    chName.extend([b['name'] for b in branches if b['name'] not in ['stable', 'master']])
    sel = platformtools.dialog_select(config.get_localized_string(80033), chDesc)
    branch = chName[sel]
    return True
Exemple #7
0
def remove_smb_credential(path):
    """
    devuelve el path sin contraseña/usuario para paths de SMB
    @param path: ruta
    @type path: str
    @return: cadena sin credenciales
    @rtype: str
    """
    logger.info()

    if not scrapertools.find_single_match(path, '(^\w+:\/\/)'):
        return path

    protocol = scrapertools.find_single_match(path, '(^\w+:\/\/)')
    path_without_credentials = scrapertools.find_single_match(
        path, '^\w+:\/\/(?:[^;\n]+;)?(?:[^:@\n]+[:|@])?(?:[^@\n]+@)?(.*?$)')

    if path_without_credentials:
        return (protocol + path_without_credentials)
    else:
        return path
def updateFromZip(message=config.get_localized_string(80050)):
    dp = platformtools.dialog_progress_bg(config.get_localized_string(20000), message)
    dp.update(0)

    remotefilename = 'https://github.com/' + user + "/" + repo + "/archive/" + branch + ".zip"
    localfilename = filetools.join(xbmc.translatePath("special://home/addons/"), "plugin.video.kod.update.zip")
    destpathname = xbmc.translatePath("special://home/addons/")
    extractedDir = filetools.join(destpathname, "addon-" + branch)

    logger.info("remotefilename=%s" % remotefilename)
    logger.info("localfilename=%s" % localfilename)
    logger.info('extract dir: ' + extractedDir)

    # pulizia preliminare
    remove(localfilename)
    removeTree(extractedDir)

    try:
        urllib.urlretrieve(remotefilename, localfilename,
                           lambda nb, bs, fs, url=remotefilename: _pbhook(nb, bs, fs, url, dp))
    except Exception as e:
        platformtools.dialog_ok(config.get_localized_string(20000), config.get_localized_string(80031))
        logger.info('Non sono riuscito a scaricare il file zip')
        logger.info(e)
        dp.close()
        return False

    # Lo descomprime
    logger.info("decompressione...")
    logger.info("destpathname=%s" % destpathname)

    if os.path.isfile(localfilename):
        logger.info('il file esiste')

    dp.update(80, config.get_localized_string(20000), config.get_localized_string(80032))

    import zipfile
    try:
        hash = fixZipGetHash(localfilename)
        logger.info(hash)

        with zipfile.ZipFile(fOpen(localfilename, 'rb')) as zip:
            size = sum([zinfo.file_size for zinfo in zip.filelist])
            cur_size = 0
            for member in zip.infolist():
                zip.extract(member, destpathname)
                cur_size += member.file_size
                dp.update(int(80 + cur_size * 15 / size))

    except Exception as e:
        logger.info('Non sono riuscito ad estrarre il file zip')
        logger.error(e)
        import traceback
        logger.error(traceback.print_exc())
        dp.close()
        remove(localfilename)

        return False

    dp.update(95)

    # puliamo tutto
    global addonDir
    if extractedDir != addonDir:
        removeTree(addonDir)
    xbmc.sleep(1000)

    rename(extractedDir, 'plugin.video.kod')
    addonDir = filetools.join(destpathname, 'plugin.video.kod')

    logger.info("Cancellando il file zip...")
    remove(localfilename)

    dp.update(100)
    xbmc.sleep(1000)
    dp.close()
    xbmc.executebuiltin("UpdateLocalAddons")

    # in run()
    # refreshLang()

    return hash
def rename(dir1, dir2):
    try:
        filetools.rename(dir1, dir2, silent=True, vfs=False)
    except:
        logger.info('cartella ' + dir1 + ' NON rinominata')
def remove(file):
    if os.path.isfile(file):
        try:
            os.remove(file)
        except:
            logger.info('File ' + file + ' NON eliminato')
def update_sources(new='', old=''):
    logger.info()
    if new == old: return

    SOURCES_PATH = xbmc.translatePath("special://userdata/sources.xml")
    if filetools.isfile(SOURCES_PATH):
        xmldoc = minidom.parse(SOURCES_PATH)
    else:
        xmldoc = minidom.Document()
        source_nodes = 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)
            source_nodes.appendChild(nodo_type)
        xmldoc.appendChild(source_nodes)

    # collect nodes
    # nodes = xmldoc.getElementsByTagName("video")
    video_node = xmldoc.childNodes[0].getElementsByTagName("video")[0]
    paths_node = video_node.getElementsByTagName("path")

    if old:
        # delete old path
        for node in paths_node:
            if node.firstChild.data == old:
                parent = node.parentNode
                remove = parent.parentNode
                remove.removeChild(parent)

        # write changes
        if sys.version_info[0] >= 3:  #PY3
            filetools.write(
                SOURCES_PATH, '\n'.join([
                    x for x in xmldoc.toprettyxml().splitlines() if x.strip()
                ]))
        else:
            filetools.write(SOURCES_PATH,
                            '\n'.join([
                                x for x in xmldoc.toprettyxml().splitlines()
                                if x.strip()
                            ]),
                            vfs=False)
        logger.info("The path %s has been removed from sources.xml" % old)

    if new:
        # create new path
        list_path = [p.firstChild.data for p in paths_node]
        if new in list_path:
            logger.info("The path %s already exists in sources.xml" % new)
            return
        logger.info("The path %s does not exist in sources.xml" % new)

        # if the path does not exist we create one
        source_node = xmldoc.createElement("source")

        # <name> Node
        name_node = xmldoc.createElement("name")
        sep = os.sep
        if new.startswith("special://") or scrapertools.find_single_match(
                new, r'(^\w+:\/\/)'):
            sep = "/"
        name = new
        if new.endswith(sep):
            name = new[:-1]
        name_node.appendChild(xmldoc.createTextNode(name.rsplit(sep)[-1]))
        source_node.appendChild(name_node)

        # <path> Node
        path_node = xmldoc.createElement("path")
        path_node.setAttribute("pathversion", "1")
        path_node.appendChild(xmldoc.createTextNode(new))
        source_node.appendChild(path_node)

        # <allowsharing> Node
        allowsharing_node = xmldoc.createElement("allowsharing")
        allowsharing_node.appendChild(xmldoc.createTextNode('true'))
        source_node.appendChild(allowsharing_node)

        # Añadimos <source>  a <video>
        video_node.appendChild(source_node)

        # write changes
        if sys.version_info[0] >= 3:  #PY3
            filetools.write(
                SOURCES_PATH, '\n'.join([
                    x for x in xmldoc.toprettyxml().splitlines() if x.strip()
                ]))
        else:
            filetools.write(SOURCES_PATH,
                            '\n'.join([
                                x for x in xmldoc.toprettyxml().splitlines()
                                if x.strip()
                            ]),
                            vfs=False)
        logger.info("The path %s has been added to sources.xml" % new)
def execute_sql_kodi(sql):
    """
    Run sql query against kodi database
    @param sql: Valid sql query
    @type sql: str
    @return: Number of records modified or returned by the query
    @rtype nun_records: int
    @return: list with the query result
    @rtype records: list of tuples
    """
    logger.info()
    file_db = ""
    nun_records = 0
    records = None

    # We look for the archive of the video database according to the version of kodi
    video_db = config.get_platform(True)['video_db']
    if video_db:
        file_db = filetools.join(
            xbmc.translatePath("special://userdata/Database"), video_db)

    # alternative method to locate the database
    if not file_db or not filetools.exists(file_db):
        file_db = ""
        for f in filetools.listdir(
                xbmc.translatePath("special://userdata/Database")):
            path_f = filetools.join(
                xbmc.translatePath("special://userdata/Database"), f)

            if filetools.isfile(path_f) and f.lower().startswith(
                    'myvideos') and f.lower().endswith('.db'):
                file_db = path_f
                break

    if file_db:
        logger.info("DB file: %s" % file_db)
        conn = None
        try:
            import sqlite3
            conn = sqlite3.connect(file_db)
            cursor = conn.cursor()

            logger.info("Running sql: %s" % sql)
            cursor.execute(sql)
            conn.commit()

            records = cursor.fetchall()
            if sql.lower().startswith("select"):
                nun_records = len(records)
                if nun_records == 1 and records[0][0] is None:
                    nun_records = 0
                    records = []
            else:
                nun_records = conn.total_changes

            conn.close()
            logger.info("Query executed. Records: %s" % nun_records)

        except:
            logger.error("Error executing sql query")
            if conn:
                conn.close()

    else:
        logger.info("Database not found")

    return nun_records, records