def create_code(): from resources.libs.common import tools dialog = xbmcgui.Dialog() url = tools.get_keyboard( '', "{0}: Insert the URL for the QR Code.".format(CONFIG.ADDONTITLE)) response = tools.open_url(url, check=True) if not response: if not dialog.yesno( CONFIG.ADDONTITLE, "[COLOR {0}]It seems the URL you entered either isn't valid or isn\'t working, Would you like to create it anyways?[/COLOR]" .format(CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, url), yeslabel="[B][COLOR red]Yes Create[/COLOR][/B]", nolabel="[B][COLOR springgreen]No Cancel[/COLOR][/B]"): return name = tools.get_keyboard( '', "{0}: Insert the name for the QR Code.".format(CONFIG.ADDONTITLE)) name = "QR_Code_{0}".format(tools.id_generator(6)) if name == "" else name image = generate_code(url, name) dialog.ok( CONFIG.ADDONTITLE, "[COLOR {0}]The QR Code image has been created and is located in the addon_data directory:[/COLOR]" .format(CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, image.replace(CONFIG.HOME, '')))
def create_code(): from resources.libs.common import tools dialog = xbmcgui.Dialog() url = tools.get_keyboard( '', "{0}: Inserte la URL del Código QR.".format(CONFIG.ADDONTITLE)) response = tools.open_url(url, check=True) if not response: if not dialog.yesno( CONFIG.ADDONTITLE, "[COLOR {0}]Parece que la URL que ingresó no es válida o no funciona. Le gustaría crearla de todos modos?[/COLOR]" .format(CONFIG.COLOR2) + '\n' + "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, url), yeslabel="[B][COLOR red]Sí, Crear[/COLOR][/B]", nolabel="[B][COLOR springgreen]No, Cancelar[/COLOR][/B]"): return name = tools.get_keyboard( '', "{0}: Inserte el nombre del Código QR.".format(CONFIG.ADDONTITLE)) name = "QR_Code_{0}".format(tools.id_generator(6)) if name == "" else name image = generate_code(url, name) dialog.ok( CONFIG.ADDONTITLE, "[COLOR {0}]La imagen del Código QR se ha creado y se encuentra en el directorio addon_data:[/COLOR]" .format(CONFIG.COLOR2) + '\n' + "[COLOR {0}]{1}[/COLOR]".format( CONFIG.COLOR1, image.replace(CONFIG.HOME, '')))
def _cache(self, tag, current): value = None if tag == 'buffermode': values = ['Buffer all internet filesystems', 'Buffer all filesystems', 'Only buffer true internet filesystems', 'No buffer', 'All network filesystems'] items = [] for i in range(len(values)): items.append(xbmcgui.ListItem(label=str(i), label2=values[i])) value = self.dialog.select('Choose a Value', items, preselect=int(current), useDetails=True) elif tag == 'memorysize': free_memory = tools.get_info_label('System.Memory(free)') free_converted = tools.convert_size(int(float(free_memory[:-2])) * 1024 * 1024) recommended = int(float(free_memory[:-2]) / 3) * 1024 * 1024 recommended_converted = tools.convert_size(int(float(free_memory[:-2]) / 3) * 1024 * 1024) value = tools.get_keyboard(default='{0}'.format(recommended), heading='Tamanho da memória em bytes \n(recomendado: {0} = {1})'.format(recommended_converted, recommended)) elif tag == 'readfactor': value = tools.get_keyboard(default='{0}'.format(current), heading='Taxa de preenchimento do cache \n(Números altos causarão uso pesado da largura de banda!)') return value
def _network(self, tag, current): msgs = {'curlclienttimeout': 'Tempo limite em segundos para conexões libcurl (http / ftp)', 'curllowspeedtime': 'Tempo em segundos para libcurl considerar uma conexão de baixa velocidade', 'curlretries': 'Quantidade de tentativas para certas operações libcurl com falha (por exemplo, tempo limite)', 'httpproxyusername': '******', 'httpproxypassword': '******'} value = tools.get_keyboard(default='{0}'.format(current), heading=msgs[tag]) return value
def create_code(): from resources.libs.common import tools dialog = xbmcgui.Dialog() url = tools.get_keyboard('', "{0}: Insert the URL for the QR Code.".format(CONFIG.ADDONTITLE)) response = tools.open_url(url, check=True) if not response: if not dialog.yesno(CONFIG.ADDONTITLE, "[COLOR {0}]Parece que o URL que você inseriu não é válido ou não está funcionando. Deseja criá-lo mesmo assim?[/COLOR]".format(CONFIG.COLOR2) +'\n'+"[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, url), yeslabel="[B][COLOR red]Sim Criar[/COLOR][/B]", nolabel="[B][COLOR springgreen]Sem Cancelar[/COLOR][/B]"): return name = tools.get_keyboard('', "{0}: Insira o nome do QR Code.".format(CONFIG.ADDONTITLE)) name = "QR_Code_{0}".format(tools.id_generator(6)) if name == "" else name image = generate_code(url, name) dialog.ok(CONFIG.ADDONTITLE, "[COLOR {0}]A imagem do código QR foi criada e está localizada no diretório addon_data:[/COLOR]".format(CONFIG.COLOR2) +'\n'+"[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, image.replace(CONFIG.HOME, '')))
def _cache(self, tag, current): value = None if tag == 'buffermode': values = [ 'Buffer all internet filesystems', 'Buffer all filesystems', 'Only buffer true internet filesystems', 'No buffer', 'All network filesystems' ] items = [] for i in range(len(values)): items.append(xbmcgui.ListItem(label=str(i), label2=values[i])) value = self.dialog.select('Choose a Value', items, preselect=int(current), useDetails=True) elif tag == 'memorysize': free_memory = tools.get_info_label('System.Memory(free)') free_converted = tools.convert_size( int(float(free_memory[:-2])) * 1024 * 1024) recommended = int(float(free_memory[:-2]) / 3) * 1024 * 1024 recommended_converted = tools.convert_size( int(float(free_memory[:-2]) / 3) * 1024 * 1024) value = tools.get_keyboard( default='{0}'.format(recommended), heading= 'Dung lượng Memcache tính theo Bytes\n(Đề xuất: {0} = {1})'. format(recommended_converted, recommended)) elif tag == 'readfactor': value = tools.get_keyboard( default='{0}'.format(current), heading= 'Fill Rate of Cache\n(High numbers will cause heavy bandwidth use!)' ) return value
def _network(self, tag, current): msgs = { 'curlclienttimeout': 'Timeout in seconds for libcurl (http/ftp) connections', 'curllowspeedtime': 'Time in seconds for libcurl to consider a connection lowspeed', 'curlretries': 'Amount of retries for certain failed libcurl operations (e.g. timeout)', 'httpproxyusername': '******', 'httpproxypassword': '******' } value = tools.get_keyboard(default='{0}'.format(current), heading=msgs[tag]) return value
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))
def _backup_theme(name=""): dialog = xbmcgui.Dialog() if not dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to create a theme backup?[/COLOR]".format(CONFIG.COLOR2), yeslabel="[B][COLOR springgreen]Continue[/COLOR][/B]", nolabel="[B][COLOR red]No Cancel[/COLOR][/B]"): logging.log_notify("Theme Backup", "Cancelled!") return False if name == "": themename = tools.get_keyboard("", "Please enter a name for the theme zip") if not themename: return False else: themename = name themename = quote_plus(themename) tempzipname = '' zipname = os.path.join(CONFIG.MYBUILDS, '{0}.zip'.format(themename)) try: zipf = zipfile.ZipFile(zipname, mode='w') except: try: tempzipname = os.path.join(CONFIG.PACKAGES, '{0}.zip'.format(themename)) zipf = zipfile.ZipFile(tempzipname, mode='w') except: logging.log("Unable to create {0}.zip".format(themename), 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 tools.convert_special(CONFIG.USERDATA, True) tools.ascii_check(CONFIG.USERDATA, True) try: if not CONFIG.SKIN not in ['skin.confluence', 'skin.estuary', 'skin.estouchy']: skinfold = os.path.join(CONFIG.SKIN, 'media') match2 = glob.glob(os.path.join(skinfold, '*.xbt')) if len(match2) > 1: if dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to go through the Texture Files for?[/COLOR]".format(CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, CONFIG.SKIN), yeslabel="[B][COLOR springgreen]Add Textures[/COLOR][/B]", nolabel="[B][COLOR red]Skip Textures[/COLOR][/B]"): for xbt in match2: if dialog.yesno( '[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to add the Texture File [COLOR {1}]{2}[/COLOR]?".format( CONFIG.COLOR1, CONFIG.COLOR2, xbt.replace(skinfold, "")[1:]), "from [COLOR {0}]{1}[/COLOR][/COLOR]".format(CONFIG.COLOR1, CONFIG.SKIN), yeslabel="[B][COLOR springgreen]Add Textures[/COLOR][/B]", nolabel="[B][COLOR red]Skip Textures[/COLOR][/B]"): fn = xbt fn2 = fn.replace(CONFIG.HOME, "") zipf.write(fn, fn2, zipfile.ZIP_DEFLATED) else: for xbt in match2: if dialog.yesno( '[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to add the Texture File [COLOR {1}]{2}[/COLOR]?".format( CONFIG.COLOR2, CONFIG.COLOR1, xbt.replace(skinfold, "")[1:]), "from [COLOR {0}]{1}[/COLOR][/COLOR]".format(CONFIG.COLOR1, CONFIG.SKIN), yeslabel="[B][COLOR springgreen]Add Textures[/COLOR][/B]", nolabel="[B][COLOR red]Skip Textures[/COLOR][/B]"): fn = xbt fn2 = fn.replace(CONFIG.HOME, "") zipf.write(fn, fn2, zipfile.ZIP_DEFLATED) ad_skin = os.path.join(CONFIG.ADDON_DATA, CONFIG.SKIN, 'settings.xml') if os.path.exists(ad_skin): if dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to go add the [COLOR {1}]settings.xml[/COLOR] in [COLOR {2}]/addon_data/[/COLOR] for?".format( CONFIG.COLOR2, CONFIG.COLOR1, CONFIG.COLOR1), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, CONFIG.SKIN), yeslabel="[B][COLOR springgreen]Add Settings[/COLOR][/B]", nolabel="[B][COLOR red]Skip Settings[/COLOR][/B]"): ad_skin2 = ad_skin.replace(CONFIG.HOME, "") zipf.write(ad_skin, ad_skin2, zipfile.ZIP_DEFLATED) match = tools.parse_dom(tools.read_from_file(os.path.join(CONFIG.SKIN, 'addon.xml')), 'import', ret='addon') if 'script.skinshortcuts' in match: if dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to go add the [COLOR {1}]settings.xml[/COLOR] for [COLOR {2}]script.skinshortcuts[/COLOR]?".format( CONFIG.COLOR2, CONFIG.COLOR1, CONFIG.COLOR1), yeslabel="[B][COLOR springgreen]Add Settings[/COLOR][/B]", nolabel="[B][COLOR red]Skip Settings[/COLOR][/B]"): 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) if dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to include a [COLOR {1}]Backgrounds[/COLOR] folder?[/COLOR]".format( CONFIG.COLOR2, CONFIG.COLOR1), yeslabel="[B][COLOR springgreen]Yes Include[/COLOR][/B]", nolabel="[B][COLOR red]No Continue[/COLOR][/B]"): fn = dialog.browse(0, 'Select location of backgrounds', 'files', '', True, False, CONFIG.HOME, False) if not fn == CONFIG.HOME: for base, dirs, files in os.walk(fn): 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: fn2 = os.path.join(base, file) zipf.write(fn2, fn2[len(CONFIG.HOME):], zipfile.ZIP_DEFLATED) except Exception as e: logging.log("[Back Up] Type = theme: Unable to backup {0}".format(file)) logging.log("Backup Error: {0}".format(str(e))) text = db.latest_db('Textures') if dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to include the [COLOR {1}]{2}[/COLOR]?[/COLOR]".format( CONFIG.COLOR2, CONFIG.COLOR1, text), yeslabel="[B][COLOR springgreen]Yes Include[/COLOR][/B]", nolabel="[B][COLOR red]No Continue[/COLOR][/B]"): zipf.write(os.path.join(CONFIG.DATABASE, text), '/userdata/Database/{0}'.format(text), zipfile.ZIP_DEFLATED) if dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to include any addons?[/COLOR]".format(CONFIG.COLOR2), yeslabel="[B][COLOR springgreen]Yes Include[/COLOR][/B]", nolabel="[B][COLOR red]No Continue[/COLOR][/B]"): fold = glob.glob(os.path.join(CONFIG.ADDONS, '*/')) addonnames = [] addonfolds = [] for folder in sorted(fold, key=lambda x: x): foldername = os.path.split(folder[:-1])[1] if foldername in CONFIG.EXCLUDES: continue elif foldername in CONFIG.DEFAULTPLUGINS: continue elif foldername == 'packages': continue xml = os.path.join(folder, 'addon.xml') if os.path.exists(xml): match = tools.parse_dom(tools.read_from_file(xml), 'addon', ret='name') if len(match) > 0: addonnames.append(match[0]) addonfolds.append(foldername) else: addonnames.append(foldername) addonfolds.append(foldername) selected = dialog.multiselect("{0}: Select the add-ons you wish to add to the zip.".format(CONFIG.ADDONTITLE), addonnames) if selected is None: selected = [] if len(selected) > 0: added = [] for item in selected: added.append(addonfolds[item]) for base, dirs, files in os.walk(os.path.join(CONFIG.ADDONS, addonfolds[item])): files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES] for file in files: if file.endswith('.pyo'): continue fn = os.path.join(base, file) zipf.write(fn, fn[len(CONFIG.HOME):], zipfile.ZIP_DEFLATED) dep = os.path.join(CONFIG.ADDONS, addonfolds[item], 'addon.xml') if os.path.exists(dep): match = tools.parse_dom(tools.read_from_file(dep), 'import', ret='addon') for depends in match: if 'xbmc.python' in depends: continue if depends in added: continue for base, dirs, files in os.walk(os.path.join(CONFIG.ADDONS, depends)): files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES] for file in files: if file.endswith('.pyo'): continue fn = os.path.join(base, file) zipf.write(fn, fn[len(CONFIG.HOME):], zipfile.ZIP_DEFLATED) added.append(depends) if dialog.yesno('[COLOR {0}]{1}[/COLOR][COLOR {2}]: Theme Backup[/COLOR]'.format(CONFIG.COLOR1, CONFIG.ADDONTITLE, CONFIG.COLOR2), "[COLOR {0}]Would you like to include the [COLOR {1}]guisettings.xml[/COLOR]?[/COLOR]".format( CONFIG.COLOR2, CONFIG.COLOR1), yeslabel="[B][COLOR springgreen]Yes Include[/COLOR][/B]", nolabel="[B][COLOR red]No Continue[/COLOR][/B]"): zipf.write(CONFIG.GUISETTINGS, '/userdata/guisettings.xml', zipfile.ZIP_DEFLATED) except Exception as e: zipf.close() logging.log("[Back Up] Type = theme: {0}".format(str(e))) dialog.ok(CONFIG.ADDONTITLE, "[COLOR {0}]{1}[/COLOR][COLOR {2}] theme zip failed:[/COLOR]".format(CONFIG.COLOR1, themename, CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, str(e))) if not tempzipname == '': try: os.remove(tempzipname) except Exception as e: logging.log(str(e)) else: try: os.remove(zipname) except Exception as e: logging.log(str(e)) return zipf.close() if not tempzipname == '': success = xbmcvfs.rename(tempzipname, zipname) if success == 0: xbmcvfs.copy(tempzipname, zipname) xbmcvfs.delete(tempzipname) dialog.ok(CONFIG.ADDONTITLE, "[COLOR {0}]{1}[/COLOR][COLOR {2}] theme zip successful:[/COLOR]".format(CONFIG.COLOR1, themename, CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, zipname))
def _backup_guifix(name=""): dialog = xbmcgui.Dialog() if name == "": guiname = tools.get_keyboard("", "Please enter a name for the GUI Fix zip") if not guiname: return False tools.convert_special(CONFIG.USERDATA, True) tools.ascii_check(CONFIG.USERDATA, True) else: guiname = name guiname = quote_plus(guiname) tempguizipname = '' guizipname = os.path.join(CONFIG.MYBUILDS, '{0}_guisettings.zip'.format(guiname)) if os.path.exists(CONFIG.GUISETTINGS): try: zipf = zipfile.ZipFile(guizipname, mode='w') except: try: tempguizipname = os.path.join(CONFIG.PACKAGES, '{0}_guisettings.zip'.format(guiname)) zipf = zipfile.ZipFile(tempguizipname, mode='w') except: logging.log("Unable to create {0}_guisettings.zip".format(guiname), 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 try: zipf.write(CONFIG.GUISETTINGS, 'guisettings.xml', zipfile.ZIP_DEFLATED) zipf.write(CONFIG.PROFILES, 'profiles.xml', zipfile.ZIP_DEFLATED) 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']: if dialog.yesno(CONFIG.ADDONTITLE, "[COLOR {0}]Would you like to add the following skin folder to the GUI Fix Zip File?[/COLOR]".format(CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, fd), yeslabel="[B][COLOR springgreen]Add Skin[/COLOR][/B]", nolabel="[B][COLOR red]Skip Skin[/COLOR][/B]"): 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.USERDATA):], zipfile.ZIP_DEFLATED) 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.USERDATA):], zipfile.ZIP_DEFLATED) else: logging.log("[Back Up] Type = guifix: {0} ignored".format(fold)) except Exception as e: logging.log("[Back Up] Type = guifix: {0}".format(e)) pass zipf.close() if not tempguizipname == '': success = xbmcvfs.rename(tempguizipname, guizipname) if success == 0: xbmcvfs.copy(tempguizipname, guizipname) xbmcvfs.delete(tempguizipname) else: logging.log("[Back Up] Type = guifix: guisettings.xml not found") if name == "": dialog.ok(CONFIG.ADDONTITLE, "[COLOR {0}]GUI Fix backup successful:[/COLOR]".format(CONFIG.COLOR2), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, guizipname))
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))
def _backup_addon_pack(name=""): dialog = xbmcgui.Dialog() progress_dialog = xbmcgui.DialogProgress() if dialog.yesno(CONFIG.ADDONTITLE, "[COLOR {0}]Are you sure you wish to create an Addon Pack?[/COLOR]".format(CONFIG.COLOR2), nolabel="[B][COLOR red]Cancel Backup[/COLOR][/B]", yeslabel="[B][COLOR springgreen]Create Pack[/COLOR][/B]"): if name == "": name = tools.get_keyboard("", "Please enter a name for the add-on pack zip") if not name: return False name = quote_plus(name) name = '{0}.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}.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 fold = glob.glob(os.path.join(CONFIG.ADDONS, '*/')) addonnames = [] addonfolds = [] for folder in sorted(fold, key=lambda x: x): foldername = os.path.split(folder[:-1])[1] if foldername in CONFIG.EXCLUDES: continue elif foldername in CONFIG.DEFAULTPLUGINS: continue elif foldername == 'packages': continue xml = os.path.join(folder, 'addon.xml') if os.path.exists(xml): match = tools.parse_dom(tools.read_from_file(xml), 'addon', ret='name') if len(match) > 0: addonnames.append(match[0]) addonfolds.append(foldername) else: addonnames.append(foldername) addonfolds.append(foldername) selected = dialog.multiselect( "{0}: Select the add-ons you wish to add to the zip.".format(CONFIG.ADDONTITLE), addonnames) if selected is None: selected = [] logging.log(selected) progress_dialog.create(CONFIG.ADDONTITLE, '[COLOR {0}][B]Creating Zip File:[/B][/COLOR]'.format(CONFIG.COLOR2), '', 'Please Wait') if len(selected) > 0: added = [] for item in selected: added.append(addonfolds[item]) progress_dialog.update(0, "", "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, addonfolds[item])) for base, dirs, files in os.walk(os.path.join(CONFIG.ADDONS, addonfolds[item])): files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES] for file in files: if file.endswith('.pyo'): continue progress_dialog.update(0, "", "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, addonfolds[item]), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, file)) fn = os.path.join(base, file) zipf.write(fn, fn[len(CONFIG.ADDONS):], zipfile.ZIP_DEFLATED) dep = os.path.join(CONFIG.ADDONS, addonfolds[item], 'addon.xml') if os.path.exists(dep): match = tools.parse_dom(tools.read_from_file(dep), 'import', ret='addon') for depends in match: if 'xbmc.python' in depends: continue if depends in added: continue progress_dialog.update(0, "", "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, depends)) for base, dirs, files in os.walk(os.path.join(CONFIG.ADDONS, depends)): files[:] = [f for f in files if f not in CONFIG.EXCLUDE_FILES] for file in files: if file.endswith('.pyo'): continue progress_dialog.update(0, "", "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, depends), "[COLOR {0}]{1}[/COLOR]".format(CONFIG.COLOR1, file)) fn = os.path.join(base, file) zipf.write(fn, fn[len(CONFIG.ADDONS):], zipfile.ZIP_DEFLATED) added.append(depends) 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))