From 97ade6ad6c90ead4f87f631c30fe3d81d348b349 Mon Sep 17 00:00:00 2001 From: Alexandre Beloin Date: Tue, 17 Feb 2015 23:35:39 -0500 Subject: [PATCH 1/2] Reworked the backup/restore to properly handle the cache directory inclusion. --- SickBeard.py | 23 ++++++++++++----------- sickbeard/__init__.py | 25 +++++++++++++++++++++++++ sickbeard/helpers.py | 28 ++++++++++++++++++++++++++++ sickbeard/webserve.py | 13 ++++++++----- 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/SickBeard.py b/SickBeard.py index 8f0f0de5..15e361d5 100755 --- a/SickBeard.py +++ b/SickBeard.py @@ -264,10 +264,10 @@ class SickRage(object): # Check if we need to perform a restore first restoreDir = os.path.join(sickbeard.DATA_DIR, 'restore') if self.consoleLogging and os.path.exists(restoreDir): - if self.restore(restoreDir, sickbeard.DATA_DIR): - sys.stdout.write("Restore successful...\n") + if self.restoreDB(restoreDir, sickbeard.DATA_DIR): + sys.stdout.write("Restore: restoring DB and config.ini successful...\n") else: - sys.stdout.write("Restore FAILED!\n") + sys.stdout.write("Restore: restoring DB and config.ini FAILED!\n") # Load the config and publish it to the sickbeard package if self.consoleLogging and not os.path.isfile(sickbeard.CONFIG_FILE): @@ -447,16 +447,17 @@ class SickRage(object): logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) - def restore(self, srcDir, dstDir): + def restoreDB(self, srcDir, dstDir): try: - for file in os.listdir(srcDir): - srcFile = os.path.join(srcDir, file) - dstFile = os.path.join(dstDir, file) - bakFile = os.path.join(dstDir, file + '.bak') - shutil.move(dstFile, bakFile) - shutil.move(srcFile, dstFile) + filesList = ['sickbeard.db', 'config.ini'] - os.rmdir(srcDir) + for filename in filesList: + srcFile = os.path.join(srcDir, filename) + dstFile = os.path.join(dstDir, filename) + bakFile = os.path.join(dstDir, '{0}.bak-{1}'.format(filename, datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d_%H%M%S'))) + if os.path.isfile(dstFile): + shutil.move(dstFile, bakFile) + shutil.move(srcFile, dstFile) return True except: return False diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index abd793e2..f83d2a7e 100755 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -631,6 +631,31 @@ def initialize(consoleLogging=True): logger.log(u"!!! Creating local cache dir failed, using system default", logger.ERROR) CACHE_DIR = None + # Check if we need to perform a restore of the cache folder + restoreDir = os.path.join(DATA_DIR, 'restore') + if os.path.exists(restoreDir): + def restoreCache(srcDir, dstDir): + import ntpath + import shutil + + def path_leaf(path): + head, tail = ntpath.split(path) + return tail or ntpath.basename(head) + + try: + if os.path.isdir(dstDir): + bakFilename = '{0}-{1}'.format(path_leaf(dstDir), datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d_%H%M%S')) + shutil.move(dstDir, os.path.join(ntpath.dirname(dstDir), bakFilename)) + + shutil.move(srcDir, dstDir) + logger.log(u"Restore: restoring cache successful", logger.INFO) + except Exception as e: + logger.log(u"Restore: restoring cache failed", logger.ERROR) + finally: + os.rmdir(restoreDir) + + restoreCache(os.path.join(restoreDir, 'cache'), CACHE_DIR) + # clean cache folders if CACHE_DIR: helpers.clearCache() diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index 262e3382..c13af25d 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -1067,6 +1067,34 @@ def extractZip(archive, targetDir): return False +def backupConfigZip(fileList, archive, arcname = None): + try: + a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) + for f in fileList: + a.write(f, os.path.relpath(f, arcname)) + a.close() + return True + except Exception as e: + logger.log(u"Zip creation error: " + str(e), logger.ERROR) + return False + + +def restoreConfigZip(archive, targetDir): + try: + if not os.path.exists(targetDir): + os.mkdir(targetDir) + + zip_file = zipfile.ZipFile(archive, 'r') + for member in zip_file.namelist(): + zip_file.extract(member, targetDir) + zip_file.close() + return True + except Exception as e: + logger.log(u"Zip extraction error: " + str(e), logger.ERROR) + shutil.rmtree(targetDir) + return False + + def mapIndexersToShow(showObj): mapped = {} diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 70e898b6..adc7afaa 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -3599,11 +3599,14 @@ class ConfigBackupRestore(Config): source = [os.path.join(sickbeard.DATA_DIR, 'sickbeard.db'), sickbeard.CONFIG_FILE] target = os.path.join(backupDir, 'sickrage-' + time.strftime('%Y%m%d%H%M%S') + '.zip') - for (dir, _, files) in os.walk(sickbeard.CACHE_DIR): - for f in files: - source.append(os.path.join(dir, f)) + for (path, dirs, files) in os.walk(sickbeard.CACHE_DIR, topdown=True): + for dirname in dirs: + if path == sickbeard.CACHE_DIR and dirname not in ['images']: + dirs.remove(dirname) + for filename in files: + source.append(os.path.join(path, filename)) - if helpers.makeZip(source, target): + if helpers.backupConfigZip(source, target, sickbeard.DATA_DIR): finalResult += "Successful backup to " + target else: finalResult += "Backup FAILED" @@ -3623,7 +3626,7 @@ class ConfigBackupRestore(Config): source = backupFile target_dir = os.path.join(sickbeard.DATA_DIR, 'restore') - if helpers.extractZip(source, target_dir): + if helpers.restoreConfigZip(source, target_dir): finalResult += "Successfully extracted restore files to " + target_dir finalResult += "
Restart sickrage to complete the restore." else: From d39bd6d39f0b0eee646d526df54429836eddf259 Mon Sep 17 00:00:00 2001 From: Alexandre Beloin Date: Wed, 18 Feb 2015 08:00:24 -0500 Subject: [PATCH 2/2] Added failed.db and cache.db --- SickBeard.py | 2 +- sickbeard/webserve.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/SickBeard.py b/SickBeard.py index 15e361d5..309687e3 100755 --- a/SickBeard.py +++ b/SickBeard.py @@ -449,7 +449,7 @@ class SickRage(object): def restoreDB(self, srcDir, dstDir): try: - filesList = ['sickbeard.db', 'config.ini'] + filesList = ['sickbeard.db', 'config.ini', 'failed.db', 'cache.db'] for filename in filesList: srcFile = os.path.join(srcDir, filename) diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index adc7afaa..a9e0f31f 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -3597,6 +3597,8 @@ class ConfigBackupRestore(Config): if backupDir: source = [os.path.join(sickbeard.DATA_DIR, 'sickbeard.db'), sickbeard.CONFIG_FILE] + source.append(os.path.join(sickbeard.DATA_DIR, 'failed.db')) + source.append(os.path.join(sickbeard.DATA_DIR, 'cache.db')) target = os.path.join(backupDir, 'sickrage-' + time.strftime('%Y%m%d%H%M%S') + '.zip') for (path, dirs, files) in os.walk(sickbeard.CACHE_DIR, topdown=True):