diff --git a/addon.xml b/addon.xml index 285ed85..994f407 100644 --- a/addon.xml +++ b/addon.xml @@ -1,6 +1,6 @@  + name="Backup" version="1.6.0~beta1" provider-name="robweber"> @@ -92,10 +92,8 @@ resources/images/screenshot3.png resources/images/screenshot4.png - Version 1.1.4 -- added file chunk support for dropbox uploads -- fixed settings duplicate ids, thanks aster-anto -- added scheduler delay to assist with time sync (rpi mostly) + Version 1.5.1 +- fix guisettings restores not working - thanks Bluerayx diff --git a/changelog.txt b/changelog.txt index 5fe992a..62a6baf 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,7 @@ +Version 1.5.1 + +fix guisettings restores not working - thanks Bluerayx + Version 1.5.0 Overhaul of file selection and restore procedures. Breaking Change with previous versions PR117 diff --git a/resources/images/screenshot1.png b/resources/images/screenshot1.png deleted file mode 100644 index 268acda..0000000 Binary files a/resources/images/screenshot1.png and /dev/null differ diff --git a/resources/images/screenshot2.png b/resources/images/screenshot2.png deleted file mode 100644 index 08ae592..0000000 Binary files a/resources/images/screenshot2.png and /dev/null differ diff --git a/resources/images/screenshot3.png b/resources/images/screenshot3.png deleted file mode 100644 index 2861573..0000000 Binary files a/resources/images/screenshot3.png and /dev/null differ diff --git a/resources/images/screenshot4.png b/resources/images/screenshot4.png deleted file mode 100644 index e8e32df..0000000 Binary files a/resources/images/screenshot4.png and /dev/null differ diff --git a/resources/lib/backup.py b/resources/lib/backup.py index 393ce8c..fd1c4cb 100644 --- a/resources/lib/backup.py +++ b/resources/lib/backup.py @@ -3,6 +3,7 @@ import time import json from kodi_six import xbmc, xbmcgui, xbmcvfs from . import utils as utils +import os from datetime import datetime from . vfs import XBMCFileSystem,DropboxFileSystem,ZipFileSystem from . progressbar import BackupProgressBar @@ -316,10 +317,10 @@ class XbmcBackup: self.xbmc_vfs.rmfile(xbmc.translatePath("special://temp/" + self.restore_point)) self.xbmc_vfs.rmdir(self.remote_vfs.root_path) - if(utils.getSetting("backup_config") == "true"): - #update the guisettings information (or what we can from it) - gui_settings = GuiSettingsManager('special://home/userdata/guisettings.xml') - gui_settings.run() + + #update the guisettings information (or what we can from it) + gui_settings = GuiSettingsManager() + gui_settings.run() #call update addons to refresh everything xbmc.executebuiltin('UpdateLocalAddons') @@ -393,13 +394,15 @@ class XbmcBackup: dest.mkdir(dest.root_path + aFile[len(source.root_path) + 1:]) else: self._updateProgress() + wroteFile = True + destFile = dest.root_path + aFile[len(source.root_path):] if(isinstance(source,DropboxFileSystem)): #if copying from cloud storage we need the file handle, use get_file - wroteFile = source.get_file(aFile,dest.root_path + aFile[len(source.root_path):]) + wroteFile = source.get_file(aFile,destFile) else: #copy using normal method - wroteFile = dest.put(aFile,dest.root_path + aFile[len(source.root_path):]) + wroteFile = dest.put(aFile,destFile) #if result is still true but this file failed if(not wroteFile and result): @@ -550,13 +553,13 @@ class FileManager: if(directory[-1:] == '/' or directory[-1:] == '\\'): directory = directory[:-1] - if(self.vfs.exists(directory + "/")): + if(self.vfs.exists(directory + os.path.sep)): dirs,files = self.vfs.listdir(directory) if(recurse): #create all the subdirs first for aDir in dirs: - dirPath = xbmc.validatePath(xbmc.translatePath(directory + "/" + aDir)) + dirPath = xbmc.validatePath(xbmc.translatePath(directory + os.path.sep + aDir)) file_ext = aDir.split('.')[-1] #check if directory is excluded @@ -576,7 +579,7 @@ class FileManager: #copy all the files for aFile in files: - filePath = xbmc.translatePath(directory + "/" + aFile) + filePath = xbmc.translatePath(directory + os.path.sep + aFile) self.addFile(filePath) def addDir(self,dirMeta): diff --git a/resources/lib/guisettings.py b/resources/lib/guisettings.py index 63e7b0d..be1c386 100644 --- a/resources/lib/guisettings.py +++ b/resources/lib/guisettings.py @@ -6,94 +6,68 @@ from xml.parsers.expat import ExpatError class GuiSettingsManager: - settingsFile = None doc = None - settings_allowed = list() - found_settings = list() - def __init__(self,settingsFile): - self._readFile(xbmc.translatePath(settingsFile)) + def __init__(self): + #first make a copy of the file + xbmcvfs.copy(xbmc.translatePath('special://home/userdata/guisettings.xml'), xbmc.translatePath("special://home/userdata/guisettings.xml.restored")) + + #read in the copy + self._readFile(xbmc.translatePath('special://home/userdata/guisettings.xml.restored')) def run(self): #get a list of all the settings we can manipulate via json json_response = json.loads(xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.GetSettings","params":{"level":"advanced"}}')) settings = json_response['result']['settings'] - - for aSetting in settings: - self.settings_allowed.append(aSetting['id']) - - #parse the existing xml file and get all the settings - root_nodes = self.__parseNodes(self.doc.documentElement) + currentSettings = {} - for aNode in root_nodes: - secondary_list = self.__parseNodes(self.doc.getElementsByTagName(aNode.name)[0]) + for aSetting in settings: + if('value' in aSetting): + currentSettings[aSetting['id']] = aSetting['value'] - for secondNode in secondary_list: - #if the node does not have children and is not default - if(not secondNode.hasChildren and not secondNode.isDefault): - - if(secondNode.json_name() in self.settings_allowed): - self.found_settings.append(secondNode) - + #parse the existing xml file and get all the settings we need to restore + restoreSettings = self.__parseNodes(self.doc.getElementsByTagName('setting')) + + #get a list where the restore setting value != the current value + updateSettings = {k: v for k, v in restoreSettings.items() if (k in currentSettings and currentSettings[k] != v)} + #go through all the found settings and update them - for aSetting in self.found_settings: - utils.log("updating: " + aSetting.json_name() + ", value: " + aSetting.value) + jsonObj = {"jsonrpc":"2.0","id":1,"method":"Settings.SetSettingValue","params":{"setting":"","value":""}} + for anId, aValue in updateSettings.items(): + utils.log("updating: " + anId + ", value: " + str(aValue)) + + jsonObj['params']['setting'] = anId + jsonObj['params']['value'] = aValue - #check for boolean and numeric values - if(aSetting.value.isdigit() or (aSetting.value == 'true' or aSetting.value == 'false')): - xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue","params":{"setting":"' + aSetting.json_name() + '","value":' + aSetting.value + '}}') - else: - xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"Settings.SetSettingValue","params":{"setting":"' + aSetting.json_name() + '","value":"' + utils.encode(aSetting.value) + '"}}') - - #make a copy of the guisettings file to make user based restores easier - xbmcvfs.copy(self.settingsFile, xbmc.translatePath("special://home/userdata/guisettings.xml.restored")) + xbmc.executeJSONRPC(json.dumps(jsonObj)) def __parseNodes(self,nodeList): - result = [] + result = {} - for node in nodeList.childNodes: - if(node.nodeType == self.doc.ELEMENT_NODE): - aSetting = SettingNode(node.nodeName) - - #detect if there are any element nodes - if(len(node.childNodes) > 0): - for child_node in node.childNodes: - if(child_node.nodeType == self.doc.ELEMENT_NODE): - aSetting.hasChildren = True - - if(not aSetting.hasChildren and len(node.childNodes) > 0): - aSetting.value = node.firstChild.nodeValue - - if('default' not in node.attributes.keys()): - aSetting.isDefault = False - - aSetting.parent = node.parentNode.nodeName - - result.append(aSetting) + for node in nodeList: + nodeValue = '' + if(node.firstChild != None): + nodeValue = node.firstChild.nodeValue + + #check for numbers and booleans + if(nodeValue.isdigit()): + nodeValue = int(nodeValue) + elif(nodeValue == 'true'): + nodeValue = True + elif(nodeValue == 'false'): + nodeValue = False + + result[node.getAttribute('id')] = nodeValue + return result - def _readFile(self,fileLoc): if(xbmcvfs.exists(fileLoc)): try: self.doc = minidom.parse(fileLoc) - self.settingsFile = fileLoc except ExpatError: utils.log("Can't read " + fileLoc) -class SettingNode: - name = '' - value = '' - hasChildren = False - isDefault = True - parent = '' - - def __init__(self,name): - self.name = name - - def json_name(self): - return self.parent + "." + self.name -