forked from openlp/openlp
Back up settings before upgrading them
This commit is contained in:
parent
1908efcdbb
commit
7a3f54e54c
@ -33,6 +33,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
from datetime import datetime
|
||||||
from traceback import format_exception
|
from traceback import format_exception
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
@ -423,7 +424,20 @@ def main(args=None):
|
|||||||
application.shared_memory.detach()
|
application.shared_memory.detach()
|
||||||
sys.exit()
|
sys.exit()
|
||||||
# Upgrade settings.
|
# Upgrade settings.
|
||||||
Settings().upgrade_settings()
|
settings = Settings()
|
||||||
|
if settings.can_upgrade():
|
||||||
|
now = datetime.now()
|
||||||
|
# Only back up if OpenLP has previously run.
|
||||||
|
if settings.value('core/has run wizard'):
|
||||||
|
back_up_path = AppLocation.get_data_path() / (now.strftime('%Y-%m-%d %H-%M') + '.conf')
|
||||||
|
log.info('Settings about to be upgraded. Existing settings are being backed up to {back_up_path}'
|
||||||
|
.format(back_up_path=back_up_path))
|
||||||
|
QtWidgets.QMessageBox.information(
|
||||||
|
None, translate('OpenLP', 'Settings Upgrade'),
|
||||||
|
translate('OpenLP', 'Your settings are about to upgraded. A backup will be created at {back_up_path}')
|
||||||
|
.format(back_up_path=back_up_path))
|
||||||
|
settings.export(back_up_path)
|
||||||
|
settings.upgrade_settings()
|
||||||
# First time checks in settings
|
# First time checks in settings
|
||||||
if not Settings().value('core/has run wizard'):
|
if not Settings().value('core/has run wizard'):
|
||||||
if not FirstTimeLanguageForm().exec():
|
if not FirstTimeLanguageForm().exec():
|
||||||
|
@ -26,12 +26,13 @@ import datetime
|
|||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from tempfile import gettempdir
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
from openlp.core.common import SlideLimits, ThemeLevel, UiStrings, is_linux, is_win
|
from openlp.core.common import SlideLimits, ThemeLevel, UiStrings, is_linux, is_win, translate
|
||||||
from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
|
from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
|
||||||
from openlp.core.common.path import Path, path_to_str, str_to_path
|
from openlp.core.common.path import Path, str_to_path
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -452,14 +453,20 @@ class Settings(QtCore.QSettings):
|
|||||||
key = self.group() + '/' + key
|
key = self.group() + '/' + key
|
||||||
return Settings.__default_settings__[key]
|
return Settings.__default_settings__[key]
|
||||||
|
|
||||||
|
def can_upgrade(self):
|
||||||
|
"""
|
||||||
|
Can / should the settings be upgraded
|
||||||
|
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
return __version__ != self.value('settings/version')
|
||||||
|
|
||||||
def upgrade_settings(self):
|
def upgrade_settings(self):
|
||||||
"""
|
"""
|
||||||
This method is only called to clean up the config. It removes old settings and it renames settings. See
|
This method is only called to clean up the config. It removes old settings and it renames settings. See
|
||||||
``__obsolete_settings__`` for more details.
|
``__obsolete_settings__`` for more details.
|
||||||
"""
|
"""
|
||||||
current_version = self.value('settings/version')
|
current_version = self.value('settings/version')
|
||||||
if __version__ == current_version:
|
|
||||||
return
|
|
||||||
for version in range(current_version, __version__):
|
for version in range(current_version, __version__):
|
||||||
version += 1
|
version += 1
|
||||||
upgrade_list = getattr(self, '__setting_upgrade_{version}__'.format(version=version))
|
upgrade_list = getattr(self, '__setting_upgrade_{version}__'.format(version=version))
|
||||||
@ -549,3 +556,59 @@ class Settings(QtCore.QSettings):
|
|||||||
if isinstance(default_value, int):
|
if isinstance(default_value, int):
|
||||||
return int(setting)
|
return int(setting)
|
||||||
return setting
|
return setting
|
||||||
|
|
||||||
|
def export(self, dest_path):
|
||||||
|
"""
|
||||||
|
Export the settings to file.
|
||||||
|
|
||||||
|
:param openlp.core.common.path.Path dest_path: The file path to create the export file.
|
||||||
|
:return: Success
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
temp_path = Path(gettempdir(), 'openlp', 'exportConf.tmp')
|
||||||
|
# Delete old files if found.
|
||||||
|
if temp_path.exists():
|
||||||
|
temp_path.unlink()
|
||||||
|
if dest_path.exists():
|
||||||
|
dest_path.unlink()
|
||||||
|
self.remove('SettingsImport')
|
||||||
|
# Get the settings.
|
||||||
|
keys = self.allKeys()
|
||||||
|
export_settings = QtCore.QSettings(str(temp_path), Settings.IniFormat)
|
||||||
|
# Add a header section.
|
||||||
|
# This is to insure it's our conf file for import.
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
# Write INI format using QSettings.
|
||||||
|
# Write our header.
|
||||||
|
export_settings.beginGroup('SettingsImport')
|
||||||
|
export_settings.setValue('Make_Changes', 'At_Own_RISK')
|
||||||
|
export_settings.setValue('type', 'OpenLP_settings_export')
|
||||||
|
export_settings.setValue('file_date_created', now.strftime("%Y-%m-%d %H:%M"))
|
||||||
|
export_settings.endGroup()
|
||||||
|
# Write all the sections and keys.
|
||||||
|
for section_key in keys:
|
||||||
|
# FIXME: We are conflicting with the standard "General" section.
|
||||||
|
if 'eneral' in section_key:
|
||||||
|
section_key = section_key.lower()
|
||||||
|
key_value = super().value(section_key)
|
||||||
|
if key_value is not None:
|
||||||
|
export_settings.setValue(section_key, key_value)
|
||||||
|
export_settings.sync()
|
||||||
|
# Temp CONF file has been written. Blanks in keys are now '%20'.
|
||||||
|
# Read the temp file and output the user's CONF file with blanks to
|
||||||
|
# make it more readable.
|
||||||
|
try:
|
||||||
|
with dest_path.open('w') as export_conf_file, temp_path.open('r') as temp_conf:
|
||||||
|
for file_record in temp_conf:
|
||||||
|
# Get rid of any invalid entries.
|
||||||
|
if file_record.find('@Invalid()') == -1:
|
||||||
|
file_record = file_record.replace('%20', ' ')
|
||||||
|
export_conf_file.write(file_record)
|
||||||
|
except OSError as ose:
|
||||||
|
QtWidgets.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'Export setting error'),
|
||||||
|
translate('OpenLP.MainWindow',
|
||||||
|
'An error occurred while exporting the settings: {err}'
|
||||||
|
).format(err=ose.strerror),
|
||||||
|
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
||||||
|
finally:
|
||||||
|
temp_path.unlink()
|
||||||
|
@ -50,6 +50,7 @@ from openlp.core.ui.media import MediaController
|
|||||||
from openlp.core.ui.printserviceform import PrintServiceForm
|
from openlp.core.ui.printserviceform import PrintServiceForm
|
||||||
from openlp.core.ui.projector.manager import ProjectorManager
|
from openlp.core.ui.projector.manager import ProjectorManager
|
||||||
from openlp.core.ui.lib.dockwidget import OpenLPDockWidget
|
from openlp.core.ui.lib.dockwidget import OpenLPDockWidget
|
||||||
|
from openlp.core.ui.lib.filedialog import FileDialog
|
||||||
from openlp.core.ui.lib.mediadockmanager import MediaDockManager
|
from openlp.core.ui.lib.mediadockmanager import MediaDockManager
|
||||||
|
|
||||||
|
|
||||||
@ -876,11 +877,12 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
|||||||
shutil.copyfile(import_file_name, temp_config)
|
shutil.copyfile(import_file_name, temp_config)
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
import_settings = Settings(temp_config, Settings.IniFormat)
|
import_settings = Settings(temp_config, Settings.IniFormat)
|
||||||
# Convert image files
|
|
||||||
log.info('hook upgrade_plugin_settings')
|
log.info('hook upgrade_plugin_settings')
|
||||||
self.plugin_manager.hook_upgrade_plugin_settings(import_settings)
|
self.plugin_manager.hook_upgrade_plugin_settings(import_settings)
|
||||||
# Upgrade settings to prepare the import.
|
# Upgrade settings to prepare the import.
|
||||||
import_settings.upgrade_settings()
|
if import_settings.can_upgrade():
|
||||||
|
import_settings.upgrade_settings()
|
||||||
# Lets do a basic sanity check. If it contains this string we can assume it was created by OpenLP and so we'll
|
# Lets do a basic sanity check. If it contains this string we can assume it was created by OpenLP and so we'll
|
||||||
# load what we can from it, and just silently ignore anything we don't recognise.
|
# load what we can from it, and just silently ignore anything we don't recognise.
|
||||||
if import_settings.value('SettingsImport/type') != 'OpenLP_settings_export':
|
if import_settings.value('SettingsImport/type') != 'OpenLP_settings_export':
|
||||||
@ -936,89 +938,17 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
Export settings to a .conf file in INI format
|
Export settings to a .conf file in INI format
|
||||||
"""
|
"""
|
||||||
export_file_name, filter_used = QtWidgets.QFileDialog.getSaveFileName(
|
export_file_path, filter_used = FileDialog.getSaveFileName(
|
||||||
self,
|
self,
|
||||||
translate('OpenLP.MainWindow', 'Export Settings File'),
|
translate('OpenLP.MainWindow', 'Export Settings File'),
|
||||||
'',
|
None,
|
||||||
translate('OpenLP.MainWindow', 'OpenLP Settings (*.conf)'))
|
translate('OpenLP.MainWindow', 'OpenLP Settings (*.conf)'))
|
||||||
if not export_file_name:
|
if not export_file_path:
|
||||||
return
|
return
|
||||||
# Make sure it's a .conf file.
|
# Make sure it's a .conf file.
|
||||||
if not export_file_name.endswith('conf'):
|
export_file_path = export_file_path.with_suffix('.conf')
|
||||||
export_file_name += '.conf'
|
|
||||||
temp_file = os.path.join(gettempdir(), 'openlp', 'exportConf.tmp')
|
|
||||||
self.save_settings()
|
self.save_settings()
|
||||||
setting_sections = []
|
Settings().export(export_file_path)
|
||||||
# Add main sections.
|
|
||||||
setting_sections.extend([self.general_settings_section])
|
|
||||||
setting_sections.extend([self.advanced_settings_section])
|
|
||||||
setting_sections.extend([self.ui_settings_section])
|
|
||||||
setting_sections.extend([self.shortcuts_settings_section])
|
|
||||||
setting_sections.extend([self.service_manager_settings_section])
|
|
||||||
setting_sections.extend([self.themes_settings_section])
|
|
||||||
setting_sections.extend([self.display_tags_section])
|
|
||||||
# Add plugin sections.
|
|
||||||
for plugin in self.plugin_manager.plugins:
|
|
||||||
setting_sections.extend([plugin.name])
|
|
||||||
# Delete old files if found.
|
|
||||||
if os.path.exists(temp_file):
|
|
||||||
os.remove(temp_file)
|
|
||||||
if os.path.exists(export_file_name):
|
|
||||||
os.remove(export_file_name)
|
|
||||||
settings = Settings()
|
|
||||||
settings.remove(self.header_section)
|
|
||||||
# Get the settings.
|
|
||||||
keys = settings.allKeys()
|
|
||||||
export_settings = Settings(temp_file, Settings.IniFormat)
|
|
||||||
# Add a header section.
|
|
||||||
# This is to insure it's our conf file for import.
|
|
||||||
now = datetime.now()
|
|
||||||
application_version = get_application_version()
|
|
||||||
# Write INI format using Qsettings.
|
|
||||||
# Write our header.
|
|
||||||
export_settings.beginGroup(self.header_section)
|
|
||||||
export_settings.setValue('Make_Changes', 'At_Own_RISK')
|
|
||||||
export_settings.setValue('type', 'OpenLP_settings_export')
|
|
||||||
export_settings.setValue('file_date_created', now.strftime("%Y-%m-%d %H:%M"))
|
|
||||||
export_settings.setValue('version', application_version['full'])
|
|
||||||
export_settings.endGroup()
|
|
||||||
# Write all the sections and keys.
|
|
||||||
for section_key in keys:
|
|
||||||
# FIXME: We are conflicting with the standard "General" section.
|
|
||||||
if 'eneral' in section_key:
|
|
||||||
section_key = section_key.lower()
|
|
||||||
try:
|
|
||||||
key_value = settings.value(section_key)
|
|
||||||
except KeyError:
|
|
||||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'Export setting error'),
|
|
||||||
translate('OpenLP.MainWindow', 'The key "{key}" does not have a default '
|
|
||||||
'value so it will be skipped in this '
|
|
||||||
'export.').format(key=section_key),
|
|
||||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
|
||||||
key_value = None
|
|
||||||
if key_value is not None:
|
|
||||||
export_settings.setValue(section_key, key_value)
|
|
||||||
export_settings.sync()
|
|
||||||
# Temp CONF file has been written. Blanks in keys are now '%20'.
|
|
||||||
# Read the temp file and output the user's CONF file with blanks to
|
|
||||||
# make it more readable.
|
|
||||||
temp_conf = open(temp_file, 'r')
|
|
||||||
try:
|
|
||||||
export_conf = open(export_file_name, 'w')
|
|
||||||
for file_record in temp_conf:
|
|
||||||
# Get rid of any invalid entries.
|
|
||||||
if file_record.find('@Invalid()') == -1:
|
|
||||||
file_record = file_record.replace('%20', ' ')
|
|
||||||
export_conf.write(file_record)
|
|
||||||
temp_conf.close()
|
|
||||||
export_conf.close()
|
|
||||||
os.remove(temp_file)
|
|
||||||
except OSError as ose:
|
|
||||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.MainWindow', 'Export setting error'),
|
|
||||||
translate('OpenLP.MainWindow',
|
|
||||||
'An error occurred while exporting the '
|
|
||||||
'settings: {err}').format(err=ose.strerror),
|
|
||||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Ok))
|
|
||||||
|
|
||||||
def on_mode_default_item_clicked(self):
|
def on_mode_default_item_clicked(self):
|
||||||
"""
|
"""
|
||||||
|
@ -71,14 +71,6 @@ class ImagePlugin(Plugin):
|
|||||||
'provided by the theme.')
|
'provided by the theme.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def upgrade_settings(self, settings):
|
|
||||||
"""
|
|
||||||
Upgrade the settings of this plugin.
|
|
||||||
|
|
||||||
:param settings: The Settings object containing the old settings.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_plugin_text_strings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin.
|
Called to define all translatable texts of the plugin.
|
||||||
|
Loading…
Reference in New Issue
Block a user