예제 #1
0
def check_repos():
    from resources.libs.common import logging
    from resources.libs.common import tools

    progress_dialog = xbmcgui.DialogProgress()

    progress_dialog.create(
        CONFIG.ADDONTITLE,
        '[COLOR {0}]Comprobación de Repositorios...[/COLOR]'.format(
            CONFIG.COLOR2))
    badrepos = []
    xbmc.executebuiltin('UpdateAddonRepos')
    repolist = glob.glob(os.path.join(CONFIG.ADDONS, 'repo*'))
    if len(repolist) == 0:
        progress_dialog.close()
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]No se Encontraron Repositorios![/COLOR]".format(
                CONFIG.COLOR2))
        return
    sleeptime = len(repolist)
    start = 0
    while start < sleeptime:
        start += 1
        if progress_dialog.iscanceled():
            break
        perc = int(tools.percentage(start, sleeptime))
        progress_dialog.update(
            perc, '\n' +
            '[COLOR {0}]Comprobando: [/COLOR][COLOR {1}]{2}[/COLOR]'.format(
                CONFIG.COLOR2, CONFIG.COLOR1, repolist[start - 1].replace(
                    CONFIG.ADDONS, '')[1:]))
        xbmc.sleep(1000)
    if progress_dialog.iscanceled():
        progress_dialog.close()
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]Habilitación de Addons Cancelado[/COLOR]".format(
                CONFIG.COLOR2))
        sys.exit()
    progress_dialog.close()
    logfile = logging.grab_log()
    fails = re.compile('CRepositoryUpdateJob(.+?)failed').findall(logfile)
    for item in fails:
        logging.log("Repositorio Incorrecto: {0} ".format(item))
        brokenrepo = item.replace('[', '').replace(']', '').replace(
            ' ', '').replace('/', '').replace('\\', '')
        if brokenrepo not in badrepos:
            badrepos.append(brokenrepo)
    if len(badrepos) > 0:
        msg = "[COLOR {0}]A continuación se muestra una lista de Repositorios que no se resolvieron.  Esto no significa que estén Depreciados, a veces los hosts caen por un período corto de tiempo.  Realice varios escaneos de su lista de repositorios antes de eliminar un repositorio, solo para asegurarse de que esté roto.[/COLOR][CR][CR][COLOR {1}]".format(
            CONFIG.COLOR2, CONFIG.COLOR1)
        msg += '[CR]'.join(badrepos)
        msg += '[/COLOR]'
        window.show_text_box("Visualización de Repositorios Rotos", msg)
    else:
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]Todos los Repositorios Funcionan![/COLOR]".format(
                CONFIG.COLOR2))
예제 #2
0
def check_repos():
    from resources.libs.common import logging
    from resources.libs.common import tools

    progress_dialog = xbmcgui.DialogProgress()

    progress_dialog.create(
        CONFIG.ADDONTITLE,
        '[COLOR {0}]Checking Repositories...[/COLOR]'.format(CONFIG.COLOR2))
    badrepos = []
    xbmc.executebuiltin('UpdateAddonRepos')
    repolist = glob.glob(os.path.join(CONFIG.ADDONS, 'repo*'))
    if len(repolist) == 0:
        progress_dialog.close()
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]No Repositories Found![/COLOR]".format(CONFIG.COLOR2))
        return
    sleeptime = len(repolist)
    start = 0
    while start < sleeptime:
        start += 1
        if progress_dialog.iscanceled():
            break
        perc = int(tools.percentage(start, sleeptime))
        progress_dialog.update(
            perc, '',
            '[COLOR {0}]Checking: [/COLOR][COLOR {1}]{2}[/COLOR]'.format(
                CONFIG.COLOR2, CONFIG.COLOR1,
                repolist[start - 1].replace(CONFIG.ADDONS, '')[1:]))
        xbmc.sleep(1000)
    if progress_dialog.iscanceled():
        progress_dialog.close()
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]Enabling Addons Cancelled[/COLOR]".format(
                CONFIG.COLOR2))
        sys.exit()
    progress_dialog.close()
    logfile = logging.grab_log()
    fails = re.compile('CRepositoryUpdateJob(.+?)failed').findall(logfile)
    for item in fails:
        logging.log("Bad Repository: {0} ".format(item))
        brokenrepo = item.replace('[', '').replace(']', '').replace(
            ' ', '').replace('/', '').replace('\\', '')
        if brokenrepo not in badrepos:
            badrepos.append(brokenrepo)
    if len(badrepos) > 0:
        msg = "[COLOR {0}]Below is a list of Repositories that did not resolve.  This does not mean that they are Depreciated, sometimes hosts go down for a short period of time.  Please do serveral scans of your repository list before removing a repository just to make sure it is broken.[/COLOR][CR][CR][COLOR {1}]".format(
            CONFIG.COLOR2, CONFIG.COLOR1)
        msg += '[CR]'.join(badrepos)
        msg += '[/COLOR]'
        window.show_text_box("Viewing Broken Repositories", msg)
    else:
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]All Repositories Working![/COLOR]".format(
                CONFIG.COLOR2))
