Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

can now backup custom directories - other functions stripped out for now

  • Loading branch information...
commit 052cd1a062bd064e16b9846c758491b591494d40 1 parent cfdc369
@robweber authored
Showing with 114 additions and 139 deletions.
  1. +101 −135 resources/lib/backup.py
  2. +12 −3 resources/lib/vfs.py
  3. +1 −1  resources/settings.xml
View
236 resources/lib/backup.py
@@ -7,54 +7,13 @@
from vfs import XBMCFileSystem,DropboxFileSystem
class FileManager:
- fileArray = None
- verbose_log = False
+ fileArray = []
not_dir = ['.zip','.xsp','.rar']
vfs = None
-
+
def __init__(self,vfs):
self.vfs = vfs
-
- def createFileList(self):
- self.fileArray = []
- self.verbose_log = utils.getSetting("verbose_log") == 'true'
-
- #figure out which syncing options to run
- if(utils.getSetting('backup_addons') == 'true'):
- self.addFile("-addons")
- self.walkTree(self.vfs.root_path + "addons/")
-
- self.addFile("-userdata")
-
- if(utils.getSetting('backup_addon_data') == 'true'):
- self.addFile("-userdata/addon_data")
- self.walkTree(self.vfs.root_path + "userdata/addon_data/")
-
- if(utils.getSetting('backup_database') == 'true'):
- self.addFile("-userdata/Database")
- self.walkTree(self.vfs.root_path + "userdata/Database")
-
- if(utils.getSetting("backup_playlists") == 'true'):
- self.addFile("-userdata/playlists")
- self.walkTree(self.vfs.root_path + "userdata/playlists")
-
- if(utils.getSetting("backup_thumbnails") == "true"):
- self.addFile("-userdata/Thumbnails")
- self.walkTree(self.vfs.root_path + "userdata/Thumbnails")
-
- if(utils.getSetting("backup_config") == "true"):
- self.addFile("-userdata/keymaps")
- self.walkTree(self.vfs.root_path + "userdata/keymaps")
-
- self.addFile("-userdata/peripheral_data")
- self.walkTree(self.vfs.root_path + "userdata/peripheral_data")
-
- #this part is an oddity
- dirs,configFiles = self.vfs.listdir(self.vfs.root_path + "userdata/")
- for aFile in configFiles:
- if(aFile.endswith(".xml")):
- self.addFile("userdata/" + aFile)
-
+
def walkTree(self,directory):
dirs,files = self.vfs.listdir(directory)
@@ -62,7 +21,7 @@ def walkTree(self,directory):
for aDir in dirs:
dirPath = xbmc.translatePath(directory + "/" + aDir)
file_ext = aDir.split('.')[-1]
- self.addFile("-" + dirPath[len(self.vfs.root_path):])
+ self.addFile("-" + dirPath)
#catch for "non directory" type files
if (not any(file_ext in s for s in self.not_dir)):
self.walkTree(dirPath)
@@ -70,7 +29,7 @@ def walkTree(self,directory):
#copy all the files
for aFile in files:
filePath = xbmc.translatePath(directory + "/" + aFile)
- self.addFile(filePath[len(self.vfs.root_path):])
+ self.addFile(filePath)
def addFile(self,filename):
try:
@@ -82,8 +41,10 @@ def addFile(self,filename):
utils.log("Add File: " + filename,xbmc.LOGDEBUG)
self.fileArray.append(filename)
- def getFileList(self):
- return self.fileArray
+ def getFiles(self):
+ result = self.fileArray
+ self.fileArray = []
+ return result
class XbmcBackup:
#constants for initiating a back or restore
@@ -91,7 +52,7 @@ class XbmcBackup:
Restore = 1
#remote file system
- local_vfs = None
+ xbmc_vfs = None
remote_vfs = None
restoreFile = None
@@ -102,26 +63,21 @@ class XbmcBackup:
fileManager = None
restore_point = None
-
+
def __init__(self):
- self.local_vfs = XBMCFileSystem()
- self.local_vfs.set_root(xbmc.translatePath("special://home"))
+ self.xbmc_vfs = XBMCFileSystem(xbmc.translatePath('special://home'))
- self.configureVFS()
-
+ self.configureRemote()
utils.log(utils.getString(30046))
- def configureVFS(self):
+ def configureRemote(self):
if(utils.getSetting('remote_selection') == '1'):
- self.remote_vfs = XBMCFileSystem()
- self.remote_vfs.set_root(utils.getSetting('remote_path_2'))
+ self.remote_vfs = XBMCFileSystem(utils.getSetting('remote_path_2'))
utils.setSetting("remote_path","")
elif(utils.getSetting('remote_selection') == '0'):
- self.remote_vfs = XBMCFileSystem()
- self.remote_vfs.set_root(utils.getSetting("remote_path"))
+ self.remote_vfs = XBMCFileSystem(utils.getSetting("remote_path"))
elif(utils.getSetting('remote_selection') == '2'):
- self.remote_vfs = DropboxFileSystem()
- self.remote_vfs.set_root('/')
+ self.remote_vfs = DropboxFileSystem("/")
def listBackups(self):
result = list()
@@ -138,7 +94,6 @@ def selectRestore(self,restore_point):
self.restore_point = restore_point
def run(self,mode=-1,runSilent=False):
-
#append backup folder name
remote_base_path = ""
progressBarTitle = utils.getString(30010) + " - "
@@ -154,7 +109,7 @@ def run(self,mode=-1,runSilent=False):
self.remote_vfs = None
return
- utils.log(utils.getString(30047) + ": " + self.local_vfs.root_path)
+ utils.log(utils.getString(30047) + ": " + self.xbmc_vfs.root_path)
utils.log(utils.getString(30048) + ": " + self.remote_vfs.root_path)
#check if we should use the progress bar
@@ -162,103 +117,114 @@ def run(self,mode=-1,runSilent=False):
self.progressBar = xbmcgui.DialogProgress()
self.progressBar.create(progressBarTitle,utils.getString(30049) + "......")
- #run the correct mode
if(mode == self.Backup):
utils.log(utils.getString(30023) + " - " + utils.getString(30016))
- self.fileManager = FileManager(self.local_vfs)
-
#for backups check if remote path exists
if(self.remote_vfs.exists(self.remote_vfs.root_path)):
#this will fail - need a disclaimer here
utils.log(utils.getString(30050))
-
- self.syncFiles()
-
- #remove old backups
- total_backups = int(utils.getSetting('backup_rotation'))
- if(total_backups > 0):
-
- dirs,files = self.remote_vfs.listdir(remote_base_path)
- 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
-
- #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])
- self.remote_vfs.rmdir(remote_base_path + dirs[remove_num] + "/")
- remove_num = remove_num - 1
-
-
- else:
- utils.log(utils.getString(30023) + " - " + utils.getString(30017))
- self.fileManager = FileManager(self.remote_vfs)
-
- #for restores remote path must exist
- if(self.remote_vfs.exists(self.remote_vfs.root_path)):
- self.restoreFiles()
else:
- xbmcgui.Dialog().ok(utils.getString(30010),utils.getString(30045),self.remote_vfs.root_path)
-
- if(utils.getSetting('run_silent') == 'false' and not runSilent):
- self.progressBar.close()
-
- def syncFiles(self):
+ #make the remote directory
+ self.remote_vfs.mkdir(self.remote_vfs.root_path)
+
+ utils.log(utils.getString(30051))
+ fileManager = FileManager(self.xbmc_vfs)
+
+ #go through each of the user selected items and write them to the backup store
+ if(utils.getSetting('backup_addons') == 'true'):
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "addons")
+ fileManager.walkTree(xbmc.translatePath('special://home/addons'))
+
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "userdata")
+
+ if(utils.getSetting('backup_addon_data') == 'true'):
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "userdata/addon_data")
+ fileManager.walkTree(xbmc.translatePath('special://home/userdata/addon_data'))
+
+ if(utils.getSetting('backup_database') == 'true'):
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "userdata/Database")
+ fileManager.walkTree(xbmc.translatePath('special://home/userdata/Database'))
- #make the remote directory
- self.remote_vfs.mkdir(self.remote_vfs.root_path)
-
- utils.log(utils.getString(30051))
- self.fileManager.createFileList()
-
- allFiles = self.fileManager.getFileList()
-
- #write list from local to remote
- self.writeFiles(allFiles,self.local_vfs,self.remote_vfs)
-
- def restoreFiles(self):
- self.fileManager.createFileList()
-
- utils.log(utils.getString(30051))
- allFiles = self.fileManager.getFileList()
-
- #write list from remote to local
- self.writeFiles(allFiles,self.remote_vfs,self.local_vfs)
+ if(utils.getSetting("backup_playlists") == 'true'):
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "userdata/playlists")
+ fileManager.walkTree(xbmc.translatePath('special://home/userdata/playlists'))
+
+ if(utils.getSetting("backup_thumbnails") == "true"):
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "userdata/Thumbnails")
+ fileManager.walkTree(xbmc.translatePath('special://home/userdata/Thumbnails'))
+
+ if(utils.getSetting("backup_config") == "true"):
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "userdata/keymaps")
+ fileManager.walkTree(xbmc.translatePath('special://home/userdata/keymaps'))
+
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "userdata/peripheral_data")
+ fileManager.walkTree(xbmc.translatePath('special://home/userdata/peripheral_data'))
+
+ #this part is an oddity
+ dirs,configFiles = self.xbmc_vfs.listdir(xbmc.translatePath('special://home/userdata/'))
+ for aFile in configFiles:
+ if(aFile.endswith(".xml")):
+ fileManager.addFile(xbmc.translatePath('special://home/userdata/') + aFile)
+
+ #backup all the files
+ self.backupFiles(fileManager.getFiles(),self.xbmc_vfs,self.remote_vfs)
+
+ #check if there are custom directories
+ if(utils.getSetting('backup_custom_dir') != ''):
+ self._updateProgress(utils.getString(30049) + "......")
+
+ #create a special remote path with hash
+ self.xbmc_vfs.set_root(utils.getSetting('backup_custom_dir'))
+ self.remote_vfs.mkdir(self.remote_vfs.root_path + "custom_1_" + self._createCRC(self.xbmc_vfs.root_path))
+ self.remote_vfs.set_root(self.remote_vfs.root_path + "custom_1_" + self._createCRC(self.xbmc_vfs.root_path))
+
+ fileManager.walkTree(self.xbmc_vfs.root_path)
+ self.backupFiles(fileManager.getFiles(),self.xbmc_vfs,self.remote_vfs)
+
- #call update addons to refresh everything
- xbmc.executebuiltin('UpdateLocalAddons')
-
- def writeFiles(self,fileList,source,dest):
+ def backupFiles(self,fileList,source,dest):
utils.log("Writing files to: " + dest.root_path)
self.filesTotal = len(fileList)
self.filesLeft = self.filesTotal
- #write each file from source to destination
for aFile in fileList:
- if(not self.checkCancel()):
- utils.log('Writing file: ' + source.root_path + aFile,xbmc.LOGDEBUG)
- self.updateProgress(aFile)
- if (aFile.startswith("-")):
- dest.mkdir(dest.root_path + aFile[1:])
+ if(not self._checkCancel()):
+ utils.log('Writing file: ' + aFile,xbmc.LOGDEBUG)
+ self._updateProgress(aFile)
+ if(aFile.startswith("-")):
+ dest.mkdir(dest.root_path + aFile[len(source.root_path) + 1:])
else:
if(isinstance(source,DropboxFileSystem)):
#if copying from dropbox we need the file handle, use get_file
- source.get_file(source.root_path + aFile,dest.root_path + aFile)
+ source.get_file(aFile,dest.root_path + aFile[len(source.root_path):])
else:
#copy using normal method
- dest.put(source.root_path + aFile,dest.root_path + aFile)
-
- def updateProgress(self,message=''):
+ dest.put(aFile,dest.root_path + aFile[len(source.root_path):])
+
+ def _createCRC(self,string):
+ #create hash from string
+ string = string.lower()
+ bytes = bytearray(string.encode())
+ crc = 0xffffffff;
+ for b in bytes:
+ crc = crc ^ (b << 24)
+ for i in range(8):
+ if (crc & 0x80000000 ):
+ crc = (crc << 1) ^ 0x04C11DB7
+ else:
+ crc = crc << 1;
+ crc = crc & 0xFFFFFFFF
+
+ return '%08x' % crc
+
+ 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):
+ def _checkCancel(self):
result = False
if(self.progressBar != None):
View
15 resources/lib/vfs.py
@@ -11,6 +11,12 @@
class Vfs:
root_path = None
+ def __init(self):
+ pass
+
+ def __init__(self,rootString):
+ self.set_root(rootString)
+
def set_root(self,rootString):
old_root = self.root_path
self.root_path = rootString
@@ -44,7 +50,7 @@ def exists(self,aFile):
return True
class XBMCFileSystem(Vfs):
-
+
def listdir(self,directory):
return xbmcvfs.listdir(directory)
@@ -63,7 +69,11 @@ def exists(self,aFile):
class DropboxFileSystem(Vfs):
client = None
- def __init__(self):
+ def __init__(self,rootString):
+ self.setup()
+ Vfs.__init__(rootString)
+
+ def setup(self):
if(APP_KEY == '' or APP_SECRET == ''):
xbmcgui.Dialog().ok(utils.getString(30010),utils.getString(30058),utils.getString(30059))
return
@@ -94,7 +104,6 @@ def __init__(self):
except:
#this didn't work, delete the token file
self.deleteToken()
-
def listdir(self,directory):
if(self.client != None and self.exists(directory)):
View
2  resources/settings.xml
@@ -16,7 +16,7 @@
<setting id="backup_playlists" type="bool" label="30033" default="true" />
<setting id="backup_thumbnails" type="bool" label="30034" default="true" />
<setting id="backup_config" type="bool" label="30035" default="true" />
- <setting id="backup_dir" type="folder" label="Additional Directory" default="" />
+ <setting id="backup_custom_dir" type="folder" label="Additional Directory" default="" />
</category>
<category id="scheduling" label="30013">
<setting id="enable_scheduler" type="bool" label="30060" default="false" />
Please sign in to comment.
Something went wrong with that request. Please try again.