added vfs module created by paddycarey. restore.txt no longer needed to find restore files

File selection criteria now used by both backup and restore
This commit is contained in:
robweber 2012-04-28 14:29:59 -05:00
parent b6d78ea77b
commit f0d98152f1
4 changed files with 32 additions and 34 deletions

View File

@ -5,15 +5,15 @@ I've had to recover my database, thumbnails, and source configuration enough tim
Usage: Usage:
In the addon settings you can define a remote path for the destination of your xbmc files. You must also include a backup folder name, all of your files will be in this folder once the backup runs. Please note that the typed path will supercede the browsed path - only one will be used. In the addon settings you can define a remote path for the destination of your xbmc files. You must also include a backup folder name, all of your files will be in this folder once the backup runs.
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. 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.
To restore your data simply switch the Mode from "backup" to "restore" and the files will be copied from your remote directory to the local path. To restore your data simply switch the Mode from "backup" to "restore" and the files will be copied from your remote directory to the local path. The file selection criteria will be used for the restore as well.
What this Addon Will Not Do: What this Addon Will Not Do:
This is not meant as an XBMC file sync solution. If you have multiple frontends you want to keep in sync this addon may work in a "poor man's" sort of way but it is not intended for that. This is not meant as an XBMC file sync solution. If you have multiple frontends you want to keep in sync this addon may work in a "poor man's" sort of way but it is not intended for that.
Your remote folder will not be "pruned" of files you have deleted. Mostly this is due to limitations with the xbmcvfs python module, it cannot list files, only tell if they exist. This behavior may change in the future but right now it is up to you to remove obsolete items from the remote path. The easiest way is to just delete the remote folder before doing a full backup. Your remote folder will not be "pruned" of files you have deleted. This behavior may change in the future but right now it is up to you to remove obsolete items from the remote path. The easiest way is to just delete the remote folder before doing a full backup.

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.xbmcbackup" <addon id="script.xbmcbackup"
name="XBMC Backup" version="0.0.5" provider-name="robweber"> name="XBMC Backup" version="0.0.6" provider-name="robweber">
<requires> <requires>
<import addon="xbmc.python" version="2.0"/> <import addon="xbmc.python" version="2.0"/>
</requires> </requires>

View File

@ -14,3 +14,8 @@ Finished code for restore mode.
Added option to manually type a path rather than browse for one (only one used) Added option to manually type a path rather than browse for one (only one used)
Show progress bar right away so you know this is doing something Show progress bar right away so you know this is doing something
[b]Version 0.0.6/b]
Added the vfs module created by paddycarey
File Selection is now followed for both backup and restore options

View File