예제 #3
0
def check_sources():
    from resources.libs.common import logging
    from resources.libs.common import tools

    dialog = xbmcgui.Dialog()
    progress_dialog = xbmcgui.DialogProgress()

    if not os.path.exists(CONFIG.SOURCES):
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]No sources.xml File Found![/COLOR]".format(
                CONFIG.COLOR2))
        return False
    x = 0
    bad = []
    remove = []
    a = tools.read_from_file(CONFIG.SOURCES)
    temp = a.replace('\r', '').replace('\n', '').replace('\t', '')
    match = re.compile('<files>.+?</files>').findall(temp)

    if len(match) > 0:
        match2 = re.compile(
            '<source>.+?<name>(.+?)</name>.+?<path pathversion="1">(.+?)</path>.+?<allowsharing>(.+?)</allowsharing>.+?</source>'
        ).findall(match[0])
        progress_dialog.create(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]Scanning Sources for Broken links[/COLOR]".format(
                CONFIG.COLOR2))
        for name, path, sharing in match2:
            x += 1
            perc = int(tools.percentage(x, len(match2)))
            progress_dialog.update(
                perc, '',
                "[COLOR {0}]Checking [COLOR {1}]{2}[/COLOR]:[/COLOR]".format(
                    CONFIG.COLOR2, CONFIG.COLOR1, name),
                "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, path))

            working = tools.open_url(path, check=True)
            if not working:
                bad.append([name, path, sharing, working])

        logging.log("Bad Sources: {0}".format(len(bad)))
        if len(bad) > 0:
            choice = dialog.yesno(
                CONFIG.ADDONTITLE,
                "[COLOR {0}]{1}[/COLOR][COLOR {2}] Source(s) have been found Broken"
                .format(CONFIG.COLOR1, len(bad), CONFIG.COLOR2),
                "Would you like to Remove all or choose one by one?[/COLOR]",
                yeslabel="[B][COLOR springgreen]Remove All[/COLOR][/B]",
                nolabel="[B][COLOR red]Choose to Delete[/COLOR][/B]")
            if choice == 1:
                remove = bad
            else:
                for name, path, sharing, working in bad:
                    logging.log("{0} sources: {1}, {2}".format(
                        name, path, working))
                    if dialog.yesno(
                            CONFIG.ADDONTITLE,
                            "[COLOR {0}]{1}[/COLOR][COLOR {2}] was reported as non working"
                            .format(CONFIG.COLOR1, name, CONFIG.COLOR2),
                            "[COLOR {0}]{1}[/COLOR]".format(
                                CONFIG.COLOR1, path),
                            "[COLOR {0}]{1}[/COLOR]".format(
                                CONFIG.COLOR1, working),
                            yeslabel=
                            "[B][COLOR springgreen]Remove Source[/COLOR][/B]",
                            nolabel="[B][COLOR red]Keep Source[/COLOR][/B]"):
                        remove.append([name, path, sharing, working])
                        logging.log("Removing Source {0}".format(name))
                    else:
                        logging.log("Source {0} was not removed".format(name))
            if len(remove) > 0:
                for name, path, sharing, working in remove:
                    a = a.replace(
                        '\n<source>\n<name>{0}</name>\n<path pathversion="1">{1}</path>\n<allowsharing>{2}</allowsharing>\n</source>'
                        .format(name, path, sharing), '')
                    logging.log("Removing Source {0}".format(name))

                tools.write_to_file(CONFIG.SOURCES, str(a))
                alive = len(match) - len(bad)
                kept = len(bad) - len(remove)
                removed = len(remove)
                dialog.ok(
                    CONFIG.ADDONTITLE,
                    "[COLOR {0}]Checking sources for broken paths has been completed"
                    .format(CONFIG.COLOR2),
                    "Working: [COLOR {0}]{1}[/COLOR] | Kept: [COLOR {2}]{3}[/COLOR] | Removed: [COLOR {4}]{5}[/COLOR][/COLOR]"
                    .format(CONFIG.COLOR2, CONFIG.COLOR1, alive, CONFIG.COLOR1,
                            kept, CONFIG.COLOR1, removed))
            else:
                logging.log("No Bad Sources to be removed.")
        else:
            logging.log_notify(
                CONFIG.ADDONTITLE,
                "[COLOR {0}]All Sources Are Working[/COLOR]".format(
                    CONFIG.COLOR2))
    else:
        logging.log("No Sources Found")
예제 #4
0
def wipe():
    from resources.libs import db
    from resources.libs.common import logging
    from resources.libs import skin
    from resources.libs.common import tools
    from resources.libs import update

    if CONFIG.KEEPTRAKT == 'true':
        from resources.libs import traktit

        traktit.auto_update('all')
        CONFIG.set_setting('traktnextsave', str(tools.get_date(days=3, formatted=True)))
    if CONFIG.KEEPDEBRID == 'true':
        from resources.libs import debridit

        debridit.auto_update('all')
        CONFIG.set_setting('debridnextsave', str(tools.get_date(days=3, formatted=True)))
    if CONFIG.KEEPLOGIN == 'true':
        from resources.libs import loginit

        loginit.auto_update('all')
        CONFIG.set_setting('loginnextsave', str(tools.get_date(days=3, formatted=True)))

    exclude_dirs = CONFIG.EXCLUDES
    exclude_dirs.append('My_Builds')
    
    progress_dialog = xbmcgui.DialogProgress()
    
    skin.skin_to_default('Fresh Install')
    
    update.addon_updates('set')
    xbmcPath = os.path.abspath(CONFIG.HOME)
    progress_dialog.create(CONFIG.ADDONTITLE, "[COLOR {0}]Calculating files and folders".format(CONFIG.COLOR2) + '\n' + '\n' + 'Please Wait![/COLOR]')
    total_files = sum([len(files) for r, d, files in os.walk(xbmcPath)])
    del_file = 0
    progress_dialog.update(0, "[COLOR {0}]Gathering Excludes list.[/COLOR]".format(CONFIG.COLOR2))
    if CONFIG.KEEPREPOS == 'true':
        repos = glob.glob(os.path.join(CONFIG.ADDONS, 'repo*/'))
        for item in repos:
            repofolder = os.path.split(item[:-1])[1]
            if not repofolder == exclude_dirs:
                exclude_dirs.append(repofolder)
    if CONFIG.KEEPSUPER == 'true':
        exclude_dirs.append('plugin.program.super.favourites')
    if CONFIG.KEEPWHITELIST == 'true':
        from resources.libs import whitelist
        
        whitelist = whitelist.whitelist('read')
        if len(whitelist) > 0:
            for item in whitelist:
                try:
                    name, id, fold = item
                except:
                    pass

                depends = db.depends_list(fold)
                for plug in depends:
                    if plug not in exclude_dirs:
                        exclude_dirs.append(plug)
                    depends2 = db.depends_list(plug)
                    for plug2 in depends2:
                        if plug2 not in exclude_dirs:
                            exclude_dirs.append(plug2)
                if fold not in exclude_dirs:
                    exclude_dirs.append(fold)

    for item in CONFIG.DEPENDENCIES:
        exclude_dirs.append(item)

    progress_dialog.update(0, "[COLOR {0}]Clearing out files and folders:".format(CONFIG.COLOR2))
    latestAddonDB = db.latest_db('Addons')
    for root, dirs, files in os.walk(xbmcPath, topdown=True):
        dirs[:] = [d for d in dirs if d not in exclude_dirs]
        for name in files:
            del_file += 1
            fold = root.replace('/', '\\').split('\\')
            x = len(fold)-1
            if name == 'sources.xml' and fold[-1] == 'userdata' and CONFIG.KEEPSOURCES == 'true':
                logging.log("Keep sources.xml: {0}".format(os.path.join(root, name)))
            elif name == 'favourites.xml' and fold[-1] == 'userdata' and CONFIG.KEEPFAVS == 'true':
                logging.log("Keep favourites.xml: {0}".format(os.path.join(root, name)))
            elif name == 'profiles.xml' and fold[-1] == 'userdata' and CONFIG.KEEPPROFILES == 'true':
                logging.log("Keep profiles.xml: {0}".format(os.path.join(root, name)))
            elif name == 'playercorefactory.xml' and fold[-1] == 'userdata' and CONFIG.KEEPPLAYERCORE == 'true':
                logging.log("Keep playercorefactory.xml: {0}".format(os.path.join(root, name)))
            elif name == 'guisettings.xml' and fold[-1] == 'userdata' and CONFIG.KEEPGUISETTINGS == 'true':
                logging.log("Keep guisettings.xml: {0}".format(os.path.join(root, name)))
            elif name == 'advancedsettings.xml' and fold[-1] == 'userdata' and CONFIG.KEEPADVANCED == 'true':
                logging.log("Keep advancedsettings.xml: {0}".format(os.path.join(root, name)))
            elif name in CONFIG.LOGFILES:
                logging.log("Keep Log File: {0}".format(name))
            elif name.endswith('.db'):
                try:
                    if name == latestAddonDB:
                        logging.log("Ignoring {0} on Kodi {1}".format(name, tools.kodi_version()))
                    else:
                        os.remove(os.path.join(root, name))
                except Exception as e:
                    if not name.startswith('Textures13'):
                        logging.log('Failed to delete, Purging DB')
                        logging.log("-> {0}".format(str(e)))
                        db.purge_db_file(os.path.join(root, name))
            else:
                progress_dialog.update(int(tools.percentage(del_file, total_files)), '\n' + '[COLOR {0}]File: [/COLOR][COLOR {1}]{2}[/COLOR]'.format(CONFIG.COLOR2, CONFIG.COLOR1, name))
                try:
                    os.remove(os.path.join(root, name))
                except Exception as e:
                    logging.log("Error removing {0}".format(os.path.join(root, name)))
                    logging.log("-> / {0}".format(str(e)))
        if progress_dialog.iscanceled():
            progress_dialog.close()
            logging.log_notify(CONFIG.ADDONTITLE,
                               "[COLOR {0}]Fresh Start Cancelled[/COLOR]".format(CONFIG.COLOR2))
            return False
    for root, dirs, files in os.walk(xbmcPath, topdown=True):
        dirs[:] = [d for d in dirs if d not in exclude_dirs]
        for name in dirs:
            progress_dialog.update(100, '\n' + 'Cleaning Up Empty Folder: [COLOR {0}]{1}[/COLOR]'.format(CONFIG.COLOR1, name))
            if name not in ["Database", "userdata", "temp", "addons", "addon_data"]:
                shutil.rmtree(os.path.join(root, name), ignore_errors=True, onerror=None)
        if progress_dialog.iscanceled():
            progress_dialog.close()
            logging.log_notify(CONFIG.ADDONTITLE,
                               "[COLOR {0}]Fresh Start Cancelled[/COLOR]".format(CONFIG.COLOR2))
            return False
            
    progress_dialog.close()
    CONFIG.clear_setting('build')
예제 #5
0
def _backup_addon_data(name=""):
    dialog = xbmcgui.Dialog()
    progress_dialog = xbmcgui.DialogProgress()

    if dialog.yesno(CONFIG.ADDONTITLE, "[COLOR {0}]Are you sure you wish to backup the current addon_data?[/COLOR]".format(CONFIG.COLOR2),
                    nolabel="[B][COLOR red]Cancel Backup[/COLOR][/B]",
                    yeslabel="[B][COLOR springgreen]Backup Addon_Data[/COLOR][/B]"):
        if name == "":
            name = tools.get_keyboard("", "Please enter a name for the addon_data zip")
            if not name:
                return False
            name = quote_plus(name)
        name = '{0}_addondata.zip'.format(name)
        tempzipname = ''
        zipname = os.path.join(CONFIG.MYBUILDS, name)
        try:
            zipf = zipfile.ZipFile(xbmc.translatePath(zipname), mode='w')
        except:
            try:
                tempzipname = os.path.join(CONFIG.PACKAGES, '{0}.zip'.format(name))
                zipf = zipfile.ZipFile(tempzipname, mode='w')
            except:
                logging.log("Unable to create {0}_addondata.zip".format(name), level=xbmc.LOGERROR)
                if dialog.yesno(CONFIG.ADDONTITLE,
                                "[COLOR {0}]We are unable to write to the current backup directory, would you like to change the location?[/COLOR]".format(CONFIG.COLOR2),
                                yeslabel="[B][COLOR springgreen]Change Directory[/COLOR][/B]",
                                nolabel="[B][COLOR red]Cancel[/COLOR][/B]"):
                    CONFIG.open_settings()
                    return
                else:
                    return
        for_progress = 0
        ITEM = []
        tools.convert_special(CONFIG.ADDON_DATA, True)
        tools.ascii_check(CONFIG.ADDON_DATA, True)
        progress_dialog.create("[COLOR {0}]{1}[/COLOR][COLOR {2}]: Creating Zip[/COLOR]".format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2),
                  "[COLOR {0}]Creating back up zip".format(CONFIG.COLOR2), "", "Please Wait...[/COLOR]")
        for base, dirs, files in os.walk(CONFIG.ADDON_DATA):
            dirs[:] = [d for d in dirs if d not in CONFIG.EXCLUDE_DIRS]
            files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES]
            for file in files:
                ITEM.append(file)
        N_ITEM = len(ITEM)

        bad_files = [
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.exodusredux', 'cache.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.exodusredux', 'cache.meta.5.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.exodusredux', 'cache.providers.13.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.thecrew', 'cache.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.thecrew', 'cache.meta.5.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.thecrew', 'cache.providers.13.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.yoda', 'cache.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.yoda', 'cache.meta.5.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.yoda', 'cache.providers.13.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.scrubsv2', 'cache.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.scrubsv2', 'cache.meta.5.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.scrubsv2', 'cache.providers.13.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.gaia', 'cache.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.gaia', 'meta.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.seren', 'cache.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'plugin.video.seren', 'torrentScrape.db')),
            (os.path.join(CONFIG.ADDON_DATA, 'script.module.simplecache', 'simplecache.db'))]

        for base, dirs, files in os.walk(CONFIG.ADDON_DATA):
            dirs[:] = [d for d in dirs if d not in CONFIG.EXCLUDE_DIRS]
            files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES]
            for file in files:
                try:
                    for_progress += 1
                    progress = tools.percentage(for_progress, N_ITEM)
                    progress_dialog.update(int(progress),
                              '[COLOR {0}]Creating back up zip: [COLOR{1}]{2}[/COLOR] / [COLOR{3}]{4}[/COLOR]'.format(
                              CONFIG.COLOR2, CONFIG.COLOR1, for_progress, CONFIG.COLOR1, N_ITEM),
                                  '[COLOR {0}]{1}[/COLOR]'.format(CONFIG.COLOR1, file),
                              '')
                    fn = os.path.join(base, file)
                    if file in CONFIG.LOGFILES:
                        logging.log("[Back Up] Type = addon_data: Ignore {0} - Log Files".format(file))
                        continue
                    elif os.path.join(base, file) in bad_files:
                        logging.log("[Back Up] Type = addon_data: Ignore {0} - Cache Files".format(file))
                        continue
                    elif os.path.join('addons', 'packages') in fn:
                        logging.log("[Back Up] Type = addon_data: Ignore {0} - Packages Folder".format(file))
                        continue
                    elif file.endswith('.csv'):
                        logging.log("[Back Up] Type = addon_data: Ignore {0} - CSV File".format(file))
                        continue
                    elif file.endswith('.db') and 'Database' in base:
                        temp = file.replace('.db', '')
                        temp = ''.join([i for i in temp if not i.isdigit()])
                        if temp in CONFIG.DB_FILES:
                            if not file == db.latest_db(temp):
                                logging.log("[Back Up] Type = addon_data: Ignore {0} - Database Files".format(file))
                                continue
                    try:
                        zipf.write(fn, fn[len(CONFIG.ADDON_DATA):], zipfile.ZIP_DEFLATED)
                    except Exception as e:
                        logging.log("[Back Up] Type = addon_data: Unable to backup {0}".format(file))
                        logging.log("Backup Error: {0}".format(str(e)))
                except Exception as e:
                    logging.log("[Back Up] Type = addon_data: Unable to backup {0}".format(file))
                    logging.log("Backup Error: {0}".format(str(e)))
        zipf.close()
        if not tempzipname == '':
            success = xbmcvfs.rename(tempzipname, zipname)
            if success == 0:
                xbmcvfs.copy(tempzipname, zipname)
                xbmcvfs.delete(tempzipname)
        progress_dialog.close()
        dialog.ok(CONFIG.ADDONTITLE, "[COLOR {0}]{1}[/COLOR] [COLOR {2}]backup successful:[/COLOR]".format(CONFIG.COLOR1, name, CONFIG.COLOR2),
                  "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, zipname))
예제 #6
0
def _backup_build(name=""):
    dialog = xbmcgui.Dialog()
    progress_dialog = xbmcgui.DialogProgress()

    if dialog.yesno(CONFIG.ADDONTITLE,
                        "[COLOR {0}]Are you sure you wish to backup the current build?[/COLOR]".format(CONFIG.COLOR2),
                    nolabel="[B][COLOR red]Cancel Backup[/COLOR][/B]",
                    yeslabel="[B][COLOR springgreen]Backup Build[/COLOR][/B]"):
        if name == "":
            name = tools.get_keyboard("", "Please enter a name for the build zip")
            if not name:
                return False
            name = name.replace('\\', '').replace('/', '').replace(':', '').replace('*', '').replace('?', '').replace(
                '"', '').replace('<', '').replace('>', '').replace('|', '')
        name = quote_plus(name)
        tempzipname = ''
        zipname = os.path.join(CONFIG.MYBUILDS, '{0}.zip'.format(name))
        for_progress = 0
        ITEM = []
        exclude_dirs = CONFIG.EXCLUDE_DIRS

        if not dialog.yesno(CONFIG.ADDONTITLE,
                                "[COLOR {0}]Do you want to include your addon_data folder?".format(CONFIG.COLOR2),
                                "This contains [COLOR {0}]ALL[/COLOR] add-on settings including passwords but may also contain important information such as skin shortcuts. We recommend [COLOR {0}]MANUALLY[/COLOR] removing the addon_data folders that aren\'t required.".format(CONFIG.COLOR1, CONFIG.COLOR1),
                                "[COLOR {0}]{1}[/COLOR] addon_data is ignored[/COLOR]".format(CONFIG.COLOR1, CONFIG.ADDON_ID),
                            yeslabel='[B][COLOR springgreen]Include data[/COLOR][/B]',
                            nolabel='[B][COLOR red]Don\'t Include[/COLOR][/B]'):
            exclude_dirs.append('addon_data')

        tools.convert_special(CONFIG.HOME, True)
        # tools.ascii_check(CONFIG.HOME, True)
        extractsize = 0
        try:
            zipf = zipfile.ZipFile(xbmc.translatePath(zipname), mode='w')
        except:
            try:
                tempzipname = os.path.join(CONFIG.PACKAGES, '{0}.zip'.format(name))
                zipf = zipfile.ZipFile(tempzipname, mode='w')
            except:
                logging.log("Unable to create {0}.zip".format(name), level=xbmc.LOGERROR)
                if dialog.yesno(CONFIG.ADDONTITLE,
                                "[COLOR {0}]We are unable to write to the current backup directory, would you like to change the location?[/COLOR]".format(CONFIG.COLOR2),
                                yeslabel="[B][COLOR springgreen]Change Directory[/COLOR][/B]",
                                nolabel="[B][COLOR red]Cancel[/COLOR][/B]"):
                    CONFIG.open_settings()
                    return
                else:
                    return
        progress_dialog.create("[COLOR {0}]{1}[/COLOR][COLOR {2}]: Creating Zip[/COLOR]".format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2),
                  "[COLOR {0}]Creating backup zip".format(CONFIG.COLOR2), "", "Please Wait...[/COLOR]")

        for base, dirs, files in os.walk(CONFIG.HOME):
            dirs[:] = [d for d in dirs if d not in exclude_dirs]
            files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES]
            for file in files:
                ITEM.append(file)

        N_ITEM = len(ITEM)
        picture = []
        music = []
        video = []
        programs = []
        repos = []
        scripts = []
        skins = []
        fold = glob.glob(os.path.join(CONFIG.ADDONS, '*/'))
        idlist = []
        
        binaries = []
        binidlist = []

        for folder in sorted(fold, key=lambda x: x):
            foldername = os.path.split(folder[:-1])[1]
            if foldername == 'packages':
                continue
                
            binaryid, binaryname = db.find_binary_addons(addon=foldername)
            
            if binaryid:
                binaries.append(binaryname)
                binidlist.append(binaryid)     
                
            xml = os.path.join(folder, 'addon.xml')
            if os.path.exists(xml):
                a = tools.read_from_file(xml)
                prov = re.compile("<provides>(.+?)</provides>").findall(a)
                match = tools.parse_dom(prov, 'addon', ret='id')

                addid = foldername if len(match) == 0 else match[0]
                if addid in idlist:
                    continue
                idlist.append(addid)
                try:
                    add = xbmcaddon.Addon(id=addid)
                    aname = add.getAddonInfo('name')
                    aname = aname.replace('[', '<').replace(']', '>')
                    aname = str(re.sub('<[^<]+?>', '', aname)).lstrip()
                except:
                    aname = foldername
                if len(prov) == 0:
                    if foldername.startswith('skin'):
                        skins.append(aname)
                    elif foldername.startswith('repo'):
                        repos.append(aname)
                    else:
                        scripts.append(aname)
                    continue
                if not (prov[0]).find('executable') == -1:
                    programs.append(aname)
                if not (prov[0]).find('video') == -1:
                    video.append(aname)
                if not (prov[0]).find('audio') == -1:
                    music.append(aname)
                if not (prov[0]).find('image') == -1:
                    picture.append(aname)
        db.fix_metas()
        
        binarytxt = _backup_binaries(binidlist)

        for base, dirs, files in os.walk(CONFIG.HOME):
            dirs[:] = [d for d in dirs if d not in exclude_dirs]
            files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES]
            for file in files:
                try:
                    for_progress += 1
                    progress = tools.percentage(for_progress, N_ITEM)
                    progress_dialog.update(int(progress),
                              '[COLOR {0}]Creating backup zip: [COLOR {1}]{2}[/COLOR] / [COLOR {3}]{4}[/COLOR]'.format(
                              CONFIG.COLOR2, CONFIG.COLOR1, for_progress, CONFIG.COLOR1, N_ITEM),
                                  '[COLOR {0}]{1}[/COLOR]'.format(CONFIG.COLOR1, file), '')
                    fn = os.path.join(base, file)
                    if file in CONFIG.LOGFILES:
                        logging.log("[Back Up] Type = build: Ignore {0} - Log File".format(file))
                        continue
                    elif os.path.join(base, file) in CONFIG.EXCLUDE_FILES:
                        logging.log("[Back Up] Type = build: Ignore {0} - Excluded File".format(file))
                        continue
                    elif os.path.join('addons', 'packages') in fn:
                        logging.log("[Back Up] Type = build: Ignore {0} - Packages Folder".format(file))
                        continue
                    elif file.endswith('.csv'):
                        logging.log("[Back Up] Type = build: Ignore {0} - CSV File".format(file))
                        continue
                    elif file.endswith('.pyo'):
                        continue
                    elif file.endswith('.db') and 'Database' in base:
                        temp = file.replace('.db', '')
                        temp = ''.join([i for i in temp if not i.isdigit()])
                        if temp in CONFIG.DB_FILES:
                            if not file == db.latest_db(temp):
                                logging.log("[Back Up] Type = build: Ignore {0} - DB File".format(file))
                                continue
                                
                    skipbinary = False 
                    if len(binidlist) > 0: 
                        for id in binidlist: 
                            id = os.path.join(CONFIG.ADDONS, id) 
                            if id in fn: 
                                skipbinary = True 
                             
                    if skipbinary: 
                        logging.log("[Back Up] Type = build: Ignore {0} - Binary Add-on".format(file)) 
                        continue
                        
                    try:
                        zipf.write(fn, fn[len(CONFIG.HOME):], zipfile.ZIP_DEFLATED)
                        extractsize += os.path.getsize(fn)
                    except Exception as e:
                        logging.log("[Back Up] Type = build: Unable to backup {0}".format(file))
                        logging.log("{0} / {1}".format(Exception, e))
                    if progress_dialog.iscanceled():
                        progress_dialog.close()
                        logging.log_notify("[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, CONFIG.ADDONTITLE),
                                  "[COLOR {0}]Backup Cancelled[/COLOR]".format(CONFIG.COLOR2))
                        sys.exit()
                except Exception as e:
                    logging.log("[Back Up] Type = build: Unable to backup {0}".format(file))
                    logging.log("Build Backup Error: {0}".format(str(e)))
                    
        if 'addon_data' in exclude_dirs:
            match = glob.glob(os.path.join(CONFIG.ADDON_DATA, 'skin.*', ''))
            for fold in match:
                fd = os.path.split(fold[:-1])[1]
                if fd not in ['skin.confluence', 'skin.estuary', 'skin.estouchy']:
                    for base, dirs, files in os.walk(os.path.join(CONFIG.ADDON_DATA, fold)):
                        files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES]
                        for file in files:
                            fn = os.path.join(base, file)
                            zipf.write(fn, fn[len(CONFIG.HOME):], zipfile.ZIP_DEFLATED)
                            extractsize += os.path.getsize(fn)
                    xml = os.path.join(CONFIG.ADDONS, fd, 'addon.xml')
                    if os.path.exists(xml):
                        matchxml = tools.parse_dom(tools.read_from_file(xml), 'import', ret='addon')
                        if 'script.skinshortcuts' in matchxml:
                            for base, dirs, files in os.walk(os.path.join(CONFIG.ADDON_DATA, 'script.skinshortcuts')):
                                files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES]
                                for file in files:
                                    fn = os.path.join(base, file)
                                    zipf.write(fn, fn[len(CONFIG.HOME):], zipfile.ZIP_DEFLATED)
                                    extractsize += os.path.getsize(fn)
        zipf.close()
        xbmc.sleep(500)
        progress_dialog.close()

        backup('guifix', name)

        if not tempzipname == '':
            success = xbmcvfs.rename(tempzipname, zipname)
            if success == 0:
                xbmcvfs.copy(tempzipname, zipname)
                xbmcvfs.delete(tempzipname)
                
        if binarytxt is not None:
            bintxtpath = os.path.join(CONFIG.USERDATA, binarytxt)
            xbmcvfs.delete(bintxtpath)
         
        _backup_info(name, extractsize, programs, video, music, picture, repos, scripts, binaries)

        if len(binaries) > 0:
            dialog.ok(CONFIG.ADDONTITLE, "[COLOR {0}]The following add-ons were excluded from the backup because they are platform specific:[/COLOR]".format(CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, ', '.join(binaries)))
        
        dialog.ok(CONFIG.ADDONTITLE, "[COLOR {0}]{1}[/COLOR] [COLOR {2}]Backup successful:[/COLOR]".format(CONFIG.COLOR1, name, CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, zipname))
