From e4f25f174f75366d411ec60cd8be5c648a8df165 Mon Sep 17 00:00:00 2001 From: robweber Date: Mon, 20 Aug 2012 14:27:35 -0500 Subject: [PATCH 01/11] removed VFS library, now using xbmcvfs exclusively --- default.py | 52 +++++--- resources/__init__.py | 0 resources/lib/__init__.py | 0 resources/lib/vfs.py | 256 -------------------------------------- 4 files changed, 32 insertions(+), 276 deletions(-) delete mode 100644 resources/__init__.py delete mode 100644 resources/lib/__init__.py delete mode 100644 resources/lib/vfs.py diff --git a/default.py b/default.py index bf88686..b767524 100644 --- a/default.py +++ b/default.py @@ -1,7 +1,7 @@ import xbmc import xbmcaddon import xbmcgui -import resources.lib.vfs as vfs +import xbmcvfs import os import time @@ -13,6 +13,7 @@ class FileManager: addonDir = '' fileArray = None verbose_log = False + not_dir = ['.zip','.xsp','.rar'] def __init__(self,path,addon_dir): self.walk_path = path @@ -29,13 +30,13 @@ class FileManager: #figure out which syncing options to run if(Addon.getSetting('backup_addons') == 'true'): self.addFile("-addons") - self.walkTree(self.walk_path + "addons/") + self.walkTree(self.walk_path + "addons") self.addFile("-userdata") if(Addon.getSetting('backup_addon_data') == 'true'): self.addFile("-userdata/addon_data") - self.walkTree(self.walk_path + "userdata/addon_data/") + self.walkTree(self.walk_path + "userdata/addon_data") if(Addon.getSetting('backup_database') == 'true'): self.addFile("-userdata/Database") @@ -57,21 +58,28 @@ class FileManager: self.walkTree(self.walk_path + "userdata/peripheral_data") #this part is an oddity - configFiles = vfs.listdir(self.walk_path + "userdata/",extra_metadata=True) + dirs,configFiles = xbmcvfs.listdir(self.walk_path + "userdata/") for aFile in configFiles: - if(aFile['file'].endswith(".xml")): - self.addFile(aFile['file'][len(self.walk_path):]) + if(aFile.endswith(".xml")): + self.addFile("userdata/" + aFile) def walkTree(self,directory): - for (path, dirs, files) in vfs.walk(directory): + dirs,files = xbmcvfs.listdir(directory) + + #create all the subdirs first + for aDir in dirs: + dirPath = xbmc.translatePath(directory + "/" + aDir) + file_ext = aDir.split('.')[-1] + + self.addFile("-" + dirPath[len(self.walk_path):].decode("UTF-8")) + #catch for "non directory" type files + if (not any(file_ext in s for s in self.not_dir)): + self.walkTree(dirPath) - #create all the subdirs first - for aDir in dirs: - self.addFile("-" + aDir[len(self.walk_path):]) - #copy all the files - for aFile in files: - filePath = aFile[len(self.walk_path):] - self.addFile(filePath) + #copy all the files + for aFile in files: + filePath = xbmc.translatePath(directory + "/" + aFile) + self.addFile(filePath[len(self.walk_path):].decode("UTF-8")) def addFile(self,filename): #write the full remote path name of this file @@ -116,6 +124,9 @@ class XbmcBackup: self.remote_path = self.remote_path + self.addon.getSetting("backup_name") + "/" else: self.remote_path = "" + + self.local_path = self.local_path.decode("UTF-8") + self.local_path = self.local_path.decode("UTF-8") log(self.addon.getLocalizedString(30046)) log(self.addon.getLocalizedString(30047) + ": " + self.local_path) @@ -132,7 +143,7 @@ class XbmcBackup: self.fileManager = FileManager(self.local_path,self.addon.getAddonInfo('profile')) #for backups check if remote path exists - if(vfs.exists(self.remote_path)): + if(xbmcvfs.exists(self.remote_path)): #this will fail - need a disclaimer here log(self.addon.getLocalizedString(30050)) @@ -141,7 +152,7 @@ class XbmcBackup: self.fileManager = FileManager(self.remote_path,self.addon.getAddonInfo('profile')) #for restores remote path must exist - if(vfs.exists(self.remote_path)): + if(xbmcvfs.exists(self.remote_path)): self.restoreFiles() else: xbmcgui.Dialog().ok(self.addon.getLocalizedString(30010),self.addon.getLocalizedString(30045)) @@ -149,7 +160,7 @@ class XbmcBackup: def syncFiles(self): #make the remote directory - vfs.mkdir(self.remote_path) + xbmcvfs.mkdir(self.remote_path) log(self.addon.getLocalizedString(30051)) self.fileManager.createFileList(self.addon) @@ -182,9 +193,9 @@ class XbmcBackup: log('Writing file: ' + source + aFile,xbmc.LOGDEBUG) self.updateProgress(aFile) if (aFile.startswith("-")): - vfs.mkdir(xbmc.makeLegalFilename(dest + aFile[1:],False)) + xbmcvfs.mkdir(xbmc.makeLegalFilename(dest + aFile[1:],False)) else: - vfs.copy(xbmc.makeLegalFilename(source + aFile),xbmc.makeLegalFilename(dest + aFile,False)) + xbmcvfs.copy(xbmc.makeLegalFilename(source + aFile),xbmc.makeLegalFilename(dest + aFile,False)) if(self.addon.getSetting('run_silent') == 'false'): self.progressBar.close() @@ -209,7 +220,8 @@ class XbmcBackup: #global functions for logging and encoding def log(message,loglevel=xbmc.LOGNOTICE): - xbmc.log(encode(__Addon.getLocalizedString(30010) + ": " + message),level=loglevel) + logM = encode(__Addon.getLocalizedString(30010) + ": " + message) + xbmc.log(logM,level=loglevel) def encode(string): return string.encode('UTF-8','replace') diff --git a/resources/__init__.py b/resources/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/resources/lib/__init__.py b/resources/lib/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/resources/lib/vfs.py b/resources/lib/vfs.py deleted file mode 100644 index 14762b6..0000000 --- a/resources/lib/vfs.py +++ /dev/null @@ -1,256 +0,0 @@ -''' - Convenience wrappers and extensions for some commonly used VFS functions - in XBMC addons. This module exposes all the functionality of xbmcvfs plus - some extra functions. - - Copyright (C) 2012 Patrick Carey - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -''' - -import json -import os -import xbmc -import xbmcvfs -import urllib - -def walk(path): - - ''' - Reimplementation of os.walk using XBMC's jsonrpc API. - - This has the nice added benefits of being able to walk remote - directories and inside compressed files such as rars/zips. - ''' - - dir_tree = [[path]] - - current_depth = 0 - - not_dir = ['.zip','.xsp','.rar'] - - while True: - - if current_depth > -1: - - try: - - current_path = dir_tree[current_depth].pop(0) - current_dirs, current_files = [], [] - - for x in listdir(current_path, extra_metadata=True): - - file_ext = x['file'].split('.')[-1] - - if x['filetype'] == 'directory' and not any(file_ext in s for s in not_dir): - - current_dirs.append(urllib.unquote(x['file'])) - - else: - - current_files.append(urllib.unquote(x['file'])) - - except IndexError: - - current_depth -= 1 - - dir_tree.pop() - - else: - - yield (current_path, current_dirs, current_files) - - if current_dirs: - - current_depth += 1 - - dir_tree.append(current_dirs) - - else: - - break - - -def listdir(path, extra_metadata=False): - - ''' - Reimplementation of os.listdir using XBMC's jsonrpc API. - - Returns a list of file/directory names from the specified path - - Accepts an optional boolean 'extra_metadata' as the second argument - which will cause the function to instead return a list of dictionaries - containing all of the metadata about each file that was retrieved from - XBMC. - ''' - - fileList = [] - - json_response = xbmc.executeJSONRPC('{ "jsonrpc" : "2.0" , "method" : "Files.GetDirectory" , "params" : { "directory" : "%s" , "sort" : { "method" : "file" } } , "id" : 1 }' % path.encode('utf-8').replace('\\', '\\\\')) - - jsonobject = json.loads(json_response) - - if jsonobject.has_key('result') and jsonobject['result']['files']: - - for item in jsonobject['result']['files']: - - if extra_metadata: - - fileList.append(item) - - else: - - fileList.append(item['file']) - - return fileList - - -def copy(source, destination): - - """ - copy(source, destination) -- Copy file to destination, returns true/false. - - source : file to copy. - destination : destination file - - example: - - success = vfs.copy(source, destination) - """ - - return xbmcvfs.copy(source, destination) - - -def delete(path): - - """ - delete(file) -- Delete file - - file : file to delete - - example: - - vfs.delete(file) - """ - - return xbmcvfs.delete(path) - - -def exists(path): - - """ - exists(path) -- Check if file exists, returns true/false. - - path : file or folder - - example: - - success = vfs.exists(path) - """ - - return xbmcvfs.exists(path) - - -def mkdir(path): - - """ - mkdir(path) -- Create a folder. - - path : folder - - example: - - success = vfs.mkdir(path) - """ - - return xbmcvfs.mkdir(path) - - -def rename(source, target): - - """ - rename(file, newFileName) -- Rename file, returns true/false. - - file : file to reaname - newFileName : new filename, including the full path - - example: - - success = vfs.rename(file, newFileName) - """ - - return xbmcvfs.rename(source, target) - - -def rmdir(path): - - """ - rmdir(path) -- Remove a folder. - - path : folder - - example: - - success = vfs.rmdir(path) - """ - - return xbmcvfs.rmdir(path) - - -def comparepathlists(list1, list2, fullpath=False): - - """ - comparepathlists(list1, list2) -- Compare two lists of paths - - list1 : list, contains paths (local or remote, absolute or relative) - list2 : list, contains paths (local or remote, absolute or relative) - fullpath : boolean, set True to compare perform straight comparison of lists - set False (default) to compare on filename portions of each list - - returns: dictionary: - common_items: list, contains paths of items common to both lists - list1_items: list, contains paths of items found only in list1 - list2_items: list, contains paths of items found only in list2 - - example: - - compare = comparepathlists(list1, list2) - """ - - # initialise dict to store results and temp data - results = {} - temp_data = {} - - if fullpath: - - temp_path = lambda x: x - - else: - - temp_path = lambda x: os.path.split(x)[1] - - for path in list1: - - temp_data['list1'].append(temp_path(path)) - - for path in list2: - - temp_data['list2'].append(temp_path(path)) - - # get items not in list 2 - results['list1_items'] = [] - gen = (i for i, x in enumerate(temp_data['list1']) if not x in temp_data['list2']) - for i in gen: - results['list1_items'].append(list1[i]) - - # get items not in list 1 - results['list2_items'] = [] - gen = (i for i, x in enumerate(temp_data['list2']) if not x in temp_data['list1']) - for i in gen: - results['list2_items'].append(list2[i]) - - return results From 38b2c0b535501e7e04b202f43466fd8ab86f54f4 Mon Sep 17 00:00:00 2001 From: robweber Date: Mon, 20 Aug 2012 14:29:28 -0500 Subject: [PATCH 02/11] updated addon.xml and changelog.txt --- addon.xml | 2 +- changelog.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 752b4d6..6c6fff3 100644 --- a/addon.xml +++ b/addon.xml @@ -1,6 +1,6 @@  + name="XBMC Backup" version="0.2.0" provider-name="robweber"> diff --git a/changelog.txt b/changelog.txt index 79c42fe..6ce0d84 100644 --- a/changelog.txt +++ b/changelog.txt @@ -58,3 +58,9 @@ updated utf-8 encoding for all logging backup now uses date as folder name, restore allows user to type date of last backup +[b]Version 0.2.0[/b] + +removed the vfs.py helper library + +default.py file now uses xbmcvfs python library exclusively for listing directories and copy operations + From d908f23d72f4a45b044777749fc81caf78544853 Mon Sep 17 00:00:00 2001 From: robweber Date: Mon, 20 Aug 2012 14:36:57 -0500 Subject: [PATCH 03/11] merge with master moved 0.2.0 info --- changelog.txt | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/changelog.txt b/changelog.txt index 265fc34..2f4a615 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,9 @@ +[b]Version 0.2.0[/b] + +removed the vfs.py helper library + +default.py file now uses xbmcvfs python library exclusively for listing directories and copy operations + [b]Version 0.1.3[/b] added German translations - thanks dersphere @@ -57,16 +63,3 @@ Added progress bar and "silent" option for running on startup or as a script [b]Version 0.0.2[/b] First version, should backup directories as needed - - - - - - - -[b]Version 0.2.0[/b] - -removed the vfs.py helper library - -default.py file now uses xbmcvfs python library exclusively for listing directories and copy operations - From 2cf9356f9cc79a3e42737642ece6c9c97ac66710 Mon Sep 17 00:00:00 2001 From: robweber Date: Wed, 12 Sep 2012 15:03:46 -0500 Subject: [PATCH 04/11] created backup.py in prep for pull from master --- resources/lib/backup.py | 216 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 resources/lib/backup.py diff --git a/resources/lib/backup.py b/resources/lib/backup.py new file mode 100644 index 0000000..ab10625 --- /dev/null +++ b/resources/lib/backup.py @@ -0,0 +1,216 @@ +import xbmc +import xbmcgui +import vfs as vfs +import utils as utils +import os +import time + +class FileManager: + walk_path = '' + addonDir = '' + fileArray = None + verbose_log = False + not_dir = ['.zip','.xsp','.rar'] + + def __init__(self,path,addon_dir): + self.walk_path = path + self.addonDir = addon_dir + + #create the addon folder if it doesn't exist + if(not os.path.exists(unicode(xbmc.translatePath(self.addonDir),'utf-8'))): + os.makedirs(unicode(xbmc.translatePath(self.addonDir),'utf-8')) + + def createFileList(self,Addon): + self.fileArray = [] + self.verbose_log = Addon.getSetting("verbose_log") == 'true' + + #figure out which syncing options to run + if(Addon.getSetting('backup_addons') == 'true'): + self.addFile("-addons") + self.walkTree(self.walk_path + "addons") + + self.addFile("-userdata") + + if(Addon.getSetting('backup_addon_data') == 'true'): + self.addFile("-userdata/addon_data") + self.walkTree(self.walk_path + "userdata/addon_data") + + if(Addon.getSetting('backup_database') == 'true'): + self.addFile("-userdata/Database") + self.walkTree(self.walk_path + "userdata/Database") + + if(Addon.getSetting("backup_playlists") == 'true'): + self.addFile("-userdata/playlists") + self.walkTree(self.walk_path + "userdata/playlists") + + if(Addon.getSetting("backup_thumbnails") == "true"): + self.addFile("-userdata/Thumbnails") + self.walkTree(self.walk_path + "userdata/Thumbnails") + + if(Addon.getSetting("backup_config") == "true"): + self.addFile("-userdata/keymaps") + self.walkTree(self.walk_path + "userdata/keymaps") + + self.addFile("-userdata/peripheral_data") + self.walkTree(self.walk_path + "userdata/peripheral_data") + + #this part is an oddity + dirs,configFiles = xbmcvfs.listdir(self.walk_path + "userdata/") + for aFile in configFiles: + if(aFile.endswith(".xml")): + self.addFile("userdata/" + aFile) + + def walkTree(self,directory): + dirs,files = xbmcvfs.listdir(directory) + + #create all the subdirs first + for aDir in dirs: + dirPath = xbmc.translatePath(directory + "/" + aDir) + file_ext = aDir.split('.')[-1] + + self.addFile("-" + dirPath[len(self.walk_path):].decode("UTF-8")) + #catch for "non directory" type files + if (not any(file_ext in s for s in self.not_dir)): + self.walkTree(dirPath) + + #copy all the files + for aFile in files: + filePath = xbmc.translatePath(directory + "/" + aFile) + self.addFile(filePath[len(self.walk_path):].decode("UTF-8")) + + def addFile(self,filename): + #write the full remote path name of this file + log("Add File: " + filename,xbmc.LOGDEBUG) + self.fileArray.append(filename) + + def getFileList(self): + return self.fileArray + +class XbmcBackup: + addon = None + local_path = '' + remote_path = '' + restoreFile = None + + #for the progress bar + progressBar = None + filesLeft = 0 + filesTotal = 1 + + fileManager = None + + def __init__(self,__Addon): + self.addon = __Addon + self.local_path = xbmc.makeLegalFilename(xbmc.translatePath("special://home"),False); + + if(self.addon.getSetting('remote_selection') == '1'): + self.remote_path = self.addon.getSetting('remote_path_2') + self.addon.setSetting("remote_path","") + elif(self.addon.getSetting('remote_selection') == '0'): + self.remote_path = self.addon.getSetting("remote_path") + + #check if trailing slash is included + if(self.remote_path[-1:] != "/"): + self.remote_path = self.remote_path + "/" + + #append backup folder name + if(int(self.addon.getSetting('addon_mode')) == 0 and self.remote_path != ''): + date_today = time.localtime(time.time()) + self.remote_path = self.remote_path + str(date_today[1]) + str(date_today[2]) + str(date_today[0]) + "/" + elif(int(self.addon.getSetting('addon_mode')) == 1 and self.addon.getSetting("backup_name") != '' and self.remote_path != ''): + self.remote_path = self.remote_path + self.addon.getSetting("backup_name") + "/" + else: + self.remote_path = "" + + self.local_path = self.local_path.decode("UTF-8") + self.local_path = self.local_path.decode("UTF-8") + + log(self.addon.getLocalizedString(30046)) + log(self.addon.getLocalizedString(30047) + ": " + self.local_path) + log(self.addon.getLocalizedString(30048) + ": " + self.remote_path) + + def run(self): + #check if we should use the progress bar + if(self.addon.getSetting('run_silent') == 'false'): + self.progressBar = xbmcgui.DialogProgress() + self.progressBar.create(self.addon.getLocalizedString(30010),self.addon.getLocalizedString(30049) + "......") + + #check what mode were are in + if(int(self.addon.getSetting('addon_mode')) == 0): + self.fileManager = FileManager(self.local_path,self.addon.getAddonInfo('profile')) + + #for backups check if remote path exists + if(xbmcvfs.exists(self.remote_path)): + #this will fail - need a disclaimer here + log(self.addon.getLocalizedString(30050)) + + self.syncFiles() + else: + self.fileManager = FileManager(self.remote_path,self.addon.getAddonInfo('profile')) + + #for restores remote path must exist + if(xbmcvfs.exists(self.remote_path)): + self.restoreFiles() + else: + xbmcgui.Dialog().ok(self.addon.getLocalizedString(30010),self.addon.getLocalizedString(30045)) + + def syncFiles(self): + + #make the remote directory + xbmcvfs.mkdir(self.remote_path) + + log(self.addon.getLocalizedString(30051)) + self.fileManager.createFileList(self.addon) + + allFiles = self.fileManager.getFileList() + + #write list from local to remote + self.writeFiles(allFiles,self.local_path,self.remote_path) + + def restoreFiles(self): + self.fileManager.createFileList(self.addon) + + log(self.addon.getLocalizedString(30051)) + allFiles = self.fileManager.getFileList() + + #write list from remote to local + self.writeFiles(allFiles,self.remote_path,self.local_path) + + #call update addons to refresh everything + xbmc.executebuiltin('UpdateLocalAddons') + + def writeFiles(self,fileList,source,dest): + log("Writing files to: " + dest) + self.filesTotal = len(fileList) + self.filesLeft = self.filesTotal + + #write each file from source to destination + for aFile in fileList: + if(not self.checkCancel()): + log('Writing file: ' + source + aFile,xbmc.LOGDEBUG) + self.updateProgress(aFile) + if (aFile.startswith("-")): + xbmcvfs.mkdir(xbmc.makeLegalFilename(dest + aFile[1:],False)) + else: + xbmcvfs.copy(xbmc.makeLegalFilename(source + aFile),xbmc.makeLegalFilename(dest + aFile,False)) + + if(self.addon.getSetting('run_silent') == 'false'): + self.progressBar.close() + + def updateProgress(self,message=''): + self.filesLeft = self.filesLeft - 1 + + #update the progress bar + if(self.progressBar != None): + self.progressBar.update(int((float(self.filesTotal - self.filesLeft)/float(self.filesTotal)) * 100),message) + + def checkCancel(self): + result = False + + if(self.progressBar != None): + result = self.progressBar.iscanceled() + + return result + + def isReady(self): + return True if self.remote_path != '' else False From dd39dc182e45525ab93194ae4c1e9ff24668d80f Mon Sep 17 00:00:00 2001 From: robweber Date: Wed, 12 Sep 2012 15:34:13 -0500 Subject: [PATCH 05/11] forgot utils import --- resources/lib/backup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/lib/backup.py b/resources/lib/backup.py index e9f5c3a..03022ee 100644 --- a/resources/lib/backup.py +++ b/resources/lib/backup.py @@ -1,6 +1,7 @@ import xbmc import xbmcgui import xbmcvfs +import utils as utils import os import time From 272ea8b8a93e3007e2e3608a01e28d8b16a27a40 Mon Sep 17 00:00:00 2001 From: robweber Date: Wed, 19 Sep 2012 11:43:36 -0500 Subject: [PATCH 06/11] added backup rotation closes #10 --- resources/language/English/strings.xml | 1 + resources/lib/backup.py | 40 +++++++++++++++++++------- resources/settings.xml | 1 + 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index 5f31fab..4603353 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -32,6 +32,7 @@ Creating Files List Writing file Starting scheduled backup + Removing backup Enable Scheduler Schedule diff --git a/resources/lib/backup.py b/resources/lib/backup.py index 03022ee..a66b531 100644 --- a/resources/lib/backup.py +++ b/resources/lib/backup.py @@ -86,6 +86,7 @@ class XbmcBackup: Restore = 1 local_path = '' + remote_root = '' remote_path = '' restoreFile = None @@ -100,17 +101,17 @@ class XbmcBackup: self.local_path = xbmc.makeLegalFilename(xbmc.translatePath("special://home"),False); if(utils.getSetting('remote_selection') == '1'): - self.remote_path = utils.getSetting('remote_path_2') + self.remote_root = utils.getSetting('remote_path_2') utils.setSetting("remote_path","") elif(utils.getSetting('remote_selection') == '0'): - self.remote_path = utils.getSetting("remote_path") + self.remote_root = utils.getSetting("remote_path") #fix slashes - self.remote_path = self.remote_path.replace("\\","/") + self.remote_root = self.remote_root.replace("\\","/") #check if trailing slash is included - if(self.remote_path[-1:] != "/"): - self.remote_path = self.remote_path + "/" + if(self.remote_root[-1:] != "/"): + self.remote_root = self.remote_root + "/" utils.log(utils.getString(30046)) @@ -125,10 +126,10 @@ class XbmcBackup: mode = int(utils.getSetting('addon_mode')) #append backup folder name - if(mode == self.Backup and self.remote_path != ''): - self.remote_path = self.remote_path + time.strftime("%Y%m%d") + "/" - elif(mode == self.Restore and utils.getSetting("backup_name") != '' and self.remote_path != ''): - self.remote_path = self.remote_path + utils.getSetting("backup_name") + "/" + if(mode == self.Backup and self.remote_root != ''): + self.remote_path = self.remote_root + time.strftime("%Y%m%d") + "/" + elif(mode == self.Restore and utils.getSetting("backup_name") != '' and self.remote_root != ''): + self.remote_path = self.remote_root + utils.getSetting("backup_name") + "/" else: self.remote_path = "" @@ -146,6 +147,25 @@ class XbmcBackup: utils.log(utils.getString(30050)) self.syncFiles() + + #remove old backups + total_backups = int(utils.getSetting('backup_rotation')) + if(total_backups > 0): + + dirs,files = xbmcvfs.listdir(self.remote_root) + if(len(dirs) > total_backups): + #remove backups to equal total wanted + remove_num = len(dirs) - total_backups - 1 + self.filesTotal = self.filesTotal + remove_num + 1 + + #update the progress bar if it is available + while(remove_num >= 0 and not self.checkCancel()): + self.updateProgress(utils.getString(30054) + " " + dirs[remove_num]) + utils.log("Removing backup " + dirs[remove_num]) + xbmcvfs.rmdir(self.remote_root + dirs[remove_num] + "/",True) + remove_num = remove_num - 1 + + else: utils.log(utils.getString(30023) + " - " + utils.getString(30017)) self.fileManager = FileManager(self.remote_path) @@ -215,4 +235,4 @@ class XbmcBackup: return result def isReady(self): - return True if self.remote_path != '' else False + return True if self.remote_root != '' else False diff --git a/resources/settings.xml b/resources/settings.xml index d32a629..ef510d1 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -6,6 +6,7 @@ + From 28e3d08f0c6c8e25c9c8102306002cf033bd5b03 Mon Sep 17 00:00:00 2001 From: robweber Date: Fri, 28 Sep 2012 09:15:20 -0500 Subject: [PATCH 07/11] added string value for backup rotation setting --- resources/language/English/strings.xml | 1 + resources/settings.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index 4603353..69410e6 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -15,6 +15,7 @@ Mode Type Remote Path Remote Path Type + Backups to keep (0 for all) User Addons Addon Data diff --git a/resources/settings.xml b/resources/settings.xml index ef510d1..0d78c58 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -6,7 +6,7 @@ - + From 6b5b465121e6c069582ccd9b38c19a09f5628b61 Mon Sep 17 00:00:00 2001 From: robweber Date: Fri, 28 Sep 2012 09:15:39 -0500 Subject: [PATCH 08/11] update changelog and version bump --- README.txt | 2 +- addon.xml | 2 +- changelog.txt | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.txt b/README.txt index 63faa3f..3928734 100644 --- a/README.txt +++ b/README.txt @@ -5,7 +5,7 @@ I've had to recover my database, thumbnails, and source configuration enough tim Usage: -In the addon settings you can define a remote path for the destination of your xbmc files. Each backup will create a folder named in a month, day, year format so you can create multiple backups. +In the addon settings you can define a remote path for the destination of your xbmc files. Each backup will create a folder named in a month, day, year format so you can create multiple backups. You can keep a set number of backups by setting the integer value of the Backups to Keep setting greater than 0. On the Backup Selection page you can select which items from your user profile folder will be sent to the backup location. By default all are turned on except the Addon Data directory. diff --git a/addon.xml b/addon.xml index 93d8e63..d8da8c6 100644 --- a/addon.xml +++ b/addon.xml @@ -1,6 +1,6 @@  + name="XBMC Backup" version="0.2.1" provider-name="robweber"> diff --git a/changelog.txt b/changelog.txt index 3e8f1a0..78eb4b0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,7 @@ +[b]Version 0.2.1[/b] + +added ability to rotate backups, keeping a set number of days + [b]Version 0.2.0[/b] removed the vfs.py helper library From 5caeff23c9aded62c5e7d261f7cde309b8a1a681 Mon Sep 17 00:00:00 2001 From: robweber Date: Mon, 22 Oct 2012 13:53:01 -0500 Subject: [PATCH 09/11] restored __init__.py files --- resources/.gitignore | 2 ++ resources/__init__.py | 0 resources/lib/.gitignore | 2 ++ resources/lib/__init__.py | 0 4 files changed, 4 insertions(+) create mode 100644 resources/.gitignore create mode 100644 resources/__init__.py create mode 100644 resources/lib/.gitignore create mode 100644 resources/lib/__init__.py diff --git a/resources/.gitignore b/resources/.gitignore new file mode 100644 index 0000000..696f993 --- /dev/null +++ b/resources/.gitignore @@ -0,0 +1,2 @@ + +*.pyo \ No newline at end of file diff --git a/resources/__init__.py b/resources/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/resources/lib/.gitignore b/resources/lib/.gitignore new file mode 100644 index 0000000..696f993 --- /dev/null +++ b/resources/lib/.gitignore @@ -0,0 +1,2 @@ + +*.pyo \ No newline at end of file diff --git a/resources/lib/__init__.py b/resources/lib/__init__.py new file mode 100644 index 0000000..e69de29 From e600703c9440cfe5710b7382bd8f2f29cb973604 Mon Sep 17 00:00:00 2001 From: robweber Date: Fri, 2 Nov 2012 15:24:45 -0500 Subject: [PATCH 10/11] fixes #20 --- resources/lib/backup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/lib/backup.py b/resources/lib/backup.py index a66b531..f66ab53 100644 --- a/resources/lib/backup.py +++ b/resources/lib/backup.py @@ -155,6 +155,7 @@ class XbmcBackup: dirs,files = xbmcvfs.listdir(self.remote_root) if(len(dirs) > total_backups): #remove backups to equal total wanted + dirs.sort() remove_num = len(dirs) - total_backups - 1 self.filesTotal = self.filesTotal + remove_num + 1 From 847ad3a5105e3546909a0cbb74df4b4b9e042bf4 Mon Sep 17 00:00:00 2001 From: robweber Date: Fri, 2 Nov 2012 15:27:59 -0500 Subject: [PATCH 11/11] version bump --- addon.xml | 2 +- changelog.txt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index d8da8c6..84ebc67 100644 --- a/addon.xml +++ b/addon.xml @@ -1,6 +1,6 @@  + name="XBMC Backup" version="0.2.2" provider-name="robweber"> diff --git a/changelog.txt b/changelog.txt index 78eb4b0..0b21115 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,7 @@ +[b]Version 0.2.2[/b] + +fix for backup rotation sort + [b]Version 0.2.1[/b] added ability to rotate backups, keeping a set number of days