mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-18 08:43:37 +00:00
Merge branch 'feature/AddConfigBackup' into dev
This commit is contained in:
commit
71787f010f
3 changed files with 125 additions and 3 deletions
|
@ -13,7 +13,6 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from collections import OrderedDict
|
||||
from threading import Lock
|
||||
|
||||
|
@ -23,6 +22,7 @@ import os
|
|||
import re
|
||||
import signal
|
||||
import socket
|
||||
import time
|
||||
import webbrowser
|
||||
|
||||
# apparently py2exe won't build these unless they're imported somewhere
|
||||
|
@ -54,6 +54,7 @@ from configobj import ConfigObj
|
|||
from api_trakt import TraktAPI
|
||||
|
||||
from _23 import b64encodestring, decode_bytes, scandir
|
||||
from sg_helpers import remove_file_perm
|
||||
from six import iteritems, string_types
|
||||
import sg_helpers
|
||||
|
||||
|
@ -2423,7 +2424,69 @@ def save_config():
|
|||
new_config['ANIME'] = {}
|
||||
new_config['ANIME']['anime_treat_as_hdtv'] = int(ANIME_TREAT_AS_HDTV)
|
||||
|
||||
from sg_helpers import copy_file
|
||||
backup_config = re.sub(r'\.ini$', '.bak', CONFIG_FILE)
|
||||
from .config import check_valid_config
|
||||
try:
|
||||
copy_file(CONFIG_FILE, backup_config)
|
||||
if not check_valid_config(backup_config):
|
||||
logger.error('config file seams to be invalid, not backing up.')
|
||||
remove_file_perm(backup_config)
|
||||
backup_config = None
|
||||
except (BaseException, Exception):
|
||||
backup_config = None
|
||||
|
||||
for _ in range(0, 3):
|
||||
new_config.write()
|
||||
if check_valid_config(CONFIG_FILE):
|
||||
return
|
||||
logger.warning('saving config file failed, retrying...')
|
||||
remove_file_perm(CONFIG_FILE)
|
||||
time.sleep(3)
|
||||
|
||||
# we only get here if the config saving failed multiple times
|
||||
if None is not backup_config and os.path.isfile(backup_config):
|
||||
logger.error('saving config file failed, using backup file')
|
||||
try:
|
||||
copy_file(backup_config, CONFIG_FILE)
|
||||
logger.log('using old backup config file')
|
||||
return
|
||||
except (BaseException, Exception):
|
||||
logger.error('failed to use backup config file')
|
||||
|
||||
from sg_helpers import scantree
|
||||
try:
|
||||
target_base = os.path.join(BACKUP_DB_PATH or os.path.join(DATA_DIR, 'backup'))
|
||||
file_list = [f for f in scantree(target_base, include='config', filter_kind=False)]
|
||||
if file_list:
|
||||
logger.log('trying to use latest config.ini backup')
|
||||
# sort newest to oldest backup
|
||||
file_list.sort(key=lambda _f: _f.stat(follow_symlinks=False).st_mtime)
|
||||
import zipfile
|
||||
try:
|
||||
with zipfile.ZipFile(file_list[0].path, mode='r') as zf:
|
||||
zf.extractall(target_base)
|
||||
backup_config_file = os.path.join(target_base, 'config.ini')
|
||||
if os.path.isfile(backup_config_file):
|
||||
os.replace(backup_config_file, CONFIG_FILE)
|
||||
if check_valid_config(CONFIG_FILE):
|
||||
logger.log(f'used latest config.ini backup file: {file_list[0].name}')
|
||||
return
|
||||
else:
|
||||
logger.error(f'failed to use latest config.ini backup file: {file_list[0].name}')
|
||||
remove_file_perm(CONFIG_FILE)
|
||||
except (BaseException, Exception):
|
||||
pass
|
||||
finally:
|
||||
try:
|
||||
remove_file_perm(backup_config_file)
|
||||
except (BaseException, Exception):
|
||||
pass
|
||||
logger.error('failed to use latest config.ini')
|
||||
except (BaseException, Exception):
|
||||
pass
|
||||
|
||||
logger.error('saving config file failed and no backup available')
|
||||
|
||||
|
||||
def launch_browser(start_port=None):
|
||||
|
|
|
@ -24,6 +24,7 @@ from . import db, helpers, logger, naming
|
|||
from lib.api_trakt import TraktAPI
|
||||
|
||||
from _23 import urlsplit, urlunsplit
|
||||
from sg_helpers import compress_file, copy_file, remove_file_perm, scantree, try_int
|
||||
from six import string_types
|
||||
|
||||
|
||||
|
@ -455,6 +456,58 @@ def check_setting_str(config, cfg_name, item_name, def_val, log=True):
|
|||
|
||||
return (my_val, def_val)['None' == my_val]
|
||||
|
||||
def check_valid_config(filename):
|
||||
# type: (str) -> bool
|
||||
"""
|
||||
check if file appears to be a vaild config file
|
||||
:param filename: full path config file name
|
||||
"""
|
||||
from configobj import ConfigObj
|
||||
try:
|
||||
conf_obj = ConfigObj(filename)
|
||||
if not (all(section in conf_obj for section in ('General', 'GUI')) and 'config_version' in conf_obj['General']
|
||||
and isinstance(try_int(conf_obj['General']['config_version'], None), int)):
|
||||
return False
|
||||
return True
|
||||
except (BaseException, Exception):
|
||||
return False
|
||||
finally:
|
||||
try:
|
||||
del conf_obj
|
||||
except (BaseException, Exception):
|
||||
pass
|
||||
|
||||
def backup_config():
|
||||
"""
|
||||
backup config.ini
|
||||
"""
|
||||
logger.log('backing up config.ini')
|
||||
try:
|
||||
if not check_valid_config(sickgear.CONFIG_FILE):
|
||||
logger.error('config file seams to be invalid, not backing up.')
|
||||
return
|
||||
now = datetime.datetime.now()
|
||||
d = datetime.datetime.strftime(now, '%Y-%m-%d')
|
||||
t = datetime.datetime.strftime(now, '%H-%M')
|
||||
target_base = os.path.join(sickgear.BACKUP_DB_PATH or os.path.join(sickgear.DATA_DIR, 'backup'))
|
||||
target = os.path.join(target_base, 'config.ini')
|
||||
copy_file(sickgear.CONFIG_FILE, target)
|
||||
if not check_valid_config(target):
|
||||
logger.error('config file seams to be invalid, not backing up.')
|
||||
remove_file_perm(target)
|
||||
return
|
||||
compress_file(target, 'config.ini')
|
||||
os.rename(re.sub(r'\.ini$', '.zip', target), os.path.join(target_base, f'config_{d}_{t}.zip'))
|
||||
# remove old files
|
||||
use_count = (1, sickgear.BACKUP_DB_MAX_COUNT)[not sickgear.BACKUP_DB_ONEDAY]
|
||||
file_list = [f for f in scantree(target_base, include='config', filter_kind=False)]
|
||||
if use_count < len(file_list):
|
||||
file_list.sort(key=lambda _f: _f.stat(follow_symlinks=False).st_mtime, reverse=True)
|
||||
for direntry in file_list[use_count:]:
|
||||
remove_file_perm(direntry.path)
|
||||
except (BaseException, Exception):
|
||||
logger.error('backup config.ini error')
|
||||
|
||||
|
||||
class ConfigMigrator(object):
|
||||
def __init__(self, config_obj):
|
||||
|
@ -926,3 +979,4 @@ class ConfigMigrator(object):
|
|||
|
||||
def _migrate_v22(self):
|
||||
self.deprecate_anon_service()
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ from exceptions_helper import ex
|
|||
import sickgear
|
||||
from . import db, logger, network_timezones, properFinder, ui
|
||||
from .scheduler import Job
|
||||
from .config import backup_config
|
||||
|
||||
# noinspection PyUnreachableCode
|
||||
if False:
|
||||
|
@ -70,7 +71,11 @@ class ShowUpdater(Job):
|
|||
if sickgear.db.db_supports_backup and 0 < sickgear.BACKUP_DB_MAX_COUNT:
|
||||
logger.log('backing up all db\'s')
|
||||
try:
|
||||
sickgear.db.backup_all_dbs(sickgear.BACKUP_DB_PATH or os.path.join(sickgear.DATA_DIR, 'backup'))
|
||||
backup_success = sickgear.db.backup_all_dbs(
|
||||
sickgear.BACKUP_DB_PATH or os.path.join(sickgear.DATA_DIR, 'backup'))
|
||||
if isinstance(backup_success, tuple) and backup_success[0]:
|
||||
# backup config.ini
|
||||
backup_config()
|
||||
except (BaseException, Exception):
|
||||
logger.error('backup db error')
|
||||
|
||||
|
|
Loading…
Reference in a new issue