예제 #7
0
def check_sources():
    from resources.libs.common import logging
    from resources.libs.common import tools

    dialog = xbmcgui.Dialog()
    progress_dialog = xbmcgui.DialogProgress()

    if not os.path.exists(CONFIG.SOURCES):
        logging.log_notify(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]No se ha Encontrado Ningún Archivo Fuentes.xml!![/COLOR]"
            .format(CONFIG.COLOR2))
        return False
    x = 0
    bad = []
    remove = []
    a = tools.read_from_file(CONFIG.SOURCES)
    temp = a.replace('\r', '').replace('\n', '').replace('\t', '')
    match = re.compile('<files>.+?</files>').findall(temp)

    if len(match) > 0:
        match2 = re.compile(
            '<source>.+?<name>(.+?)</name>.+?<path pathversion="1">(.+?)</path>.+?<allowsharing>(.+?)</allowsharing>.+?</source>'
        ).findall(match[0])
        progress_dialog.create(
            CONFIG.ADDONTITLE,
            "[COLOR {0}]Escaneo de Fuentes en Busca de enlaces Rotos[/COLOR]".
            format(CONFIG.COLOR2))
        for name, path, sharing in match2:
            x += 1
            perc = int(tools.percentage(x, len(match2)))
            progress_dialog.update(
                perc, '' + '\n' +
                "[COLOR {0}]Comprobando [COLOR {1}]{2}[/COLOR]:[/COLOR]".
                format(CONFIG.COLOR2, CONFIG.COLOR1, name) + '\n' +
                "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, path))

            working = tools.open_url(path, check=True)
            if not working:
                bad.append([name, path, sharing, working])

        logging.log("Fuentes Malas: {0}".format(len(bad)))
        if len(bad) > 0:
            choice = dialog.yesno(
                CONFIG.ADDONTITLE,
                "[COLOR {0}]{1}[/COLOR][COLOR {2}] Fuente(s) se han encontrado Rotas"
                .format(CONFIG.COLOR1, len(bad), CONFIG.COLOR2) + '\n' +
                "Le gustaría Eliminar todos o elegir uno por uno?[/COLOR]",
                yeslabel="[B][COLOR dodgerblue]Eliminar Todo[/COLOR][/B]",
                nolabel="[B][COLOR red]Elija Eliminar[/COLOR][/B]")
            if choice == 1:
                remove = bad
            else:
                for name, path, sharing, working in bad:
                    logging.log("{0} fuentes: {1}, {2}".format(
                        name, path, working))
                    if dialog.yesno(
                            CONFIG.ADDONTITLE,
                            "[COLOR {0}]{1}[/COLOR][COLOR {2}] se informó que no funciona"
                            .format(CONFIG.COLOR1, name, CONFIG.COLOR2) +
                            '\n' + "[COLOR {0}]{1}[/COLOR]".format(
                                CONFIG.COLOR1, path) + '\n' +
                            "[COLOR {0}]{1}[/COLOR]".format(
                                CONFIG.COLOR1, working),
                            yeslabel=
                            "[B][COLOR dodgerblue]Eliminar Fuente[/COLOR][/B]",
                            nolabel="[B][COLOR red]Mantener Fuente[/COLOR][/B]"
                    ):
                        remove.append([name, path, sharing, working])
                        logging.log("Eliminando Fuente {0}".format(name))
                    else:
                        logging.log("La Fuente {0} no se eliminó".format(name))
            if len(remove) > 0:
                for name, path, sharing, working in remove:
                    a = a.replace(
                        '\n<source>\n<name>{0}</name>\n<path pathversion="1">{1}</path>\n<allowsharing>{2}</allowsharing>\n</source>'
                        .format(name, path, sharing), '')
                    logging.log("Eliminando Fuente {0}".format(name))

                tools.write_to_file(CONFIG.SOURCES, str(a))
                alive = len(match) - len(bad)
                kept = len(bad) - len(remove)
                removed = len(remove)
                dialog.ok(
                    CONFIG.ADDONTITLE,
                    "[COLOR {0}]La Comprobación de las fuentes en busca de rutas rotas ha finalizado."
                    .format(CONFIG.COLOR2) + '\n' +
                    "Funciona: [COLOR {0}]{1}[/COLOR] | Conservo: [COLOR {2}]{3}[/COLOR] | Eliminado: [COLOR {4}]{5}[/COLOR][/COLOR]"
                    .format(CONFIG.COLOR2, CONFIG.COLOR1, alive, CONFIG.COLOR1,
                            kept, CONFIG.COLOR1, removed))
            else:
                logging.log("No hay Fuentes Malas que eliminar.")
        else:
            logging.log_notify(
                CONFIG.ADDONTITLE,
                "[COLOR {0}]Todas las Fuentes están Funcionando[/COLOR]".
                format(CONFIG.COLOR2))
    else:
        logging.log("No se Encontraron Fuentes")
예제 #8
0
 def __init__(self,
              msg='',
              L=0,
              T=0,
              W=1280,
              H=720,
              TxtColor='0xFFFFFFFF',
              Font='font10',
              BorderWidth=10):
     buttonfocus, buttonnofocus = window.get_artwork('button')
     self.BG = xbmcgui.ControlImage(L + BorderWidth,
                                    T + BorderWidth,
                                    W - (BorderWidth * 2),
                                    H - (BorderWidth * 2),
                                    CONFIG.ADDON_FANART,
                                    aspectRatio=0)
     self.addControl(self.BG)
     top = T + BorderWidth
     leftside = L + BorderWidth
     rightside = L + (W / 2) - (BorderWidth * 2)
     header = '[COLOR {0}]Quick Advanced Settings Configurator[/COLOR]'.format(
         CONFIG.COLOR2)
     self.Header = xbmcgui.ControlLabel(L,
                                        top,
                                        W,
                                        30,
                                        header,
                                        font='font13',
                                        textColor=TxtColor,
                                        alignment=0x00000002)
     self.addControl(self.Header)
     top += 30 + BorderWidth
     freeMemory = int(
         float(tools.get_info_label('System.Memory(free)')[:-2]) * .33)
     recMemory = int(
         float(tools.get_info_label('System.Memory(free)')[:-2]) * .23)
     self.videomin = 0
     self.videomax = freeMemory if freeMemory < 2000 else 2000
     self.recommendedVideo = recMemory if recMemory < 500 else 500
     self.currentVideo = self.recommendedVideo
     current1 = '[COLOR {0}]Video Cache Size[/COLOR]=[COLOR {1}]{2} MB[/COLOR]'.format(
         CONFIG.COLOR1, CONFIG.COLOR2, self.currentVideo)
     recommended1 = '[COLOR {0}]Video Cache Size:[/COLOR] [COLOR {1}]{2} MB[/COLOR]'.format(
         CONFIG.COLOR1, CONFIG.COLOR2, self.recommendedVideo)
     self.curlmin = 0
     self.curlmax = 20
     self.recommendedCurl = 10
     self.currentCurl = self.recommendedCurl
     curlpos = tools.percentage(self.currentCurl, self.curlmax)
     recommended2 = '[COLOR {0}]CURL Timeout/CURL Low Speed:[/COLOR] [COLOR {1}]{2}s[/COLOR]'.format(
         CONFIG.COLOR1, CONFIG.COLOR2, self.recommendedCurl)
     self.readmin = 0
     self.readmax = 10
     self.recommendedRead = 5
     self.currentRead = self.recommendedRead
     readpos = tools.percentage(self.currentRead, self.readmax)
     recommended3 = '[COLOR {0}]Read Buffer Factor:[/COLOR] [COLOR {1}]{2}[/COLOR]'.format(
         CONFIG.COLOR1, CONFIG.COLOR2, self.recommendedRead)
     recommended4 = '[COLOR {0}]Buffer Mode:[/COLOR] [COLOR {1}]2[/COLOR]'.format(
         CONFIG.COLOR1, CONFIG.COLOR2)
     msgbox = '[COLOR {0}]These settings will be written to the advancedsettings.xml[/COLOR]\r\n\r\n{1}\r\n{2}\r\n{3}\r\n{4}'.format(
         CONFIG.COLOR1, recommended4, recommended1, recommended3,
         recommended2)
     self.box = xbmcgui.ControlTextBox(L + 25,
                                       T + 50,
                                       W,
                                       H,
                                       font='font14')
     self.addControl(self.box)
     self.box.setText(msgbox)
     self.buttonWrite = xbmcgui.ControlButton(
         leftside,
         T + H - 40 - BorderWidth, (W / 2) - (BorderWidth * 2),
         35,
         "Write File",
         textColor="0xFF000000",
         focusedColor="0xFF000000",
         alignment=2,
         focusTexture=buttonfocus,
         noFocusTexture=buttonnofocus)
     self.buttonCancel = xbmcgui.ControlButton(
         rightside + BorderWidth * 2,
         T + H - 40 - BorderWidth, (W / 2) - (BorderWidth * 2),
         35,
         "Cancel",
         textColor="0xFF000000",
         focusedColor="0xFF000000",
         alignment=2,
         focusTexture=buttonfocus,
         noFocusTexture=buttonnofocus)
     self.addControl(self.buttonWrite)
     self.addControl(self.buttonCancel)
     self.setFocus(self.buttonCancel)
     self.buttonWrite.controlLeft(self.buttonCancel)
     self.buttonWrite.controlRight(self.buttonCancel)
     self.buttonCancel.controlLeft(self.buttonWrite)
     self.buttonCancel.controlRight(self.buttonWrite)
예제 #9
0
        def __init__(self,
                     msg='',
                     L=0,
                     T=0,
                     W=1280,
                     H=720,
                     TxtColor='0xFFFFFFFF',
                     Font='font12',
                     BorderWidth=10):
            buttonfocus, buttonnofocus = window.get_artwork('button')
            radiobgfocus, radiobgnofocus, radiofocus, radionofocus = window.get_artwork(
                'radio')
            slidernibfocus, slidernibnofocus, sliderfocus, slidernofocus = window.get_artwork(
                'slider')
            image_path = os.path.join(CONFIG.ART, 'ContentPanel.png')
            boxbg = os.path.join(CONFIG.ART, 'bgg2.png')
            self.border = xbmcgui.ControlImage(L, T, W, H, image_path)
            self.addControl(self.border)
            self.BG = xbmcgui.ControlImage(L + BorderWidth,
                                           T + BorderWidth,
                                           W - (BorderWidth * 2),
                                           H - (BorderWidth * 2),
                                           CONFIG.ADDON_FANART,
                                           aspectRatio=0,
                                           colorDiffuse='0x5FFFFFFF')
            self.addControl(self.BG)
            top = T + BorderWidth
            leftside = L + BorderWidth
            rightside = L + (W / 2) - (BorderWidth * 2)
            firstrow = top + 30
            secondrow = firstrow + 275 + (BorderWidth / 2)
            currentwidth = ((W / 2) - (BorderWidth * 4)) / 2

            header = '[COLOR {0}]Advanced Settings Configurator[/COLOR]'.format(
                CONFIG.COLOR2)
            self.Header = xbmcgui.ControlLabel(L,
                                               top,
                                               W,
                                               30,
                                               header,
                                               font='font13',
                                               textColor=TxtColor,
                                               alignment=0x00000002)
            self.addControl(self.Header)
            top += 30 + BorderWidth
            self.bgarea = xbmcgui.ControlImage(leftside,
                                               firstrow,
                                               rightside - L,
                                               275,
                                               boxbg,
                                               aspectRatio=0,
                                               colorDiffuse='0x5FFFFFFF')
            self.addControl(self.bgarea)
            self.bgarea2 = xbmcgui.ControlImage(rightside + BorderWidth +
                                                BorderWidth,
                                                firstrow,
                                                rightside - L,
                                                275,
                                                boxbg,
                                                aspectRatio=0,
                                                colorDiffuse='0x5FFFFFFF')
            self.addControl(self.bgarea2)
            self.bgarea3 = xbmcgui.ControlImage(leftside,
                                                secondrow,
                                                rightside - L,
                                                275,
                                                boxbg,
                                                aspectRatio=0,
                                                colorDiffuse='0x5FFFFFFF')
            self.addControl(self.bgarea3)
            self.bgarea4 = xbmcgui.ControlImage(rightside + BorderWidth +
                                                BorderWidth,
                                                secondrow,
                                                rightside - L,
                                                275,
                                                boxbg,
                                                aspectRatio=0,
                                                colorDiffuse='0x5FFFFFFF')
            self.addControl(self.bgarea4)

            header = '[COLOR {0}]Video Cache Size[/COLOR]'.format(
                CONFIG.COLOR2)
            self.Header2 = xbmcgui.ControlLabel(leftside + BorderWidth,
                                                firstrow + 5,
                                                (W / 2) - (BorderWidth * 2),
                                                20,
                                                header,
                                                font='font13',
                                                textColor=TxtColor,
                                                alignment=0x00000002)
            self.addControl(self.Header2)
            freeMemory = int(
                float(xbmc.getInfoLabel('System.Memory(free)')[:-2]) * .33)
            recMemory = int(
                float(xbmc.getInfoLabel('System.Memory(free)')[:-2]) * .23)
            msg3 = "[COLOR {0}]Number of bytes used for buffering streams in memory.  When set to [COLOR {1}]0[/COLOR] the cache will be written to disk instead of RAM.  Note: For the memory size set here, Kodi will require 3x the amount of RAM to be free. Setting this too high might cause Kodi to crash if it can't get enough RAM(1/3 of Free Memory: [COLOR {2}]{3}[/COLOR])[/COLOR]".format(
                CONFIG.COLOR2, CONFIG.COLOR1, CONFIG.COLOR1, freeMemory)
            self.Support3 = xbmcgui.ControlTextBox(
                leftside + int(BorderWidth * 1.5),
                firstrow + 30 + BorderWidth, (W / 2) - (BorderWidth * 4),
                150,
                font='font12',
                textColor=TxtColor)
            self.addControl(self.Support3)
            self.Support3.setText(msg3)
            try:
                self.videoCacheSize = xbmcgui.ControlSlider(
                    leftside + int(BorderWidth * 1.5),
                    firstrow + 210, (W / 2) - (BorderWidth * 5),
                    20,
                    textureback=sliderfocus,
                    texture=slidernibnofocus,
                    texturefocus=slidernibfocus,
                    orientation=xbmcgui.HORIZONTAL)
            except:
                self.videoCacheSize = xbmcgui.ControlSlider(
                    leftside + int(BorderWidth * 1.5),
                    firstrow + 210, (W / 2) - (BorderWidth * 5),
                    20,
                    textureback=sliderfocus,
                    texture=slidernibnofocus,
                    texturefocus=slidernibfocus)
            self.addControl(self.videoCacheSize)
            self.videomin = 0
            self.videomax = freeMemory if freeMemory < 2000 else 2000
            self.recommendedVideo = recMemory if recMemory < 500 else 500
            self.currentVideo = self.recommendedVideo
            videopos = tools.percentage(self.currentVideo, self.videomax)
            self.videoCacheSize.setPercent(videopos)
            current1 = '[COLOR {0}]Current:[/COLOR] [COLOR {1}]{2} MB[/COLOR]'.format(
                CONFIG.COLOR1, CONFIG.COLOR2, self.currentVideo)
            recommended1 = '[COLOR {0}]Recommended:[/COLOR] [COLOR {1}]{2} MB[/COLOR]'.format(
                CONFIG.COLOR1, CONFIG.COLOR2, self.recommendedVideo)
            self.currentVideo1 = xbmcgui.ControlTextBox(leftside + BorderWidth,
                                                        firstrow + 235,
                                                        currentwidth,
                                                        20,
                                                        font=Font,
                                                        textColor=TxtColor)
            self.addControl(self.currentVideo1)
            self.currentVideo1.setText(current1)
            self.recommendedVideo1 = xbmcgui.ControlTextBox(
                leftside + BorderWidth + currentwidth,
                firstrow + 235,
                currentwidth,
                20,
                font=Font,
                textColor=TxtColor)
            self.addControl(self.recommendedVideo1)
            self.recommendedVideo1.setText(recommended1)

            header = '[COLOR {0}]CURL Timeout/CURL Low Speed[/COLOR]'.format(
                CONFIG.COLOR2)
            self.Header3 = xbmcgui.ControlLabel(rightside + BorderWidth,
                                                firstrow + 5,
                                                (W / 2) - (BorderWidth * 2),
                                                20,
                                                header,
                                                font='font13',
                                                textColor=TxtColor,
                                                alignment=0x00000002)
            self.addControl(self.Header3)
            msg3 = "[COLOR {0}][B]curlclienttimeout[/B] is the time in seconds for how long it takes for libcurl connection will timeout and [B]curllowspeedtime[/B] is the time in seconds for libcurl to consider a connection lowspeed.  For slower connections set it to 20.[/COLOR]".format(
                CONFIG.COLOR2)
            self.Support3 = xbmcgui.ControlTextBox(
                rightside + int(BorderWidth * 3.5),
                firstrow + 30 + BorderWidth, (W / 2) - (BorderWidth * 4),
                150,
                font='font12',
                textColor=TxtColor)
            self.addControl(self.Support3)
            self.Support3.setText(msg3)
            try:
                self.CURLTimeout = xbmcgui.ControlSlider(
                    rightside + int(BorderWidth * 3.5),
                    firstrow + 210, (W / 2) - (BorderWidth * 5),
                    20,
                    textureback=sliderfocus,
                    texture=slidernibnofocus,
                    texturefocus=slidernibfocus,
                    orientation=xbmcgui.HORIZONTAL)
            except:
                self.CURLTimeout = xbmcgui.ControlSlider(
                    rightside + int(BorderWidth * 3.5),
                    firstrow + 210, (W / 2) - (BorderWidth * 5),
                    20,
                    textureback=sliderfocus,
                    texture=slidernibnofocus,
                    texturefocus=slidernibfocus)
            self.addControl(self.CURLTimeout)
            self.curlmin = 0
            self.curlmax = 20
            self.recommendedCurl = 10
            self.currentCurl = self.recommendedCurl
            curlpos = tools.percentage(self.currentCurl, self.curlmax)
            self.CURLTimeout.setPercent(curlpos)
            current2 = '[COLOR {0}]Current:[/COLOR] [COLOR {1}]{2}s[/COLOR]'.format(
                CONFIG.COLOR1, CONFIG.COLOR2, self.currentCurl)
            recommended2 = '[COLOR {0}]Recommended:[/COLOR] [COLOR {1}]{2}s[/COLOR]'.format(
                CONFIG.COLOR1, CONFIG.COLOR2, self.recommendedCurl)
            self.currentCurl2 = xbmcgui.ControlTextBox(rightside +
                                                       (BorderWidth * 3),
                                                       firstrow + 235,
                                                       currentwidth,
                                                       20,
                                                       font=Font,
                                                       textColor=TxtColor)
            self.addControl(self.currentCurl2)
            self.currentCurl2.setText(current2)
            self.recommendedCurl2 = xbmcgui.ControlTextBox(
                rightside + (BorderWidth * 3) + currentwidth,
                firstrow + 235,
                currentwidth,
                20,
                font=Font,
                textColor=TxtColor)
            self.addControl(self.recommendedCurl2)
            self.recommendedCurl2.setText(recommended2)

            header = '[COLOR {0}]Read Buffer Factor[/COLOR]'.format(
                CONFIG.COLOR2)
            self.Header4 = xbmcgui.ControlLabel(leftside,
                                                secondrow + 5,
                                                (W / 2) - (BorderWidth * 2),
                                                20,
                                                header,
                                                font='font13',
                                                textColor=TxtColor,
                                                alignment=0x00000002)
            self.addControl(self.Header4)
            msg3 = "[COLOR {0}]The value of this setting is a multiplier of the default limit. If Kodi is loading a typical bluray raw file at 36 Mbit/s, then a value of 2 will need at least 72 Mbit/s of network bandwidth. However, unlike with the RAM setting, you can safely increase this value however high you want, and Kodi won't crash.[/COLOR]".format(
                CONFIG.COLOR2)
            self.Support3 = xbmcgui.ControlTextBox(
                leftside + int(BorderWidth * 1.5),
                secondrow + 30 + BorderWidth, (W / 2) - (BorderWidth * 4),
                150,
                font='font12',
                textColor=TxtColor)
            self.addControl(self.Support3)
            self.Support3.setText(msg3)
            try:
                self.readBufferFactor = xbmcgui.ControlSlider(
                    leftside + int(BorderWidth * 1.5),
                    secondrow + 210, (W / 2) - (BorderWidth * 5),
                    20,
                    textureback=sliderfocus,
                    texture=slidernibnofocus,
                    texturefocus=slidernibfocus,
                    orientation=xbmcgui.HORIZONTAL)
            except:
                self.readBufferFactor = xbmcgui.ControlSlider(
                    leftside + int(BorderWidth * 1.5),
                    secondrow + 210, (W / 2) - (BorderWidth * 5),
                    20,
                    textureback=sliderfocus,
                    texture=slidernibnofocus,
                    texturefocus=slidernibfocus)
            self.addControl(self.readBufferFactor)
            self.readmin = 0
            self.readmax = 10
            self.recommendedRead = 5
            self.currentRead = self.recommendedRead
            readpos = tools.percentage(self.currentRead, self.readmax)
            self.readBufferFactor.setPercent(readpos)
            current3 = '[COLOR {0}]Current:[/COLOR] [COLOR {1}]{2}[/COLOR]'.format(
                CONFIG.COLOR1, CONFIG.COLOR2, self.currentRead)
            recommended3 = '[COLOR {0}]Recommended:[/COLOR] [COLOR {1}]{2}[/COLOR]'.format(
                CONFIG.COLOR1, CONFIG.COLOR2, self.recommendedRead)
            self.currentRead3 = xbmcgui.ControlTextBox(leftside + BorderWidth,
                                                       secondrow + 235,
                                                       currentwidth,
                                                       20,
                                                       font=Font,
                                                       textColor=TxtColor)
            self.addControl(self.currentRead3)
            self.currentRead3.setText(current3)
            self.recommendedRead3 = xbmcgui.ControlTextBox(
                leftside + BorderWidth + currentwidth,
                secondrow + 235,
                currentwidth,
                20,
                font=Font,
                textColor=TxtColor)
            self.addControl(self.recommendedRead3)
            self.recommendedRead3.setText(recommended3)

            header = '[COLOR {0}]Buffer Mode[/COLOR]'.format(CONFIG.COLOR2)
            self.Header4 = xbmcgui.ControlLabel(rightside + BorderWidth,
                                                secondrow + 5,
                                                (W / 2) - (BorderWidth * 2),
                                                20,
                                                header,
                                                font='font13',
                                                textColor=TxtColor,
                                                alignment=0x00000002)
            self.addControl(self.Header4)
            msg4 = "[COLOR {0}]This setting will force Kodi to use a cache for all video files, including local network, internet, and even the local hard drive. Default value is 0 and will only cache videos that use internet file paths/sources.[/COLOR]".format(
                CONFIG.COLOR2)
            self.Support4 = xbmcgui.ControlTextBox(
                rightside + int(BorderWidth * 3.5),
                secondrow + 30 + BorderWidth, (W / 2) - (BorderWidth * 4),
                110,
                font='font12',
                textColor=TxtColor)
            self.addControl(self.Support4)
            self.Support4.setText(msg4)
            B1 = secondrow + 130 + BorderWidth
            B2 = B1 + 30
            B3 = B2 + 30
            B4 = B3 + 30
            self.Button0 = xbmcgui.ControlRadioButton(
                rightside + (BorderWidth * 3),
                B1, (W / 2) - (BorderWidth * 4),
                30,
                '0: Buffer all internet filesystems',
                font='font12',
                focusTexture=radiobgfocus,
                noFocusTexture=radiobgnofocus,
                focusOnTexture=radiofocus,
                noFocusOnTexture=radiofocus,
                focusOffTexture=radionofocus,
                noFocusOffTexture=radionofocus)
            self.Button1 = xbmcgui.ControlRadioButton(
                rightside + (BorderWidth * 3),
                B2, (W / 2) - (BorderWidth * 4),
                30,
                '1: Buffer all filesystems',
                font='font12',
                focusTexture=radiobgfocus,
                noFocusTexture=radiobgnofocus,
                focusOnTexture=radiofocus,
                noFocusOnTexture=radiofocus,
                focusOffTexture=radionofocus,
                noFocusOffTexture=radionofocus)
            self.Button2 = xbmcgui.ControlRadioButton(
                rightside + (BorderWidth * 3),
                B3, (W / 2) - (BorderWidth * 4),
                30,
                '2: Only buffer true internet filesystems',
                font='font12',
                focusTexture=radiobgfocus,
                noFocusTexture=radiobgnofocus,
                focusOnTexture=radiofocus,
                noFocusOnTexture=radiofocus,
                focusOffTexture=radionofocus,
                noFocusOffTexture=radionofocus)
            self.Button3 = xbmcgui.ControlRadioButton(
                rightside + (BorderWidth * 3),
                B4, (W / 2) - (BorderWidth * 4),
                30,
                '3: No Buffer',
                font='font12',
                focusTexture=radiobgfocus,
                noFocusTexture=radiobgnofocus,
                focusOnTexture=radiofocus,
                noFocusOnTexture=radiofocus,
                focusOffTexture=radionofocus,
                noFocusOffTexture=radionofocus)
            self.addControl(self.Button0)
            self.addControl(self.Button1)
            self.addControl(self.Button2)
            self.addControl(self.Button3)
            self.Button0.setSelected(False)
            self.Button1.setSelected(False)
            self.Button2.setSelected(True)
            self.Button3.setSelected(False)

            self.buttonWrite = xbmcgui.ControlButton(
                leftside,
                T + H - 40 - BorderWidth, (W / 2) - (BorderWidth * 2),
                35,
                "Write File",
                textColor="0xFF000000",
                focusedColor="0xFF000000",
                alignment=2,
                focusTexture=buttonfocus,
                noFocusTexture=buttonnofocus)
            self.buttonCancel = xbmcgui.ControlButton(
                rightside + BorderWidth * 2,
                T + H - 40 - BorderWidth, (W / 2) - (BorderWidth * 2),
                35,
                "Cancel",
                textColor="0xFF000000",
                focusedColor="0xFF000000",
                alignment=2,
                focusTexture=buttonfocus,
                noFocusTexture=buttonnofocus)
            self.addControl(self.buttonWrite)
            self.addControl(self.buttonCancel)

            self.buttonWrite.controlLeft(self.buttonCancel)
            self.buttonWrite.controlRight(self.buttonCancel)
            self.buttonWrite.controlUp(self.Button3)
            self.buttonWrite.controlDown(self.videoCacheSize)
            self.buttonCancel.controlLeft(self.buttonWrite)
            self.buttonCancel.controlRight(self.buttonWrite)
            self.buttonCancel.controlUp(self.Button3)
            self.buttonCancel.controlDown(self.videoCacheSize)
            self.videoCacheSize.controlUp(self.buttonWrite)
            self.videoCacheSize.controlDown(self.CURLTimeout)
            self.CURLTimeout.controlUp(self.videoCacheSize)
            self.CURLTimeout.controlDown(self.readBufferFactor)
            self.readBufferFactor.controlUp(self.CURLTimeout)
            self.readBufferFactor.controlDown(self.Button0)
            self.Button0.controlUp(self.CURLTimeout)
            self.Button0.controlDown(self.Button1)
            self.Button0.controlLeft(self.readBufferFactor)
            self.Button0.controlRight(self.readBufferFactor)
            self.Button1.controlUp(self.Button0)
            self.Button1.controlDown(self.Button2)
            self.Button1.controlLeft(self.readBufferFactor)
            self.Button1.controlRight(self.readBufferFactor)
            self.Button2.controlUp(self.Button1)
            self.Button2.controlDown(self.Button3)
            self.Button2.controlLeft(self.readBufferFactor)
            self.Button2.controlRight(self.readBufferFactor)
            self.Button3.controlUp(self.Button2)
            self.Button3.controlDown(self.buttonWrite)
            self.Button3.controlLeft(self.readBufferFactor)
            self.Button3.controlRight(self.readBufferFactor)
            self.setFocus(self.videoCacheSize)