From d899b71fea69fa1f3a589665a4681c5aff44ba0e Mon Sep 17 00:00:00 2001 From: Brian Cipriano Date: Wed, 30 Mar 2022 13:59:00 -0400 Subject: [PATCH] [cuegui] Split config code into a new module. (#1095) --- cuegui/cuegui/Config.py | 63 ++++++++++++++++++++++++ cuegui/cuegui/Main.py | 27 +---------- cuegui/tests/Config_tests.py | 93 ++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 25 deletions(-) create mode 100644 cuegui/cuegui/Config.py create mode 100644 cuegui/tests/Config_tests.py diff --git a/cuegui/cuegui/Config.py b/cuegui/cuegui/Config.py new file mode 100644 index 000000000..2c80f8492 --- /dev/null +++ b/cuegui/cuegui/Config.py @@ -0,0 +1,63 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Functions for loading application state and settings from disk.""" + +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import + +import os +import shutil + +from PySide2 import QtCore + +import cuegui.Constants +import cuegui.Logger + +logger = cuegui.Logger.getLogger(__file__) + + +def startup(app_name): + """ + Reads config from disk, restoring default config if necessary. + + :param app_name: application window name + :type app_name: str + :return: settings object containing the loaded settings + :rtype: QtCore.QSettings + """ + # read saved config from disk + # copy default config + config_path = "/.%s/config" % app_name.lower() + settings = QtCore.QSettings(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, config_path) + logger.info('Reading config file from %s', settings.fileName()) + local = settings.fileName() + + # If the user has chose to revert the layout. delete the file and copy the default back. + if settings.value('RevertLayout'): + logger.warning('Found RevertLayout flag, will restore default config') + os.remove(local) + + # If the config file does not exist, copy over the default + if not os.path.exists(local): + default = os.path.join(cuegui.Constants.DEFAULT_INI_PATH, "%s.ini" % app_name.lower()) + logger.warning('Local config file not found at %s', local) + logger.warning('Copying %s to %s', default, local) + os.makedirs(os.path.dirname(local), exist_ok=True) + shutil.copy2(default, local) + settings.sync() + + return settings diff --git a/cuegui/cuegui/Main.py b/cuegui/cuegui/Main.py index b97e3d885..58bb3073d 100644 --- a/cuegui/cuegui/Main.py +++ b/cuegui/cuegui/Main.py @@ -20,14 +20,13 @@ from __future__ import print_function from __future__ import division -import os -import shutil import signal from PySide2 import QtCore from PySide2 import QtGui from PySide2 import QtWidgets +import cuegui.Config import cuegui.Constants import cuegui.Logger import cuegui.MainWindow @@ -92,33 +91,11 @@ def startup(app_name, app_version, argv): QtGui.qApp.threads = [] # pylint: enable=attribute-defined-outside-init - config_path = "/.%s/config" % app_name.lower() - settings = QtCore.QSettings(QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, config_path) - local = settings.fileName() - # If the user has chose to revert the layout. delete the file and copy the default back. - if settings.value('RevertLayout'): - os.remove(local) - + settings = cuegui.Config.startup(app_name) QtGui.qApp.settings = settings # pylint: disable=attribute-defined-outside-init cuegui.Style.init() - # If the config file does not exist, copy over the default - # pylint: disable=broad-except - if not os.path.exists(local): - default = os.path.join(cuegui.Constants.DEFAULT_INI_PATH, "%s.ini" % app_name.lower()) - logger.warning('Not found: %s\nCopying: %s', local, default) - try: - os.mkdir(os.path.dirname(local)) - except Exception as e: - logger.debug(e) - try: - shutil.copy2(default, local) - except Exception as e: - logger.debug(e) - settings.sync() - # pylint: enable=broad-except - mainWindow = cuegui.MainWindow.MainWindow(app_name, app_version, None) mainWindow.displayStartupNotice() mainWindow.show() diff --git a/cuegui/tests/Config_tests.py b/cuegui/tests/Config_tests.py new file mode 100644 index 000000000..61ab2c193 --- /dev/null +++ b/cuegui/tests/Config_tests.py @@ -0,0 +1,93 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Tests for cuegui.Config""" + + +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import + +import os +import shutil +import tempfile +import unittest + +from PySide2 import QtCore + +import cuegui.Config + + +CONFIG_INI = ''' +[General] +Version=0.14 + +[CueCommander] +Open=true +Title=CustomWindowTitle +OtherAttr=arbitrary-value +''' + +CONFIG_WITH_RESTORE_FLAG = ''' +[General] +Version=0.14 +RevertLayout=true + +[CueCommander] +OtherAttr=arbitrary-value +''' + + +class ConfigTests(unittest.TestCase): + def setUp(self): + self.config_dir = tempfile.mkdtemp() + QtCore.QSettings.setPath( + QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, self.config_dir) + + def tearDown(self): + shutil.rmtree(self.config_dir) + + def test__should_load_user_config(self): + app_name = 'arbitraryapp' + config_file_path = os.path.join(self.config_dir, '.%s' % app_name, 'config.ini') + os.mkdir(os.path.dirname(config_file_path)) + with open(config_file_path, 'w') as fp: + fp.write(CONFIG_INI) + + settings = cuegui.Config.startup(app_name) + + self.assertEqual('0.14', settings.value('Version')) + self.assertEqual('true', settings.value('CueCommander/Open')) + self.assertEqual('CustomWindowTitle', settings.value('CueCommander/Title')) + self.assertEqual('arbitrary-value', settings.value('CueCommander/OtherAttr')) + + def test__should_load_default_config(self): + settings = cuegui.Config.startup('CueCommander') + + self.assertEqual('false', settings.value('CueCommander/Open')) + self.assertEqual('CueCommander', settings.value('CueCommander/Title')) + self.assertFalse(settings.value('CueCommander/OtherAttr', False)) + + def test__should_restore_default_config(self): + config_file_path = os.path.join(self.config_dir, '.cuecommander', 'config.ini') + os.mkdir(os.path.dirname(config_file_path)) + with open(config_file_path, 'w') as fp: + fp.write(CONFIG_WITH_RESTORE_FLAG) + + settings = cuegui.Config.startup('CueCommander') + + self.assertEqual('false', settings.value('CueCommander/Open')) + self.assertEqual('CueCommander', settings.value('CueCommander/Title')) + self.assertFalse(settings.value('CueCommander/OtherAttr', False))