Commit fe70b173 authored by echel0n's avatar echel0n

Added backup and restore functions to database class.

Refactored backup and restore system for app to accommodate for migration to python 3.
parent 01dfecd8
# Changelog
- * 8f00c06 - 2019-02-24: Release v9.4.77
- * d2e85f8 - 2019-03-03: Added backup and restore functions to database class. Refactored backup and restore system for app to accommodate for migration to python 3.
- * a72ca25 - 2019-02-24: Release v9.4.77
- * b09d78a - 2019-02-24: Added Anime regex for Erai-raws
- * e0f2db6 - 2019-02-24: Release v9.4.76
- * ed84483 - 2019-02-24: Fixed IndexerErrors for TV cache. Added files to .gitignore related to AniDB.
......@@ -48,7 +48,7 @@ from sickrage.core.config import Config
from sickrage.core.databases.cache import CacheDB
from sickrage.core.databases.main import MainDB
from sickrage.core.helpers import findCertainShow, generate_secret, makeDir, get_lan_ip, restoreSR, \
getDiskSpaceUsage, getFreeSpace, launch_browser, torrent_webui_url
getDiskSpaceUsage, getFreeSpace, launch_browser, torrent_webui_url, move_file
from sickrage.core.helpers.encoding import get_sys_encoding, ek, patch_modules
from sickrage.core.logger import Logger
from sickrage.core.nameparser.validator import check_force_season_folders
......@@ -202,7 +202,7 @@ class Core(object):
# Check if we need to perform a restore first
if os.path.exists(os.path.abspath(os.path.join(self.data_dir, 'restore'))):
success = restoreSR(os.path.abspath(os.path.join(self.data_dir, 'restore')), self.data_dir)
print("Restoring SiCKRAGE backup: %s!\n" % ("FAILED", "SUCCESSFUL")[success])"Restoring SiCKRAGE backup: {}!".format(("FAILED", "SUCCESSFUL")[success]))
if success:
shutil.rmtree(os.path.abspath(os.path.join(self.data_dir, 'restore')), ignore_errors=True)
......@@ -18,7 +18,10 @@
from __future__ import unicode_literals
import datetime
import io
import os
import pickle
import re
import shutil
import tarfile
......@@ -61,7 +64,7 @@ class srDatabase(object):
if self.db.exists():
# self.backup()
......@@ -69,7 +72,7 @@ class srDatabase(object):
# setup database indexes
def backup(self):
def old_backup(self):
# Backup before start and cleanup old backups
backup_path = os.path.join(, 'db_backup',
backup_count = 5
......@@ -197,6 +200,9 @@ class srDatabase(object):
self.db.add_index(self._indexes[index_name](self.db.path, index_name))
def open(self):
def close(self):
......@@ -346,7 +352,7 @@ class srDatabase(object):
def all(self, *args, **kwargs):
with_doc = kwargs.pop('with_doc', True)
for data in self.db.all(*args, **kwargs):
if with_doc :
if with_doc:
doc = self.db.get('id', data['_id'])
yield doc
......@@ -387,6 +393,49 @@ class srDatabase(object):
def insert(self, *args):
return self.db.insert(*args)
def delete_all(self):
for index_name in self.db.indexes_names.keys():
for x in self.all(index_name):
def backup(self, backup_file=None):
backup_file = backup_file or os.path.join(, '{}_db.pickle'.format('Backing up {} database to {}'.format(, backup_file))
with, 'wb') as f:
rows = []
for index_name in self.db.indexes_names.keys():
if index_name in ['id']:
for row in self.all(index_name):
for x in ['_rev', '_id']:
del row[x]
rows += [row]
pickle.dump(rows, f)
del rows
return backup_file
def restore(self):
restore_file = os.path.join(, 'restore', '{}_db.pickle'.format(
backup_file = os.path.join(, '{}_db.pickle.bak-{}'.format(,
if os.path.exists(restore_file):
self.backup(backup_file)'Restoring database file {}'.format(restore_file))
with, 'rb') as f:
rows = pickle.load(f)
[self.insert(row) for row in rows]
del rows
# Monkey-Patch storage to suppress logging messages
IU_Storage.get = Custom_IU_Storage_get
......@@ -985,7 +985,7 @@ def restoreConfigZip(archive, targetDir, restore_database=True, restore_config=T
with zipfile.ZipFile(archive, 'r', allowZip64=True) as zip_file:
for member in zip_file.namelist():
if not restore_database and member.split('/')[0] == 'database':
if not restore_database and member.split('/')[0] in ['database', 'main_db.pickle', 'cache_db.pickle']:
if not restore_config and member.split('/')[0] == 'config.ini':
......@@ -1002,13 +1002,11 @@ def restoreConfigZip(archive, targetDir, restore_database=True, restore_config=T
def backupSR(backupDir, keep_latest=False):
def backupSR(backupDir, keep_latest=False, migrate=True):
source = []
filesList = ['sickrage.db',
file_list = [os.path.basename(]
file_list += ['sickrage.db', 'failed.db', 'cache.db']
def _keep_latest_backup():
import glob
......@@ -1023,15 +1021,15 @@ def backupSR(backupDir, keep_latest=False):
# individual files
for f in filesList:
for f in file_list:
fp = os.path.join(, f)
if os.path.exists(fp):
source += [fp]
# database folder
for (path, __, files) in os.walk(os.path.join(, 'database'), topdown=True):
for filename in files:
source += [os.path.join(path, filename)]
# database
for db in [,]:
backup_file = db.backup()
source += [backup_file]
# cache folder
......@@ -1051,13 +1049,13 @@ def backupSR(backupDir, keep_latest=False):
def restoreSR(srcDir, dstDir):
filesList = ['sickrage.db',
files_list = ['sickrage.db',
for filename in filesList:
for filename in files_list:
srcFile = os.path.join(srcDir, filename)
dstFile = os.path.join(dstDir, filename)
bakFile = os.path.join(dstDir, '{}.bak-{}'
......@@ -1068,14 +1066,11 @@ def restoreSR(srcDir, dstDir):
move_file(dstFile, bakFile)
move_file(srcFile, dstFile)
# databse
if os.path.exists(os.path.join(srcDir, 'database')):
if os.path.exists(os.path.join(dstDir, 'database')):
move_file(os.path.join(dstDir, 'database'), os.path.join(dstDir, '{}.bak-{}'
move_file(os.path.join(srcDir, 'database'), dstDir)
# database
for db in [,]:
# cache
if os.path.exists(os.path.join(srcDir, 'cache')):
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment