diff --git a/CHANGES.md b/CHANGES.md
index dc3afd9..fe2ff33 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,11 @@
### 0.23.0 (2019-xx-xx xx:xx:xx UTC)
+* Add db backup to the scheduled daily update
+* Add display "Database backups" location at config/about if feature available
+* Add option "Backup database plan" to config/general/advanced if feature available
+* Add py7zr to recommended.txt for optional 7z compression
+* Add `backup_db_path` setting to config.ini to customise backup db location
+* Add `backup_db_max_count` to config.ini with range 0-90 where 0 = disable backup, 14 = default
* Change improve list performance for file/directory browser
* Change improve import shows listing performance
* Change improve performance during show rescan process
diff --git a/gui/slick/interfaces/default/config.tmpl b/gui/slick/interfaces/default/config.tmpl
index ed83147..85c7784 100644
--- a/gui/slick/interfaces/default/config.tmpl
+++ b/gui/slick/interfaces/default/config.tmpl
@@ -31,6 +31,9 @@
$sg_str('CONFIG_FILE')
$db.dbFilename()
+#if $db.db_supports_backup
+ $backup_db_path
+#end if
$sg_str('CACHE_DIR')
#echo $sg_var('MY_ARGS') or 'None used'#
$sg_str('WEB_ROOT')
diff --git a/gui/slick/interfaces/default/config_general.tmpl b/gui/slick/interfaces/default/config_general.tmpl
index 87f2ebf..16f48f4 100644
--- a/gui/slick/interfaces/default/config_general.tmpl
+++ b/gui/slick/interfaces/default/config_general.tmpl
@@ -5,6 +5,7 @@
#from sickbeard import config, metadata
#from sickbeard.metadata.generic import GenericMetadata
#from sickbeard.common import *
+#from sickbeard.db import db_supports_backup
#from sickbeard.helpers import anon_url, maybe_plural
#from sickbeard.logger import reverseNames as file_logging_presets
#from sickbeard.sgdatetime import *
@@ -796,6 +797,17 @@
+#if $db_supports_backup
+
+
+ Backup database plan
+
+
+ backup one day instead of multiple days (helps existing backup strategies)
+
+
+
+#end if
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index 1b4fb30..66d6f21 100755
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -545,9 +545,10 @@ SUBTITLES_FINDER_FREQUENCY = 1
USE_FAILED_DOWNLOADS = False
DELETE_FAILED = False
-MAX_DB_BACKUP_COUNT = 14
-DEFAULT_DB_BACKUP_COUNT = 14
-DB_BACKUP_PATH = ''
+BACKUP_DB_PATH = ''
+BACKUP_DB_ONEDAY = False
+BACKUP_DB_MAX_COUNT = 14
+BACKUP_DB_DEFAULT_COUNT = 14
EXTRA_SCRIPTS = []
SG_EXTRA_SCRIPTS = []
@@ -748,7 +749,7 @@ def init_stage_1(console_logging):
# Anime Settings
global ANIME_TREAT_AS_HDTV, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST
# db backup settings
- global MAX_DB_BACKUP_COUNT, DEFAULT_DB_BACKUP_COUNT, DB_BACKUP_PATH
+ global BACKUP_DB_PATH, BACKUP_DB_ONEDAY, BACKUP_DB_MAX_COUNT, BACKUP_DB_DEFAULT_COUNT
for stanza in ('General', 'Blackhole', 'SABnzbd', 'NZBGet', 'Emby', 'Kodi', 'XBMC', 'PLEX',
'Growl', 'Prowl', 'Slack', 'Discord', 'Boxcar2', 'NMJ', 'NMJv2',
@@ -1312,10 +1313,10 @@ def init_stage_1(console_logging):
if not isinstance(BROWSELIST_MRU, dict):
BROWSELIST_MRU = {}
- MAX_DB_BACKUP_COUNT = minimax(check_setting_int(CFG, 'Backup', 'max_db_backup_count', DEFAULT_DB_BACKUP_COUNT),
- DEFAULT_DB_BACKUP_COUNT, 0, 90)
-
- DB_BACKUP_PATH = check_setting_str(CFG, 'Backup', 'db_backup_path', '')
+ BACKUP_DB_PATH = check_setting_str(CFG, 'Backup', 'backup_db_path', '')
+ BACKUP_DB_ONEDAY = bool(check_setting_int(CFG, 'Backup', 'backup_db_oneday', 0))
+ use_count = (1, BACKUP_DB_DEFAULT_COUNT)[not BACKUP_DB_ONEDAY]
+ BACKUP_DB_MAX_COUNT = minimax(check_setting_int(CFG, 'Backup', 'backup_db_max_count', use_count), use_count, 0, 90)
sg_helpers.db = db
sg_helpers.DOMAIN_FAILURES.load_from_db()
@@ -1885,9 +1886,12 @@ def save_config():
new_config['General']['ignore_words'] = helpers.generate_word_str(IGNORE_WORDS, IGNORE_WORDS_REGEX)
new_config['General']['require_words'] = helpers.generate_word_str(REQUIRE_WORDS, REQUIRE_WORDS_REGEX)
new_config['General']['calendar_unprotected'] = int(CALENDAR_UNPROTECTED)
- new_config['Backup']['max_db_backup_count'] = MAX_DB_BACKUP_COUNT
- if DB_BACKUP_PATH:
- new_config['Backup']['db_backup_path'] = DB_BACKUP_PATH
+
+ new_config['Backup'] = {}
+ if BACKUP_DB_PATH:
+ new_config['Backup']['backup_db_path'] = BACKUP_DB_PATH
+ new_config['Backup']['backup_db_oneday'] = int(BACKUP_DB_ONEDAY)
+ new_config['Backup']['backup_db_max_count'] = BACKUP_DB_MAX_COUNT
default_not_zero = ('enable_recentsearch', 'enable_backlog', 'enable_scheduled_backlog', 'use_after_get_data')
for src in filter_iter(lambda px: GenericProvider.TORRENT == px.providerType, providers.sortedProviderList()):
diff --git a/sickbeard/db.py b/sickbeard/db.py
index db2ade9..9b07fa8 100644
--- a/sickbeard/db.py
+++ b/sickbeard/db.py
@@ -776,7 +776,7 @@ def get_rollback_module():
def delete_old_db_backups(target):
# type: (AnyStr) -> None
"""
- remove old db backups (> MAX_DB_BACKUP_COUNT)
+ remove old db backups (> BACKUP_DB_MAX_COUNT)
:param target: backup folder to check
"""
@@ -786,9 +786,9 @@ def delete_old_db_backups(target):
file_list = [f for f in ek.ek(scandir, target) if f.is_file()]
for filename in ['sickbeard', 'cache', 'failed']:
tb = filter_list(lambda fn: fn.is_file() and filename in fn.name, file_list)
- if sickbeard.MAX_DB_BACKUP_COUNT < len(tb):
+ if sickbeard.BACKUP_DB_MAX_COUNT < len(tb):
tb.sort(key=lambda f: f.stat(follow_symlinks=False).st_mtime, reverse=True)
- for t in tb[sickbeard.MAX_DB_BACKUP_COUNT:]:
+ for t in tb[sickbeard.BACKUP_DB_MAX_COUNT:]:
try:
ek.ek(os.unlink, t.path)
except (BaseException, Exception):
@@ -810,12 +810,10 @@ def backup_all_dbs(target, compress=True, prefer_7z=True):
:param prefer_7z: prefer 7z compression if available
:return: success, message
"""
- if not ek.ek(os.path.isdir, target):
- make_dirs(target)
- if not ek.ek(os.path.isdir, target):
+ if not make_dirs(target):
logger.log('Failed to create db backup dir', logger.ERROR)
return False, 'Failed to create db backup dir'
- my_db = DBConnection()
+ my_db = DBConnection('cache.db')
last_backup = my_db.select('SELECT time FROM lastUpdate WHERE provider = ?', ['sickgear_db_backup'])
if last_backup:
now_stamp = int(timestamp_near(datetime.datetime.now()))
@@ -823,10 +821,10 @@ def backup_all_dbs(target, compress=True, prefer_7z=True):
# only backup every 23 hours
if now_stamp - the_time < 60 * 60 * 23:
return False, 'Too early to backup db again'
- now = datetime.datetime.now()
- d = sgdatetime.SGDatetime.sbfdate(now, d_preset='%d-%m-%Y')
+ now = sgdatetime.SGDatetime.now()
+ d = sgdatetime.SGDatetime.sbfdate(now, d_preset='%Y-%m-%d')
t = sgdatetime.SGDatetime.sbftime(now, t_preset='%H-%M')
- ds = '%s_%s' % (t, d)
+ ds = '%s_%s' % (d, t)
for c in ['sickbeard', 'cache', 'failed']:
cur_db = DBConnection('%s.db' % c)
b_name = '%s_%s.db' % (c, ds)
diff --git a/sickbeard/show_updater.py b/sickbeard/show_updater.py
index c469518..bfc6da7 100644
--- a/sickbeard/show_updater.py
+++ b/sickbeard/show_updater.py
@@ -71,13 +71,13 @@ class ShowUpdater(object):
update_date = update_datetime.date()
# backup db's
- if sickbeard.db.db_supports_backup and 0 < sickbeard.MAX_DB_BACKUP_COUNT:
+ if sickbeard.db.db_supports_backup and 0 < sickbeard.BACKUP_DB_MAX_COUNT:
logger.log('backing up all db\'s')
try:
- sickbeard.db.backup_all_dbs(sickbeard.DB_BACKUP_PATH or
+ sickbeard.db.backup_all_dbs(sickbeard.BACKUP_DB_PATH or
ek.ek(os.path.join, sickbeard.DATA_DIR, 'backup'))
except (BaseException, Exception):
- logger.log('DB backup error', logger.ERROR)
+ logger.log('backup db error', logger.ERROR)
# refresh network timezones
try:
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 3e17a40..379ccb6 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -6730,6 +6730,9 @@ class Config(MainHandler):
except (BaseException, Exception):
t.version = ''
+ t.backup_db_path = sickbeard.BACKUP_DB_MAX_COUNT and \
+ (sickbeard.BACKUP_DB_PATH or ek.ek(os.path.join, sickbeard.DATA_DIR, 'backup')) or 'Disabled'
+
return t.respond()
@@ -6957,7 +6960,7 @@ class ConfigGeneral(Config):
handle_reverse_proxy=None, send_security_headers=None, allowed_hosts=None, allow_anyip=None,
git_remote=None,
git_path=None, cpu_preset=None, anon_redirect=None, encryption_version=None,
- proxy_setting=None, proxy_indexers=None, file_logging_preset=None):
+ proxy_setting=None, proxy_indexers=None, file_logging_preset=None, backup_db_oneday=None):
results = []
@@ -7067,6 +7070,7 @@ class ConfigGeneral(Config):
sickbeard.PROXY_INDEXERS = config.checkbox_to_value(proxy_indexers)
sickbeard.FILE_LOGGING_PRESET = file_logging_preset
# sickbeard.LOG_DIR is set in config.change_log_dir()
+ sickbeard.BACKUP_DB_ONEDAY = config.checkbox_to_value(backup_db_oneday)
logger.log_set_level()