Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: for both config editors, catch and alert on file permission errors #105

Merged
merged 2 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion software/control/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3598,6 +3598,7 @@ def display_image(self, image, illumination_source):
class ConfigurationManager(QObject):
def __init__(self, filename="channel_configurations.xml"):
QObject.__init__(self)
self._log = squid.logging.get_logger(self.__class__.__name__)
self.config_filename = filename
self.configurations = []
self.read_configurations()
Expand All @@ -3606,7 +3607,12 @@ def save_configurations(self):
self.write_configuration(self.config_filename)

def write_configuration(self, filename):
self.config_xml_tree.write(filename, encoding="utf-8", xml_declaration=True, pretty_print=True)
try:
self.config_xml_tree.write(filename, encoding="utf-8", xml_declaration=True, pretty_print=True)
return True
except IOError:
self._log.exception("Couldn't write configuration.")
return False

def read_configurations(self):
if os.path.isfile(self.config_filename) == False:
Expand Down
22 changes: 18 additions & 4 deletions software/control/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ def save_to_file(self):
self, "Save Acquisition Config File", "", "XML Files (*.xml);;All Files (*)"
)
if file_path:
self.config.write_configuration(file_path)
if not self.config.write_configuration(file_path):
QMessageBox.warning(
self, "Warning", f"Failed to write config to file '{file_path}'. Check permissions!"
)

def load_config_from_file(self, only_z_offset=None):
file_path, _ = QFileDialog.getOpenFileName(
Expand All @@ -205,7 +208,7 @@ def load_config_from_file(self, only_z_offset=None):
class ConfigEditor(QDialog):
def __init__(self, config):
super().__init__()

self._log = squid.logging.get_logger(self.__class__.__name__)
self.config = config

self.scroll_area = QScrollArea()
Expand Down Expand Up @@ -287,12 +290,23 @@ def save_config(self):
if old_val != self.config.get(section, option):
print(self.config.get(section, option))

def save_to_filename(self, filename: str):
try:
with open(filename, "w") as configfile:
self.config.write(configfile)
return True
except IOError:
self._log.exception(f"Failed to write config file to '{filename}'")
return False

def save_to_file(self):
self.save_config()
file_path, _ = QFileDialog.getSaveFileName(self, "Save Config File", "", "INI Files (*.ini);;All Files (*)")
if file_path:
with open(file_path, "w") as configfile:
self.config.write(configfile)
if not self.save_to_filename(file_path):
QMessageBox.warning(
self, "Warning", f"Failed to write config file to '{file_path}'. Check permissions!"
)

def load_config_from_file(self):
file_path, _ = QFileDialog.getOpenFileName(self, "Load Config File", "", "INI Files (*.ini);;All Files (*)")
Expand Down
42 changes: 42 additions & 0 deletions software/tests/control/test_gui_config_editors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os
import tempfile
from configparser import ConfigParser

import pytest

import tests.control.gui_test_stubs
import control.widgets


def test_config_editor_for_acquisitions_save_to_file(qtbot):
config_editor = control.widgets.ConfigEditorForAcquisitions(
tests.control.gui_test_stubs.get_test_configuration_manager()
)

(good_fd, good_filename) = tempfile.mkstemp()
os.close(good_fd)
assert config_editor.config.write_configuration(good_filename)
os.remove(good_filename)

(bad_fd, bad_filename) = tempfile.mkstemp()
os.close(bad_fd)
read_only_permissions = 0o444
os.chmod(bad_filename, read_only_permissions)

assert not config_editor.config.write_configuration(bad_filename)


def test_config_editor_save_to_file(qtbot):
config_editor = control.widgets.ConfigEditor(ConfigParser())

(good_fd, good_filename) = tempfile.mkstemp()
os.close(good_fd)
assert config_editor.save_to_filename(good_filename)
os.remove(good_filename)

(bad_fd, bad_filename) = tempfile.mkstemp()
os.close(bad_fd)
read_only_permissions = 0o444
os.chmod(bad_filename, read_only_permissions)

assert not config_editor.save_to_filename(bad_filename)
Loading