@ -1,16 +1,16 @@
import xbmc import xbmc
import xbmcaddon import xbmcaddon
import xbmcgui import xbmcgui
import xbmcvfs import resources.lib.vfs as vfs
import os import os
class FileManager: class FileManager:
local_path = '' walk_path = ''
addonDir = '' addonDir = ''
fHandle = None fHandle = None
def __init__(self,addon_dir): def __init__(self,path,addon_dir):
self.local_path = xbmc.translatePath("special://home") self.walk_path = path
self.addonDir = addon_dir self.addonDir = addon_dir
#create the addon folder if it doesn't exist #create the addon folder if it doesn't exist
@ -23,29 +23,29 @@ class FileManager:
#figure out which syncing options to run #figure out which syncing options to run
if(Addon.getSetting('backup_addons') == 'true'): if(Addon.getSetting('backup_addons') == 'true'):
self.addFile("-addons") self.addFile("-addons")
self.walkTree(self.local_path + "addons/") self.walkTree(self.walk_path + "addons/")
self.addFile("-userdata") self.addFile("-userdata")
if(Addon.getSetting('backup_addon_data') == 'true'): if(Addon.getSetting('backup_addon_data') == 'true'):
self.addFile("-userdata/addon_data") self.addFile("-userdata/addon_data")
self.walkTree(self.local_path + "userdata/addon_data/") self.walkTree(self.walk_path + "userdata/addon_data/")
if(Addon.getSetting('backup_database') == 'true'): if(Addon.getSetting('backup_database') == 'true'):
self.addFile("-userdata/Database") self.addFile("-userdata/Database")
self.walkTree(self.local_path + "userdata/Database") self.walkTree(self.walk_path + "userdata/Database")
if(Addon.getSetting("backup_playlists") == 'true'): if(Addon.getSetting("backup_playlists") == 'true'):
self.addFile("-userdata/playlists") self.addFile("-userdata/playlists")
self.walkTree(self.local_path + "userdata/playlists") self.walkTree(self.walk_path + "userdata/playlists")
if(Addon.getSetting("backup_thumbnails") == "true"): if(Addon.getSetting("backup_thumbnails") == "true"):
self.addFile("-userdata/Thumbnails") self.addFile("-userdata/Thumbnails")
self.walkTree(self.local_path + "userdata/Thumbnails") self.walkTree(self.walk_path + "userdata/Thumbnails")
if(Addon.getSetting("backup_config") == "true"): if(Addon.getSetting("backup_config") == "true"):
#this one is an oddity #this one is an oddity
configFiles = os.listdir(self.local_path + "userdata/") configFiles = os.listdir(self.walk_path + "userdata/")
for aFile in configFiles: for aFile in configFiles:
if(aFile.endswith(".xml")): if(aFile.endswith(".xml")):
self.addFile("userdata/" + aFile) self.addFile("userdata/" + aFile)
@ -54,17 +54,14 @@ class FileManager:
self.fHandle.close() self.fHandle.close()
def walkTree(self,directory): def walkTree(self,directory):
for (path, dirs, files) in os.walk(directory): for (path, dirs, files) in vfs.walk(directory):
#get the relative part of this path
path = path[len(self.local_path):]
#create all the subdirs first #create all the subdirs first
for aDir in dirs: for aDir in dirs:
self.addFile("-" + path + os.sep + aDir) self.addFile("-" + aDir[len(self.walk_path):])
#copy all the files #copy all the files
for aFile in files: for aFile in files:
filePath = path + os.sep + aFile filePath = aFile[len(self.walk_path):]
self.addFile(filePath) self.addFile(filePath)
def addFile(self,filename): def addFile(self,filename):
@ -94,10 +91,10 @@ class XbmcBackup:
def __init__(self): def __init__(self):
self.local_path = xbmc.translatePath("special://home") self.local_path = xbmc.translatePath("special://home")
if(self.Addon.getSetting('remote_path_2') != '' and xbmcvfs.exists(self.Addon.getSetting('remote_path_2'))): if(self.Addon.getSetting('remote_path_2') != '' and vfs.exists(self.Addon.getSetting('remote_path_2'))):
self.remote_path = self.Addon.getSetting('remote_path_2') self.remote_path = self.Addon.getSetting('remote_path_2')
self.Addon.setSetting("remote_path","") self.Addon.setSetting("remote_path","")
elif(self.Addon.getSetting('remote_path') != '' and xbmcvfs.exists(self.Addon.getSetting("remote_path"))): elif(self.Addon.getSetting('remote_path') != '' and vfs.exists(self.Addon.getSetting("remote_path"))):
self.remote_path = self.Addon.getSetting("remote_path") self.remote_path = self.Addon.getSetting("remote_path")
if(self.Addon.getSetting("backup_name") != ''): if(self.Addon.getSetting("backup_name") != ''):
@ -105,8 +102,6 @@ class XbmcBackup:
else: else:
self.remote_path = "" self.remote_path = ""
self.fileManager = FileManager(self.Addon.getAddonInfo('profile'))
self.log("Starting") self.log("Starting")
self.log('Local Dir: ' + self.local_path) self.log('Local Dir: ' + self.local_path)
self.log('Remote Dir: ' + self.remote_path) self.log('Remote Dir: ' + self.remote_path)
@ -119,17 +114,19 @@ class XbmcBackup:
#check what mode were are in #check what mode were are in
if(int(self.Addon.getSetting('addon_mode')) == 0): if(int(self.Addon.getSetting('addon_mode')) == 0):
self.fileManager = FileManager(self.local_path,self.Addon.getAddonInfo('profile'))
self.syncFiles() self.syncFiles()
else: else:
self.fileManager = FileManager(self.remote_path,self.Addon.getAddonInfo('profile'))
self.restoreFiles() self.restoreFiles()
def syncFiles(self): def syncFiles(self):
if(xbmcvfs.exists(self.remote_path)): if(vfs.exists(self.remote_path)):
#this will fail - need a disclaimer here #this will fail - need a disclaimer here
self.log("Remote Path exists - may have old files in it!") self.log("Remote Path exists - may have old files in it!")
#make the remote directory #make the remote directory
xbmcvfs.mkdir(self.remote_path) vfs.mkdir(self.remote_path)
self.fileManager.createFileList(self.Addon) self.fileManager.createFileList(self.Addon)
@ -138,12 +135,8 @@ class XbmcBackup:
#write list from local to remote #write list from local to remote
self.writeFiles(allFiles,self.local_path,self.remote_path) self.writeFiles(allFiles,self.local_path,self.remote_path)
#write the restore list
xbmcvfs.copy(self.Addon.getAddonInfo('profile') + "restore.txt",self.remote_path + "restore.txt")
def restoreFiles(self): def restoreFiles(self):
#copy the restore file self.fileManager.createFileList(self.Addon)
xbmcvfs.copy(self.remote_path + "restore.txt",self.Addon.getAddonInfo('profile') + "restore.txt")
allFiles = self.fileManager.readFileList() allFiles = self.fileManager.readFileList()
@ -159,9 +152,9 @@ class XbmcBackup:
if(not self.checkCancel()): if(not self.checkCancel()):
self.updateProgress(aFile) self.updateProgress(aFile)
if (aFile.startswith("-")): if (aFile.startswith("-")):
xbmcvfs.mkdir(dest + aFile[1:]) vfs.mkdir(dest + aFile[1:])
else: else:
xbmcvfs.copy(source + aFile,dest + aFile) vfs.copy(source + aFile,dest + aFile)
if(self.Addon.getSetting('run_silent') == 'false'): if(self.Addon.getSetting('run_silent') == 'false'):
self.progressBar.close() self.progressBar.close()