From ad96e57d457ad0dbd207fcf037c8e3f1fa6ad814 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 19 Aug 2022 11:50:55 +0100 Subject: [PATCH 01/82] Draft of config class --- src/sas/config.py | 183 +++++++++++++++++++++++++++++++++++++++++ src/sas/config_meta.py | 27 ++++++ 2 files changed, 210 insertions(+) create mode 100644 src/sas/config.py create mode 100644 src/sas/config_meta.py diff --git a/src/sas/config.py b/src/sas/config.py new file mode 100644 index 0000000000..7c26e9f45b --- /dev/null +++ b/src/sas/config.py @@ -0,0 +1,183 @@ +""" Configuration class - stores configuration information for SasView + +The Config class cannot be subclassed or dynamically modified, +this prevents the config from having fields that are unspecified in +the base class, and makes it so that all usages of fields can be +automatically tracked. This allows the configs to be much more +easily maintained. + +Dev note: I have opted not to use frozen dataclasses at this time +because, as they currently work, the behaviour would make creating +different configs difficult. +""" + +from config_meta import ConfigBase, ConfigMeta + +import sas.sasview +import os +import time + + +class Config(ConfigBase, metaclass=ConfigMeta): + + def __init__(self): + super().__init__() + + # Version of the application + self.__appname__ = "SasView" + self.__version__ = sas.sasview.__version__ + self.__build__ = sas.sasview.__build__ + self.__download_page__ = 'https://github.com/SasView/sasview/releases' + self.__update_URL__ = 'https://www.sasview.org/latestversion.json' + + # Debug message flag + self.__EVT_DEBUG__ = False + + # Flag for automated testing + self.__TEST__ = False + + # Debug message should be written to a file? + self.__EVT_DEBUG_2_FILE__ = False + self.__EVT_DEBUG_FILENAME__ = "debug.log" + + # About box info + self._do_aboutbox = True + self._do_acknowledge = True + self._do_tutorial = True + self._acknowledgement_preamble = \ + '''To ensure the long term support and development of this software please''' + \ + ''' remember to:''' + self._acknowledgement_preamble_bullet1 = \ + '''Acknowledge its use in your publications as :''' + self._acknowledgement_preamble_bullet2 = \ + '''Reference SasView as:''' + self._acknowledgement_preamble_bullet3 = \ + '''Reference the model you used if appropriate (see documentation for refs)''' + self._acknowledgement_preamble_bullet4 = \ + '''Send us your reference for our records: developers@sasview.org''' + self._acknowledgement_publications = \ + '''This work benefited from the use of the SasView application, originally developed under NSF Award DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000.''' + self._acknowledgement_citation = \ + '''M. Doucet et al. SasView Version 5.0''' + + self._acknowledgement = \ + '''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS, and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: http://www.sasview.org/contact.html + ''' + + self._homepage = "https://www.sasview.org" + self._download = self.__download_page__ + self._authors = [] + self._paper = "http://sourceforge.net/p/sasview/tickets/" + self._license = "mailto:help@sasview.org" + + self.icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images")) + # logging.info("icon path: %s" % icon_path) + self.media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) + self.test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test")) + + self._nist_logo = os.path.join(self.icon_path, "nist_logo.png") + self._umd_logo = os.path.join(self.icon_path, "umd_logo.png") + self._sns_logo = os.path.join(self.icon_path, "sns_logo.png") + self._ornl_logo = os.path.join(self.icon_path, "ornl_logo.png") + self._isis_logo = os.path.join(self.icon_path, "isis_logo.png") + self._ess_logo = os.path.join(self.icon_path, "ess_logo.png") + self._ill_logo = os.path.join(self.icon_path, "ill_logo.png") + self._ansto_logo = os.path.join(self.icon_path, "ansto_logo.png") + self._tudelft_logo = os.path.join(self.icon_path, "tudelft_logo.png") + self._dls_logo = os.path.join(self.icon_path, "dls_logo.png") + self._nsf_logo = os.path.join(self.icon_path, "nsf_logo.png") + self._danse_logo = os.path.join(self.icon_path, "danse_logo.png") + self._inst_logo = os.path.join(self.icon_path, "utlogo.gif") + self._nist_url = "https://www.nist.gov/" + self._umd_url = "https://www.umd.edu/" + self._sns_url = "https://neutrons.ornl.gov/" + self._ornl_url = "https://neutrons.ornl.gov/" + self._nsf_url = "https://www.nsf.gov" + self._isis_url = "https://www.isis.stfc.ac.uk/" + self._ess_url = "https://europeanspallationsource.se/" + self._ill_url = "https://www.ill.eu/" + self._ansto_url = "https://www.ansto.gov.au/" + self._tudelft_url = "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" + self._dls_url = "https://www.diamond.ac.uk/" + self._danse_url = "https://www.its.caltech.edu/~matsci/btf/DANSE_web_page.html" + self._inst_url = "https://www.utk.edu" + self._corner_image = os.path.join(self.icon_path, "angles_flat.png") + self._welcome_image = os.path.join(self.icon_path, "SVwelcome.png") + self._copyright = "(c) 2009 - 2022, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft and DLS" + self.marketplace_url = "http://marketplace.sasview.org/" + + # edit the list of file state your plugin can read + self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' + self.APPLICATION_STATE_EXTENSION = '.svs' + self.GUIFRAME_WIDTH = 1150 + self.GUIFRAME_HEIGHT = 840 + self.PLUGIN_STATE_EXTENSIONS = ['.fitv', '.inv', '.prv', '.crf'] + self.PLUGINS_WLIST = ['Fitting files (*.fitv)|*.fitv', + 'Invariant files (*.inv)|*.inv', + 'P(r) files (*.prv)|*.prv', + 'Corfunc files (*.crf)|*.crf'] + self.PLOPANEL_WIDTH = 415 + self.PLOPANEL_HEIGTH = 370 + self.DATAPANEL_WIDTH = 235 + self.DATAPANEL_HEIGHT = 700 + self.SPLASH_SCREEN_PATH = os.path.join(self.icon_path, "SVwelcome_mini.png") + self.TUTORIAL_PATH = os.path.join(self.media_path, "Tutorial.pdf") + # DEFAULT_STYLE = GUIFRAME.MULTIPLE_APPLICATIONS|GUIFRAME.MANAGER_ON\ + # |GUIFRAME.CALCULATOR_ON|GUIFRAME.TOOLBAR_ON + self.DEFAULT_STYLE = 64 + + self.SPLASH_SCREEN_WIDTH = 512 + self.SPLASH_SCREEN_HEIGHT = 366 + self.SS_MAX_DISPLAY_TIME = 2000 + self.WELCOME_PANEL_ON = True + self.WELCOME_PANEL_SHOW = False + self.CLEANUP_PLOT = False + # OPEN and SAVE project menu + self.OPEN_SAVE_PROJECT_MENU = True + # VIEW MENU + self.VIEW_MENU = True + # EDIT MENU + self.EDIT_MENU = True + + self.SetupIconFile_win = os.path.join(self.icon_path, "ball.ico") + self.SetupIconFile_mac = os.path.join(self.icon_path, "ball.icns") + self.DefaultGroupName = "." + self.OutputBaseFilename = "setupSasView" + + self.FIXED_PANEL = True + self.DATALOADER_SHOW = True + self.CLEANUP_PLOT = False + self.WELCOME_PANEL_SHOW = False + # Show or hide toolbar at the start up + self.TOOLBAR_SHOW = True + # set a default perspective + self.DEFAULT_PERSPECTIVE = 'None' + + # Time out for updating sasview + self.UPDATE_TIMEOUT = 2 + + # OpenCL option + self.SAS_OPENCL = None + + # + # Lock the class down + # + self._lock() + + def printEVT(self, message): + if self.__EVT_DEBUG__: + """ + :TODO - Need method doc string + """ + print("%g: %s" % (time.clock(), message)) + + if self.__EVT_DEBUG_2_FILE__: + out = open(self.__EVT_DEBUG_FILENAME__, 'a') + out.write("%10g: %s\n" % (time.clock(), message)) + out.close() + + + + + + diff --git a/src/sas/config_meta.py b/src/sas/config_meta.py new file mode 100644 index 0000000000..1dc797fc6d --- /dev/null +++ b/src/sas/config_meta.py @@ -0,0 +1,27 @@ + +class ConfigLocked(Exception): + def __init__(self): + super().__init__(self, + "The Config class cannot be subclassed or added to dynamically, see config.py for details") + + +class ConfigMeta(type): + def __new__(typ, name, bases, classdict): + for b in bases: + if isinstance(b, ConfigMeta): + raise TypeError + return type.__new__(typ, name, bases, dict(classdict)) + + +class ConfigBase: + def __init__(self): + self._locked = False + + def _lock(self): + self._locked = True + + def __setattr__(self, key, value): + if key not in self.__dict__: + raise ConfigLocked() + + super().__setattr__(key, value) \ No newline at end of file From 2e9a9a1ab2fcd9468a420374acce30530c44a1a7 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 19 Aug 2022 14:55:57 +0100 Subject: [PATCH 02/82] Initial part of migration to temporary config --- .../sphinx-docs/source/_extensions/mathjax.py | 8 +- docs/sphinx-docs/source/conf.py | 2 +- installers/installer_generator.py | 4 +- installers/installer_generator64.py | 2 +- run.py | 2 +- setup.py | 2 +- src/sas/__init__.py | 60 ++++++++++++++- src/sas/_config.py | 74 ++----------------- src/sas/config_system/__init__.py | 2 + src/sas/{ => config_system}/config.py | 23 +++++- src/sas/{ => config_system}/config_meta.py | 7 +- src/sas/config_system/default_config.yml | 0 src/sas/config_system/schema.py | 1 + src/sas/config_system/util.py | 28 +++++++ src/sas/logger_config.py | 2 +- src/sas/qtgui/MainWindow/GuiManager.py | 6 +- src/sas/qtgui/Utilities/CategoryInstaller.py | 2 +- src/sas/qtgui/Utilities/CustomDir.py | 10 +-- src/sas/qtgui/Utilities/GuiUtils.py | 10 +-- 19 files changed, 145 insertions(+), 100 deletions(-) create mode 100644 src/sas/config_system/__init__.py rename src/sas/{ => config_system}/config.py (91%) rename src/sas/{ => config_system}/config_meta.py (75%) create mode 100644 src/sas/config_system/default_config.yml create mode 100644 src/sas/config_system/schema.py create mode 100644 src/sas/config_system/util.py diff --git a/docs/sphinx-docs/source/_extensions/mathjax.py b/docs/sphinx-docs/source/_extensions/mathjax.py index 4565a219f2..505388a29f 100644 --- a/docs/sphinx-docs/source/_extensions/mathjax.py +++ b/docs/sphinx-docs/source/_extensions/mathjax.py @@ -81,10 +81,10 @@ def html_visit_displaymath(self, node): def builder_inited(app): jaxpath = app.config.mathjax_path if not jaxpath: - raise ExtensionError('mathjax_path config value must be set for the ' + raise ExtensionError('mathjax_path config_system value must be set for the ' 'mathjax extension to work') - # app.config.mathjax_path can be a string or a list of strings + # app.config_system.mathjax_path can be a string or a list of strings if isinstance(jaxpath, basestring): app.add_javascript(jaxpath) else: @@ -105,8 +105,8 @@ def setup(app): # http://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn app.add_config_value('mathjax_path', 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?' - 'config=TeX-MML-AM_CHTML', - #'config=TeX-AMS-MML_HTMLorMML', + 'config_system=TeX-MML-AM_CHTML', + #'config_system=TeX-AMS-MML_HTMLorMML', False) app.add_config_value('mathjax_css', None, 'html') app.add_config_value('mathjax_use_katex', False, 'html') diff --git a/docs/sphinx-docs/source/conf.py b/docs/sphinx-docs/source/conf.py index f695e6dfff..b7649bfea0 100644 --- a/docs/sphinx-docs/source/conf.py +++ b/docs/sphinx-docs/source/conf.py @@ -41,7 +41,7 @@ mathjax_path = ( 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?' - 'config=TeX-MML-AM_CHTML') + 'config_system=TeX-MML-AM_CHTML') # For katex uncomment the following """ diff --git a/installers/installer_generator.py b/installers/installer_generator.py index 98bc4651c7..03bd5aae1d 100644 --- a/installers/installer_generator.py +++ b/installers/installer_generator.py @@ -1,5 +1,5 @@ """ -This module generates .iss file according to the local config of +This module generates .iss file according to the local config_system of the current application. Please make sure a file named "local_config.py" exists in the current directory. Edit local_config.py according to your needs. """ @@ -11,7 +11,7 @@ root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(root, 'sasview-install', 'Lib', 'site-packages')) -from sas.sasview import local_config +from sas import config as local_config #REG_PROGRAM = """{app}\MYPROG.EXE"" ""%1""" APPLICATION = str(local_config.__appname__ )+ '.exe' diff --git a/installers/installer_generator64.py b/installers/installer_generator64.py index aae6b20647..6547593980 100644 --- a/installers/installer_generator64.py +++ b/installers/installer_generator64.py @@ -1,5 +1,5 @@ """ -This module generates .iss file according to the local config of +This module generates .iss file according to the local config_system of the current application. Please make sure a file named "local_config.py" exists in the current directory. Edit local_config.py according to your needs. """ diff --git a/run.py b/run.py index db22b2e712..11563f3c27 100644 --- a/run.py +++ b/run.py @@ -111,7 +111,7 @@ def prepare(): # initialize OpenCL setting import sas - SAS_OPENCL = sas.get_custom_config().SAS_OPENCL + SAS_OPENCL = sas.config.SAS_OPENCL if SAS_OPENCL and "SAS_OPENCL" not in os.environ: os.environ["SAS_OPENCL"] = SAS_OPENCL diff --git a/setup.py b/setup.py index 2151c68313..bb943bd132 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ #f_path = os.path.join(sas_dir, "categories.json") #if os.path.isfile(f_path): # os.remove(f_path) - f_path = os.path.join(sas_dir, 'config', "custom_config.py") + f_path = os.path.join(sas_dir, 'config_system', "custom_config.py") if os.path.isfile(f_path): os.remove(f_path) #f_path = os.path.join(sas_dir, 'plugin_models') diff --git a/src/sas/__init__.py b/src/sas/__init__.py index 261f1cfb26..26ef2d96d1 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -1,3 +1,7 @@ +import os +import sys +from sas.config_system import configuration as config + __all__ = ['get_app_dir', 'get_user_dir', 'get_local_config', 'get_custom_config'] @@ -12,10 +16,59 @@ def get_app_dir(): """ global _APP_DIR if not _APP_DIR: - from ._config import find_app_dir _APP_DIR = find_app_dir() return _APP_DIR +# TODO: Replace with more idomatic version +def dirn(path, n): + """ + Return the directory n up from the current path + """ + path = os.path.realpath(path) + for _ in range(n): + path = os.path.dirname(path) + return path + + +def find_app_dir(): + """ + Locate the parent directory of the sasview resources. For the normal + application this will be the directory containing sasview.py. For the + frozen application this will be the path where the resources are installed. + """ + # We are starting out with the following info: + # __file__ = .../sas/__init__.pyc + # Check if the path .../sas/sasview exists, and use it as the + # app directory. This will only be the case if the app is not frozen. + path = os.path.join(os.path.dirname(__file__), 'sasview') + if os.path.exists(path): + return path + + # If we are running frozen, then root is a parent directory + if sys.platform == 'darwin': + # Here is the path to the file on the mac: + # .../Sasview.app/Contents/Resources/lib/python2.7/site-packages.zip/sas/__init__.pyc + # We want the path to the Resources directory. + path = dirn(__file__, 5) + elif os.name == 'nt': + # Here is the path to the file on windows: + # ../Sasview/library.zip/sas/__init__.pyc + # We want the path to the Sasview directory. + path = dirn(__file__, 3) + else: + raise RuntimeError("Couldn't find the app directory") + return path + +def make_user_dir(): + """ + Create the user directory ~/.sasview if it doesn't already exist. + """ + path = os.path.join(os.path.expanduser("~"),'.sasview') + if not os.path.exists(path): + os.mkdir(path) + return path + + _USER_DIR = None def get_user_dir(): """ @@ -25,7 +78,6 @@ def get_user_dir(): """ global _USER_DIR if not _USER_DIR: - from ._config import make_user_dir _USER_DIR = make_user_dir() return _USER_DIR @@ -36,7 +88,7 @@ def make_custom_config_path(): _CUSTOM_CONFIG = None def get_custom_config(): """ - Setup the custom config dir and cat file + Setup the custom config_system dir and cat file """ global _CUSTOM_CONFIG if not _CUSTOM_CONFIG: @@ -48,7 +100,7 @@ def get_custom_config(): _LOCAL_CONFIG = None def get_local_config(): """ - Loads the local config file. + Loads the local config_system file. """ global _LOCAL_CONFIG if not _LOCAL_CONFIG: diff --git a/src/sas/_config.py b/src/sas/_config.py index 7c998672eb..3941d08ee8 100644 --- a/src/sas/_config.py +++ b/src/sas/_config.py @@ -1,4 +1,4 @@ -# Setup and find Custom config dir +# Setup and find Custom config_system dir from __future__ import print_function import sys @@ -11,72 +11,14 @@ logger = logging.getLogger(__name__) -def dirn(path, n): - """ - Return the directory n up from the current path - """ - path = realpath(path) - for _ in range(n): - path = dirname(path) - return path - -def find_app_dir(): - """ - Locate the parent directory of the sasview resources. For the normal - application this will be the directory containing sasview.py. For the - frozen application this will be the path where the resources are installed. - """ - # We are starting out with the following info: - # __file__ = .../sas/__init__.pyc - # Check if the path .../sas/sasview exists, and use it as the - # app directory. This will only be the case if the app is not frozen. - path = joinpath(dirname(__file__), 'sasview') - if exists(path): - return path - - # If we are running frozen, then root is a parent directory - if sys.platform == 'darwin': - # Here is the path to the file on the mac: - # .../Sasview.app/Contents/Resources/lib/python2.7/site-packages.zip/sas/__init__.pyc - # We want the path to the Resources directory. - path = dirn(__file__, 5) - elif os.name == 'nt': - # Here is the path to the file on windows: - # ../Sasview/library.zip/sas/__init__.pyc - # We want the path to the Sasview directory. - path = dirn(__file__, 3) - else: - raise RuntimeError("Couldn't find the app directory") - return path - -def make_user_dir(): - """ - Create the user directory ~/.sasview if it doesn't already exist. - """ - path = joinpath(expanduser("~"),'.sasview') - if not exists(path): - os.mkdir(path) - return path - -def load_local_config(app_dir): - logger = logging.getLogger(__name__) - filename = 'local_config.py' - path = os.path.join(app_dir, filename) - try: - module = load_module_from_path('sas.local_config', path) - #logger.info("GuiManager loaded %s", path) - return module - except Exception as exc: - #logger.critical("Error loading %s: %s", path, exc) - sys.exit() def make_custom_config_path(user_dir): """ - The location of the cusstom config file. + The location of the cusstom config_system file. - Returns ~/.sasview/config/custom_config.py + Returns ~/.sasview/config_system/custom_config.py """ - dirname = os.path.join(user_dir, 'config') + dirname = os.path.join(user_dir, 'config_system') # If the directory doesn't exist, create it if not os.path.exists(dirname): os.makedirs(dirname) @@ -87,19 +29,19 @@ def setup_custom_config(app_dir, user_dir): path = make_custom_config_path(user_dir) if not os.path.isfile(path): try: - # if the custom config file does not exist, copy the default from + # if the custom config_system file does not exist, copy the default from # the app dir shutil.copyfile(os.path.join(app_dir, "custom_config.py"), path) except Exception: - logger.error("Could not copy default custom config.") + logger.error("Could not copy default custom config_system.") - #Adding SAS_OPENCL if it doesn't exist in the config file + #Adding SAS_OPENCL if it doesn't exist in the config_system file # - to support backcompability if not "SAS_OPENCL" in open(path).read(): try: open(path, "a+").write("SAS_OPENCL = \"None\"\n") except Exception: - logger.error("Could not update custom config with SAS_OPENCL.") + logger.error("Could not update custom config_system with SAS_OPENCL.") custom_config = load_custom_config(path) return custom_config diff --git a/src/sas/config_system/__init__.py b/src/sas/config_system/__init__.py new file mode 100644 index 0000000000..849193d2f9 --- /dev/null +++ b/src/sas/config_system/__init__.py @@ -0,0 +1,2 @@ +from sas.config_system.util import configuration + diff --git a/src/sas/config.py b/src/sas/config_system/config.py similarity index 91% rename from src/sas/config.py rename to src/sas/config_system/config.py index 7c26e9f45b..2514673aa3 100644 --- a/src/sas/config.py +++ b/src/sas/config_system/config.py @@ -1,7 +1,7 @@ """ Configuration class - stores configuration information for SasView The Config class cannot be subclassed or dynamically modified, -this prevents the config from having fields that are unspecified in +this prevents the config_system from having fields that are unspecified in the base class, and makes it so that all usages of fields can be automatically tracked. This allows the configs to be much more easily maintained. @@ -11,7 +11,7 @@ different configs difficult. """ -from config_meta import ConfigBase, ConfigMeta +from sas.config_system.config_meta import ConfigBase, ConfigMeta import sas.sasview import os @@ -159,6 +159,25 @@ def __init__(self): # OpenCL option self.SAS_OPENCL = None + self.DATAPANEL_WIDTH = -1 + self.CLEANUP_PLOT = False + self.FIXED_PANEL = True + self.PLOPANEL_WIDTH = -1 + self.DATALOADER_SHOW = True + self.GUIFRAME_HEIGHT = -1 + self.GUIFRAME_WIDTH = -1 + self.CONTROL_WIDTH = -1 + self.CONTROL_HEIGHT = -1 + self.DEFAULT_OPEN_FOLDER = None + self.WELCOME_PANEL_SHOW = False + self.TOOLBAR_SHOW = True + self.DEFAULT_PERSPECTIVE = "Fitting" + self.SAS_OPENCL = "None" + self.MARKETPLACE_URL = "http://marketplace.sasview.org/" + + # Logging options + self.FILTER_DEBUG_LOGS = True + # # Lock the class down # diff --git a/src/sas/config_meta.py b/src/sas/config_system/config_meta.py similarity index 75% rename from src/sas/config_meta.py rename to src/sas/config_system/config_meta.py index 1dc797fc6d..b224b50bdd 100644 --- a/src/sas/config_meta.py +++ b/src/sas/config_system/config_meta.py @@ -2,7 +2,7 @@ class ConfigLocked(Exception): def __init__(self): super().__init__(self, - "The Config class cannot be subclassed or added to dynamically, see config.py for details") + "The Config class cannot be subclassed or added to dynamically, see config_system.py for details") class ConfigMeta(type): @@ -21,7 +21,8 @@ def _lock(self): self._locked = True def __setattr__(self, key, value): - if key not in self.__dict__: - raise ConfigLocked() + if hasattr(self, "_locked") and self._locked: + if key not in self.__dict__: + raise ConfigLocked() super().__setattr__(key, value) \ No newline at end of file diff --git a/src/sas/config_system/default_config.yml b/src/sas/config_system/default_config.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/sas/config_system/schema.py b/src/sas/config_system/schema.py new file mode 100644 index 0000000000..8e2b21ea47 --- /dev/null +++ b/src/sas/config_system/schema.py @@ -0,0 +1 @@ +""" Code for verifying config files""" \ No newline at end of file diff --git a/src/sas/config_system/util.py b/src/sas/config_system/util.py new file mode 100644 index 0000000000..3d41ce7fc5 --- /dev/null +++ b/src/sas/config_system/util.py @@ -0,0 +1,28 @@ +from sas.config_system.config import Config + +import sys +import os +import os + +def get_config() -> Config: + return Config() + + + + + + + +def load_local_config(app_dir): + assert False + filename = 'local_config.py' + path = os.path.join(app_dir, filename) + try: + module = load_module_from_path('sas.local_config', path) + #logger.info("GuiManager loaded %s", path) + return module + except Exception as exc: + #logger.critical("Error loading %s: %s", path, exc) + sys.exit() + +configuration = get_config() \ No newline at end of file diff --git a/src/sas/logger_config.py b/src/sas/logger_config.py index 8a182c2b43..d77fd5f898 100644 --- a/src/sas/logger_config.py +++ b/src/sas/logger_config.py @@ -74,7 +74,7 @@ def _update_all_logs_to_debug(self, logger): def _find_config_file(self, filename="logging.ini"): ''' - The config file is in: + The config_system file is in: Debug ./sasview/ Packaging: sas/sasview/ Packaging / production does not work well with absolute paths diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index df49c2e2f1..5396bcf039 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1303,7 +1303,7 @@ def checkAnalysisOption(self, analysisMenuOption): def saveCustomConfig(self): """ - Save the config file based on current session values + Save the config_system file based on current session values """ # Load the current file config_content = GuiUtils.custom_config @@ -1316,7 +1316,7 @@ def saveCustomConfig(self): def customSavePaths(self, config_content): """ - Update the config module with current session paths + Update the config_system module with current session paths Returns True if update was done, False, otherwise """ changed = False @@ -1331,7 +1331,7 @@ def customSavePaths(self, config_content): def customSaveOpenCL(self, config_content): """ - Update the config module with current session OpenCL choice + Update the config_system module with current session OpenCL choice Returns True if update was done, False, otherwise """ changed = False diff --git a/src/sas/qtgui/Utilities/CategoryInstaller.py b/src/sas/qtgui/Utilities/CategoryInstaller.py index b2ee7c5418..420a17b4ab 100644 --- a/src/sas/qtgui/Utilities/CategoryInstaller.py +++ b/src/sas/qtgui/Utilities/CategoryInstaller.py @@ -29,7 +29,7 @@ def __init__(self): @staticmethod def _get_home_dir(): """ - returns the users sasview config dir + returns the users sasview config_system dir """ return os.path.join(os.path.expanduser("~"), ".sasview") diff --git a/src/sas/qtgui/Utilities/CustomDir.py b/src/sas/qtgui/Utilities/CustomDir.py index 1ac75f2123..755be02ab6 100755 --- a/src/sas/qtgui/Utilities/CustomDir.py +++ b/src/sas/qtgui/Utilities/CustomDir.py @@ -1,8 +1,8 @@ -# Setup and find Custom config dir +# Setup and find Custom config_system dir import os.path import shutil -CONF_DIR = 'config' +CONF_DIR = 'config_system' APPLICATION_NAME = 'sasview' def _find_usersasview_dir(): @@ -13,7 +13,7 @@ def _find_usersasview_dir(): def _find_customconf_dir(): """ - Find path of the config directory. + Find path of the config_system directory. The plugin directory is located in the user's home directory. """ u_dir = _find_usersasview_dir() @@ -21,7 +21,7 @@ def _find_customconf_dir(): def setup_conf_dir(path): """ - Setup the custom config dir and cat file + Setup the custom config_system dir and cat file """ conf_dir = _find_customconf_dir() # If the plugin directory doesn't exist, create it @@ -34,7 +34,7 @@ def setup_conf_dir(path): if not os.path.isfile(config_file): shutil.copyfile(os.path.join(path, "custom_config.py"), config_file) - #Adding SAS_OPENCL if it doesn't exist in the config file + #Adding SAS_OPENCL if it doesn't exist in the config_system file # - to support backcompability if not "SAS_OPENCL" in open(config_file).read(): open(config_file,"a+").write("SAS_OPENCL = \"None\"\n") diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 9122680b56..3843001f34 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -89,7 +89,7 @@ def get_app_dir(): # Finally, try the directory of the sasview module # TODO: gui_manager will have to know about sasview until we - # clean all these module variables and put them into a config class + # clean all these module variables and put them into a config_system class # that can be passed by sasview.py. # logging.info(sys.executable) # logging.info(str(sys.argv)) @@ -130,7 +130,7 @@ def _find_local_config(confg_file, path): # Get APP folder PATH_APP = get_app_dir() DATAPATH = PATH_APP -# Read in the local config, which can either be with the main +# Read in the local config_system, which can either be with the main # application or in the installation directory config = _find_local_config('local_config', PATH_APP) @@ -145,9 +145,9 @@ def _find_local_config(confg_file, path): custom_config = _find_local_config('custom_config', os.getcwd()) if custom_config is None: msgConfig = "Custom_config file was not imported" -logging.info("Custom config path: %s", custom_config) +logging.info("Custom config_system path: %s", custom_config) -#read some constants from config +#read some constants from config_system APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION APPLICATION_NAME = config.__appname__ SPLASH_SCREEN_PATH = config.SPLASH_SCREEN_PATH @@ -196,7 +196,7 @@ def _find_local_config(confg_file, path): DEFAULT_OPEN_FOLDER = PATH_APP SAS_OPENCL = config.SAS_OPENCL -#DEFAULT_STYLE = config.DEFAULT_STYLE +#DEFAULT_STYLE = config_system.DEFAULT_STYLE PLUGIN_STATE_EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS OPEN_SAVE_MENU = config.OPEN_SAVE_PROJECT_MENU From 2dd219b643321b41ef46c99542313189c2489f7e Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 19 Aug 2022 16:22:54 +0100 Subject: [PATCH 03/82] Reverted file name --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bb943bd132..3dda61e39f 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ #f_path = os.path.join(sas_dir, "categories.json") #if os.path.isfile(f_path): # os.remove(f_path) - f_path = os.path.join(sas_dir, 'config_system', "custom_config.py") + f_path = os.path.join(sas_dir, 'sasview', "custom_config.py") if os.path.isfile(f_path): os.remove(f_path) #f_path = os.path.join(sas_dir, 'plugin_models') From 64d665922d5d3121ff854cacedcf71f32e38ca7d Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 19 Aug 2022 16:49:44 +0100 Subject: [PATCH 04/82] Some migration to config object --- src/sas/__init__.py | 2 +- src/sas/config_system/config.py | 18 +++++++- src/sas/config_system/config_meta.py | 4 ++ src/sas/config_system/test_list | 6 +++ .../UnitTesting/DensityCalculatorTest.py | 1 - .../UnitTesting/SLDCalculatorTest.py | 2 - src/sas/qtgui/MainWindow/AboutBox.py | 31 +++++++------- src/sas/qtgui/MainWindow/Acknowledgements.py | 15 +------ src/sas/qtgui/MainWindow/GuiManager.py | 15 +++---- .../MainWindow/UnitTesting/AboutBoxTest.py | 41 +++++++++---------- .../Perspectives/Fitting/ConstraintWidget.py | 7 ++-- .../Fitting/UnitTesting/FittingWidgetTest.py | 1 - 12 files changed, 77 insertions(+), 66 deletions(-) create mode 100644 src/sas/config_system/test_list diff --git a/src/sas/__init__.py b/src/sas/__init__.py index 26ef2d96d1..b44e2587fa 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -3,7 +3,7 @@ from sas.config_system import configuration as config __all__ = ['get_app_dir', 'get_user_dir', - 'get_local_config', 'get_custom_config'] + 'get_local_config', 'get_custom_config', 'config'] _APP_DIR = None def get_app_dir(): diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 2514673aa3..6b00688c4f 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -16,6 +16,7 @@ import sas.sasview import os import time +import logging class Config(ConfigBase, metaclass=ConfigMeta): @@ -97,13 +98,17 @@ def __init__(self): self._ess_url = "https://europeanspallationsource.se/" self._ill_url = "https://www.ill.eu/" self._ansto_url = "https://www.ansto.gov.au/" + self._bam_url = "http://www.bam.de/" self._tudelft_url = "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" + self._delft_url = "http://www.tudelft.nl/en/tnw/business/facilities/reactor-instituut-delft/" self._dls_url = "https://www.diamond.ac.uk/" self._danse_url = "https://www.its.caltech.edu/~matsci/btf/DANSE_web_page.html" self._inst_url = "https://www.utk.edu" + self._diamond_url = "http://www.diamond.ac.uk" self._corner_image = os.path.join(self.icon_path, "angles_flat.png") self._welcome_image = os.path.join(self.icon_path, "SVwelcome.png") - self._copyright = "(c) 2009 - 2022, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft and DLS" + # self._copyright = "(c) 2009 - 2022, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft and DLS" + self._copyright = "Copyright (c) 2009-2022 UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, TUD, BAM and ANSTO" self.marketplace_url = "http://marketplace.sasview.org/" # edit the list of file state your plugin can read @@ -178,6 +183,17 @@ def __init__(self): # Logging options self.FILTER_DEBUG_LOGS = True + # Default threading model + self.USING_TWISTED = False + + # Time out for updating sasview + self.UPDATE_TIMEOUT = 2 + + # Logging levels to disable, if any + self.DISABLE_LOGGING = logging.NOTSET + + # Location of the marketplace + # # Lock the class down # diff --git a/src/sas/config_system/config_meta.py b/src/sas/config_system/config_meta.py index b224b50bdd..9e5303ad40 100644 --- a/src/sas/config_system/config_meta.py +++ b/src/sas/config_system/config_meta.py @@ -20,6 +20,10 @@ def __init__(self): def _lock(self): self._locked = True + def save(self): + #TODO: Implement save functionality to yaml (and load, with schema) + raise NotImplementedError() + def __setattr__(self, key, value): if hasattr(self, "_locked") and self._locked: if key not in self.__dict__: diff --git a/src/sas/config_system/test_list b/src/sas/config_system/test_list new file mode 100644 index 0000000000..0c95744325 --- /dev/null +++ b/src/sas/config_system/test_list @@ -0,0 +1,6 @@ +Places where config has been replaced + +AboutBox +GuiManger save state +DensityCalculatorTest +AboutBoxTest \ No newline at end of file diff --git a/src/sas/qtgui/Calculators/UnitTesting/DensityCalculatorTest.py b/src/sas/qtgui/Calculators/UnitTesting/DensityCalculatorTest.py index 0015d2c20d..e5e7f70f5d 100644 --- a/src/sas/qtgui/Calculators/UnitTesting/DensityCalculatorTest.py +++ b/src/sas/qtgui/Calculators/UnitTesting/DensityCalculatorTest.py @@ -16,7 +16,6 @@ from sas.qtgui.Calculators.DensityPanel import toMolarMass from sas.qtgui.Utilities.GuiUtils import FormulaValidator -import sas.qtgui.Utilities.LocalConfig if not QtWidgets.QApplication.instance(): app = QtWidgets.QApplication(sys.argv) diff --git a/src/sas/qtgui/Calculators/UnitTesting/SLDCalculatorTest.py b/src/sas/qtgui/Calculators/UnitTesting/SLDCalculatorTest.py index 4a46bac20e..07178f3e8f 100644 --- a/src/sas/qtgui/Calculators/UnitTesting/SLDCalculatorTest.py +++ b/src/sas/qtgui/Calculators/UnitTesting/SLDCalculatorTest.py @@ -17,8 +17,6 @@ from sas.qtgui.Calculators.SldPanel import neutronSldAlgorithm, xraySldAlgorithm from sas.qtgui.Utilities.GuiUtils import FormulaValidator -import sas.qtgui.Utilities.LocalConfig - if not QtWidgets.QApplication.instance(): app = QtWidgets.QApplication(sys.argv) diff --git a/src/sas/qtgui/MainWindow/AboutBox.py b/src/sas/qtgui/MainWindow/AboutBox.py index 5c3ef63ab6..a9f134e3b5 100644 --- a/src/sas/qtgui/MainWindow/AboutBox.py +++ b/src/sas/qtgui/MainWindow/AboutBox.py @@ -2,11 +2,12 @@ from PyQt5 import QtWidgets, QtCore import sas.sasview -import sas.qtgui.Utilities.LocalConfig as LocalConfig import sas.qtgui.Utilities.GuiUtils as GuiUtils from sas.qtgui.UI import images_rc from sas.qtgui.UI import main_resources_rc +from sas import config + from .UI.AboutUI import Ui_AboutUI class AboutBox(QtWidgets.QDialog, Ui_AboutUI): @@ -33,12 +34,12 @@ def addText(self): lbl_font.setPointSize(24) self.lblVersion.setFont(lbl_font) about_text = r'

' - about_text += '

Build ' + str(LocalConfig.__build__) +'

' - about_text += '

' + LocalConfig._copyright + '

' + about_text += '

Build ' + str(config.__build__) +'

' + about_text += '

' + config._copyright + '

' about_text += r'

http://www.sasview.org


' about_text += '

Comments? Bugs? Requests?
' about_text += r'Send us a ticket


' - about_text += r'


' self.lblAbout.setText(about_text) @@ -50,26 +51,26 @@ def addActions(self): Add actions to the logo push buttons """ self.cmdLinkUT.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._inst_url)) + GuiUtils.openLink, config._inst_url)) self.cmdLinkUMD.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._umd_url)) + GuiUtils.openLink, config._umd_url)) self.cmdLinkNIST.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._nist_url)) + GuiUtils.openLink, config._nist_url)) self.cmdLinkSNS.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._sns_url)) + GuiUtils.openLink, config._sns_url)) self.cmdLinkISIS.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._isis_url)) + GuiUtils.openLink, config._isis_url)) self.cmdLinkESS.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._ess_url)) + GuiUtils.openLink, config._ess_url)) self.cmdLinkILL.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._ill_url)) + GuiUtils.openLink, config._ill_url)) self.cmdLinkANSTO.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._ansto_url)) + GuiUtils.openLink, config._ansto_url)) self.cmdLinkBAM.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._bam_url)) + GuiUtils.openLink, config._bam_url)) self.cmdLinkDELFT.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._delft_url)) + GuiUtils.openLink, config._delft_url)) self.cmdLinkDIAMOND.clicked.connect(functools.partial( - GuiUtils.openLink, LocalConfig._diamond_url)) + GuiUtils.openLink, config._diamond_url)) self.cmdOK.clicked.connect(self.close) diff --git a/src/sas/qtgui/MainWindow/Acknowledgements.py b/src/sas/qtgui/MainWindow/Acknowledgements.py index 38f05e8488..e14f41cc05 100644 --- a/src/sas/qtgui/MainWindow/Acknowledgements.py +++ b/src/sas/qtgui/MainWindow/Acknowledgements.py @@ -2,14 +2,11 @@ from PyQt5 import QtWidgets, QtCore import sas.sasview -import sas.qtgui.Utilities.LocalConfig as LocalConfig -import sas.qtgui.Utilities.GuiUtils as GuiUtils -from sas.qtgui.UI import images_rc -from sas.qtgui.UI import main_resources_rc from .UI.AcknowledgementsUI import Ui_Acknowledgements class Acknowledgements(QtWidgets.QDialog, Ui_Acknowledgements): + def __init__(self, parent=None): super(Acknowledgements, self).__init__(parent) self.setupUi(self) @@ -18,8 +15,6 @@ def __init__(self, parent=None): self.addText() - #self.addActions() - def addText(self): """ Modify the labels so the text corresponds to the current version @@ -33,11 +28,3 @@ def addText(self): self.textBrowser.setText(acknowledgement_text_1) acknowledgement_text_2 = 'M. Doucet et al. SasView Version ' + str(version) + ', ' + str(doi) self.textBrowser_2.setText(acknowledgement_text_2) - - - # def addActions(self): - # """ - # Add actions to the logo push buttons - # """ - # - # self.cmdOK.clicked.connect(self.close) diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 5396bcf039..53ce0d3b89 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -67,6 +67,8 @@ from sas.qtgui.Utilities.ImageViewer import ImageViewer from sas.qtgui.Utilities.FileConverter import FileConverterWidget +from sas import config + logger = logging.getLogger(__name__) @@ -599,13 +601,8 @@ def showWelcomeMessage(self): """ Show the Welcome panel, when required """ # Assure the welcome screen is requested show_welcome_widget = True - custom_config = get_custom_config() - if hasattr(custom_config, "WELCOME_PANEL_SHOW"): - if isinstance(custom_config.WELCOME_PANEL_SHOW, bool): - show_welcome_widget = custom_config.WELCOME_PANEL_SHOW - else: - logging.warning("WELCOME_PANEL_SHOW has invalid value in custom_config.py") - if show_welcome_widget: + + if config.WELCOME_PANEL_SHOW: self.actionWelcome() def addCallbacks(self): @@ -1305,6 +1302,10 @@ def saveCustomConfig(self): """ Save the config_system file based on current session values """ + + config.save() + return + # Load the current file config_content = GuiUtils.custom_config diff --git a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py index 7e63021634..869b77ba38 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py @@ -7,12 +7,11 @@ from PyQt5 import QtCore from unittest.mock import MagicMock -# set up import paths -import path_prepare +from sas import config + # Local from sas.qtgui.MainWindow.AboutBox import AboutBox -import sas.qtgui.Utilities.LocalConfig as LocalConfig if not QtWidgets.QApplication.instance(): app = QtWidgets.QApplication(sys.argv) @@ -45,7 +44,7 @@ def testVersion(self): """ version = self.widget.lblVersion self.assertIsInstance(version, QtWidgets.QLabel) - self.assertEqual(str(version.text()), str(LocalConfig.__version__)) + self.assertEqual(str(version.text()), str(config.__version__)) def testAbout(self): """ @@ -54,13 +53,13 @@ def testAbout(self): about = self.widget.lblAbout self.assertIsInstance(about, QtWidgets.QLabel) # build version - self.assertIn(str(LocalConfig.__build__), about.text()) + self.assertIn(str(config.__build__), about.text()) # License - self.assertIn(str(LocalConfig._copyright), about.text()) + self.assertIn(str(config._copyright), about.text()) # URLs - self.assertIn(str(LocalConfig._homepage), about.text()) - self.assertIn(str(LocalConfig.__download_page__), about.text()) - self.assertIn(str(LocalConfig._license), about.text()) + self.assertIn(str(config._homepage), about.text()) + self.assertIn(str(config.__download_page__), about.text()) + self.assertIn(str(config._license), about.text()) # Are links enabled? self.assertTrue(about.openExternalLinks()) @@ -71,18 +70,18 @@ def testAddActions(self): """ webbrowser.open = MagicMock() all_hosts = [ - LocalConfig._nist_url, - LocalConfig._umd_url, - LocalConfig._sns_url, - LocalConfig._nsf_url, - LocalConfig._isis_url, - LocalConfig._ess_url, - LocalConfig._ill_url, - LocalConfig._ansto_url, - LocalConfig._inst_url, - LocalConfig._delft_url, - LocalConfig._bam_url, - LocalConfig._diamond_url] + config._nist_url, + config._umd_url, + config._sns_url, + config._nsf_url, + config._isis_url, + config._ess_url, + config._ill_url, + config._ansto_url, + config._inst_url, + config._delft_url, + config._bam_url, + config._diamond_url] # Press the buttons buttonList = self.widget.findChildren(QtWidgets.QPushButton) diff --git a/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py b/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py index fdcb33cb63..1a1d0dbd5f 100644 --- a/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py +++ b/src/sas/qtgui/Perspectives/Fitting/ConstraintWidget.py @@ -5,7 +5,6 @@ from twisted.internet import threads import sas.qtgui.Utilities.GuiUtils as GuiUtils -import sas.qtgui.Utilities.LocalConfig as LocalConfig from PyQt5 import QtGui, QtCore, QtWidgets @@ -20,6 +19,8 @@ from sas.qtgui.Perspectives.Fitting import FittingUtilities from sas.qtgui.Perspectives.Fitting.Constraint import Constraint +from sas import config + logger = logging.getLogger(__name__) class DnDTableWidget(QtWidgets.QTableWidget): @@ -348,7 +349,7 @@ def onFit(self): # Create the fitting thread, based on the fitter completefn = self.onBatchFitComplete if self.currentType=='BatchPage' else self.onFitComplete - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: handler = None updater = None else: @@ -373,7 +374,7 @@ def onFit(self): completefn=completefn, reset_flag=self.is_chain_fitting) - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: # start the trhrhread with twisted self.calc_fit = threads.deferToThread(self.calc_fit.compute) self.calc_fit.addCallback(completefn) diff --git a/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py b/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py index 5c1cad5c03..3e27c36f24 100644 --- a/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py +++ b/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py @@ -20,7 +20,6 @@ from sas.qtgui.Utilities.GuiUtils import * from sas.qtgui.Perspectives.Fitting.FittingWidget import * from sas.qtgui.Perspectives.Fitting.Constraint import Constraint -import sas.qtgui.Utilities.LocalConfig from sas.qtgui.UnitTesting.TestUtils import QtSignalSpy from sas.qtgui.Perspectives.Fitting.ModelThread import Calc1D from sas.qtgui.Perspectives.Fitting.ModelThread import Calc2D From 32d2ab18410ddae1c97118e2313504b465e2e662 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 19 Aug 2022 17:11:15 +0100 Subject: [PATCH 05/82] More migration --- src/sas/config_system/test_list | 6 +++++- src/sas/qtgui/MainWindow/GuiManager.py | 14 ++++++-------- .../qtgui/MainWindow/UnitTesting/GuiManagerTest.py | 2 +- src/sas/qtgui/MainWindow/WelcomePanel.py | 5 +++-- .../qtgui/Perspectives/Fitting/FittingWidget.py | 13 ++++++------- src/sas/qtgui/Perspectives/Fitting/ModelThread.py | 6 +++--- .../Fitting/UnitTesting/FittingWidgetTest.py | 2 +- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/sas/config_system/test_list b/src/sas/config_system/test_list index 0c95744325..fdb8513cbb 100644 --- a/src/sas/config_system/test_list +++ b/src/sas/config_system/test_list @@ -3,4 +3,8 @@ Places where config has been replaced AboutBox GuiManger save state DensityCalculatorTest -AboutBoxTest \ No newline at end of file +AboutBoxTest +WelcomePanel +ModelThread.Calc2D +FittingWidget +FittingWidgetTest \ No newline at end of file diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 53ce0d3b89..b2ee8f9e2a 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -19,11 +19,9 @@ from twisted.internet import reactor # General SAS imports -from sas import get_custom_config from sas.qtgui.Utilities.ConnectionProxy import ConnectionProxy from sas.qtgui.Utilities.SasviewLogger import setup_qt_logging -import sas.qtgui.Utilities.LocalConfig as LocalConfig import sas.qtgui.Utilities.GuiUtils as GuiUtils import sas.qtgui.Utilities.ObjectLibrary as ObjectLibrary @@ -178,7 +176,7 @@ def addWidgets(self): self.results_frame.setVisible(False) self.results_panel.windowClosedSignal.connect(lambda: self.results_frame.setVisible(False)) - self._workspace.toolBar.setVisible(LocalConfig.TOOLBAR_SHOW) + self._workspace.toolBar.setVisible(config.TOOLBAR_SHOW) self._workspace.actionHide_Toolbar.setText("Show Toolbar") # Add calculators - floating for usability @@ -531,7 +529,7 @@ def checkUpdate(self): a call-back method when the current version number has been obtained. """ version_info = {"version": "0.0.0"} - c = ConnectionProxy(LocalConfig.__update_URL__, LocalConfig.UPDATE_TIMEOUT) + c = ConnectionProxy(config.__update_URL__, config.UPDATE_TIMEOUT) response = c.connect() if response is None: return @@ -572,16 +570,16 @@ def processVersion(self, version_info): msg += " Please try again later." self.communicate.statusBarUpdateSignal.emit(msg) - elif version.__gt__(LocalConfig.__version__): + elif version.__gt__(config.__version__): msg = "Version %s is available! " % str(version) if "download_url" in version_info: webbrowser.open(version_info["download_url"]) else: - webbrowser.open(LocalConfig.__download_page__) + webbrowser.open(config.__download_page__) self.communicate.statusBarUpdateSignal.emit(msg) else: msg = "You have the latest version" - msg += " of %s" % str(LocalConfig.__appname__) + msg += " of %s" % str(config.__appname__) self.communicate.statusBarUpdateSignal.emit(msg) except: msg = "guiframe: could not get latest application" @@ -1214,7 +1212,7 @@ def actionMarketplace(self): """ Open the marketplace link in default browser """ - url = LocalConfig.MARKETPLACE_URL + url = config.MARKETPLACE_URL webbrowser.open_new(url) def actionAbout(self): diff --git a/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py b/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py index 1e4f626506..48a01eb0a4 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py @@ -170,7 +170,7 @@ def testProcessVersion(self): message = 'Could not connect to the application server. Please try again later.' self.assertIn(message, str(spy_status_update.signal(index=0))) - # 2. version < LocalConfig.__version__ + # 2. version < config.__version__ version_info = {'version' : '0.0.1'} spy_status_update = QtSignalSpy(self.manager, self.manager.communicate.statusBarUpdateSignal) diff --git a/src/sas/qtgui/MainWindow/WelcomePanel.py b/src/sas/qtgui/MainWindow/WelcomePanel.py index 10fba0a9ef..5aa74026a9 100644 --- a/src/sas/qtgui/MainWindow/WelcomePanel.py +++ b/src/sas/qtgui/MainWindow/WelcomePanel.py @@ -1,7 +1,8 @@ from PyQt5 import QtWidgets import sas.sasview -import sas.qtgui.Utilities.LocalConfig as LocalConfig + +from sas import config from sas.qtgui.MainWindow.UI.WelcomePanelUI import Ui_WelcomePanelUI @@ -15,7 +16,7 @@ def __init__(self, parent=None): version = sas.sasview.__version__ build = sas.sasview.__build__ - ver = "\nSasView %s\nBuild: %s\n%s" % (version, build, LocalConfig._copyright) + ver = "\nSasView %s\nBuild: %s\n%s" % (version, build, config._copyright) self.lblVersion.setText(ver) diff --git a/src/sas/qtgui/Perspectives/Fitting/FittingWidget.py b/src/sas/qtgui/Perspectives/Fitting/FittingWidget.py index df4652d555..7c35e04f0e 100644 --- a/src/sas/qtgui/Perspectives/Fitting/FittingWidget.py +++ b/src/sas/qtgui/Perspectives/Fitting/FittingWidget.py @@ -2,6 +2,7 @@ import os import sys from collections import defaultdict +from typing import Any, Tuple import copy import logging @@ -20,12 +21,11 @@ from sasmodels.sasview_model import MultiplicationModel from sasmodels.weights import MODELS as POLYDISPERSITY_MODELS +from sas import config from sas.sascalc.fit.BumpsFitting import BumpsFit as Fit -from sas.sascalc.fit.pagestate import PageState from sas.sascalc.fit import models import sas.qtgui.Utilities.GuiUtils as GuiUtils -import sas.qtgui.Utilities.LocalConfig as LocalConfig from sas.qtgui.Utilities.CategoryInstaller import CategoryInstaller from sas.qtgui.Plotting.PlotterData import Data1D from sas.qtgui.Plotting.PlotterData import Data2D @@ -65,11 +65,10 @@ # https://github.com/SasView/sasview/pull/181#discussion_r218135162 from sasmodels.sasview_model import SasviewModel if not hasattr(SasviewModel, 'get_weights'): - def get_weights(self, name): + def get_weights(self: Any, name: str) -> Tuple[np.ndarray, np.ndarray]: """ Returns the polydispersity distribution for parameter *name* as *value* and *weight* arrays. """ - # type: (str) -> Tuple(np.ndarray, np.ndarray) _, x, w = self._get_weights(self._model_info.parameters[name]) return x, w @@ -1664,7 +1663,7 @@ def onFit(self): batch_inputs = {} batch_outputs = {} #--------------------------------- - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: handler = None updater = None else: @@ -1696,7 +1695,7 @@ def onFit(self): completefn=completefn, reset_flag=self.is_chain_fitting) - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: # start the trhrhread with twisted calc_thread = threads.deferToThread(self.calc_fit.compute) calc_thread.addCallback(completefn) @@ -2900,7 +2899,7 @@ def calculateQGridForModelExt(self, data=None, model=None, completefn=None, use_ exception_handler=self.calcException, source=None) if use_threads: - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: # start the thread with twisted thread = threads.deferToThread(calc_thread.compute) thread.addCallback(completefn) diff --git a/src/sas/qtgui/Perspectives/Fitting/ModelThread.py b/src/sas/qtgui/Perspectives/Fitting/ModelThread.py index eacbdc5350..dd992d4ea5 100644 --- a/src/sas/qtgui/Perspectives/Fitting/ModelThread.py +++ b/src/sas/qtgui/Perspectives/Fitting/ModelThread.py @@ -7,7 +7,7 @@ import math from sas.sascalc.data_util.calcthread import CalcThread from sas.sascalc.fit.MultiplicationModel import MultiplicationModel -import sas.qtgui.Utilities.LocalConfig as LocalConfig +from sas import config class Calc2D(CalcThread): """ @@ -108,7 +108,7 @@ def compute(self): weight = self.weight, update_chisqr = self.update_chisqr, source = self.source) - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: return res else: self.completefn(res) @@ -263,7 +263,7 @@ def compute(self): unsmeared_data = unsmeared_data, unsmeared_error = unsmeared_error, intermediate_results = intermediate_results) - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: return res else: self.completefn(res) diff --git a/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py b/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py index 3e27c36f24..e3105b8df4 100644 --- a/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py +++ b/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py @@ -427,7 +427,7 @@ def testCalculateQGridForModel(self): Check that the fitting 1D data object is ready """ - if LocalConfig.USING_TWISTED: + if config.USING_TWISTED: # Mock the thread creation threads.deferToThread = MagicMock() # Model for theory From a5962b56743592a624f67a48bc26dd88d57ec547 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 31 Aug 2022 10:44:34 +0100 Subject: [PATCH 06/82] Undid erronious substitutions: config -> config_system --- docs/sphinx-docs/source/_extensions/mathjax.py | 7 +++---- docs/sphinx-docs/source/conf.py | 2 +- installers/installer_generator.py | 2 +- installers/installer_generator64.py | 2 +- src/sas/__init__.py | 4 ++-- src/sas/_config.py | 16 ++++++++-------- src/sas/config_system/config.py | 2 +- src/sas/config_system/config_meta.py | 2 +- src/sas/logger_config.py | 2 +- src/sas/qtgui/MainWindow/GuiManager.py | 6 +++--- src/sas/qtgui/Utilities/CategoryInstaller.py | 2 +- src/sas/qtgui/Utilities/CustomDir.py | 10 +++++----- src/sas/qtgui/Utilities/GuiUtils.py | 10 +++++----- 13 files changed, 33 insertions(+), 34 deletions(-) diff --git a/docs/sphinx-docs/source/_extensions/mathjax.py b/docs/sphinx-docs/source/_extensions/mathjax.py index 505388a29f..ecec479128 100644 --- a/docs/sphinx-docs/source/_extensions/mathjax.py +++ b/docs/sphinx-docs/source/_extensions/mathjax.py @@ -81,10 +81,10 @@ def html_visit_displaymath(self, node): def builder_inited(app): jaxpath = app.config.mathjax_path if not jaxpath: - raise ExtensionError('mathjax_path config_system value must be set for the ' + raise ExtensionError('mathjax_path config value must be set for the ' 'mathjax extension to work') - # app.config_system.mathjax_path can be a string or a list of strings + # app.config.mathjax_path can be a string or a list of strings if isinstance(jaxpath, basestring): app.add_javascript(jaxpath) else: @@ -105,8 +105,7 @@ def setup(app): # http://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn app.add_config_value('mathjax_path', 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?' - 'config_system=TeX-MML-AM_CHTML', - #'config_system=TeX-AMS-MML_HTMLorMML', + 'config=TeX-MML-AM_CHTML', False) app.add_config_value('mathjax_css', None, 'html') app.add_config_value('mathjax_use_katex', False, 'html') diff --git a/docs/sphinx-docs/source/conf.py b/docs/sphinx-docs/source/conf.py index b7649bfea0..f695e6dfff 100644 --- a/docs/sphinx-docs/source/conf.py +++ b/docs/sphinx-docs/source/conf.py @@ -41,7 +41,7 @@ mathjax_path = ( 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?' - 'config_system=TeX-MML-AM_CHTML') + 'config=TeX-MML-AM_CHTML') # For katex uncomment the following """ diff --git a/installers/installer_generator.py b/installers/installer_generator.py index 03bd5aae1d..17cd4f4f8e 100644 --- a/installers/installer_generator.py +++ b/installers/installer_generator.py @@ -1,5 +1,5 @@ """ -This module generates .iss file according to the local config_system of +This module generates .iss file according to the local config of the current application. Please make sure a file named "local_config.py" exists in the current directory. Edit local_config.py according to your needs. """ diff --git a/installers/installer_generator64.py b/installers/installer_generator64.py index 6547593980..aae6b20647 100644 --- a/installers/installer_generator64.py +++ b/installers/installer_generator64.py @@ -1,5 +1,5 @@ """ -This module generates .iss file according to the local config_system of +This module generates .iss file according to the local config of the current application. Please make sure a file named "local_config.py" exists in the current directory. Edit local_config.py according to your needs. """ diff --git a/src/sas/__init__.py b/src/sas/__init__.py index b44e2587fa..3d38a44cb0 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -88,7 +88,7 @@ def make_custom_config_path(): _CUSTOM_CONFIG = None def get_custom_config(): """ - Setup the custom config_system dir and cat file + Setup the custom config dir and cat file """ global _CUSTOM_CONFIG if not _CUSTOM_CONFIG: @@ -100,7 +100,7 @@ def get_custom_config(): _LOCAL_CONFIG = None def get_local_config(): """ - Loads the local config_system file. + Loads the local config file. """ global _LOCAL_CONFIG if not _LOCAL_CONFIG: diff --git a/src/sas/_config.py b/src/sas/_config.py index 3941d08ee8..d6805d65a9 100644 --- a/src/sas/_config.py +++ b/src/sas/_config.py @@ -1,4 +1,4 @@ -# Setup and find Custom config_system dir +# Setup and find Custom config dir from __future__ import print_function import sys @@ -14,11 +14,11 @@ def make_custom_config_path(user_dir): """ - The location of the cusstom config_system file. + The location of the cusstom config file. - Returns ~/.sasview/config_system/custom_config.py + Returns ~/.sasview/config/custom_config.py """ - dirname = os.path.join(user_dir, 'config_system') + dirname = os.path.join(user_dir, 'config') # If the directory doesn't exist, create it if not os.path.exists(dirname): os.makedirs(dirname) @@ -29,19 +29,19 @@ def setup_custom_config(app_dir, user_dir): path = make_custom_config_path(user_dir) if not os.path.isfile(path): try: - # if the custom config_system file does not exist, copy the default from + # if the custom config file does not exist, copy the default from # the app dir shutil.copyfile(os.path.join(app_dir, "custom_config.py"), path) except Exception: - logger.error("Could not copy default custom config_system.") + logger.error("Could not copy default custom config.") - #Adding SAS_OPENCL if it doesn't exist in the config_system file + #Adding SAS_OPENCL if it doesn't exist in the config file # - to support backcompability if not "SAS_OPENCL" in open(path).read(): try: open(path, "a+").write("SAS_OPENCL = \"None\"\n") except Exception: - logger.error("Could not update custom config_system with SAS_OPENCL.") + logger.error("Could not update custom config with SAS_OPENCL.") custom_config = load_custom_config(path) return custom_config diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 6b00688c4f..ca42cd7f7e 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -1,7 +1,7 @@ """ Configuration class - stores configuration information for SasView The Config class cannot be subclassed or dynamically modified, -this prevents the config_system from having fields that are unspecified in +this prevents the config from having fields that are unspecified in the base class, and makes it so that all usages of fields can be automatically tracked. This allows the configs to be much more easily maintained. diff --git a/src/sas/config_system/config_meta.py b/src/sas/config_system/config_meta.py index 9e5303ad40..ccbcd7ce56 100644 --- a/src/sas/config_system/config_meta.py +++ b/src/sas/config_system/config_meta.py @@ -2,7 +2,7 @@ class ConfigLocked(Exception): def __init__(self): super().__init__(self, - "The Config class cannot be subclassed or added to dynamically, see config_system.py for details") + "The Config class cannot be subclassed or added to dynamically, see config.py for details") class ConfigMeta(type): diff --git a/src/sas/logger_config.py b/src/sas/logger_config.py index d77fd5f898..8a182c2b43 100644 --- a/src/sas/logger_config.py +++ b/src/sas/logger_config.py @@ -74,7 +74,7 @@ def _update_all_logs_to_debug(self, logger): def _find_config_file(self, filename="logging.ini"): ''' - The config_system file is in: + The config file is in: Debug ./sasview/ Packaging: sas/sasview/ Packaging / production does not work well with absolute paths diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index b2ee8f9e2a..44fd524d0e 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1298,7 +1298,7 @@ def checkAnalysisOption(self, analysisMenuOption): def saveCustomConfig(self): """ - Save the config_system file based on current session values + Save the config file based on current session values """ config.save() @@ -1315,7 +1315,7 @@ def saveCustomConfig(self): def customSavePaths(self, config_content): """ - Update the config_system module with current session paths + Update the config module with current session paths Returns True if update was done, False, otherwise """ changed = False @@ -1330,7 +1330,7 @@ def customSavePaths(self, config_content): def customSaveOpenCL(self, config_content): """ - Update the config_system module with current session OpenCL choice + Update the config module with current session OpenCL choice Returns True if update was done, False, otherwise """ changed = False diff --git a/src/sas/qtgui/Utilities/CategoryInstaller.py b/src/sas/qtgui/Utilities/CategoryInstaller.py index 420a17b4ab..b2ee7c5418 100644 --- a/src/sas/qtgui/Utilities/CategoryInstaller.py +++ b/src/sas/qtgui/Utilities/CategoryInstaller.py @@ -29,7 +29,7 @@ def __init__(self): @staticmethod def _get_home_dir(): """ - returns the users sasview config_system dir + returns the users sasview config dir """ return os.path.join(os.path.expanduser("~"), ".sasview") diff --git a/src/sas/qtgui/Utilities/CustomDir.py b/src/sas/qtgui/Utilities/CustomDir.py index 755be02ab6..92c8f64d8a 100755 --- a/src/sas/qtgui/Utilities/CustomDir.py +++ b/src/sas/qtgui/Utilities/CustomDir.py @@ -1,8 +1,8 @@ -# Setup and find Custom config_system dir +# Setup and find Custom config dir import os.path import shutil -CONF_DIR = 'config_system' +CONF_DIR = 'config' APPLICATION_NAME = 'sasview' def _find_usersasview_dir(): @@ -13,7 +13,7 @@ def _find_usersasview_dir(): def _find_customconf_dir(): """ - Find path of the config_system directory. + Find path of the config directory. The plugin directory is located in the user's home directory. """ u_dir = _find_usersasview_dir() @@ -21,7 +21,7 @@ def _find_customconf_dir(): def setup_conf_dir(path): """ - Setup the custom config_system dir and cat file + Setup the custom config dir and cat file """ conf_dir = _find_customconf_dir() # If the plugin directory doesn't exist, create it @@ -34,7 +34,7 @@ def setup_conf_dir(path): if not os.path.isfile(config_file): shutil.copyfile(os.path.join(path, "custom_config.py"), config_file) - #Adding SAS_OPENCL if it doesn't exist in the config_system file + #Adding SAS_OPENCL if it doesn't exist in the config file # - to support backcompability if not "SAS_OPENCL" in open(config_file).read(): open(config_file,"a+").write("SAS_OPENCL = \"None\"\n") diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 3843001f34..9122680b56 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -89,7 +89,7 @@ def get_app_dir(): # Finally, try the directory of the sasview module # TODO: gui_manager will have to know about sasview until we - # clean all these module variables and put them into a config_system class + # clean all these module variables and put them into a config class # that can be passed by sasview.py. # logging.info(sys.executable) # logging.info(str(sys.argv)) @@ -130,7 +130,7 @@ def _find_local_config(confg_file, path): # Get APP folder PATH_APP = get_app_dir() DATAPATH = PATH_APP -# Read in the local config_system, which can either be with the main +# Read in the local config, which can either be with the main # application or in the installation directory config = _find_local_config('local_config', PATH_APP) @@ -145,9 +145,9 @@ def _find_local_config(confg_file, path): custom_config = _find_local_config('custom_config', os.getcwd()) if custom_config is None: msgConfig = "Custom_config file was not imported" -logging.info("Custom config_system path: %s", custom_config) +logging.info("Custom config path: %s", custom_config) -#read some constants from config_system +#read some constants from config APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION APPLICATION_NAME = config.__appname__ SPLASH_SCREEN_PATH = config.SPLASH_SCREEN_PATH @@ -196,7 +196,7 @@ def _find_local_config(confg_file, path): DEFAULT_OPEN_FOLDER = PATH_APP SAS_OPENCL = config.SAS_OPENCL -#DEFAULT_STYLE = config_system.DEFAULT_STYLE +#DEFAULT_STYLE = config.DEFAULT_STYLE PLUGIN_STATE_EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS OPEN_SAVE_MENU = config.OPEN_SAVE_PROJECT_MENU From b04b37014d7f8e7f863f5fe73844102f868e20e1 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 31 Aug 2022 10:56:26 +0100 Subject: [PATCH 07/82] Added tempory package to setup.py --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index 3dda61e39f..ecf70ec2f7 100644 --- a/setup.py +++ b/setup.py @@ -289,6 +289,9 @@ def run(self): ] packages.append("sas.qtgui") +package_data["sas.config_system"] = ["*"] +packages.append("sas.config_system") + required = [ 'bumps>=0.7.5.9', 'periodictable>=1.5.0', 'pyparsing>=2.0.0', 'lxml', 'h5py', From 19b3fd628d00e0e822f9010af11383a02db815c9 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 31 Aug 2022 11:53:20 +0100 Subject: [PATCH 08/82] Removed local_config.py --- installers/installer_generator.py | 37 ++++--- installers/installer_generator64.py | 36 +++---- src/sas/config_system/util.py | 18 ---- src/sas/qtgui/Utilities/GuiUtils.py | 13 ++- src/sas/sasview/local_config.py | 161 ---------------------------- 5 files changed, 43 insertions(+), 222 deletions(-) delete mode 100644 src/sas/sasview/local_config.py diff --git a/installers/installer_generator.py b/installers/installer_generator.py index 17cd4f4f8e..9fd6f40192 100644 --- a/installers/installer_generator.py +++ b/installers/installer_generator.py @@ -1,7 +1,6 @@ """ This module generates .iss file according to the local config of -the current application. Please make sure a file named "local_config.py" -exists in the current directory. Edit local_config.py according to your needs. +the current application. """ from __future__ import print_function @@ -11,25 +10,26 @@ root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(root, 'sasview-install', 'Lib', 'site-packages')) -from sas import config as local_config + +from sas import config as config #REG_PROGRAM = """{app}\MYPROG.EXE"" ""%1""" -APPLICATION = str(local_config.__appname__ )+ '.exe' -AppName = str(local_config.__appname__ ) -AppVerName = str(local_config.__appname__ )+'-'+ str(local_config.__version__) +APPLICATION = str(config.__appname__) + '.exe' +AppName = str(config.__appname__) +AppVerName = str(config.__appname__) + '-' + str(config.__version__) Dev = '' if AppVerName.lower().count('dev') > 0: Dev = '-Dev' -AppPublisher = local_config._copyright -AppPublisherURL = local_config._homepage -AppSupportURL = local_config._homepage -AppUpdatesURL = local_config._homepage +AppPublisher = config._copyright +AppPublisherURL = config._homepage +AppSupportURL = config._homepage +AppUpdatesURL = config._homepage ChangesEnvironment = 'true' DefaultDirName = os.path.join("{pf}" , AppName+Dev) -DefaultGroupName = os.path.join(local_config.DefaultGroupName, AppVerName) +DefaultGroupName = os.path.join(config.DefaultGroupName, AppVerName) -OutputBaseFilename = local_config.OutputBaseFilename -SetupIconFile = local_config.SetupIconFile_win +OutputBaseFilename = config.OutputBaseFilename +SetupIconFile = config.SetupIconFile_win LicenseFile = 'license.txt' DisableProgramGroupPage = 'yes' Compression = 'lzma' @@ -37,9 +37,9 @@ PrivilegesRequired = 'none' INSTALLER_FILE = 'installer' -icon_path = local_config.icon_path -media_path = local_config.media_path -test_path = local_config.test_path +icon_path = config.icon_path +media_path = config.media_path +test_path = config.test_path def find_extension(): """ @@ -60,13 +60,13 @@ def find_extension(): except Exception: pass try: - file_type, ext = local_config.APPLICATION_WLIST.split("|*", 1) + file_type, ext = config.APPLICATION_WLIST.split("|*", 1) if ext.strip() not in ['.', ''] and ext.strip() not in list_app: list_app.append((ext, 'string', file_type)) except Exception: pass try: - for item in local_config.PLUGINS_WLIST: + for item in config.PLUGINS_WLIST: file_type, ext = item.split("|*", 1) if ext.strip() not in ['.', ''] and ext.strip() not in list_app: list_app.append((ext, 'string', file_type)) @@ -330,7 +330,6 @@ def generate_installer(): """ """ TEMPLATE = "\n; Script generated by the Inno Setup Script Wizard\n" - TEMPLATE += "\n; and local_config.py located in this directory.\n " TEMPLATE += "; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!" TEMPLATE += "\n[Setup]\n\n" TEMPLATE += "ChangesAssociations=%s\n" %str('yes') diff --git a/installers/installer_generator64.py b/installers/installer_generator64.py index aae6b20647..e390f69798 100644 --- a/installers/installer_generator64.py +++ b/installers/installer_generator64.py @@ -1,7 +1,6 @@ """ This module generates .iss file according to the local config of -the current application. Please make sure a file named "local_config.py" -exists in the current directory. Edit local_config.py according to your needs. +the current application. """ from __future__ import print_function @@ -11,25 +10,25 @@ root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.join(root, 'sasview-install', 'Lib', 'site-packages')) -from sas.sasview import local_config +from sas import config as config #REG_PROGRAM = """{app}\MYPROG.EXE"" ""%1""" -APPLICATION = str(local_config.__appname__ )+ '.exe' -AppName = str(local_config.__appname__ ) -AppVerName = str(local_config.__appname__ )+'-'+ str(local_config.__version__) +APPLICATION = str(config.__appname__) + '.exe' +AppName = str(config.__appname__) +AppVerName = str(config.__appname__) + '-' + str(config.__version__) Dev = '' if AppVerName.lower().count('dev') > 0: Dev = '-Dev' -AppPublisher = local_config._copyright -AppPublisherURL = local_config._homepage -AppSupportURL = local_config._homepage -AppUpdatesURL = local_config._homepage +AppPublisher = config._copyright +AppPublisherURL = config._homepage +AppSupportURL = config._homepage +AppUpdatesURL = config._homepage ChangesEnvironment = 'true' DefaultDirName = os.path.join("{pf}" , AppName+Dev) -DefaultGroupName = os.path.join(local_config.DefaultGroupName, AppVerName) +DefaultGroupName = os.path.join(config.DefaultGroupName, AppVerName) -OutputBaseFilename = local_config.OutputBaseFilename -SetupIconFile = local_config.SetupIconFile_win +OutputBaseFilename = config.OutputBaseFilename +SetupIconFile = config.SetupIconFile_win LicenseFile = 'license.txt' DisableProgramGroupPage = 'yes' DisableDirPage = 'no' @@ -38,9 +37,9 @@ PrivilegesRequired = 'none' INSTALLER_FILE = 'installer' -icon_path = local_config.icon_path -media_path = local_config.media_path -test_path = local_config.test_path +icon_path = config.icon_path +media_path = config.media_path +test_path = config.test_path def find_extension(): """ @@ -61,13 +60,13 @@ def find_extension(): except Exception: pass try: - file_type, ext = local_config.APPLICATION_WLIST.split("|*", 1) + file_type, ext = config.APPLICATION_WLIST.split("|*", 1) if ext.strip() not in ['.', ''] and ext.strip() not in list_app: list_app.append((ext, 'string', file_type)) except Exception: pass try: - for item in local_config.PLUGINS_WLIST: + for item in config.PLUGINS_WLIST: file_type, ext = item.split("|*", 1) if ext.strip() not in ['.', ''] and ext.strip() not in list_app: list_app.append((ext, 'string', file_type)) @@ -331,7 +330,6 @@ def generate_installer(): """ """ TEMPLATE = "\n; Script generated by the Inno Setup Script Wizard\n" - TEMPLATE += "\n; and local_config.py located in this directory.\n " TEMPLATE += "; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!" TEMPLATE += "\n[Setup]\n\n" TEMPLATE += "ChangesAssociations=%s\n" %str('yes') diff --git a/src/sas/config_system/util.py b/src/sas/config_system/util.py index 3d41ce7fc5..0260719051 100644 --- a/src/sas/config_system/util.py +++ b/src/sas/config_system/util.py @@ -7,22 +7,4 @@ def get_config() -> Config: return Config() - - - - - - -def load_local_config(app_dir): - assert False - filename = 'local_config.py' - path = os.path.join(app_dir, filename) - try: - module = load_module_from_path('sas.local_config', path) - #logger.info("GuiManager loaded %s", path) - return module - except Exception as exc: - #logger.critical("Error loading %s: %s", path, exc) - sys.exit() - configuration = get_config() \ No newline at end of file diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 9122680b56..25f6b04cae 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -45,6 +45,7 @@ from sasmodels.sasview_model import SasviewModel from sas.sascalc.dataloader.loader import Loader +from sas import config from sas.sascalc.file_converter.nxcansas_writer import NXcanSASWriter from sas.qtgui.Utilities import CustomDir @@ -132,12 +133,14 @@ def _find_local_config(confg_file, path): DATAPATH = PATH_APP # Read in the local config, which can either be with the main # application or in the installation directory -config = _find_local_config('local_config', PATH_APP) +# config = _find_local_config('local_config', PATH_APP) +# +# if config is None: +# config = _find_local_config('local_config', os.getcwd()) +# else: +# pass + -if config is None: - config = _find_local_config('local_config', os.getcwd()) -else: - pass c_conf_dir = CustomDir.setup_conf_dir(PATH_APP) custom_config = _find_local_config('custom_config', c_conf_dir) diff --git a/src/sas/sasview/local_config.py b/src/sas/sasview/local_config.py deleted file mode 100644 index 78a6e788c3..0000000000 --- a/src/sas/sasview/local_config.py +++ /dev/null @@ -1,161 +0,0 @@ -""" - Application settings -""" -from __future__ import print_function - -import time -import os -#from sas.sasgui.guiframe.gui_style import GUIFRAME -import sas.sasview -import logging - -logger = logging.getLogger(__name__) - -# Version of the application -__appname__ = "SasView" -__version__ = sas.sasview.__version__ -__build__ = sas.sasview.__build__ -__download_page__ = 'https://github.com/SasView/sasview/releases' -__update_URL__ = 'https://www.sasview.org/latestversion.json' - -# Debug message flag -__EVT_DEBUG__ = False - -# Flag for automated testing -__TEST__ = False - -# Debug message should be written to a file? -__EVT_DEBUG_2_FILE__ = False -__EVT_DEBUG_FILENAME__ = "debug.log" - -# About box info -_do_aboutbox = True -_do_acknowledge = True -_do_tutorial = True -_acknowledgement_preamble =\ -'''To ensure the long term support and development of this software please''' +\ -''' remember to:''' -_acknowledgement_preamble_bullet1 =\ -'''Acknowledge its use in your publications as :''' -_acknowledgement_preamble_bullet2 =\ -'''Reference SasView as:''' -_acknowledgement_preamble_bullet3 =\ -'''Reference the model you used if appropriate (see documentation for refs)''' -_acknowledgement_preamble_bullet4 =\ -'''Send us your reference for our records: developers@sasview.org''' -_acknowledgement_publications = \ -'''This work benefited from the use of the SasView application, originally developed under NSF Award DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000.''' -_acknowledgement_citation = \ -'''M. Doucet et al. SasView Version 5.0''' - -_acknowledgement = \ -'''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS, and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: http://www.sasview.org/contact.html -''' - -_homepage = "https://www.sasview.org" -_download = __download_page__ -_authors = [] -_paper = "http://sourceforge.net/p/sasview/tickets/" -_license = "mailto:help@sasview.org" - - -icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images")) -# logging.info("icon path: %s" % icon_path) -media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) -test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test")) - -_nist_logo = os.path.join(icon_path, "nist_logo.png") -_umd_logo = os.path.join(icon_path, "umd_logo.png") -_sns_logo = os.path.join(icon_path, "sns_logo.png") -_ornl_logo = os.path.join(icon_path, "ornl_logo.png") -_isis_logo = os.path.join(icon_path, "isis_logo.png") -_ess_logo = os.path.join(icon_path, "ess_logo.png") -_ill_logo = os.path.join(icon_path, "ill_logo.png") -_ansto_logo = os.path.join(icon_path, "ansto_logo.png") -_tudelft_logo = os.path.join(icon_path, "tudelft_logo.png") -_dls_logo = os.path.join(icon_path, "dls_logo.png") -_nsf_logo = os.path.join(icon_path, "nsf_logo.png") -_danse_logo = os.path.join(icon_path, "danse_logo.png") -_inst_logo = os.path.join(icon_path, "utlogo.gif") -_nist_url = "https://www.nist.gov/" -_umd_url = "https://www.umd.edu/" -_sns_url = "https://neutrons.ornl.gov/" -_ornl_url = "https://neutrons.ornl.gov/" -_nsf_url = "https://www.nsf.gov" -_isis_url = "https://www.isis.stfc.ac.uk/" -_ess_url = "https://europeanspallationsource.se/" -_ill_url = "https://www.ill.eu/" -_ansto_url = "https://www.ansto.gov.au/" -_tudelft_url = "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" -_dls_url = "https://www.diamond.ac.uk/" -_danse_url = "https://www.its.caltech.edu/~matsci/btf/DANSE_web_page.html" -_inst_url = "https://www.utk.edu" -_corner_image = os.path.join(icon_path, "angles_flat.png") -_welcome_image = os.path.join(icon_path, "SVwelcome.png") -_copyright = "(c) 2009 - 2022, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft and DLS" -marketplace_url = "http://marketplace.sasview.org/" - -#edit the list of file state your plugin can read -APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' -APPLICATION_STATE_EXTENSION = '.svs' -GUIFRAME_WIDTH = 1150 -GUIFRAME_HEIGHT = 840 -PLUGIN_STATE_EXTENSIONS = ['.fitv', '.inv', '.prv', '.crf'] -PLUGINS_WLIST = ['Fitting files (*.fitv)|*.fitv', - 'Invariant files (*.inv)|*.inv', - 'P(r) files (*.prv)|*.prv', - 'Corfunc files (*.crf)|*.crf'] -PLOPANEL_WIDTH = 415 -PLOPANEL_HEIGTH = 370 -DATAPANEL_WIDTH = 235 -DATAPANEL_HEIGHT = 700 -SPLASH_SCREEN_PATH = os.path.join(icon_path, "SVwelcome_mini.png") -TUTORIAL_PATH = os.path.join(media_path, "Tutorial.pdf") -#DEFAULT_STYLE = GUIFRAME.MULTIPLE_APPLICATIONS|GUIFRAME.MANAGER_ON\ -# |GUIFRAME.CALCULATOR_ON|GUIFRAME.TOOLBAR_ON -DEFAULT_STYLE = 64 - -SPLASH_SCREEN_WIDTH = 512 -SPLASH_SCREEN_HEIGHT = 366 -SS_MAX_DISPLAY_TIME = 2000 -WELCOME_PANEL_ON = True -WELCOME_PANEL_SHOW = False -CLEANUP_PLOT = False -# OPEN and SAVE project menu -OPEN_SAVE_PROJECT_MENU = True -#VIEW MENU -VIEW_MENU = True -#EDIT MENU -EDIT_MENU = True - -SetupIconFile_win = os.path.join(icon_path, "ball.ico") -SetupIconFile_mac = os.path.join(icon_path, "ball.icns") -DefaultGroupName = "." -OutputBaseFilename = "setupSasView" - -FIXED_PANEL = True -DATALOADER_SHOW = True -CLEANUP_PLOT = False -WELCOME_PANEL_SHOW = False -#Show or hide toolbar at the start up -TOOLBAR_SHOW = True -# set a default perspective -DEFAULT_PERSPECTIVE = 'None' - -# Time out for updating sasview -UPDATE_TIMEOUT = 2 - -#OpenCL option -SAS_OPENCL = None - -def printEVT(message): - if __EVT_DEBUG__: - """ - :TODO - Need method doc string - """ - print("%g: %s" % (time.clock(), message)) - - if __EVT_DEBUG_2_FILE__: - out = open(__EVT_DEBUG_FILENAME__, 'a') - out.write("%10g: %s\n" % (time.clock(), message)) - out.close() From 1dc5e605d0cad710a41ecb9b057f452f850c43a7 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 31 Aug 2022 13:19:01 +0100 Subject: [PATCH 09/82] Removed some references to local_config.py --- installers/sasview.spec | 2 +- src/sas/qtgui/Utilities/GuiUtils.py | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/installers/sasview.spec b/installers/sasview.spec index c5010a2b64..46e90bed1d 100644 --- a/installers/sasview.spec +++ b/installers/sasview.spec @@ -15,7 +15,7 @@ datas = [ ('../src/sas/example_data', 'example_data'), ('../src/sas/qtgui/Utilities/Reports/report_style.css', 'sas/qtgui/Utilities/Reports'), ('../src/sas/sasview/custom_config.py', '.'), - ('../src/sas/sasview/local_config.py', '.'), +# ('../src/sas/sasview/local_config.py', '.'), # ('../src/sas/sasview/wxcruft.py', '.'), ('../src/sas/qtgui/Perspectives/Fitting/plugin_models', 'plugin_models'), ('../src/sas/logger_config.py', '.'), diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 37bbd0ecad..dec1536620 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -141,15 +141,16 @@ def _find_local_config(confg_file, path): # else: # pass - - -c_conf_dir = CustomDir.setup_conf_dir(PATH_APP) -custom_config = _find_local_config('custom_config', c_conf_dir) -if custom_config is None: - custom_config = _find_local_config('custom_config', os.getcwd()) - if custom_config is None: - msgConfig = "Custom_config file was not imported" -logging.info("Custom config path: %s", custom_config) +# +# +# c_conf_dir = CustomDir.setup_conf_dir(PATH_APP) +# custom_config = _find_local_config('custom_config', c_conf_dir) +# if custom_config is None: +# custom_config = _find_local_config('custom_config', os.getcwd()) +# if custom_config is None: +# msgConfig = "Custom_config file was not imported" +custom_config = config +# logging.info("Custom config path: %s", custom_config) #read some constants from config APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION From 7047c2925d4b097f37951db4b43fb4af52b45944 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 31 Aug 2022 13:59:13 +0100 Subject: [PATCH 10/82] Removed custom_config.py --- setup.py | 36 ++++++------ src/sas/__init__.py | 34 ++++++----- src/sas/_config.py | 88 +++++++++++++++------------- src/sas/logger_config.py | 14 +---- src/sas/qtgui/Utilities/CustomDir.py | 82 +++++++++++++------------- src/sas/qtgui/Utilities/GuiUtils.py | 22 +++---- src/sas/sasview/custom_config.py | 21 ------- 7 files changed, 132 insertions(+), 165 deletions(-) delete mode 100644 src/sas/sasview/custom_config.py diff --git a/setup.py b/setup.py index 19509a628c..7ad66afad4 100644 --- a/setup.py +++ b/setup.py @@ -42,24 +42,24 @@ CURRENT_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) SASVIEW_BUILD = os.path.join(CURRENT_SCRIPT_DIR, "build") -# TODO: build step should not be messing with existing installation!! -sas_dir = os.path.join(os.path.expanduser("~"), '.sasview') -if os.path.isdir(sas_dir): - f_path = os.path.join(sas_dir, "sasview.log") - if os.path.isfile(f_path): - os.remove(f_path) - #f_path = os.path.join(sas_dir, "categories.json") - #if os.path.isfile(f_path): - # os.remove(f_path) - f_path = os.path.join(sas_dir, 'sasview', "custom_config.py") - if os.path.isfile(f_path): - os.remove(f_path) - #f_path = os.path.join(sas_dir, 'plugin_models') - # if os.path.isdir(f_path): - # for f in os.listdir(f_path): - # if f in plugin_model_list: - # file_path = os.path.join(f_path, f) - # os.remove(file_path) +# # TODO: build step should not be messing with existing installation!! +# sas_dir = os.path.join(os.path.expanduser("~"), '.sasview') +# if os.path.isdir(sas_dir): +# f_path = os.path.join(sas_dir, "sasview.log") +# if os.path.isfile(f_path): +# os.remove(f_path) +# #f_path = os.path.join(sas_dir, "categories.json") +# #if os.path.isfile(f_path): +# # os.remove(f_path) +# f_path = os.path.join(sas_dir, 'sasview', "custom_config.py") +# if os.path.isfile(f_path): +# os.remove(f_path) +# #f_path = os.path.join(sas_dir, 'plugin_models') +# # if os.path.isdir(f_path): +# # for f in os.listdir(f_path): +# # if f in plugin_model_list: +# # file_path = os.path.join(f_path, f) +# # os.remove(file_path) # Optionally clean before build. diff --git a/src/sas/__init__.py b/src/sas/__init__.py index 3d38a44cb0..a97a621b11 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -87,23 +87,25 @@ def make_custom_config_path(): _CUSTOM_CONFIG = None def get_custom_config(): - """ - Setup the custom config dir and cat file - """ - global _CUSTOM_CONFIG - if not _CUSTOM_CONFIG: - from ._config import setup_custom_config - _CUSTOM_CONFIG = setup_custom_config(get_app_dir(), get_user_dir()) - return _CUSTOM_CONFIG + raise RuntimeError("Tried to call get_custom_config - this is now forbidden") + # """ + # Setup the custom config dir and cat file + # """ + # global _CUSTOM_CONFIG + # if not _CUSTOM_CONFIG: + # from ._config import setup_custom_config + # _CUSTOM_CONFIG = setup_custom_config(get_app_dir(), get_user_dir()) + # return _CUSTOM_CONFIG _LOCAL_CONFIG = None def get_local_config(): - """ - Loads the local config file. - """ - global _LOCAL_CONFIG - if not _LOCAL_CONFIG: - from ._config import load_local_config - _LOCAL_CONFIG = load_local_config(get_app_dir()) - return _LOCAL_CONFIG + raise RuntimeError("Tried to call get_local_config - this is now forbidden") + # """ + # Loads the local config file. + # """ + # global _LOCAL_CONFIG + # if not _LOCAL_CONFIG: + # from ._config import load_local_config + # _LOCAL_CONFIG = load_local_config(get_app_dir()) + # return _LOCAL_CONFIG diff --git a/src/sas/_config.py b/src/sas/_config.py index d6805d65a9..99beda90e7 100644 --- a/src/sas/_config.py +++ b/src/sas/_config.py @@ -11,51 +11,55 @@ logger = logging.getLogger(__name__) - +# TODO: REMOVE def make_custom_config_path(user_dir): - """ - The location of the cusstom config file. - - Returns ~/.sasview/config/custom_config.py - """ - dirname = os.path.join(user_dir, 'config') - # If the directory doesn't exist, create it - if not os.path.exists(dirname): - os.makedirs(dirname) - path = os.path.join(dirname, "custom_config.py") - return path + raise RuntimeError("Tried to run make_custom_config_path - this is now forbidden") + # """ + # The location of the cusstom config file. + # + # Returns ~/.sasview/config/custom_config.py + # """ + # dirname = os.path.join(user_dir, 'config') + # # If the directory doesn't exist, create it + # if not os.path.exists(dirname): + # os.makedirs(dirname) + # path = os.path.join(dirname, "custom_config.py") + # return path def setup_custom_config(app_dir, user_dir): - path = make_custom_config_path(user_dir) - if not os.path.isfile(path): - try: - # if the custom config file does not exist, copy the default from - # the app dir - shutil.copyfile(os.path.join(app_dir, "custom_config.py"), path) - except Exception: - logger.error("Could not copy default custom config.") - - #Adding SAS_OPENCL if it doesn't exist in the config file - # - to support backcompability - if not "SAS_OPENCL" in open(path).read(): - try: - open(path, "a+").write("SAS_OPENCL = \"None\"\n") - except Exception: - logger.error("Could not update custom config with SAS_OPENCL.") - - custom_config = load_custom_config(path) - return custom_config + raise RuntimeError("Tried to run setup_custom_config - this is now forbidden") + + # path = make_custom_config_path(user_dir) + # if not os.path.isfile(path): + # try: + # # if the custom config file does not exist, copy the default from + # # the app dir + # shutil.copyfile(os.path.join(app_dir, "custom_config.py"), path) + # except Exception: + # logger.error("Could not copy default custom config.") + # + # #Adding SAS_OPENCL if it doesn't exist in the config file + # # - to support backcompability + # if not "SAS_OPENCL" in open(path).read(): + # try: + # open(path, "a+").write("SAS_OPENCL = \"None\"\n") + # except Exception: + # logger.error("Could not update custom config with SAS_OPENCL.") + # + # custom_config = load_custom_config(path) + # return custom_config def load_custom_config(path): - if os.path.exists(path): - try: - module = load_module_from_path('sas.custom_config', path) - #logger.info("GuiManager loaded %s", path) - return module - except Exception as exc: - logger.error("Error loading %s: %s", path, exc) - - from sas.sasview import custom_config - logger.info("GuiManager custom_config defaults to sas.sasview.custom_config") - return custom_config \ No newline at end of file + raise RuntimeError("Tried to call load_custom_config - this is now forbidden") + # if os.path.exists(path): + # try: + # module = load_module_from_path('sas.custom_config', path) + # #logger.info("GuiManager loaded %s", path) + # return module + # except Exception as exc: + # logger.error("Error loading %s: %s", path, exc) + # + # from sas.sasview import custom_config + # logger.info("GuiManager custom_config defaults to sas.sasview.custom_config") + # return custom_config \ No newline at end of file diff --git a/src/sas/logger_config.py b/src/sas/logger_config.py index 8a182c2b43..de2f2ad73e 100644 --- a/src/sas/logger_config.py +++ b/src/sas/logger_config.py @@ -8,7 +8,7 @@ import pkg_resources -from sas import get_custom_config +from sas import config ''' Module that manages the global logging @@ -46,17 +46,7 @@ def config_development(self): def _disable_debug_from_config(self): '''disable DEBUG logs as per user configuration (DEBUG logs disabled by default)''' - disable_debug = True - custom_config = get_custom_config() - - if hasattr(custom_config, "FILTER_DEBUG_LOGS"): - if type(custom_config.FILTER_DEBUG_LOGS) is bool: - disable_debug = custom_config.FILTER_DEBUG_LOGS - else: - logging.warning("FILTER_DEBUG_LOGS has invalid value in custom_config.py") - - if disable_debug: - # logging.info("Note: DEBUG logs are disabled.") + if config.FILTER_DEBUG_LOGS: logging.disable(logging.DEBUG) def _read_config_file(self): diff --git a/src/sas/qtgui/Utilities/CustomDir.py b/src/sas/qtgui/Utilities/CustomDir.py index 92c8f64d8a..8ca8ebe4b2 100755 --- a/src/sas/qtgui/Utilities/CustomDir.py +++ b/src/sas/qtgui/Utilities/CustomDir.py @@ -1,15 +1,12 @@ # Setup and find Custom config dir import os.path -import shutil - -CONF_DIR = 'config' -APPLICATION_NAME = 'sasview' +from sas import config def _find_usersasview_dir(): """ Find and return user/.sasview dir """ - return os.path.join(os.path.expanduser("~"), ("." + APPLICATION_NAME)) + return os.path.join(os.path.expanduser("~"), ("." + config.APPLICATION_NAME)) def _find_customconf_dir(): """ @@ -17,42 +14,43 @@ def _find_customconf_dir(): The plugin directory is located in the user's home directory. """ u_dir = _find_usersasview_dir() - return os.path.join(u_dir, CONF_DIR) + return os.path.join(u_dir, config.CONF_DIR) def setup_conf_dir(path): - """ - Setup the custom config dir and cat file - """ - conf_dir = _find_customconf_dir() - # If the plugin directory doesn't exist, create it - if not os.path.isdir(conf_dir): - os.makedirs(conf_dir) - config_file = os.path.join(conf_dir, "custom_config.py") - - # Place example user models as needed - try: - if not os.path.isfile(config_file): - shutil.copyfile(os.path.join(path, "custom_config.py"), config_file) - - #Adding SAS_OPENCL if it doesn't exist in the config file - # - to support backcompability - if not "SAS_OPENCL" in open(config_file).read(): - open(config_file,"a+").write("SAS_OPENCL = \"None\"\n") - except: - # Check for data path next to exe/zip file. - #Look for maximum n_dir up of the current dir to find plugins dir - n_dir = 12 - is_dir = False - f_dir = path - for i in range(n_dir): - if i > 1: - f_dir, _ = os.path.split(f_dir) - temp_path = os.path.join(f_dir, "custom_config.py") - if os.path.isfile(temp_path): - shutil.copyfile(temp_path, config_file) - is_dir = True - break - if not is_dir: - raise - return conf_dir - + raise RuntimeError("Tried to call setup_conf_dir") + # """ + # Setup the custom config dir and cat file + # """ + # conf_dir = _find_customconf_dir() + # # If the plugin directory doesn't exist, create it + # if not os.path.isdir(conf_dir): + # os.makedirs(conf_dir) + # config_file = os.path.join(conf_dir, "custom_config.py") + # + # # Place example user models as needed + # try: + # if not os.path.isfile(config_file): + # shutil.copyfile(os.path.join(path, "custom_config.py"), config_file) + # + # #Adding SAS_OPENCL if it doesn't exist in the config file + # # - to support backcompability + # if not "SAS_OPENCL" in open(config_file).read(): + # open(config_file,"a+").write("SAS_OPENCL = \"None\"\n") + # except: + # # Check for data path next to exe/zip file. + # #Look for maximum n_dir up of the current dir to find plugins dir + # n_dir = 12 + # is_dir = False + # f_dir = path + # for i in range(n_dir): + # if i > 1: + # f_dir, _ = os.path.split(f_dir) + # temp_path = os.path.join(f_dir, "custom_config.py") + # if os.path.isfile(temp_path): + # shutil.copyfile(temp_path, config_file) + # is_dir = True + # break + # if not is_dir: + # raise + # return conf_dir + # diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index dec1536620..b08cd34e62 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -70,24 +70,18 @@ def get_app_dir(): """ - The application directory is the one where the default custom_config.py - file resides. - - :returns: app_path - the path to the applicatin directory + :returns: app_path - the path to the application directory """ # First, try the directory of the executable we are running app_path = sys.path[0] if os.path.isfile(app_path): - app_path = os.path.dirname(app_path) - if os.path.isfile(os.path.join(app_path, "custom_config.py")): - app_path = os.path.abspath(app_path) - #logging.info("Using application path: %s", app_path) - return app_path - - # Next, try the current working directory - if os.path.isfile(os.path.join(os.getcwd(), "custom_config.py")): - #logging.info("Using application path: %s", os.getcwd()) - return os.path.abspath(os.getcwd()) + return os.path.dirname(app_path) + + # + # # Next, try the current working directory + # if os.path.isfile(os.path.join(os.getcwd(), "custom_config.py")): + # #logging.info("Using application path: %s", os.getcwd()) + # return os.path.abspath(os.getcwd()) # Finally, try the directory of the sasview module # TODO: gui_manager will have to know about sasview until we diff --git a/src/sas/sasview/custom_config.py b/src/sas/sasview/custom_config.py deleted file mode 100644 index 732ce49406..0000000000 --- a/src/sas/sasview/custom_config.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -Application appearance custom configuration -""" -DATAPANEL_WIDTH = -1 -CLEANUP_PLOT = False -FIXED_PANEL = True -PLOPANEL_WIDTH = -1 -DATALOADER_SHOW = True -GUIFRAME_HEIGHT = -1 -GUIFRAME_WIDTH = -1 -CONTROL_WIDTH = -1 -CONTROL_HEIGHT = -1 -DEFAULT_OPEN_FOLDER = None -WELCOME_PANEL_SHOW = False -TOOLBAR_SHOW = True -DEFAULT_PERSPECTIVE = "Fitting" -SAS_OPENCL = "None" -MARKETPLACE_URL = "http://marketplace.sasview.org/" - -# Logging options -FILTER_DEBUG_LOGS = True From 314e93d533a1e836aa214f0e5c5be388f39b3252 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 31 Aug 2022 14:39:34 +0100 Subject: [PATCH 11/82] Removed custom_config from spec --- installers/sasview.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/installers/sasview.spec b/installers/sasview.spec index 46e90bed1d..749b52cc5a 100644 --- a/installers/sasview.spec +++ b/installers/sasview.spec @@ -9,12 +9,13 @@ import sys block_cipher = None PYTHON_LOC = sys.exec_prefix +#TODO: Removed commented lines datas = [ ('../src/sas/sasview/images', 'images'), ('../src/sas/sasview/media', 'media'), ('../src/sas/example_data', 'example_data'), ('../src/sas/qtgui/Utilities/Reports/report_style.css', 'sas/qtgui/Utilities/Reports'), - ('../src/sas/sasview/custom_config.py', '.'), +# ('../src/sas/sasview/custom_config.py', '.'), # ('../src/sas/sasview/local_config.py', '.'), # ('../src/sas/sasview/wxcruft.py', '.'), ('../src/sas/qtgui/Perspectives/Fitting/plugin_models', 'plugin_models'), From b490e5cc0a5ba03e3973ab844883f5c5e2a0594a Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 31 Aug 2022 15:28:37 +0100 Subject: [PATCH 12/82] Replaced references to custom_config --- src/sas/qtgui/MainWindow/MainWindow.py | 4 ++-- src/sas/qtgui/Perspectives/Corfunc/CorfuncCanvas.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sas/qtgui/MainWindow/MainWindow.py b/src/sas/qtgui/MainWindow/MainWindow.py index 1545e1086b..ba4cb1d321 100644 --- a/src/sas/qtgui/MainWindow/MainWindow.py +++ b/src/sas/qtgui/MainWindow/MainWindow.py @@ -75,11 +75,11 @@ def run_sasview(): SetupLogger(__name__).config_development() # initialize sasmodels settings - from sas import get_custom_config, get_user_dir + from sas import config, get_user_dir if "SAS_DLL_PATH" not in os.environ: os.environ["SAS_DLL_PATH"] = os.path.join( get_user_dir(), "compiled_models") - SAS_OPENCL = get_custom_config().SAS_OPENCL + SAS_OPENCL = config.SAS_OPENCL if SAS_OPENCL and "SAS_OPENCL" not in os.environ: os.environ["SAS_OPENCL"] = SAS_OPENCL diff --git a/src/sas/qtgui/Perspectives/Corfunc/CorfuncCanvas.py b/src/sas/qtgui/Perspectives/Corfunc/CorfuncCanvas.py index bdd5c8e175..85da8cdb01 100644 --- a/src/sas/qtgui/Perspectives/Corfunc/CorfuncCanvas.py +++ b/src/sas/qtgui/Perspectives/Corfunc/CorfuncCanvas.py @@ -7,7 +7,7 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure -from sas.sascalc.dataloader.data_info import Data1D +from sasdata.dataloader.data_info import Data1D if TYPE_CHECKING: From 2e3ba4806a418ab484f51d23d3e65ecf62617e91 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 1 Sep 2022 17:29:42 +0100 Subject: [PATCH 13/82] Adding schema system to config --- build_tools/requirements.txt | 1 + src/sas/config_system/__init__.py | 1 - src/sas/config_system/config.py | 2 +- src/sas/config_system/config_meta.py | 78 +++++++- src/sas/config_system/default_config.yml | 0 src/sas/config_system/schema.py | 1 - src/sas/config_system/schema_elements.py | 232 +++++++++++++++++++++++ src/sas/qtgui/MainWindow/GuiManager.py | 2 + test/config/utest_config.py | 176 +++++++++++++++++ 9 files changed, 480 insertions(+), 13 deletions(-) delete mode 100644 src/sas/config_system/default_config.yml delete mode 100644 src/sas/config_system/schema.py create mode 100644 src/sas/config_system/schema_elements.py create mode 100644 test/config/utest_config.py diff --git a/build_tools/requirements.txt b/build_tools/requirements.txt index 50194d148c..057c4412f7 100644 --- a/build_tools/requirements.txt +++ b/build_tools/requirements.txt @@ -32,3 +32,4 @@ html5lib importlib-resources bumps html2text +jsonschema \ No newline at end of file diff --git a/src/sas/config_system/__init__.py b/src/sas/config_system/__init__.py index 849193d2f9..715f89dab7 100644 --- a/src/sas/config_system/__init__.py +++ b/src/sas/config_system/__init__.py @@ -1,2 +1 @@ from sas.config_system.util import configuration - diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index ca42cd7f7e..dedf875de3 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -197,7 +197,7 @@ def __init__(self): # # Lock the class down # - self._lock() + self.finalise() def printEVT(self, message): if self.__EVT_DEBUG__: diff --git a/src/sas/config_system/config_meta.py b/src/sas/config_system/config_meta.py index ccbcd7ce56..bb988a607c 100644 --- a/src/sas/config_system/config_meta.py +++ b/src/sas/config_system/config_meta.py @@ -1,32 +1,90 @@ +from typing import Optional, Dict, Any +import json +import logging +from sas.config_system.schema_elements import create_schema_element, CoercionError class ConfigLocked(Exception): - def __init__(self): - super().__init__(self, - "The Config class cannot be subclassed or added to dynamically, see config.py for details") + def __init__(self, message): + super().__init__(self, f"{message}: The Config class cannot be subclassed or added to dynamically, " + "see config class definition for details") class ConfigMeta(type): - def __new__(typ, name, bases, classdict): + def __new__(mcs, name, bases, classdict): for b in bases: if isinstance(b, ConfigMeta): - raise TypeError - return type.__new__(typ, name, bases, dict(classdict)) + raise ConfigLocked("Subclass attempt") + return type.__new__(mcs, name, bases, dict(classdict)) class ConfigBase: + """ Base class for Config, keep the definition of config variables and workings as separate as possible """ def __init__(self): + + # Note on editing the following variables: + # they are referenced as strings in functions below + # remember that the strings will have to be updated self._locked = False + self._schema = {} + self._modified_values = set() + + def finalise(self): + """ Call this to make this class 'final' """ - def _lock(self): + self._schema = self.generate_schema() self._locked = True - def save(self): + def update(self, data: Dict[str, Any]): + """ Set the fields of the config from a dictionary""" + + for key in data: + + if key not in self._schema: + logging.error(f"Unknown config key: '{key}', skipping") + + else: + try: + coerced = self._schema[key].coerce(data[key]) + setattr(self, key, coerced) + + except CoercionError as e: + logging.error(f"Cannot set set variable '{key}', improper type ({e.message})") + + + def generate_schema(self): + """ Auto-generate schema for the current config class and validate config class + + Note: there is an assumption here that the class of the value in the default + config file is + """ + + schema = {} + variables = vars(self) + for variable_name in variables: + if variable_name in ["_locked", "_schema", "_modified_values"]: + continue + + schema[variable_name] = create_schema_element(variable_name, variables[variable_name]) + + return schema + + def load(self, filename: str): + pass + + def save(self, filename: Optional[str]=None): + """ Save the configuration to a file""" #TODO: Implement save functionality to yaml (and load, with schema) raise NotImplementedError() def __setattr__(self, key, value): if hasattr(self, "_locked") and self._locked: if key not in self.__dict__: - raise ConfigLocked() + raise ConfigLocked("New attribute attempt") + + + # if not self._locked: + # self._modified_values.add(key) + + super().__setattr__(key, value) + - super().__setattr__(key, value) \ No newline at end of file diff --git a/src/sas/config_system/default_config.yml b/src/sas/config_system/default_config.yml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/sas/config_system/schema.py b/src/sas/config_system/schema.py deleted file mode 100644 index 8e2b21ea47..0000000000 --- a/src/sas/config_system/schema.py +++ /dev/null @@ -1 +0,0 @@ -""" Code for verifying config files""" \ No newline at end of file diff --git a/src/sas/config_system/schema_elements.py b/src/sas/config_system/schema_elements.py new file mode 100644 index 0000000000..8030241c5e --- /dev/null +++ b/src/sas/config_system/schema_elements.py @@ -0,0 +1,232 @@ +from abc import ABC, abstractmethod +from typing import Optional, List +import logging + +""" Type representation for config elements + +Unfortunately, json schemas are not flexible enough to make this unnecessary""" + +class SchemaError(Exception): + """ Raised when there are problems creating a schema""" + def __init__(self, message): + super().__init__(message) + +class CoercionError(Exception): + """ Raised when we can't make a variable conform to the schema""" + def __init__(self, message): + self.message = message + super().__init__(message) + + +class SchemaElement(ABC): + """ Base class for schema elements""" + @abstractmethod + def coerce(self, value): + """ Force a variable to conform to the schema, if possible""" + pass + + def __eq__(self, value): + return False + + +class SchemaVariable(SchemaElement): + """ SchemaElement for values (i.e. float, int, bool, str)""" + def __init__(self): + pass + + schema_variable_type: str = "" + + def __eq__(self, other: SchemaElement): + if isinstance(other, SchemaVariable): + return self.schema_variable_type == other.schema_variable_type + else: + return False + + def __repr__(self): + return f"Schema{self.schema_variable_type.capitalize()}" + + +class SchemaBool(SchemaVariable): + schema_variable_type = "bool" + + def coerce(self, value): + if isinstance(value, bool): + return value + else: + raise CoercionError(f"Cannot coerce {type(value)} to bool") + + +class SchemaInt(SchemaVariable): + schema_variable_type = "int" + + def coerce(self, value): + if isinstance(value, int): + return value + else: + raise CoercionError(f"Cannot coerce {type(value)} to int") + + +class SchemaFloat(SchemaVariable): + schema_variable_type = "float" + + def coerce(self, value): + if isinstance(value, (int, float)): + return float(value) + else: + raise CoercionError(f"Cannot coerce {type(value)} to bool") + + +class SchemaStr(SchemaVariable): + schema_variable_type = "str" + + def coerce(self, value): + return str(value) + + + +class SchemaNonSpecified(SchemaElement): + """ Representation of a list with elements of an unknown type - + we use this when an empty list is in the config, or default is set to None""" + + def __init__(self): + pass + + def coerce(self, value): + return value + + def __eq__(self, other: SchemaElement): + return isinstance(other, SchemaNonSpecified) + + def __repr__(self): + return f"SchemaNonSpecified" + + +class SchemaList(SchemaElement): + """ Schema Element representing a homogeneous list""" + def __init__(self, child_type: SchemaElement): + self.child_type = child_type + + def coerce(self, value): + # Only really need to check for list as this should be the only json object made, but let's make it more general + if not isinstance(value, (tuple, set, list)): + raise CoercionError(f"Cannot coerce {value} ({type(value)}) to list") + + if not isinstance(value, list): + logging.warning(f"Corercing variable of type {type(value)} to list ({value})") + + return [self.child_type.coerce(x) for x in value] + + def __eq__(self, other: SchemaElement): + if isinstance(other, SchemaList): + return self.child_type == other.child_type + else: + return False + + def __repr__(self): + return f"SchemaList({repr(self.child_type)})" + + +def create_schema_element(name: str, value, recursion_depth: int=10): + """ Get an appropriate schema element for a specified config datum""" + + # Limits the depth of list config items + if recursion_depth <= 0: + raise SchemaError(f"Config element '{name}' is too nested, or is self-referential") + + if value is None: + logging.warning(f"Non-specified type for variable '{name}'") + return SchemaNonSpecified() + + # List case + elif isinstance(value, list): + + # Empty list + if len(value) == 0: + logging.warning(f"Non-specified list type for variable '{name}'") + return SchemaList(SchemaNonSpecified()) + + elif len(value) == 1: + return SchemaList(create_schema_element(name, value[0], recursion_depth-1)) + + else: + schema_children = [create_schema_element(name, x, recursion_depth-1) for x in value] + + union_type = schema_union(schema_children) + + if union_type is None: + # No homogeneous type possible + raise SchemaError(f"Config does not support inhomogeneous lists, '{name}' has types {schema_children}") + else: + return SchemaList(union_type) + + # Not a list + elif isinstance(value, bool): + return SchemaBool() + + elif isinstance(value, int): + return SchemaInt() + + elif isinstance(value, float): + return SchemaFloat() + + elif isinstance(value, str): + return SchemaStr() + + else: + raise SchemaError(f"Config element is not a bool, int, float, str, or a homogeneous list thereof ({value})") + + +def schema_union(elements: List[SchemaElement]): + """ Union of an arbitrary number of Schema Elements""" + if len(elements) == 0: + return SchemaNonSpecified() + + elif len(elements) == 1: + return elements[0] + + else: + unioned = elements[0] + for element in elements[1:]: + unioned = pairwise_schema_union(unioned, element) + return unioned + + +def pairwise_schema_union(a: Optional[SchemaElement], b: Optional[SchemaElement]) -> Optional[SchemaElement]: + """ Pairwise union of Schema Elements""" + + if a is None or b is None: + return None + + # Union of list types should be list of union type + if isinstance(a, SchemaList) and isinstance(b, SchemaList): + type_parameter = pairwise_schema_union(a.child_type, b.child_type) + if type_parameter is None: + return None + else: + return SchemaList(type_parameter) + + # Different types don't union, except for float and int + if isinstance(a, SchemaVariable) and isinstance(b, SchemaVariable): + + if a.schema_variable_type == "int" and b.schema_variable_type == "float": + return SchemaFloat() + + elif b.schema_variable_type == "int" and a.schema_variable_type == "float": + return SchemaFloat() + + elif a == b: + return a + + else: + return None + + # Union of non specified with anything else is whatever that other thing is + if isinstance(a, SchemaNonSpecified): + return b + + if isinstance(b, SchemaNonSpecified): + return a + + # All other combinations have no union type + return None + diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 44fd524d0e..ace591c800 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1304,6 +1304,8 @@ def saveCustomConfig(self): config.save() return + # TODO: Remove the rest of this function + # Load the current file config_content = GuiUtils.custom_config diff --git a/test/config/utest_config.py b/test/config/utest_config.py new file mode 100644 index 0000000000..065629a9f1 --- /dev/null +++ b/test/config/utest_config.py @@ -0,0 +1,176 @@ + +import unittest +from sas import config +from sas.config_system.schema_elements import \ + pairwise_schema_union, \ + SchemaBool, SchemaInt, SchemaFloat, SchemaStr, \ + SchemaList, SchemaNonSpecified + +""" Unit tests for Config system. """ + + +class TestConfig(unittest.TestCase): + + def a_test_dict(self) -> dict: + """ A dictionary with field names from the config, but with different values""" + + # config variables (exclude the ones used by the base class) + all_variables = vars(config).copy() + del all_variables["_locked"] + del all_variables["_schema"] + del all_variables["_modified_values"] + + + # New values + bool_value = True + int_value = 42 + float_value = 2.7669 + string_value_suffix = 7 + + target_values = {} + + for key in all_variables: + + if isinstance(all_variables[key], bool): + target_values[key] = bool_value + bool_value = not bool_value + + + elif isinstance(all_variables[key], int): + target_values[key] = int_value + int_value += 1 + + elif isinstance(all_variables[key], float): + target_values[key] = int_value + float_value += 3.149999 + + elif isinstance(all_variables[key], str): + target_values[key] = f"A string ending in the number {string_value_suffix}" + string_value_suffix += 1 + + elif isinstance(all_variables[key], list): + target_values[key] = all_variables[key] * 2 # Finding a more specific test is too complicated + + elif all_variables[key] is None: + target_values[key] = None + + else: + raise TypeError(f"Config entry '{key}' is not bool, int, float, str ({all_variables[key]})") + + return target_values + + def test_valid_update(self): + """ Test setting variables with known valid options""" + + test_dict = self.a_test_dict() + + config.update(test_dict) + + for key in test_dict: + var = getattr(config, key) + self.assertEqual(var, test_dict[key]) + self.assertEqual(type(var), type(test_dict[key])) + + def test_config_variable_change_tracker(self): + pass + + def test_invalid_update_bad_name(self): + pass + + def test_invalid_update_bad_type(self): + pass + + def test_load_and_save(self): + pass + + def test_schema_union(self): + + anything = SchemaNonSpecified() + + boolean = SchemaBool() + integer = SchemaInt() + floating = SchemaFloat() + string = SchemaStr() + + empty_list = SchemaList(anything) + bool_list = SchemaList(boolean) + int_list = SchemaList(integer) + float_list = SchemaList(floating) + str_list = SchemaList(string) + + empty_list2 = SchemaList(empty_list) + bool_list2 = SchemaList(bool_list) + int_list2 = SchemaList(int_list) + float_list2 = SchemaList(float_list) + str_list2 = SchemaList(str_list) + + all_base = [anything, boolean, integer, floating, string] + all_level_1 = [empty_list, bool_list, int_list, float_list, str_list] + all_level_2 = [empty_list2, bool_list2, int_list2, float_list2, str_list2] + + # + # Unspecified + # + for x in all_base + all_level_1 + all_level_2: + self.assertEqual(pairwise_schema_union(x, anything), x) + self.assertEqual(pairwise_schema_union(anything, x), x) + + # + # Variable classes + # + + # Incompatible cases + + self.assertIsNone(pairwise_schema_union(integer, string)) + self.assertIsNone(pairwise_schema_union(integer, boolean)) + self.assertIsNone(pairwise_schema_union(string, integer)) + self.assertIsNone(pairwise_schema_union(boolean, integer)) + + self.assertIsNone(pairwise_schema_union(floating, string)) + self.assertIsNone(pairwise_schema_union(floating, boolean)) + self.assertIsNone(pairwise_schema_union(string, floating)) + self.assertIsNone(pairwise_schema_union(boolean, floating)) + + # Compatible cases + self.assertEqual(pairwise_schema_union(floating, integer), floating) + self.assertEqual(pairwise_schema_union(integer, floating), floating) + + # + # Lists - a few important cases + # + + # lists of non-compatible types should not be combined + self.assertIsNone(pairwise_schema_union(str_list, int_list)) + self.assertIsNone(pairwise_schema_union(str_list, bool_list)) + self.assertIsNone(pairwise_schema_union(int_list, str_list)) + self.assertIsNone(pairwise_schema_union(bool_list, str_list)) + + # Lists of the same kind but with different nesting should not combine + self.assertIsNone(pairwise_schema_union(str_list, str_list2)) + self.assertIsNone(pairwise_schema_union(str_list2, str_list)) + + # empty list should not care about level + self.assertEqual(pairwise_schema_union(empty_list, str_list), str_list) + self.assertEqual(pairwise_schema_union(empty_list, str_list2), str_list2) + self.assertEqual(pairwise_schema_union(str_list, empty_list), str_list) + self.assertEqual(pairwise_schema_union(str_list2, empty_list), str_list2) + + # lists of floats and ints should combine to float + self.assertEqual(pairwise_schema_union(float_list, int_list), float_list) + self.assertEqual(pairwise_schema_union(float_list2, int_list2), float_list2) + self.assertEqual(pairwise_schema_union(int_list, float_list), float_list) + self.assertEqual(pairwise_schema_union(int_list2, float_list2), float_list2) + + #... but only at the same level + self.assertIsNone(pairwise_schema_union(float_list2, int_list)) + self.assertIsNone(pairwise_schema_union(float_list, int_list2)) + self.assertIsNone(pairwise_schema_union(int_list2, float_list)) + self.assertIsNone(pairwise_schema_union(int_list, float_list2)) + + + def test_schema_extraction(self): + pass + + +if __name__ == '__main__': + unittest.main() From a7578e49fb30e3456e8579f8b5174624e538b7f9 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 2 Sep 2022 14:22:46 +0100 Subject: [PATCH 14/82] Unit tests for config class, start of load/save --- src/sas/__init__.py | 2 + src/sas/config_system/config.py | 126 +++++++++++++++++++++++++-- src/sas/config_system/config_meta.py | 44 ++++++---- src/sas/version.py | 5 ++ test/config/utest_config.py | 60 ++++++++++--- 5 files changed, 202 insertions(+), 35 deletions(-) create mode 100644 src/sas/version.py diff --git a/src/sas/__init__.py b/src/sas/__init__.py index a97a621b11..0f380f1722 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -1,3 +1,5 @@ +from version import __version__ + import os import sys from sas.config_system import configuration as config diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index dedf875de3..34df82d2e0 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -1,12 +1,124 @@ -""" Configuration class - stores configuration information for SasView +r""" Configuration class - stores configuration information for SasView -The Config class cannot be subclassed or dynamically modified, -this prevents the config from having fields that are unspecified in -the base class, and makes it so that all usages of fields can be -automatically tracked. This allows the configs to be much more -easily maintained. -Dev note: I have opted not to use frozen dataclasses at this time + _____ ________ _______ _ + | __ \| ____\ \ / / ____| | + | | | | |__ \ \ / / (___ | | + | | | | __| \ \/ / \___ \| | + | |__| | |____ \ / ____) |_| + |_____/|______| \/ |_____/(_) + + + _____ ______ _____ _______ _ _ _____ _____ _ + | __ \| ____| /\ | __ \ |__ __| | | |_ _|/ ____| | + | |__) | |__ / \ | | | | | | | |__| | | | | (___ | | + | _ /| __| / /\ \ | | | | | | | __ | | | \___ \| | + | | \ \| |____ / ____ \| |__| | | | | | | |_| |_ ____) |_| + |_| \_\______/_/ \_\_____/ |_| |_| |_|_____|_____/(_) + + + +If you're looking to change a field in the config file, you should read this + + + +Configs +======= + +In general, configs are a nightmare from the perspective of code maintainability. +There are three main reasons for this + 1) They have a tendency to accumulate junk because people don't realise that a + config item is no longer needed + 2) It's hard to trace the usages and types because values are loaded at runtime + 3) Maintaining synchrony between config files and config usages is difficult, as + it is the users that have control over the config files. + +The Config class here attempts to resolve some of these issues in a way that +preserves as many of the current uses as possible. It is a compromise between +SasView's current methods, and more standard ways of handling configurations. + +Brief Outline +============= + +The main Config class provides a definition of the variables allowed in a config +file, along with their default values. This class is used to generate a schema +that determines how config files are read. Only a few types of variable are allowed + +* bool +* int +* float +* str +* Homogeneous lists of the above, to 10 levels of depth +* None and empty list (please try to avoid) + +Other types will throw an error at runtime when the schema is created. + +None types and +empty lists have no type information at runtime, so the schema cannot check/coerce +the type of config variables when they are loaded. It is best to avoid having these +as default values if possible. + +The presence of a config file is not necessary for the functioning of the config +system, only for making changes that differ from the default values. + + +What Belongs in a Config +======================== + +Things that do belong: + 1) Program settings that are configurable by users through the GUI + 2) Program settings that have no GUI editor, but that some advanced users + might want to set manually with a text editor + 3) Settings that control developer tools, e.g. debug modes + 4) Very little else + +Things that don't belong, but were previously in the config: + 1) dynamic content, i.e. values that are modified programmatically, + this includes variables that are defined in terms of other variables, + but otherwise don't change + 2) Paths to resources within sasview (use importlib.resources instead) + 3) Blocks of data that won't be modified by the user and used primarily + by single class - e.g. the text for a message + 4) Large blocks of text in general + +Making Changes to the Config Class +================================== + +As users have their own copy of the sasview configuration, deletions, +name changes, default value changes, and variable type changes +often constitute a breaking change from the perspective of version +control. The users locally stored config will, in general, not be +backwards compatible with the new config. Extreme caution should be +exercised - when changing the config, don't just think about the +problem at hand, but about the future maintainability of SasView in +general. + +Deleting from Config class: +Currently (02/09/2022) the consequences of providing an entry in a +config file that is not properly reflected in the Config class is a +error. To ease backward compatibility, it is possible to disable +the errors for a deleted class member by adding their name to +the `_deleted_attributes` list. The suggested deletion process would +be + +``` +[-] self.my_variable = 10 +[+] self._deleted_attributes.append("my_variable") +``` + +At major releases, additions to _deleted_attributes should be removed. + + +Other Design Decisions made for the Config Class +================================================ + +The Config class cannot be dynamically modified, this prevents the config +from having fields that are unspecified in the base class, +and makes it so that all usages of fields can be automatically tracked. + +Subclassing of Config is also disabled for similar reasons. + +I have opted not to use frozen dataclasses at this time because, as they currently work, the behaviour would make creating different configs difficult. """ diff --git a/src/sas/config_system/config_meta.py b/src/sas/config_system/config_meta.py index bb988a607c..86ecf5ce7a 100644 --- a/src/sas/config_system/config_meta.py +++ b/src/sas/config_system/config_meta.py @@ -1,7 +1,11 @@ -from typing import Optional, Dict, Any +from typing import Optional, Dict, Any, List import json import logging -from sas.config_system.schema_elements import create_schema_element, CoercionError +from sas.config_system.schema_elements import create_schema_element, CoercionError, SchemaElement + + + +logger = logging.getLogger("sas.config_system") class ConfigLocked(Exception): def __init__(self, message): @@ -25,11 +29,12 @@ def __init__(self): # they are referenced as strings in functions below # remember that the strings will have to be updated self._locked = False - self._schema = {} - self._modified_values = set() + self._schema: Dict[str, SchemaElement] = {} + self._deleted_attributes: List[str] = [] def finalise(self): - """ Call this to make this class 'final' """ + """ Call this at the end of the config to make this class 'final' + and to set up the config file schema""" self._schema = self.generate_schema() self._locked = True @@ -39,16 +44,22 @@ def update(self, data: Dict[str, Any]): for key in data: - if key not in self._schema: - logging.error(f"Unknown config key: '{key}', skipping") + # Skip over any deleted attributes + if key in self._deleted_attributes: + continue + + # Check the variable is in the schema + if key in self._schema: - else: try: coerced = self._schema[key].coerce(data[key]) setattr(self, key, coerced) except CoercionError as e: - logging.error(f"Cannot set set variable '{key}', improper type ({e.message})") + logger.error(f"Cannot set set variable '{key}', improper type ({e.message})") + + else: + logger.error(f"Unknown config key: '{key}', skipping") def generate_schema(self): @@ -61,17 +72,22 @@ def generate_schema(self): schema = {} variables = vars(self) for variable_name in variables: - if variable_name in ["_locked", "_schema", "_modified_values"]: + if variable_name in ["_locked", "_schema", "_deleted_attributes"]: continue schema[variable_name] = create_schema_element(variable_name, variables[variable_name]) return schema - def load(self, filename: str): + def load(self, file_object: StringIO): + + # TODO: Add check for major version change + + {} + pass - def save(self, filename: Optional[str]=None): + def save(self, file_object: StringIO): """ Save the configuration to a file""" #TODO: Implement save functionality to yaml (and load, with schema) raise NotImplementedError() @@ -81,10 +97,6 @@ def __setattr__(self, key, value): if key not in self.__dict__: raise ConfigLocked("New attribute attempt") - - # if not self._locked: - # self._modified_values.add(key) - super().__setattr__(key, value) diff --git a/src/sas/version.py b/src/sas/version.py new file mode 100644 index 0000000000..024bb246f3 --- /dev/null +++ b/src/sas/version.py @@ -0,0 +1,5 @@ +""" This file is just for containing the version number, nothing else + +It is imported by sas.__init__ so that sas.__version__ exists too""" + +__version__ = "5.0.5" \ No newline at end of file diff --git a/test/config/utest_config.py b/test/config/utest_config.py index 065629a9f1..c0bf3069d5 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -2,13 +2,13 @@ import unittest from sas import config from sas.config_system.schema_elements import \ - pairwise_schema_union, \ + pairwise_schema_union, create_schema_element, \ SchemaBool, SchemaInt, SchemaFloat, SchemaStr, \ - SchemaList, SchemaNonSpecified + SchemaList, SchemaNonSpecified, \ + CoercionError """ Unit tests for Config system. """ - class TestConfig(unittest.TestCase): def a_test_dict(self) -> dict: @@ -18,7 +18,7 @@ def a_test_dict(self) -> dict: all_variables = vars(config).copy() del all_variables["_locked"] del all_variables["_schema"] - del all_variables["_modified_values"] + del all_variables["_deleted_attributes"] # New values @@ -71,19 +71,59 @@ def test_valid_update(self): self.assertEqual(var, test_dict[key]) self.assertEqual(type(var), type(test_dict[key])) - def test_config_variable_change_tracker(self): - pass def test_invalid_update_bad_name(self): - pass + """ Check that an error is logged when there is a bad name in the config""" + + # Create a variable that isn't in the config + test_dict = self.a_test_dict() + + name = "x" + while name in test_dict: + name += "x" + + # try and set it + with self.assertLogs('sas.config_system', level="ERROR") as cm: + config.update({name: None}) + self.assertTrue(cm.output[0].startswith("ERROR:sas.config_system:")) def test_invalid_update_bad_type(self): - pass + + """Check that bad types give an error, this tries a bunch of incompatable types with each of the + existing entries in config + + For this test to be useful it requires config to have at least one default entry with a schematisable type + """ + + test_dict = self.a_test_dict() + for key in test_dict: + + # find types that should be incompatable + for test_value in [False, 0, 1.0, "string", [1,2,3], [[["deep"]]]]: + test_value_schema = create_schema_element("value not important", test_value) + + try: + config._schema[key].coerce(test_value) + + except CoercionError: + + # Only test the ones that fail, i.e. cannot be coerced + if pairwise_schema_union(test_value_schema, config._schema[key]) is None: + with self.assertLogs('sas.config_system', level="ERROR") as cm: + + # Try the bad value + config.update({key: test_value}) + + self.assertTrue(cm.output[0].startswith("ERROR:sas.config_system:")) + + + def test_load_and_save(self): pass def test_schema_union(self): + """ Check the typing behaviour of the schema system""" anything = SchemaNonSpecified() @@ -168,9 +208,5 @@ def test_schema_union(self): self.assertIsNone(pairwise_schema_union(int_list, float_list2)) - def test_schema_extraction(self): - pass - - if __name__ == '__main__': unittest.main() From eb93ad14fcf898fa030d55ff85287ff855a9d412 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 2 Sep 2022 16:56:12 +0100 Subject: [PATCH 15/82] load and save implemented, tests pass --- src/sas/__init__.py | 2 +- src/sas/config_system/config_meta.py | 103 +++++++++++++---- src/sas/config_system/schema_elements.py | 12 +- test/config/utest_config.py | 135 ++++++++++++++++++++++- 4 files changed, 220 insertions(+), 32 deletions(-) diff --git a/src/sas/__init__.py b/src/sas/__init__.py index 0f380f1722..8758a7e48b 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -1,4 +1,4 @@ -from version import __version__ +from sas.version import __version__ import os import sys diff --git a/src/sas/config_system/config_meta.py b/src/sas/config_system/config_meta.py index 86ecf5ce7a..eb72c17796 100644 --- a/src/sas/config_system/config_meta.py +++ b/src/sas/config_system/config_meta.py @@ -1,11 +1,17 @@ -from typing import Optional, Dict, Any, List +from typing import Optional, Dict, Any, List, Set import json import logging from sas.config_system.schema_elements import create_schema_element, CoercionError, SchemaElement +from copy import deepcopy +import sas +logger = logging.getLogger("sas.config_system") -logger = logging.getLogger("sas.config_system") +class MalformedFile(Exception): + def __init__(self, message): + super().__init__(message) + class ConfigLocked(Exception): def __init__(self, message): @@ -26,17 +32,21 @@ class ConfigBase: def __init__(self): # Note on editing the following variables: - # they are referenced as strings in functions below - # remember that the strings will have to be updated + # they are referenced as strings via _meta_attributes + # you need to keep this up to date (probably shouldn't be + # changing it anyway) self._locked = False self._schema: Dict[str, SchemaElement] = {} + self._defaults: Dict[str, SchemaElement] = {} self._deleted_attributes: List[str] = [] + self._meta_attributes = ["_locked", "_schema", "_defaults", "_deleted_attributes", "_meta_attributes"] def finalise(self): """ Call this at the end of the config to make this class 'final' and to set up the config file schema""" - self._schema = self.generate_schema() + self._schema = self._generate_schema() + self._defaults = self._state_copy() self._locked = True def update(self, data: Dict[str, Any]): @@ -61,42 +71,93 @@ def update(self, data: Dict[str, Any]): else: logger.error(f"Unknown config key: '{key}', skipping") + def save(self, file): + """ Save config file + + Only changed variables will be included in the saved file + """ + data = {} + for key in self._defaults: + old_value = self._defaults[key] + new_value = getattr(self, key) + if new_value != old_value: + data[key] = new_value + + output_data = { + "sasview_version": sas.__version__, + "config_data": data} + + json.dump(output_data, file) + + def load(self, file): + """ Load config file """ + data = json.load(file) + + if "sasview_version" not in data: + raise MalformedFile("Malformed config file - no 'sasview_version' key") + + try: + parts = [int(s) for s in data["sasview_version"].split(".")] + if len(parts) != 3: + raise Exception + + except Exception: + raise MalformedFile("Malformed version in config file, should be a string of the form 'X.Y.Z'") + + if "config_data" not in data: + raise MalformedFile("Malformed config file - no 'config_data' key") + + if not isinstance(data["config_data"], dict): + raise MalformedFile("Malformed config file - expected 'config_data' to be a dictionary") + + + # Check major version + file_version = data["sasview_version"] + file_major_version = file_version.split(".")[0] + sasview_major_version = sas.__version__.split(".")[0] - def generate_schema(self): + if int(file_major_version) != int(sasview_major_version): + logger.warning(f"Attempting to used outdated config file (config is" + f" for {file_version}, this SasView version is {sas.__version__})") + + self.update(data["config_data"]) + + def _state_copy(self) -> Dict[str, Any]: + """ Get a copy of all the data in the config""" + state: Dict[str, Any] = {} + variables = vars(self) + for variable_name in variables: + if variable_name in self._meta_attributes: + continue + + state[variable_name] = deepcopy(variables[variable_name]) + + return state + + def _generate_schema(self) -> Dict[str, SchemaElement]: """ Auto-generate schema for the current config class and validate config class Note: there is an assumption here that the class of the value in the default config file is """ - schema = {} + schema: Dict[str, SchemaElement] = {} variables = vars(self) for variable_name in variables: - if variable_name in ["_locked", "_schema", "_deleted_attributes"]: + if variable_name in self._meta_attributes: continue schema[variable_name] = create_schema_element(variable_name, variables[variable_name]) return schema - def load(self, file_object: StringIO): - - # TODO: Add check for major version change - - {} - - pass - - def save(self, file_object: StringIO): - """ Save the configuration to a file""" - #TODO: Implement save functionality to yaml (and load, with schema) - raise NotImplementedError() - def __setattr__(self, key, value): if hasattr(self, "_locked") and self._locked: if key not in self.__dict__: raise ConfigLocked("New attribute attempt") + + super().__setattr__(key, value) diff --git a/src/sas/config_system/schema_elements.py b/src/sas/config_system/schema_elements.py index 8030241c5e..3154b3c03b 100644 --- a/src/sas/config_system/schema_elements.py +++ b/src/sas/config_system/schema_elements.py @@ -2,6 +2,7 @@ from typing import Optional, List import logging + """ Type representation for config elements Unfortunately, json schemas are not flexible enough to make this unnecessary""" @@ -112,7 +113,8 @@ def coerce(self, value): raise CoercionError(f"Cannot coerce {value} ({type(value)}) to list") if not isinstance(value, list): - logging.warning(f"Corercing variable of type {type(value)} to list ({value})") + logger = logging.getLogger(self.__class__.__name__) + logger.warning(f"Corercing variable of type {type(value)} to list ({value})") return [self.child_type.coerce(x) for x in value] @@ -126,7 +128,7 @@ def __repr__(self): return f"SchemaList({repr(self.child_type)})" -def create_schema_element(name: str, value, recursion_depth: int=10): +def create_schema_element(name: str, value, recursion_depth: int=10) -> SchemaElement: """ Get an appropriate schema element for a specified config datum""" # Limits the depth of list config items @@ -134,7 +136,8 @@ def create_schema_element(name: str, value, recursion_depth: int=10): raise SchemaError(f"Config element '{name}' is too nested, or is self-referential") if value is None: - logging.warning(f"Non-specified type for variable '{name}'") + logger = logging.getLogger("create_schema_element") + logger.warning(f"Non-specified type for variable '{name}'") return SchemaNonSpecified() # List case @@ -142,7 +145,8 @@ def create_schema_element(name: str, value, recursion_depth: int=10): # Empty list if len(value) == 0: - logging.warning(f"Non-specified list type for variable '{name}'") + logger = logging.getLogger("create_schema_element") + logger.warning(f"Non-specified list type for variable '{name}'") return SchemaList(SchemaNonSpecified()) elif len(value) == 1: diff --git a/test/config/utest_config.py b/test/config/utest_config.py index c0bf3069d5..7c3e5a454c 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -1,13 +1,25 @@ +""" Unit tests for Config system. """ + import unittest + +from io import StringIO +import json + +import sas + from sas import config +from sas.config_system.config import Config + +from sas.config_system.config_meta import MalformedFile + from sas.config_system.schema_elements import \ pairwise_schema_union, create_schema_element, \ SchemaBool, SchemaInt, SchemaFloat, SchemaStr, \ SchemaList, SchemaNonSpecified, \ CoercionError -""" Unit tests for Config system. """ + class TestConfig(unittest.TestCase): @@ -16,9 +28,8 @@ def a_test_dict(self) -> dict: # config variables (exclude the ones used by the base class) all_variables = vars(config).copy() - del all_variables["_locked"] - del all_variables["_schema"] - del all_variables["_deleted_attributes"] + for skipped in config._meta_attributes: + del all_variables[skipped] # New values @@ -117,10 +128,122 @@ def test_invalid_update_bad_type(self): self.assertTrue(cm.output[0].startswith("ERROR:sas.config_system:")) + def test_save_basics(self): + file = StringIO() + + # Check saving with no changes, should be empty and + config = Config() + config.save(file) + + file.seek(0) + + observed = json.load(file) + + empty_file = { + "sasview_version": sas.__version__, + "config_data": {} + } + + self.assertEqual(observed, empty_file) + + + + def test_save_changes(self): + """ Check that save saves a change that has been made""" + + test_dict = self.a_test_dict() + for key in test_dict: + file = StringIO() + config = Config() + config.update({key: test_dict[key]}) + config.save(file) + file.seek(0) + + observed = json.load(file) + + expected = { + "sasview_version": sas.__version__, + "config_data": {key: test_dict[key]} + } + + self.assertEqual(observed, expected) + + def test_only_save_actual_changes(self): + """ Check that if a field is set back to its default, it isn't saved in the config""" + + # (1) make a single change + # (2) change back to the default value + # (3) Check + + empty_file = { + "sasview_version": sas.__version__, + "config_data": {} + } + + backup = Config() + + test_dict = self.a_test_dict() + for key in test_dict: + file = StringIO() + config = Config() + + config.update({key: test_dict[key]}) + config.update({key: getattr(backup, key)}) + config.save(file) + + file.seek(0) + observed = json.load(file) + + self.assertEqual(observed, empty_file) + + + def test_bad_config_version(self): + file = StringIO() + + json.dump({ + "sasview_version": "1.2.3", + "config_data": {}}, + file) + + file.seek(0) + + with self.assertLogs('sas.config_system', level="WARN") as cm: + # Try the bad value + config.load(file) + + self.assertTrue(cm.output[0].startswith("WARNING:sas.config_system:")) + + def test_bad_config_file_structure(self): + bad_structures = [ + { + "sasview_version": sas.__version__, + "quanfig_data": {} + }, + { + "sasview_version": "bad version", + "config_data": {} + }, + { + "sassy_verberry": sas.__version__, + "config_data": {} + }, + { + "sasview_version": sas.__version__, + "config_data": [] + }, + {} + ] + + for structure in bad_structures: + file = StringIO() + + json.dump(structure,file) + + file.seek(0) + with self.assertRaises(MalformedFile): + config.load(file) - def test_load_and_save(self): - pass def test_schema_union(self): """ Check the typing behaviour of the schema system""" From 3b4566c8073f4f884839fd5e9aeac94873a0fe7e Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 2 Sep 2022 17:08:34 +0100 Subject: [PATCH 16/82] Config saved to config.json on exit, a decision needs to be made about where this should be in future --- src/sas/qtgui/MainWindow/GuiManager.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index ace591c800..c3fc74a23a 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1300,20 +1300,10 @@ def saveCustomConfig(self): """ Save the config file based on current session values """ - - config.save() - return - - # TODO: Remove the rest of this function - - # Load the current file - config_content = GuiUtils.custom_config - - changed = self.customSavePaths(config_content) - changed = changed or self.customSaveOpenCL(config_content) - - if changed: - self.writeCustomConfig(config_content) + # TODO: Decide what to do with config locations + logger.warning("Config paths have not yet been set up") + with open("config.json", 'w') as file: + config.save(file) def customSavePaths(self, config_content): """ From 96b1dee8f1928038c8dea9dfacd840d2aab0e012 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 2 Sep 2022 17:27:56 +0100 Subject: [PATCH 17/82] Fixed issue with test values that should be different for defaults not being so --- test/config/utest_config.py | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/test/config/utest_config.py b/test/config/utest_config.py index 7c3e5a454c..e4fde29b6f 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -31,39 +31,34 @@ def a_test_dict(self) -> dict: for skipped in config._meta_attributes: del all_variables[skipped] - - # New values - bool_value = True - int_value = 42 - float_value = 2.7669 - string_value_suffix = 7 + string_value_suffix = 42 target_values = {} for key in all_variables: if isinstance(all_variables[key], bool): - target_values[key] = bool_value - bool_value = not bool_value + target_values[key] = not all_variables[key] elif isinstance(all_variables[key], int): - target_values[key] = int_value - int_value += 1 + target_values[key] = all_variables[key] + 42 elif isinstance(all_variables[key], float): - target_values[key] = int_value - float_value += 3.149999 + target_values[key] = all_variables[key] + 3.149999 elif isinstance(all_variables[key], str): - target_values[key] = f"A string ending in the number {string_value_suffix}" + target_values[key] = all_variables[key] + f" with string making it end in the number {string_value_suffix}" string_value_suffix += 1 + elif all_variables[key] == []: + target_values[key] = ["something else"] + elif isinstance(all_variables[key], list): - target_values[key] = all_variables[key] * 2 # Finding a more specific test is too complicated + target_values[key] = all_variables[key] * 2 elif all_variables[key] is None: - target_values[key] = None + target_values[key] = "something" else: raise TypeError(f"Config entry '{key}' is not bool, int, float, str ({all_variables[key]})") From c2d028a38649c8116805d5a7061dcb5b50781600 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 2 Sep 2022 18:37:57 +0100 Subject: [PATCH 18/82] Used config copies in config, not the main config item as this appears to affect tests --- src/sas/config_system/config.py | 4 ++-- test/config/utest_config.py | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 34df82d2e0..e685daf9e5 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -25,8 +25,8 @@ Configs ======= -In general, configs are a nightmare from the perspective of code maintainability. -There are three main reasons for this +Configs are a nightmare from the perspective of code maintainability. There are +three main reasons for this 1) They have a tendency to accumulate junk because people don't realise that a config item is no longer needed 2) It's hard to trace the usages and types because values are loaded at runtime diff --git a/test/config/utest_config.py b/test/config/utest_config.py index e4fde29b6f..b02d72f94b 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -8,7 +8,6 @@ import sas -from sas import config from sas.config_system.config import Config from sas.config_system.config_meta import MalformedFile @@ -26,6 +25,8 @@ class TestConfig(unittest.TestCase): def a_test_dict(self) -> dict: """ A dictionary with field names from the config, but with different values""" + config = Config() + # config variables (exclude the ones used by the base class) all_variables = vars(config).copy() for skipped in config._meta_attributes: @@ -68,6 +69,7 @@ def a_test_dict(self) -> dict: def test_valid_update(self): """ Test setting variables with known valid options""" + config = Config() test_dict = self.a_test_dict() config.update(test_dict) @@ -81,6 +83,8 @@ def test_valid_update(self): def test_invalid_update_bad_name(self): """ Check that an error is logged when there is a bad name in the config""" + config = Config() + # Create a variable that isn't in the config test_dict = self.a_test_dict() @@ -101,6 +105,7 @@ def test_invalid_update_bad_type(self): For this test to be useful it requires config to have at least one default entry with a schematisable type """ + config = Config() test_dict = self.a_test_dict() for key in test_dict: @@ -193,6 +198,8 @@ def test_only_save_actual_changes(self): def test_bad_config_version(self): + + config = Config() file = StringIO() json.dump({ @@ -209,6 +216,9 @@ def test_bad_config_version(self): self.assertTrue(cm.output[0].startswith("WARNING:sas.config_system:")) def test_bad_config_file_structure(self): + + config = Config() + bad_structures = [ { "sasview_version": sas.__version__, From 41fed40ec142beb32ab0aba62da0f40997b85179 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 11:21:04 +0100 Subject: [PATCH 19/82] Removed installer_generator files --- installers/installer_generator.py | 372 --------------------------- installers/installer_generator64.py | 374 ---------------------------- 2 files changed, 746 deletions(-) delete mode 100644 installers/installer_generator.py delete mode 100644 installers/installer_generator64.py diff --git a/installers/installer_generator.py b/installers/installer_generator.py deleted file mode 100644 index 9fd6f40192..0000000000 --- a/installers/installer_generator.py +++ /dev/null @@ -1,372 +0,0 @@ -""" -This module generates .iss file according to the local config of -the current application. -""" -from __future__ import print_function - -import os -import sys -import string - -root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -sys.path.insert(0, os.path.join(root, 'sasview-install', 'Lib', 'site-packages')) - -from sas import config as config - -#REG_PROGRAM = """{app}\MYPROG.EXE"" ""%1""" -APPLICATION = str(config.__appname__) + '.exe' -AppName = str(config.__appname__) -AppVerName = str(config.__appname__) + '-' + str(config.__version__) -Dev = '' -if AppVerName.lower().count('dev') > 0: - Dev = '-Dev' -AppPublisher = config._copyright -AppPublisherURL = config._homepage -AppSupportURL = config._homepage -AppUpdatesURL = config._homepage -ChangesEnvironment = 'true' -DefaultDirName = os.path.join("{pf}" , AppName+Dev) -DefaultGroupName = os.path.join(config.DefaultGroupName, AppVerName) - -OutputBaseFilename = config.OutputBaseFilename -SetupIconFile = config.SetupIconFile_win -LicenseFile = 'license.txt' -DisableProgramGroupPage = 'yes' -Compression = 'lzma' -SolidCompression = 'yes' -PrivilegesRequired = 'none' -INSTALLER_FILE = 'installer' - -icon_path = config.icon_path -media_path = config.media_path -test_path = config.test_path - -def find_extension(): - """ - Describe the extensions that can be read by the current application - """ - list_data = [] - list_app =[] - try: - - #(ext, type, name, flags) - from sas.sascalc.dataloader.loader import Loader - wild_cards = Loader().get_wildcards() - for item in wild_cards: - #['All (*.*)|*.*'] - file_type, ext = item.split("|*", 1) - if ext.strip() not in ['.*', ''] and ext.strip() not in list_data: - list_data.append((ext, 'string', file_type)) - except Exception: - pass - try: - file_type, ext = config.APPLICATION_WLIST.split("|*", 1) - if ext.strip() not in ['.', ''] and ext.strip() not in list_app: - list_app.append((ext, 'string', file_type)) - except Exception: - pass - try: - for item in config.PLUGINS_WLIST: - file_type, ext = item.split("|*", 1) - if ext.strip() not in ['.', ''] and ext.strip() not in list_app: - list_app.append((ext, 'string', file_type)) - except Exception: - pass - return list_data, list_app -DATA_EXTENSION, APP_EXTENSION = find_extension() - -def write_registry(data_extension=None, app_extension=None): - """ - create file association for windows. - Allow open file on double click - """ - msg = "" - if data_extension is not None and data_extension: - msg = "\n\n[Registry]\n" - openwithlist = "OpenWithList\%s" % str(APPLICATION) - for (ext, type, _) in data_extension: - list = os.path.join(ext, openwithlist) - msg += """Root: HKCR;\tSubkey: "%s";\t""" % str(list) - msg += """ Flags: %s""" % str('uninsdeletekey noerror') - msg += "\n" - #list the file on right-click - msg += """Root: HKCR; Subkey: "applications\%s\shell\open\command";\t"""\ - % str(APPLICATION) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" %str('') - msg += """ValueData: \"""{app}\%s"" ""%s1\"""; \t"""% (str(APPLICATION), - str('%')) - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - user_list = "Software\Classes" - for (ext, type, _) in data_extension: - list = os.path.join(user_list, ext, openwithlist) - msg += """Root: HKCU;\tSubkey: "%s";\t""" % str(list) - msg += """ Flags: %s""" % str('uninsdeletekey noerror') - msg += "\n" - #list the file on right-click - user_list = os.path.join("Software", "Classes", "applications") - msg += """Root: HKCU; Subkey: "%s\%s\shell\open\command";\t"""\ - % (str(user_list), str(APPLICATION)) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" %str('') - msg += """ValueData: \"""{app}\%s"" ""%s1\"""; \t"""% (str(APPLICATION), - str('%')) - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - if app_extension is not None and app_extension: - for (ext, type, _) in app_extension: - msg += """Root: HKCR;\tSubkey: "%s";\t""" % str(ext) - msg += """ValueType: %s;\t""" % str(type) - #file type empty set the current application as the default - #reader for this file. change the value of file_type to another - #string modify the default reader - file_type = '' - msg += """ValueName: "%s";\t""" % str('') - msg += """ValueData: "{app}\%s";\t""" % str(APPLICATION) - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - msg += """Root: HKCR; Subkey: "{app}\%s";\t""" % str(APPLICATION) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" % str('') - msg += """ValueData: "{app}\%s";\t""" % str("SasView File") - msg += """ Flags: %s \t""" % str("uninsdeletekey noerror") - msg += "\n" - - #execute the file on double-click - msg += """Root: HKCR; Subkey: "{app}\%s\shell\open\command";\t""" % str(APPLICATION) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" %str('') - msg += """ValueData: \"""{app}\%s"" ""%s1\""";\t"""% (str(APPLICATION), - str('%')) - msg += """ Flags: %s \t""" % str("uninsdeletevalue noerror") - msg += "\n" - #create default icon - msg += """Root: HKCR; Subkey: "{app}\%s";\t""" % str(SetupIconFile) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" % str('') - msg += """ValueData: "{app}\%s,0";\t""" % str(APPLICATION) - msg += """ Flags: %s \t""" % str("uninsdeletevalue noerror") - msg += "\n" - - - #SASVIEWPATH - msg += """Root: HKLM; Subkey: "%s";\t""" % str('SYSTEM\CurrentControlSet\Control\Session Manager\Environment') - msg += """ValueType: %s; """ % str('expandsz') - msg += """ValueName: "%s";\t""" % str('SASVIEWPATH') - msg += """ValueData: "{app}";\t""" - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - - #PATH - msg += """; Write to PATH (below) is disabled; need more tests\n""" - msg += """;Root: HKCU; Subkey: "%s";\t""" % str('Environment') - msg += """ValueType: %s; """ % str('expandsz') - msg += """ValueName: "%s";\t""" % str('PATH') - msg += """ValueData: "%s;{olddata}";\t""" % str('%SASVIEWPATH%') - msg += """ Check: %s""" % str('NeedsAddPath()') - msg += "\n" - - return msg - -def write_languages(languages=('english',), msfile="compiler:Default.isl"): - """ - define the language of the application - """ - msg = '' - if languages: - msg = "\n\n[Languages]\n" - for lang in languages: - msg += """Name: "%s";\tMessagesFile: "%s"\n""" % (str(lang), str(msfile)) - return msg - -def write_tasks(): - """ - create desktop icon - """ - msg = """\n\n[Tasks]\n""" - msg += """Name: "desktopicon";\tDescription: "{cm:CreateDesktopIcon}";\t""" - msg += """GroupDescription: "{cm:AdditionalIcons}";\tFlags: unchecked\n""" - msg += """Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}";\t""" - msg += """GroupDescription: "{cm:AdditionalIcons}";\n""" - return msg - -dist_path = "dist\sasview" -def write_file(): - """ - copy some data files - """ - msg = "\n\n[Files]\n" - msg += """Source: "%s\%s";\t""" % (dist_path, str(APPLICATION)) - msg += """DestDir: "{app}";\tFlags: ignoreversion\n""" - msg += """Source: "dist\sasview\*";\tDestDir: "{app}";\t""" - msg += """Flags: ignoreversion recursesubdirs createallsubdirs\n""" - msg += """Source: "dist\sasview\plugin_models\*";\tDestDir: "{userdesktop}\..\.sasview\plugin_models";\t""" - msg += """Flags: recursesubdirs createallsubdirs\n""" - msg += """Source: "dist\sasview\custom_config.py";\tDestDir: "{userdesktop}\..\.sasview\config";\t""" - msg += """Flags: recursesubdirs createallsubdirs\n""" - #msg += """Source: "dist\default_categories.json"; DestDir: "{userdesktop}\..\.sasview";\t""" - #msg += """DestName: "categories.json";\n""" - msg += """;\tNOTE: Don't use "Flags: ignoreversion" on any shared system files""" - return msg - -def write_icon(): - """ - Create application icon - """ - msg = """\n\n[Icons]\n""" - msg += """Name: "{group}\%s";\t""" % str(AppName) - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """WorkingDir: "{app}"; IconFilename: "{app}\images\\ball.ico" \n""" - msg += """Name: "{group}\{cm:UninstallProgram, %s}";\t""" % str(AppName) - msg += """ Filename: "{uninstallexe}" \n""" - msg += """Name: "{commondesktop}\%s";\t""" % str(AppVerName) - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """Tasks: desktopicon; WorkingDir: "{app}" ; IconFilename: "{app}\images\\ball.ico" \n""" - msg += """Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\%s";\t""" % str(AppVerName) - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """Tasks: quicklaunchicon; WorkingDir: "{app}"; IconFilename: "{app}\images\\ball.ico" \n""" - return msg - -def write_run(): - """ - execute some file - """ - msg = """\n\n[Run]\n""" - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """Description: "{cm:LaunchProgram, %s}";\t""" %str(AppName) - msg += """Flags: nowait postinstall skipifsilent\n""" - msg += """; Install the Microsoft C++ DLL redistributable package if it is """ - msg += """provided and the DLLs are not present on the target system.\n""" - msg += """; Note that the redistributable package is included if the app was """ - msg += """built using Python 2.6 or 2.7, but not with 2.5.\n""" - msg += """; Parameter options:\n""" - msg += """; - for silent install use: "/q"\n""" - msg += """; - for silent install with progress bar use: "/qb"\n""" - msg += """; - for silent install with progress bar but disallow """ - msg += """cancellation of operation use: "/qb!"\n""" - msg += """; Note that we do not use the postinstall flag as this would """ - msg += """display a checkbox and thus require the user to decide what to do.\n""" - msg += """;Filename: "{app}\\vcredist_x86.exe"; Parameters: "/qb!"; """ - msg += """WorkingDir: "{tmp}"; StatusMsg: "Installing Microsoft Visual """ - msg += """C++ 2008 Redistributable Package ..."; Check: InstallVC90CRT(); """ - msg += """Flags: skipifdoesntexist waituntilterminated\n""" - return msg - -def write_dirs(): - """ - Define Dir permission - """ - msg = """\n\n[Dirs]\n""" - msg += """Name: "{app}\%s";\t""" % str('') - msg += """Permissions: everyone-modify\t""" - msg += """\n""" - return msg - -def write_code(): - """ - Code that checks the existing path and snaviewpath - in the environmental viriables/PATH - """ - msg = """\n\n[Code]\n""" - msg += """function InstallVC90CRT(): Boolean;\n""" - msg += """begin\n""" - msg += """ Result := not DirExists('C:\WINDOWS\WinSxS\\x86_Microsoft.VC90.""" - msg += """CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375');\n""" - msg += """end;\n\n""" - msg += """function NeedsAddPath(): boolean;\n""" - msg += """var\n""" - msg += """ oldpath: string;\n""" - msg += """ newpath: string;\n""" - msg += """ pathArr: TArrayOfString;\n""" - msg += """ i: Integer;\n""" - msg += """begin\n""" - msg += """ RegQueryStringValue(HKEY_CURRENT_USER,'Environment',""" - msg += """'PATH', oldpath)\n""" - msg += """ oldpath := oldpath + ';';\n""" - msg += """ newpath := '%SASVIEWPATH%';\n""" - msg += """ i := 0;\n""" - msg += """ while (Pos(';', oldpath) > 0) do begin\n""" - msg += """ SetArrayLength(pathArr, i+1);\n""" - msg += """ pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);\n""" - msg += """ oldpath := Copy(oldpath, Pos(';', oldpath)+1,""" - msg += """ Length(oldpath));\n""" - msg += """ i := i + 1;\n""" - msg += """ // Check if current directory matches app dir\n""" - msg += """ if newpath = pathArr[i-1] \n""" - msg += """ then begin\n""" - msg += """ Result := False;\n""" - msg += """ exit;\n""" - msg += """ end;\n""" - msg += """ end;\n""" - msg += """ Result := True;\n""" - msg += """end;\n""" - msg += """\n""" - return msg - -def write_uninstalldelete(): - """ - Define uninstalldelete - """ - msg = """\n[UninstallDelete]\n""" - msg += """; Delete directories and files that are dynamically created by """ - msg += """the application (i.e. at runtime).\n""" - msg += """Type: filesandordirs; Name: "{app}\.matplotlib"\n""" - msg += """Type: files; Name: "{app}\*.*"\n""" - msg += """; The following is a workaround for the case where the """ - msg += """application is installed and uninstalled but the\n""" - msg += """;{app} directory is not deleted because it has user files. """ - msg += """Then the application is installed into the\n""" - msg += """; existing directory, user files are deleted, and the """ - msg += """application is un-installed again. Without the\n""" - msg += """; directive below, {app} will not be deleted because Inno Setup """ - msg += """did not create it during the previous\n""" - msg += """; installation.\n""" - msg += """Type: dirifempty; Name: "{app}"\n""" - msg += """\n""" - return msg - -def generate_installer(): - """ - """ - TEMPLATE = "\n; Script generated by the Inno Setup Script Wizard\n" - TEMPLATE += "; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!" - TEMPLATE += "\n[Setup]\n\n" - TEMPLATE += "ChangesAssociations=%s\n" %str('yes') - TEMPLATE += "AppName=%s\n" % str(AppName) - TEMPLATE += "AppVerName=%s\n" % str(AppVerName) - TEMPLATE += "AppPublisher=%s\n" % str(AppPublisher) - TEMPLATE += "AppPublisherURL=%s\n" % str(AppPublisherURL) - TEMPLATE += "AppSupportURL=%s\n" % str(AppSupportURL) - TEMPLATE += "AppUpdatesURL=%s \n" % str(AppUpdatesURL) - TEMPLATE += "ChangesEnvironment=%s \n" % str(ChangesEnvironment) - TEMPLATE += "DefaultDirName=%s\n" % str(DefaultDirName) - TEMPLATE += "DefaultGroupName=%s\n" % str(DefaultGroupName) - TEMPLATE += "DisableProgramGroupPage=%s\n" % str(DisableProgramGroupPage) - TEMPLATE += "LicenseFile=%s\n" % str(LicenseFile) - TEMPLATE += "OutputBaseFilename=%s\n" % str(OutputBaseFilename) - TEMPLATE += "SetupIconFile=%s\n" % str(SetupIconFile) - TEMPLATE += "Compression=%s\n" % str(Compression) - TEMPLATE += "SolidCompression=%s\n" % str(SolidCompression) - TEMPLATE += "PrivilegesRequired=%s\n" % str(PrivilegesRequired) - TEMPLATE += "UsePreviousAppDir=no\n" - - TEMPLATE += write_registry(data_extension=DATA_EXTENSION, - app_extension=APP_EXTENSION) - TEMPLATE += write_languages() - TEMPLATE += write_tasks() - TEMPLATE += write_file() - TEMPLATE += write_icon() - TEMPLATE += write_run() - TEMPLATE += write_dirs() - TEMPLATE += write_code() - TEMPLATE += write_uninstalldelete() - path = '%s.iss' % str(INSTALLER_FILE) - f = open(path,'w') - f.write(TEMPLATE) - f.close() - print("Generate Inno setup installer script complete") - print("A new file %s.iss should be created.Please refresh your directory" % str(INSTALLER_FILE)) - -if __name__ == "__main__": - generate_installer() diff --git a/installers/installer_generator64.py b/installers/installer_generator64.py deleted file mode 100644 index e390f69798..0000000000 --- a/installers/installer_generator64.py +++ /dev/null @@ -1,374 +0,0 @@ -""" -This module generates .iss file according to the local config of -the current application. -""" -from __future__ import print_function - -import os -import sys -import string - -root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -sys.path.insert(0, os.path.join(root, 'sasview-install', 'Lib', 'site-packages')) -from sas import config as config - -#REG_PROGRAM = """{app}\MYPROG.EXE"" ""%1""" -APPLICATION = str(config.__appname__) + '.exe' -AppName = str(config.__appname__) -AppVerName = str(config.__appname__) + '-' + str(config.__version__) -Dev = '' -if AppVerName.lower().count('dev') > 0: - Dev = '-Dev' -AppPublisher = config._copyright -AppPublisherURL = config._homepage -AppSupportURL = config._homepage -AppUpdatesURL = config._homepage -ChangesEnvironment = 'true' -DefaultDirName = os.path.join("{pf}" , AppName+Dev) -DefaultGroupName = os.path.join(config.DefaultGroupName, AppVerName) - -OutputBaseFilename = config.OutputBaseFilename -SetupIconFile = config.SetupIconFile_win -LicenseFile = 'license.txt' -DisableProgramGroupPage = 'yes' -DisableDirPage = 'no' -Compression = 'lzma' -SolidCompression = 'yes' -PrivilegesRequired = 'none' -INSTALLER_FILE = 'installer' - -icon_path = config.icon_path -media_path = config.media_path -test_path = config.test_path - -def find_extension(): - """ - Describe the extensions that can be read by the current application - """ - list_data = [] - list_app =[] - try: - - #(ext, type, name, flags) - from sas.sascalc.dataloader.loader import Loader - wild_cards = Loader().get_wildcards() - for item in wild_cards: - #['All (*.*)|*.*'] - file_type, ext = item.split("|*", 1) - if ext.strip() not in ['.*', ''] and ext.strip() not in list_data: - list_data.append((ext, 'string', file_type)) - except Exception: - pass - try: - file_type, ext = config.APPLICATION_WLIST.split("|*", 1) - if ext.strip() not in ['.', ''] and ext.strip() not in list_app: - list_app.append((ext, 'string', file_type)) - except Exception: - pass - try: - for item in config.PLUGINS_WLIST: - file_type, ext = item.split("|*", 1) - if ext.strip() not in ['.', ''] and ext.strip() not in list_app: - list_app.append((ext, 'string', file_type)) - except Exception: - pass - return list_data, list_app -DATA_EXTENSION, APP_EXTENSION = find_extension() - -def write_registry(data_extension=None, app_extension=None): - """ - create file association for windows. - Allow open file on double click - """ - msg = "" - if data_extension is not None and data_extension: - msg = "\n\n[Registry]\n" - openwithlist = "OpenWithList\%s" % str(APPLICATION) - for (ext, type, _) in data_extension: - list = os.path.join(ext, openwithlist) - msg += """Root: HKCR;\tSubkey: "%s";\t""" % str(list) - msg += """ Flags: %s""" % str('uninsdeletekey noerror') - msg += "\n" - #list the file on right-click - msg += """Root: HKCR; Subkey: "applications\%s\shell\open\command";\t"""\ - % str(APPLICATION) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" %str('') - msg += """ValueData: \"""{app}\%s"" ""%s1\"""; \t"""% (str(APPLICATION), - str('%')) - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - user_list = "Software\Classes" - for (ext, type, _) in data_extension: - list = os.path.join(user_list, ext, openwithlist) - msg += """Root: HKCU;\tSubkey: "%s";\t""" % str(list) - msg += """ Flags: %s""" % str('uninsdeletekey noerror') - msg += "\n" - #list the file on right-click - user_list = os.path.join("Software", "Classes", "applications") - msg += """Root: HKCU; Subkey: "%s\%s\shell\open\command";\t"""\ - % (str(user_list), str(APPLICATION)) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" %str('') - msg += """ValueData: \"""{app}\%s"" ""%s1\"""; \t"""% (str(APPLICATION), - str('%')) - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - if app_extension is not None and app_extension: - for (ext, type, _) in app_extension: - msg += """Root: HKCR;\tSubkey: "%s";\t""" % str(ext) - msg += """ValueType: %s;\t""" % str(type) - #file type empty set the current application as the default - #reader for this file. change the value of file_type to another - #string modify the default reader - file_type = '' - msg += """ValueName: "%s";\t""" % str('') - msg += """ValueData: "{app}\%s";\t""" % str(APPLICATION) - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - msg += """Root: HKCR; Subkey: "{app}\%s";\t""" % str(APPLICATION) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" % str('') - msg += """ValueData: "{app}\%s";\t""" % str("SasView File") - msg += """ Flags: %s \t""" % str("uninsdeletekey noerror") - msg += "\n" - - #execute the file on double-click - msg += """Root: HKCR; Subkey: "{app}\%s\shell\open\command";\t""" % str(APPLICATION) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" %str('') - msg += """ValueData: \"""{app}\%s"" ""%s1\""";\t"""% (str(APPLICATION), - str('%')) - msg += """ Flags: %s \t""" % str("uninsdeletevalue noerror") - msg += "\n" - #create default icon - msg += """Root: HKCR; Subkey: "{app}\%s";\t""" % str(SetupIconFile) - msg += """ValueType: %s; """ % str('string') - msg += """ValueName: "%s";\t""" % str('') - msg += """ValueData: "{app}\%s,0";\t""" % str(APPLICATION) - msg += """ Flags: %s \t""" % str("uninsdeletevalue noerror") - msg += "\n" - - - #SASVIEWPATH - msg += """Root: HKLM; Subkey: "%s";\t""" % str('SYSTEM\CurrentControlSet\Control\Session Manager\Environment') - msg += """ValueType: %s; """ % str('expandsz') - msg += """ValueName: "%s";\t""" % str('SASVIEWPATH') - msg += """ValueData: "{app}";\t""" - msg += """ Flags: %s""" % str('uninsdeletevalue noerror') - msg += "\n" - - #PATH - msg += """; Write to PATH (below) is disabled; need more tests\n""" - msg += """;Root: HKCU; Subkey: "%s";\t""" % str('Environment') - msg += """ValueType: %s; """ % str('expandsz') - msg += """ValueName: "%s";\t""" % str('PATH') - msg += """ValueData: "%s;{olddata}";\t""" % str('%SASVIEWPATH%') - msg += """ Check: %s""" % str('NeedsAddPath()') - msg += "\n" - - return msg - -def write_languages(languages=('english',), msfile="compiler:Default.isl"): - """ - define the language of the application - """ - msg = '' - if languages: - msg = "\n\n[Languages]\n" - for lang in languages: - msg += """Name: "%s";\tMessagesFile: "%s"\n""" % (str(lang), str(msfile)) - return msg - -def write_tasks(): - """ - create desktop icon - """ - msg = """\n\n[Tasks]\n""" - msg += """Name: "desktopicon";\tDescription: "{cm:CreateDesktopIcon}";\t""" - msg += """GroupDescription: "{cm:AdditionalIcons}";\tFlags: unchecked\n""" - msg += """Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}";\t""" - msg += """GroupDescription: "{cm:AdditionalIcons}";\n""" - return msg - -dist_path = "dist\sasview" -def write_file(): - """ - copy some data files - """ - msg = "\n\n[Files]\n" - msg += """Source: "%s\%s";\t""" % (dist_path, str(APPLICATION)) - msg += """DestDir: "{app}";\tFlags: ignoreversion\n""" - msg += """Source: "dist\sasview\*";\tDestDir: "{app}";\t""" - msg += """Flags: ignoreversion recursesubdirs createallsubdirs\n""" - msg += """Source: "dist\sasview\plugin_models\*";\tDestDir: "{%%USERPROFILE}\.sasview\plugin_models";\t""" - msg += """Flags: recursesubdirs createallsubdirs\n""" - msg += """Source: "dist\sasview\custom_config.py";\tDestDir: "{%%USERPROFILE}\.sasview\config";\t""" - msg += """Flags: recursesubdirs createallsubdirs\n""" - #msg += """Source: "dist\default_categories.json"; DestDir: "{userdesktop}\..\.sasview";\t""" - #msg += """DestName: "categories.json";\n""" - msg += """;\tNOTE: Don't use "Flags: ignoreversion" on any shared system files""" - return msg - -def write_icon(): - """ - Create application icon - """ - msg = """\n\n[Icons]\n""" - msg += """Name: "{group}\%s";\t""" % str(AppName) - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """WorkingDir: "{app}"; IconFilename: "{app}\images\\ball.ico" \n""" - msg += """Name: "{group}\{cm:UninstallProgram, %s}";\t""" % str(AppName) - msg += """ Filename: "{uninstallexe}" \n""" - msg += """Name: "{commondesktop}\%s";\t""" % str(AppVerName) - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """Tasks: desktopicon; WorkingDir: "{app}" ; IconFilename: "{app}\images\\ball.ico" \n""" - msg += """Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\%s";\t""" % str(AppVerName) - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """Tasks: quicklaunchicon; WorkingDir: "{app}"; IconFilename: "{app}\images\\ball.ico" \n""" - return msg - -def write_run(): - """ - execute some file - """ - msg = """\n\n[Run]\n""" - msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) - msg += """Description: "{cm:LaunchProgram, %s}";\t""" %str(AppName) - msg += """Flags: nowait postinstall skipifsilent\n""" - msg += """; Install the Microsoft C++ DLL redistributable package if it is """ - msg += """provided and the DLLs are not present on the target system.\n""" - msg += """; Note that the redistributable package is included if the app was """ - msg += """built using Python 2.6 or 2.7, but not with 2.5.\n""" - msg += """; Parameter options:\n""" - msg += """; - for silent install use: "/q"\n""" - msg += """; - for silent install with progress bar use: "/qb"\n""" - msg += """; - for silent install with progress bar but disallow """ - msg += """cancellation of operation use: "/qb!"\n""" - msg += """; Note that we do not use the postinstall flag as this would """ - msg += """display a checkbox and thus require the user to decide what to do.\n""" - msg += """;Filename: "{app}\\vcredist_x86.exe"; Parameters: "/qb!"; """ - msg += """WorkingDir: "{tmp}"; StatusMsg: "Installing Microsoft Visual """ - msg += """C++ 2008 Redistributable Package ..."; Check: InstallVC90CRT(); """ - msg += """Flags: skipifdoesntexist waituntilterminated\n""" - return msg - -def write_dirs(): - """ - Define Dir permission - """ - msg = """\n\n[Dirs]\n""" - msg += """Name: "{app}\%s";\t""" % str('') - msg += """Permissions: everyone-modify\t""" - msg += """\n""" - return msg - -def write_code(): - """ - Code that checks the existing path and snaviewpath - in the environmental viriables/PATH - """ - msg = """\n\n[Code]\n""" - msg += """function InstallVC90CRT(): Boolean;\n""" - msg += """begin\n""" - msg += """ Result := not DirExists('C:\WINDOWS\WinSxS\\x86_Microsoft.VC90.""" - msg += """CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375');\n""" - msg += """end;\n\n""" - msg += """function NeedsAddPath(): boolean;\n""" - msg += """var\n""" - msg += """ oldpath: string;\n""" - msg += """ newpath: string;\n""" - msg += """ pathArr: TArrayOfString;\n""" - msg += """ i: Integer;\n""" - msg += """begin\n""" - msg += """ RegQueryStringValue(HKEY_CURRENT_USER,'Environment',""" - msg += """'PATH', oldpath)\n""" - msg += """ oldpath := oldpath + ';';\n""" - msg += """ newpath := '%SASVIEWPATH%';\n""" - msg += """ i := 0;\n""" - msg += """ while (Pos(';', oldpath) > 0) do begin\n""" - msg += """ SetArrayLength(pathArr, i+1);\n""" - msg += """ pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);\n""" - msg += """ oldpath := Copy(oldpath, Pos(';', oldpath)+1,""" - msg += """ Length(oldpath));\n""" - msg += """ i := i + 1;\n""" - msg += """ // Check if current directory matches app dir\n""" - msg += """ if newpath = pathArr[i-1] \n""" - msg += """ then begin\n""" - msg += """ Result := False;\n""" - msg += """ exit;\n""" - msg += """ end;\n""" - msg += """ end;\n""" - msg += """ Result := True;\n""" - msg += """end;\n""" - msg += """\n""" - return msg - -def write_uninstalldelete(): - """ - Define uninstalldelete - """ - msg = """\n[UninstallDelete]\n""" - msg += """; Delete directories and files that are dynamically created by """ - msg += """the application (i.e. at runtime).\n""" - msg += """Type: filesandordirs; Name: "{app}\.matplotlib"\n""" - msg += """Type: files; Name: "{app}\*.*"\n""" - msg += """; The following is a workaround for the case where the """ - msg += """application is installed and uninstalled but the\n""" - msg += """;{app} directory is not deleted because it has user files. """ - msg += """Then the application is installed into the\n""" - msg += """; existing directory, user files are deleted, and the """ - msg += """application is un-installed again. Without the\n""" - msg += """; directive below, {app} will not be deleted because Inno Setup """ - msg += """did not create it during the previous\n""" - msg += """; installation.\n""" - msg += """Type: dirifempty; Name: "{app}"\n""" - msg += """\n""" - return msg - -def generate_installer(): - """ - """ - TEMPLATE = "\n; Script generated by the Inno Setup Script Wizard\n" - TEMPLATE += "; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!" - TEMPLATE += "\n[Setup]\n\n" - TEMPLATE += "ChangesAssociations=%s\n" %str('yes') - TEMPLATE += "AppName=%s\n" % str(AppName) - TEMPLATE += "AppVerName=%s\n" % str(AppVerName) - TEMPLATE += "AppPublisher=%s\n" % str(AppPublisher) - TEMPLATE += "AppPublisherURL=%s\n" % str(AppPublisherURL) - TEMPLATE += "AppSupportURL=%s\n" % str(AppSupportURL) - TEMPLATE += "AppUpdatesURL=%s \n" % str(AppUpdatesURL) - TEMPLATE += "ArchitecturesInstallIn64BitMode=x64\n" - TEMPLATE += "ChangesEnvironment=%s \n" % str(ChangesEnvironment) - TEMPLATE += "DefaultDirName=%s\n" % str(DefaultDirName) - TEMPLATE += "DefaultGroupName=%s\n" % str(DefaultGroupName) - TEMPLATE += "DisableProgramGroupPage=%s\n" % str(DisableProgramGroupPage) - TEMPLATE += "DisableDirPage=%s\n" % str(DisableDirPage) - TEMPLATE += "LicenseFile=%s\n" % str(LicenseFile) - TEMPLATE += "OutputBaseFilename=%s\n" % str(OutputBaseFilename) - TEMPLATE += "SetupIconFile=%s\n" % str(SetupIconFile) - TEMPLATE += "Compression=%s\n" % str(Compression) - TEMPLATE += "SolidCompression=%s\n" % str(SolidCompression) - TEMPLATE += "PrivilegesRequired=%s\n" % str(PrivilegesRequired) - TEMPLATE += "UsePreviousAppDir=no\n" - - TEMPLATE += write_registry(data_extension=DATA_EXTENSION, - app_extension=APP_EXTENSION) - TEMPLATE += write_languages() - TEMPLATE += write_tasks() - TEMPLATE += write_file() - TEMPLATE += write_icon() - TEMPLATE += write_run() - TEMPLATE += write_dirs() - TEMPLATE += write_code() - TEMPLATE += write_uninstalldelete() - path = '%s.iss' % str(INSTALLER_FILE) - f = open(path,'w') - f.write(TEMPLATE) - f.close() - print("Generate Inno setup installer script complete") - print("A new file %s.iss should be created.Please refresh your directory" % str(INSTALLER_FILE)) - -if __name__ == "__main__": - generate_installer() From a32de61ba038da9a1435c15875d6ce764262cea9 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 11:26:48 +0100 Subject: [PATCH 20/82] Removed another local config --- src/sas/qtgui/Utilities/LocalConfig.py | 157 ------------------------- 1 file changed, 157 deletions(-) delete mode 100644 src/sas/qtgui/Utilities/LocalConfig.py diff --git a/src/sas/qtgui/Utilities/LocalConfig.py b/src/sas/qtgui/Utilities/LocalConfig.py deleted file mode 100644 index 25847aa6e7..0000000000 --- a/src/sas/qtgui/Utilities/LocalConfig.py +++ /dev/null @@ -1,157 +0,0 @@ -""" - Application settings -""" -import time -import os -import logging - -import sas.sasview - -# Version of the application -__appname__ = "SasView" -__version__ = sas.sasview.__version__ -__build__ = sas.sasview.__build__ -__download_page__ = 'https://github.com/SasView/sasview/releases' -__update_URL__ = 'http://www.sasview.org/latestversion.json' - -# Debug message flag -__EVT_DEBUG__ = False - -# Flag for automated testing -__TEST__ = False - -# Debug message should be written to a file? -__EVT_DEBUG_2_FILE__ = False -__EVT_DEBUG_FILENAME__ = "debug.log" - -# About box info -_do_aboutbox = True -_do_acknowledge = True -_do_tutorial = True -_acknowledgement_preamble =\ -'''To ensure the long term support and development of this software please''' +\ -''' remember to do the following.''' -_acknowledgement_preamble_bullet1 =\ -'''Acknowledge its use in your publications as suggested below''' -_acknowledgement_preamble_bullet2 =\ -'''Reference the following website: http://www.sasview.org''' -_acknowledgement_preamble_bullet3 =\ -'''Reference the model you used if appropriate (see documentation for refs)''' -_acknowledgement_preamble_bullet4 =\ -'''Send us your reference for our records: developers@sasview.org''' -_acknowledgement_publications = \ -'''This work benefited from the use of the SasView application, originally -developed under NSF award DMR-0520547. -''' -_acknowledgement = \ -'''This work originally developed as part of the DANSE project funded by the NSF -under grant DMR-0520547, and currently maintained by UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, -TUD, BAM and ANSTO. - -''' -_homepage = "http://www.sasview.org" -_download = __download_page__ -_authors = [] -_paper = "http://sourceforge.net/p/sasview/tickets/" -_license = "mailto:help@sasview.org" - -icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images")) - -media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) -test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test")) - -_nist_logo = os.path.join(icon_path, "nist_logo.png") -_umd_logo = os.path.join(icon_path, "umd_logo.png") -_sns_logo = os.path.join(icon_path, "sns_logo.png") -_isis_logo = os.path.join(icon_path, "isis_logo.png") -_ess_logo = os.path.join(icon_path, "ess_logo.png") -_ill_logo = os.path.join(icon_path, "ill_logo.png") -_ansto_logo = os.path.join(icon_path, "ansto_logo.png") -_nsf_logo = os.path.join(icon_path, "nsf_logo.png") -_danse_logo = os.path.join(icon_path, "danse_logo.png") -_inst_logo = os.path.join(icon_path, "utlogo.png") -_nist_url = "http://www.nist.gov/" -_umd_url = "http://www.umd.edu/" -_sns_url = "http://neutrons.ornl.gov/" -_nsf_url = "http://www.nsf.gov" -_isis_url = "http://www.isis.stfc.ac.uk/" -_ess_url = "http://ess-scandinavia.eu/" -_ill_url = "http://www.ill.eu/" -_ansto_url = "http://www.ansto.gov.au/" -_bam_url = "http://www.bam.de/" -_danse_url = "http://www.cacr.caltech.edu/projects/danse/release/index.html" -_inst_url = "http://www.utk.edu" -_delft_url = "http://www.tudelft.nl/en/tnw/business/facilities/reactor-instituut-delft/" -_diamond_url = "http://www.diamond.ac.uk" -_corner_image = os.path.join(icon_path, "angles_flat.png") -_welcome_image = os.path.join(icon_path, "SVwelcome.png") -_copyright = "Copyright (c) 2009-2022 UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, TUD, BAM and ANSTO" - - -#edit the list of file state your plugin can read -APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' -APPLICATION_STATE_EXTENSION = '.svs' -GUIFRAME_WIDTH = 1150 -GUIFRAME_HEIGHT = 840 -PLUGIN_STATE_EXTENSIONS = ['.fitv', '.inv', '.prv'] -PLUGINS_WLIST = ['Fitting files (*.fitv)|*.fitv', - 'Invariant files (*.inv)|*.inv', - 'P(r) files (*.prv)|*.prv'] -PLOPANEL_WIDTH = 415 -PLOPANEL_HEIGTH = 370 -DATAPANEL_WIDTH = 235 -DATAPANEL_HEIGHT = 700 -SPLASH_SCREEN_PATH = os.path.join(icon_path, "SVwelcome_mini.png") -TUTORIAL_PATH = os.path.join(media_path, "Tutorial.pdf") -#DEFAULT_STYLE = GUIFRAME.MULTIPLE_APPLICATIONS|GUIFRAME.MANAGER_ON\ -# |GUIFRAME.CALCULATOR_ON|GUIFRAME.TOOLBAR_ON -SPLASH_SCREEN_WIDTH = 512 -SPLASH_SCREEN_HEIGHT = 366 -SS_MAX_DISPLAY_TIME = 2000 -WELCOME_PANEL_ON = True -WELCOME_PANEL_SHOW = False -CLEANUP_PLOT = False -# OPEN and SAVE project menu -OPEN_SAVE_PROJECT_MENU = True -#VIEW MENU -VIEW_MENU = True -#EDIT MENU -EDIT_MENU = True - -SetupIconFile_win = os.path.join(icon_path, "ball.ico") -SetupIconFile_mac = os.path.join(icon_path, "ball.icns") -DefaultGroupName = "." -OutputBaseFilename = "setupSasView" - -FIXED_PANEL = True -DATALOADER_SHOW = True -CLEANUP_PLOT = False -WELCOME_PANEL_SHOW = False -#Show or hide toolbar at the start up -TOOLBAR_SHOW = False -# set a default perspective -DEFAULT_PERSPECTIVE = 'None' - -# Default threading model -USING_TWISTED = False - -# Time out for updating sasview -UPDATE_TIMEOUT = 2 - -# Logging levels to disable, if any -DISABLE_LOGGING = logging.NOTSET - -# Location of the marketplace -MARKETPLACE_URL = "http://marketplace.sasview.org/" - -def printEVT(message): - """ - Post a debug message to console/file - """ - if __EVT_DEBUG__: - print("%g: %s" % (time.clock(), message)) - - if __EVT_DEBUG_2_FILE__: - out = open(__EVT_DEBUG_FILENAME__, 'a') - out.write("%10g: %s\n" % (time.clock(), message)) - out.close() From 6fe1f6723f12ed137446ebed8b92852dbe34eb8a Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 11:28:59 +0100 Subject: [PATCH 21/82] Removed unused text from config --- src/sas/config_system/config.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index e685daf9e5..126a84374b 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -157,26 +157,7 @@ def __init__(self): self._do_aboutbox = True self._do_acknowledge = True self._do_tutorial = True - self._acknowledgement_preamble = \ - '''To ensure the long term support and development of this software please''' + \ - ''' remember to:''' - self._acknowledgement_preamble_bullet1 = \ - '''Acknowledge its use in your publications as :''' - self._acknowledgement_preamble_bullet2 = \ - '''Reference SasView as:''' - self._acknowledgement_preamble_bullet3 = \ - '''Reference the model you used if appropriate (see documentation for refs)''' - self._acknowledgement_preamble_bullet4 = \ - '''Send us your reference for our records: developers@sasview.org''' - self._acknowledgement_publications = \ - '''This work benefited from the use of the SasView application, originally developed under NSF Award DMR-0520547. SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000.''' - self._acknowledgement_citation = \ - '''M. Doucet et al. SasView Version 5.0''' - - self._acknowledgement = \ - '''This work was originally developed as part of the DANSE project funded by the US NSF under Award DMR-0520547,\n but is currently maintained by a collaboration between UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft, DLS, and the scattering community.\n\n SasView also contains code developed with funding from the EU Horizon 2020 programme under the SINE2020 project (Grant No 654000).\nA list of individual contributors can be found at: http://www.sasview.org/contact.html - ''' - + self._homepage = "https://www.sasview.org" self._download = self.__download_page__ self._authors = [] From 6b7d9ef0f6b7829518f69a78c9dac41b6fca5c06 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 11:45:29 +0100 Subject: [PATCH 22/82] Preparing for migration of urls --- src/sas/config_system/config.py | 2 +- .../MainWindow/DroppableDataLoadWidget.py | 2 +- src/sas/system/__init__.py | 3 +++ src/sas/system/urls.py | 22 +++++++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/sas/system/__init__.py create mode 100644 src/sas/system/urls.py diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 126a84374b..a9caa856d4 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -157,7 +157,7 @@ def __init__(self): self._do_aboutbox = True self._do_acknowledge = True self._do_tutorial = True - + self._homepage = "https://www.sasview.org" self._download = self.__download_page__ self._authors = [] diff --git a/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py b/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py index 40310846a8..ed548a502f 100644 --- a/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py +++ b/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py @@ -57,7 +57,7 @@ def dropEvent(self, event): """ if self.dragIsOK(event): filenames=[] - for url in event.mimeData().urls(): + for url in event.mimeData().url(): files = url.toLocalFile() if os.path.isdir(files): # get content of dir into a list diff --git a/src/sas/system/__init__.py b/src/sas/system/__init__.py new file mode 100644 index 0000000000..d08cf4b480 --- /dev/null +++ b/src/sas/system/__init__.py @@ -0,0 +1,3 @@ +from urls import url + +__all__ = ["url"] \ No newline at end of file diff --git a/src/sas/system/urls.py b/src/sas/system/urls.py new file mode 100644 index 0000000000..e6182cf64f --- /dev/null +++ b/src/sas/system/urls.py @@ -0,0 +1,22 @@ +class URL: + def __init__(self): + self._nist_url = "https://www.nist.gov/" + self._umd_url = "https://www.umd.edu/" + self._sns_url = "https://neutrons.ornl.gov/" + self._ornl_url = "https://neutrons.ornl.gov/" + self._nsf_url = "https://www.nsf.gov" + self._isis_url = "https://www.isis.stfc.ac.uk/" + self._ess_url = "https://europeanspallationsource.se/" + self._ill_url = "https://www.ill.eu/" + self._ansto_url = "https://www.ansto.gov.au/" + self._bam_url = "http://www.bam.de/" + self._tudelft_url = "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" + self._delft_url = "http://www.tudelft.nl/en/tnw/business/facilities/reactor-instituut-delft/" + self._dls_url = "https://www.diamond.ac.uk/" + self._danse_url = "https://www.its.caltech.edu/~matsci/btf/DANSE_web_page.html" + self._inst_url = "https://www.utk.edu" + self._diamond_url = "http://www.diamond.ac.uk" + + +url = URL() + From 906ec91a9856258f48e2fcd6513bf60849457f71 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 11:47:10 +0100 Subject: [PATCH 23/82] Removed unused methods from __init__ --- src/sas/__init__.py | 32 +------------------------- src/sas/qtgui/MainWindow/GuiManager.py | 16 ------------- 2 files changed, 1 insertion(+), 47 deletions(-) diff --git a/src/sas/__init__.py b/src/sas/__init__.py index 8758a7e48b..d2133d3999 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -4,8 +4,7 @@ import sys from sas.config_system import configuration as config -__all__ = ['get_app_dir', 'get_user_dir', - 'get_local_config', 'get_custom_config', 'config'] +__all__ = ['get_app_dir', 'get_user_dir', 'config'] _APP_DIR = None def get_app_dir(): @@ -82,32 +81,3 @@ def get_user_dir(): if not _USER_DIR: _USER_DIR = make_user_dir() return _USER_DIR - -def make_custom_config_path(): - from ._config import make_custom_config_path as _make_path - return _make_path(get_user_dir()) - -_CUSTOM_CONFIG = None -def get_custom_config(): - raise RuntimeError("Tried to call get_custom_config - this is now forbidden") - # """ - # Setup the custom config dir and cat file - # """ - # global _CUSTOM_CONFIG - # if not _CUSTOM_CONFIG: - # from ._config import setup_custom_config - # _CUSTOM_CONFIG = setup_custom_config(get_app_dir(), get_user_dir()) - # return _CUSTOM_CONFIG - - -_LOCAL_CONFIG = None -def get_local_config(): - raise RuntimeError("Tried to call get_local_config - this is now forbidden") - # """ - # Loads the local config file. - # """ - # global _LOCAL_CONFIG - # if not _LOCAL_CONFIG: - # from ._config import load_local_config - # _LOCAL_CONFIG = load_local_config(get_app_dir()) - # return _LOCAL_CONFIG diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index c3fc74a23a..385f8e8163 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1335,19 +1335,3 @@ def customSaveOpenCL(self, config_content): changed = True return changed - def writeCustomConfig(self, config): - """ - Write custom configuration - """ - from sas import make_custom_config_path - path = make_custom_config_path() - # Just clobber the file - we already have its content read in - with open(path, 'w') as out_f: - out_f.write("#Application appearance custom configuration\n") - for key, item in config.__dict__.items(): - if key[:2] == "__": - continue - if isinstance(item, str): - item = '"' + item + '"' - out_f.write("%s = %s\n" % (key, str(item))) - pass # debugger anchor From a2c7602b42f9450179b0a1f8c99465f81dbf1792 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 14:01:09 +0100 Subject: [PATCH 24/82] Introduced url container --- src/sas/qtgui/MainWindow/AboutBox.py | 60 +++++++++++++------ .../MainWindow/UnitTesting/AboutBoxTest.py | 4 +- src/sas/system/__init__.py | 4 +- src/sas/system/legal.py | 6 ++ src/sas/system/urls.py | 4 ++ 5 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 src/sas/system/legal.py diff --git a/src/sas/qtgui/MainWindow/AboutBox.py b/src/sas/qtgui/MainWindow/AboutBox.py index a9f134e3b5..6beeb5f296 100644 --- a/src/sas/qtgui/MainWindow/AboutBox.py +++ b/src/sas/qtgui/MainWindow/AboutBox.py @@ -6,6 +6,7 @@ from sas.qtgui.UI import images_rc from sas.qtgui.UI import main_resources_rc +from sas.system import url, legal from sas import config from .UI.AboutUI import Ui_AboutUI @@ -33,14 +34,35 @@ def addText(self): lbl_font = self.font() lbl_font.setPointSize(24) self.lblVersion.setFont(lbl_font) - about_text = r'

' - about_text += '

Build ' + str(config.__build__) +'

' - about_text += '

' + config._copyright + '

' - about_text += r'

http://www.sasview.org


' - about_text += '

Comments? Bugs? Requests?
' - about_text += r'Send us a ticket


' - about_text += r'


' + + about_text = f""" + + + +

+ Build{config.__build__} +

+

+ {legal._copyright} +

+

+ {url._homepage} +

+
+

+ Comments? Bugs? Requests? +
+ Send us a ticket +

+
+

+ Get the latest version +

+
+ + + """ + self.lblAbout.setText(about_text) # Enable link clicking on the label @@ -51,26 +73,26 @@ def addActions(self): Add actions to the logo push buttons """ self.cmdLinkUT.clicked.connect(functools.partial( - GuiUtils.openLink, config._inst_url)) + GuiUtils.openLink, url._inst_url)) self.cmdLinkUMD.clicked.connect(functools.partial( - GuiUtils.openLink, config._umd_url)) + GuiUtils.openLink, url._umd_url)) self.cmdLinkNIST.clicked.connect(functools.partial( - GuiUtils.openLink, config._nist_url)) + GuiUtils.openLink, url._nist_url)) self.cmdLinkSNS.clicked.connect(functools.partial( - GuiUtils.openLink, config._sns_url)) + GuiUtils.openLink, url._sns_url)) self.cmdLinkISIS.clicked.connect(functools.partial( - GuiUtils.openLink, config._isis_url)) + GuiUtils.openLink, url._isis_url)) self.cmdLinkESS.clicked.connect(functools.partial( - GuiUtils.openLink, config._ess_url)) + GuiUtils.openLink, url._ess_url)) self.cmdLinkILL.clicked.connect(functools.partial( - GuiUtils.openLink, config._ill_url)) + GuiUtils.openLink, url._ill_url)) self.cmdLinkANSTO.clicked.connect(functools.partial( - GuiUtils.openLink, config._ansto_url)) + GuiUtils.openLink, url._ansto_url)) self.cmdLinkBAM.clicked.connect(functools.partial( - GuiUtils.openLink, config._bam_url)) + GuiUtils.openLink, url._bam_url)) self.cmdLinkDELFT.clicked.connect(functools.partial( - GuiUtils.openLink, config._delft_url)) + GuiUtils.openLink, url._delft_url)) self.cmdLinkDIAMOND.clicked.connect(functools.partial( - GuiUtils.openLink, config._diamond_url)) + GuiUtils.openLink, url._diamond_url)) self.cmdOK.clicked.connect(self.close) diff --git a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py index 869b77ba38..3d284951de 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py @@ -8,7 +8,7 @@ from unittest.mock import MagicMock from sas import config - +from sas.system import url # Local from sas.qtgui.MainWindow.AboutBox import AboutBox @@ -57,7 +57,7 @@ def testAbout(self): # License self.assertIn(str(config._copyright), about.text()) # URLs - self.assertIn(str(config._homepage), about.text()) + self.assertIn(str(url._homepage), about.text()) self.assertIn(str(config.__download_page__), about.text()) self.assertIn(str(config._license), about.text()) diff --git a/src/sas/system/__init__.py b/src/sas/system/__init__.py index d08cf4b480..b85af9e1a4 100644 --- a/src/sas/system/__init__.py +++ b/src/sas/system/__init__.py @@ -1,3 +1,3 @@ from urls import url - -__all__ = ["url"] \ No newline at end of file +from legal import legal +__all__ = ["url", "legal"] \ No newline at end of file diff --git a/src/sas/system/legal.py b/src/sas/system/legal.py new file mode 100644 index 0000000000..7274590fe6 --- /dev/null +++ b/src/sas/system/legal.py @@ -0,0 +1,6 @@ +class Legal: + def __init__(self): + self._copyright = "Copyright (c) 2009-2022 UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, TUD, BAM and ANSTO" + + +legal = Legal() \ No newline at end of file diff --git a/src/sas/system/urls.py b/src/sas/system/urls.py index e6182cf64f..916fd5bd63 100644 --- a/src/sas/system/urls.py +++ b/src/sas/system/urls.py @@ -17,6 +17,10 @@ def __init__(self): self._inst_url = "https://www.utk.edu" self._diamond_url = "http://www.diamond.ac.uk" + self._homepage = "https://www.sasview.org" + self.__download_page__ = 'https://github.com/SasView/sasview/releases' + + self._license = "help@sasview.org" # TODO: Rename url = URL() From 6182c3547a505600fc946e6a1b994e13ce8dd1b3 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 14:09:24 +0100 Subject: [PATCH 25/82] Factored out urls --- src/sas/config_system/config.py | 17 +-------- src/sas/qtgui/MainWindow/AboutBox.py | 30 ++++++++-------- .../MainWindow/DroppableDataLoadWidget.py | 2 +- src/sas/qtgui/MainWindow/GuiManager.py | 2 +- .../MainWindow/UnitTesting/AboutBoxTest.py | 30 ++++++++-------- .../UnitTesting/DataExplorerTest.py | 4 +-- src/sas/system/__init__.py | 7 ++-- src/sas/system/urls.py | 36 +++++++++---------- 8 files changed, 55 insertions(+), 73 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index a9caa856d4..5e160e4c14 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -182,22 +182,7 @@ def __init__(self): self._nsf_logo = os.path.join(self.icon_path, "nsf_logo.png") self._danse_logo = os.path.join(self.icon_path, "danse_logo.png") self._inst_logo = os.path.join(self.icon_path, "utlogo.gif") - self._nist_url = "https://www.nist.gov/" - self._umd_url = "https://www.umd.edu/" - self._sns_url = "https://neutrons.ornl.gov/" - self._ornl_url = "https://neutrons.ornl.gov/" - self._nsf_url = "https://www.nsf.gov" - self._isis_url = "https://www.isis.stfc.ac.uk/" - self._ess_url = "https://europeanspallationsource.se/" - self._ill_url = "https://www.ill.eu/" - self._ansto_url = "https://www.ansto.gov.au/" - self._bam_url = "http://www.bam.de/" - self._tudelft_url = "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" - self._delft_url = "http://www.tudelft.nl/en/tnw/business/facilities/reactor-instituut-delft/" - self._dls_url = "https://www.diamond.ac.uk/" - self._danse_url = "https://www.its.caltech.edu/~matsci/btf/DANSE_web_page.html" - self._inst_url = "https://www.utk.edu" - self._diamond_url = "http://www.diamond.ac.uk" + self._corner_image = os.path.join(self.icon_path, "angles_flat.png") self._welcome_image = os.path.join(self.icon_path, "SVwelcome.png") # self._copyright = "(c) 2009 - 2022, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft and DLS" diff --git a/src/sas/qtgui/MainWindow/AboutBox.py b/src/sas/qtgui/MainWindow/AboutBox.py index 6beeb5f296..c838cc80ca 100644 --- a/src/sas/qtgui/MainWindow/AboutBox.py +++ b/src/sas/qtgui/MainWindow/AboutBox.py @@ -6,7 +6,7 @@ from sas.qtgui.UI import images_rc from sas.qtgui.UI import main_resources_rc -from sas.system import url, legal +from sas.system import web, legal from sas import config from .UI.AboutUI import Ui_AboutUI @@ -46,17 +46,17 @@ def addText(self): {legal._copyright}

- {url._homepage} + {web.homepage_url}


Comments? Bugs? Requests?
- Send us a ticket + Send us a ticket


- Get the latest version + Get the latest version


@@ -73,26 +73,26 @@ def addActions(self): Add actions to the logo push buttons """ self.cmdLinkUT.clicked.connect(functools.partial( - GuiUtils.openLink, url._inst_url)) + GuiUtils.openLink, web.inst_url)) self.cmdLinkUMD.clicked.connect(functools.partial( - GuiUtils.openLink, url._umd_url)) + GuiUtils.openLink, web.umd_url)) self.cmdLinkNIST.clicked.connect(functools.partial( - GuiUtils.openLink, url._nist_url)) + GuiUtils.openLink, web.nist_url)) self.cmdLinkSNS.clicked.connect(functools.partial( - GuiUtils.openLink, url._sns_url)) + GuiUtils.openLink, web.sns_url)) self.cmdLinkISIS.clicked.connect(functools.partial( - GuiUtils.openLink, url._isis_url)) + GuiUtils.openLink, web.isis_url)) self.cmdLinkESS.clicked.connect(functools.partial( - GuiUtils.openLink, url._ess_url)) + GuiUtils.openLink, web.ess_url)) self.cmdLinkILL.clicked.connect(functools.partial( - GuiUtils.openLink, url._ill_url)) + GuiUtils.openLink, web.ill_url)) self.cmdLinkANSTO.clicked.connect(functools.partial( - GuiUtils.openLink, url._ansto_url)) + GuiUtils.openLink, web.ansto_url)) self.cmdLinkBAM.clicked.connect(functools.partial( - GuiUtils.openLink, url._bam_url)) + GuiUtils.openLink, web.bam_url)) self.cmdLinkDELFT.clicked.connect(functools.partial( - GuiUtils.openLink, url._delft_url)) + GuiUtils.openLink, web.delft_url)) self.cmdLinkDIAMOND.clicked.connect(functools.partial( - GuiUtils.openLink, url._diamond_url)) + GuiUtils.openLink, web.diamond_url)) self.cmdOK.clicked.connect(self.close) diff --git a/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py b/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py index ed548a502f..0e8e53ae56 100644 --- a/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py +++ b/src/sas/qtgui/MainWindow/DroppableDataLoadWidget.py @@ -57,7 +57,7 @@ def dropEvent(self, event): """ if self.dragIsOK(event): filenames=[] - for url in event.mimeData().url(): + for url in event.mimeData().web(): files = url.toLocalFile() if os.path.isdir(files): # get content of dir into a list diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 385f8e8163..c3c9b6a112 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -575,7 +575,7 @@ def processVersion(self, version_info): if "download_url" in version_info: webbrowser.open(version_info["download_url"]) else: - webbrowser.open(config.__download_page__) + webbrowser.open(config.download_url) self.communicate.statusBarUpdateSignal.emit(msg) else: msg = "You have the latest version" diff --git a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py index 3d284951de..3bb8b6b588 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py @@ -8,7 +8,7 @@ from unittest.mock import MagicMock from sas import config -from sas.system import url +from sas.system import web # Local from sas.qtgui.MainWindow.AboutBox import AboutBox @@ -57,8 +57,8 @@ def testAbout(self): # License self.assertIn(str(config._copyright), about.text()) # URLs - self.assertIn(str(url._homepage), about.text()) - self.assertIn(str(config.__download_page__), about.text()) + self.assertIn(str(web.homepage_url), about.text()) + self.assertIn(str(config.download_url), about.text()) self.assertIn(str(config._license), about.text()) # Are links enabled? @@ -70,18 +70,18 @@ def testAddActions(self): """ webbrowser.open = MagicMock() all_hosts = [ - config._nist_url, - config._umd_url, - config._sns_url, - config._nsf_url, - config._isis_url, - config._ess_url, - config._ill_url, - config._ansto_url, - config._inst_url, - config._delft_url, - config._bam_url, - config._diamond_url] + config.nist_url, + config.umd_url, + config.sns_url, + config.nsf_url, + config.isis_url, + config.ess_url, + config.ill_url, + config.ansto_url, + config.inst_url, + config.delft_url, + config.bam_url, + config.diamond_url] # Press the buttons buttonList = self.widget.findChildren(QtWidgets.QPushButton) diff --git a/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py b/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py index 1cef86d93c..b6f6acf9e6 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py @@ -505,7 +505,7 @@ def skip_testDisplayHelp(self): # Skip due to help path change qApp.processEvents() # Check the browser - self.assertIn(partial_url, str(self.form._helpView.url())) + self.assertIn(partial_url, str(self.form._helpView.web())) # Close the browser self.form._helpView.close() @@ -513,7 +513,7 @@ def skip_testDisplayHelp(self): # Skip due to help path change QTest.mouseClick(button2, Qt.LeftButton) qApp.processEvents() # Check the browser - self.assertIn(partial_url, str(self.form._helpView.url())) + self.assertIn(partial_url, str(self.form._helpView.web())) def testLoadFile(self): """ diff --git a/src/sas/system/__init__.py b/src/sas/system/__init__.py index b85af9e1a4..06282a9144 100644 --- a/src/sas/system/__init__.py +++ b/src/sas/system/__init__.py @@ -1,3 +1,4 @@ -from urls import url -from legal import legal -__all__ = ["url", "legal"] \ No newline at end of file +from .urls import web +from .legal import legal + +__all__ = ["web", "legal"] \ No newline at end of file diff --git a/src/sas/system/urls.py b/src/sas/system/urls.py index 916fd5bd63..4a309b7ef0 100644 --- a/src/sas/system/urls.py +++ b/src/sas/system/urls.py @@ -1,26 +1,22 @@ -class URL: +class WebLinks: def __init__(self): - self._nist_url = "https://www.nist.gov/" - self._umd_url = "https://www.umd.edu/" - self._sns_url = "https://neutrons.ornl.gov/" - self._ornl_url = "https://neutrons.ornl.gov/" - self._nsf_url = "https://www.nsf.gov" - self._isis_url = "https://www.isis.stfc.ac.uk/" - self._ess_url = "https://europeanspallationsource.se/" - self._ill_url = "https://www.ill.eu/" - self._ansto_url = "https://www.ansto.gov.au/" - self._bam_url = "http://www.bam.de/" - self._tudelft_url = "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" - self._delft_url = "http://www.tudelft.nl/en/tnw/business/facilities/reactor-instituut-delft/" - self._dls_url = "https://www.diamond.ac.uk/" - self._danse_url = "https://www.its.caltech.edu/~matsci/btf/DANSE_web_page.html" - self._inst_url = "https://www.utk.edu" - self._diamond_url = "http://www.diamond.ac.uk" + self.nist_url = "https://www.nist.gov/" + self.umd_url = "https://www.umd.edu/" + self.sns_url = "https://neutrons.ornl.gov/" + self.nsf_url = "https://www.nsf.gov" + self.isis_url = "https://www.isis.stfc.ac.uk/" + self.ess_url = "https://europeanspallationsource.se/" + self.ill_url = "https://www.ill.eu/" + self.ansto_url = "https://www.ansto.gov.au/" + self.bam_url = "http://www.bam.de/" + self.delft_url = "http://www.tudelft.nl/en/tnw/business/facilities/reactor-instituut-delft/" + self.inst_url = "https://www.utk.edu" + self.diamond_url = "http://www.diamond.ac.uk" - self._homepage = "https://www.sasview.org" - self.__download_page__ = 'https://github.com/SasView/sasview/releases' + self.homepage_url = "https://www.sasview.org" + self.download_url = 'https://github.com/SasView/sasview/releases' self._license = "help@sasview.org" # TODO: Rename -url = URL() +web = WebLinks() From 7f6386093210a21f5b741395037c279e2e1e0df3 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 14:12:12 +0100 Subject: [PATCH 26/82] More deletions of unused fields --- src/sas/config_system/config.py | 5 +---- src/sas/qtgui/MainWindow/WelcomePanel.py | 7 ++++--- src/sas/system/__init__.py | 2 +- src/sas/system/{urls.py => web.py} | 0 4 files changed, 6 insertions(+), 8 deletions(-) rename src/sas/system/{urls.py => web.py} (100%) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 5e160e4c14..ef6ce7f229 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -157,9 +157,7 @@ def __init__(self): self._do_aboutbox = True self._do_acknowledge = True self._do_tutorial = True - - self._homepage = "https://www.sasview.org" - self._download = self.__download_page__ + self._authors = [] self._paper = "http://sourceforge.net/p/sasview/tickets/" self._license = "mailto:help@sasview.org" @@ -187,7 +185,6 @@ def __init__(self): self._welcome_image = os.path.join(self.icon_path, "SVwelcome.png") # self._copyright = "(c) 2009 - 2022, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft and DLS" self._copyright = "Copyright (c) 2009-2022 UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, TUD, BAM and ANSTO" - self.marketplace_url = "http://marketplace.sasview.org/" # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' diff --git a/src/sas/qtgui/MainWindow/WelcomePanel.py b/src/sas/qtgui/MainWindow/WelcomePanel.py index 5aa74026a9..9f1d98d546 100644 --- a/src/sas/qtgui/MainWindow/WelcomePanel.py +++ b/src/sas/qtgui/MainWindow/WelcomePanel.py @@ -3,6 +3,7 @@ import sas.sasview from sas import config +from sas.system import legal from sas.qtgui.MainWindow.UI.WelcomePanelUI import Ui_WelcomePanelUI @@ -13,10 +14,10 @@ def __init__(self, parent=None): self.setWindowTitle("Welcome") - version = sas.sasview.__version__ - build = sas.sasview.__build__ + version = sas.sasview.__version__ # TODO: Make consistent with other version references + build = sas.sasview.__build__ # TODO: Make consistent with other build references - ver = "\nSasView %s\nBuild: %s\n%s" % (version, build, config._copyright) + ver = "\nSasView %s\nBuild: %s\n%s" % (version, build, legal._copyright) self.lblVersion.setText(ver) diff --git a/src/sas/system/__init__.py b/src/sas/system/__init__.py index 06282a9144..ecca45334f 100644 --- a/src/sas/system/__init__.py +++ b/src/sas/system/__init__.py @@ -1,4 +1,4 @@ -from .urls import web +from .web import web from .legal import legal __all__ = ["web", "legal"] \ No newline at end of file diff --git a/src/sas/system/urls.py b/src/sas/system/web.py similarity index 100% rename from src/sas/system/urls.py rename to src/sas/system/web.py From 0b95f6a2a1681e70f73e257d1ce8877c02d21668 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 14:13:31 +0100 Subject: [PATCH 27/82] Removed more unused fields from config --- src/sas/config_system/config.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index ef6ce7f229..a3cbbc7871 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -157,29 +157,12 @@ def __init__(self): self._do_aboutbox = True self._do_acknowledge = True self._do_tutorial = True - - self._authors = [] - self._paper = "http://sourceforge.net/p/sasview/tickets/" - self._license = "mailto:help@sasview.org" self.icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images")) # logging.info("icon path: %s" % icon_path) self.media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) self.test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test")) - self._nist_logo = os.path.join(self.icon_path, "nist_logo.png") - self._umd_logo = os.path.join(self.icon_path, "umd_logo.png") - self._sns_logo = os.path.join(self.icon_path, "sns_logo.png") - self._ornl_logo = os.path.join(self.icon_path, "ornl_logo.png") - self._isis_logo = os.path.join(self.icon_path, "isis_logo.png") - self._ess_logo = os.path.join(self.icon_path, "ess_logo.png") - self._ill_logo = os.path.join(self.icon_path, "ill_logo.png") - self._ansto_logo = os.path.join(self.icon_path, "ansto_logo.png") - self._tudelft_logo = os.path.join(self.icon_path, "tudelft_logo.png") - self._dls_logo = os.path.join(self.icon_path, "dls_logo.png") - self._nsf_logo = os.path.join(self.icon_path, "nsf_logo.png") - self._danse_logo = os.path.join(self.icon_path, "danse_logo.png") - self._inst_logo = os.path.join(self.icon_path, "utlogo.gif") self._corner_image = os.path.join(self.icon_path, "angles_flat.png") self._welcome_image = os.path.join(self.icon_path, "SVwelcome.png") From 63d2a4973e896662e5a9dca50190284d69a60ba0 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 14:19:50 +0100 Subject: [PATCH 28/82] Removed yet more fields from config --- src/sas/config_system/config.py | 8 -------- src/sas/qtgui/MainWindow/AboutBox.py | 2 +- src/sas/qtgui/MainWindow/GuiManager.py | 3 ++- src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py | 4 ++-- src/sas/qtgui/MainWindow/WelcomePanel.py | 2 +- src/sas/system/legal.py | 2 +- src/sas/system/web.py | 1 + 7 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index a3cbbc7871..db9b2a1ac8 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -140,8 +140,6 @@ def __init__(self): self.__appname__ = "SasView" self.__version__ = sas.sasview.__version__ self.__build__ = sas.sasview.__build__ - self.__download_page__ = 'https://github.com/SasView/sasview/releases' - self.__update_URL__ = 'https://www.sasview.org/latestversion.json' # Debug message flag self.__EVT_DEBUG__ = False @@ -166,8 +164,6 @@ def __init__(self): self._corner_image = os.path.join(self.icon_path, "angles_flat.png") self._welcome_image = os.path.join(self.icon_path, "SVwelcome.png") - # self._copyright = "(c) 2009 - 2022, UTK, UMD, NIST, ORNL, ISIS, ESS, ILL, ANSTO, TU Delft and DLS" - self._copyright = "Copyright (c) 2009-2022 UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, TUD, BAM and ANSTO" # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' @@ -247,10 +243,6 @@ def __init__(self): # Time out for updating sasview self.UPDATE_TIMEOUT = 2 - # Logging levels to disable, if any - self.DISABLE_LOGGING = logging.NOTSET - - # Location of the marketplace # # Lock the class down diff --git a/src/sas/qtgui/MainWindow/AboutBox.py b/src/sas/qtgui/MainWindow/AboutBox.py index c838cc80ca..117d1f7f0f 100644 --- a/src/sas/qtgui/MainWindow/AboutBox.py +++ b/src/sas/qtgui/MainWindow/AboutBox.py @@ -43,7 +43,7 @@ def addText(self): Build{config.__build__}

- {legal._copyright} + {legal.copyright}

{web.homepage_url} diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index c3c9b6a112..3b2a177f59 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -66,6 +66,7 @@ from sas.qtgui.Utilities.FileConverter import FileConverterWidget from sas import config +from sas.system import web logger = logging.getLogger(__name__) @@ -529,7 +530,7 @@ def checkUpdate(self): a call-back method when the current version number has been obtained. """ version_info = {"version": "0.0.0"} - c = ConnectionProxy(config.__update_URL__, config.UPDATE_TIMEOUT) + c = ConnectionProxy(web.update_url, config.UPDATE_TIMEOUT) response = c.connect() if response is None: return diff --git a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py index 3bb8b6b588..42c51a5860 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py @@ -8,7 +8,7 @@ from unittest.mock import MagicMock from sas import config -from sas.system import web +from sas.system import web, legal # Local from sas.qtgui.MainWindow.AboutBox import AboutBox @@ -55,7 +55,7 @@ def testAbout(self): # build version self.assertIn(str(config.__build__), about.text()) # License - self.assertIn(str(config._copyright), about.text()) + self.assertIn(str(legal.copyright), about.text()) # URLs self.assertIn(str(web.homepage_url), about.text()) self.assertIn(str(config.download_url), about.text()) diff --git a/src/sas/qtgui/MainWindow/WelcomePanel.py b/src/sas/qtgui/MainWindow/WelcomePanel.py index 9f1d98d546..729761c4a6 100644 --- a/src/sas/qtgui/MainWindow/WelcomePanel.py +++ b/src/sas/qtgui/MainWindow/WelcomePanel.py @@ -17,7 +17,7 @@ def __init__(self, parent=None): version = sas.sasview.__version__ # TODO: Make consistent with other version references build = sas.sasview.__build__ # TODO: Make consistent with other build references - ver = "\nSasView %s\nBuild: %s\n%s" % (version, build, legal._copyright) + ver = "\nSasView %s\nBuild: %s\n%s" % (version, build, legal.copyright) self.lblVersion.setText(ver) diff --git a/src/sas/system/legal.py b/src/sas/system/legal.py index 7274590fe6..1c900b1dbd 100644 --- a/src/sas/system/legal.py +++ b/src/sas/system/legal.py @@ -1,6 +1,6 @@ class Legal: def __init__(self): - self._copyright = "Copyright (c) 2009-2022 UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, TUD, BAM and ANSTO" + self.copyright = "Copyright (c) 2009-2022 UTK, UMD, ESS, NIST, ORNL, ISIS, ILL, DLS, TUD, BAM and ANSTO" legal = Legal() \ No newline at end of file diff --git a/src/sas/system/web.py b/src/sas/system/web.py index 4a309b7ef0..45a665945d 100644 --- a/src/sas/system/web.py +++ b/src/sas/system/web.py @@ -15,6 +15,7 @@ def __init__(self): self.homepage_url = "https://www.sasview.org" self.download_url = 'https://github.com/SasView/sasview/releases' + self.update_url = 'https://www.sasview.org/latestversion.json' self._license = "help@sasview.org" # TODO: Rename From 351359d3fbc2e4a53564bfb6f23d93e89d93d21b Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 14:23:24 +0100 Subject: [PATCH 29/82] Moved more urls out of config --- src/sas/config_system/config.py | 4 ++-- src/sas/qtgui/MainWindow/GuiManager.py | 3 +-- src/sas/system/web.py | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index db9b2a1ac8..8ae4308338 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -232,7 +232,6 @@ def __init__(self): self.TOOLBAR_SHOW = True self.DEFAULT_PERSPECTIVE = "Fitting" self.SAS_OPENCL = "None" - self.MARKETPLACE_URL = "http://marketplace.sasview.org/" # Logging options self.FILTER_DEBUG_LOGS = True @@ -245,7 +244,8 @@ def __init__(self): # - # Lock the class down + # Lock the class down, this is necessary both for + # securing the class, and for setting up reading/writing files # self.finalise() diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 3b2a177f59..a2ecba6ce1 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1213,8 +1213,7 @@ def actionMarketplace(self): """ Open the marketplace link in default browser """ - url = config.MARKETPLACE_URL - webbrowser.open_new(url) + webbrowser.open_new(web.marketplace_url) def actionAbout(self): """ diff --git a/src/sas/system/web.py b/src/sas/system/web.py index 45a665945d..feb442666d 100644 --- a/src/sas/system/web.py +++ b/src/sas/system/web.py @@ -15,6 +15,7 @@ def __init__(self): self.homepage_url = "https://www.sasview.org" self.download_url = 'https://github.com/SasView/sasview/releases' + self.marketplace_url = "http://marketplace.sasview.org/" self.update_url = 'https://www.sasview.org/latestversion.json' self._license = "help@sasview.org" # TODO: Rename From d68dc077da7c8dba4e9b5a6b3cb650de84e65495 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 15:04:32 +0100 Subject: [PATCH 30/82] More notes in config --- src/sas/config_system/config.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 8ae4308338..ca4fb8e570 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -93,7 +93,14 @@ problem at hand, but about the future maintainability of SasView in general. -Deleting from Config class: +Adding to the Config class: +Before adding a variable, think about whether it might more properly +belong somewhere else, perhaps in the web or legal classes in the +system package. +Remember that config variables are accessed across the whole of sasview +and that names need to be suitably descriptive. + +Deleting from the Config class: Currently (02/09/2022) the consequences of providing an entry in a config file that is not properly reflected in the Config class is a error. To ease backward compatibility, it is possible to disable From ed5ab9027ee98264396d013f63e14b33e32da445 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 15:19:38 +0100 Subject: [PATCH 31/82] Removed more stuff from config --- src/sas/config_system/config.py | 3 +- src/sas/qtgui/Utilities/GuiUtils.py | 67 ++++++++++------------------- 2 files changed, 23 insertions(+), 47 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index ca4fb8e570..0d1eedfcea 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -188,8 +188,7 @@ def __init__(self): self.DATAPANEL_HEIGHT = 700 self.SPLASH_SCREEN_PATH = os.path.join(self.icon_path, "SVwelcome_mini.png") self.TUTORIAL_PATH = os.path.join(self.media_path, "Tutorial.pdf") - # DEFAULT_STYLE = GUIFRAME.MULTIPLE_APPLICATIONS|GUIFRAME.MANAGER_ON\ - # |GUIFRAME.CALCULATOR_ON|GUIFRAME.TOOLBAR_ON + self.DEFAULT_STYLE = 64 self.SPLASH_SCREEN_WIDTH = 512 diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index b08cd34e62..8b1c64ff84 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -135,16 +135,6 @@ def _find_local_config(confg_file, path): # else: # pass -# -# -# c_conf_dir = CustomDir.setup_conf_dir(PATH_APP) -# custom_config = _find_local_config('custom_config', c_conf_dir) -# if custom_config is None: -# custom_config = _find_local_config('custom_config', os.getcwd()) -# if custom_config is None: -# msgConfig = "Custom_config file was not imported" -custom_config = config -# logging.info("Custom config path: %s", custom_config) #read some constants from config APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION @@ -154,46 +144,33 @@ def _find_local_config(confg_file, path): SPLASH_SCREEN_WIDTH = config.SPLASH_SCREEN_WIDTH SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME + if not WELCOME_PANEL_ON: WELCOME_PANEL_SHOW = False else: WELCOME_PANEL_SHOW = True -try: - DATALOADER_SHOW = custom_config.DATALOADER_SHOW - TOOLBAR_SHOW = custom_config.TOOLBAR_SHOW - FIXED_PANEL = custom_config.FIXED_PANEL - if WELCOME_PANEL_ON: - WELCOME_PANEL_SHOW = custom_config.WELCOME_PANEL_SHOW - PLOPANEL_WIDTH = custom_config.PLOPANEL_WIDTH - DATAPANEL_WIDTH = custom_config.DATAPANEL_WIDTH - GUIFRAME_WIDTH = custom_config.GUIFRAME_WIDTH - GUIFRAME_HEIGHT = custom_config.GUIFRAME_HEIGHT - CONTROL_WIDTH = custom_config.CONTROL_WIDTH - CONTROL_HEIGHT = custom_config.CONTROL_HEIGHT - DEFAULT_PERSPECTIVE = custom_config.DEFAULT_PERSPECTIVE - CLEANUP_PLOT = custom_config.CLEANUP_PLOT - SAS_OPENCL = custom_config.SAS_OPENCL - # custom open_path - open_folder = custom_config.DEFAULT_OPEN_FOLDER - if open_folder is not None and os.path.isdir(open_folder): - DEFAULT_OPEN_FOLDER = os.path.abspath(open_folder) - else: - DEFAULT_OPEN_FOLDER = PATH_APP -except AttributeError: - DATALOADER_SHOW = True - TOOLBAR_SHOW = True - FIXED_PANEL = True - WELCOME_PANEL_SHOW = False - PLOPANEL_WIDTH = config.PLOPANEL_WIDTH - DATAPANEL_WIDTH = config.DATAPANEL_WIDTH - GUIFRAME_WIDTH = config.GUIFRAME_WIDTH - GUIFRAME_HEIGHT = config.GUIFRAME_HEIGHT - CONTROL_WIDTH = -1 - CONTROL_HEIGHT = -1 - DEFAULT_PERSPECTIVE = None - CLEANUP_PLOT = False + +DATALOADER_SHOW = config.DATALOADER_SHOW +TOOLBAR_SHOW = config.TOOLBAR_SHOW +FIXED_PANEL = config.FIXED_PANEL +if WELCOME_PANEL_ON: + WELCOME_PANEL_SHOW = config.WELCOME_PANEL_SHOW +PLOPANEL_WIDTH = config.PLOPANEL_WIDTH +DATAPANEL_WIDTH = config.DATAPANEL_WIDTH +GUIFRAME_WIDTH = config.GUIFRAME_WIDTH +GUIFRAME_HEIGHT = config.GUIFRAME_HEIGHT +CONTROL_WIDTH = config.CONTROL_WIDTH +CONTROL_HEIGHT = config.CONTROL_HEIGHT +DEFAULT_PERSPECTIVE = config.DEFAULT_PERSPECTIVE +CLEANUP_PLOT = config.CLEANUP_PLOT +SAS_OPENCL = config.SAS_OPENCL +# custom open_path +open_folder = config.DEFAULT_OPEN_FOLDER +if open_folder is not None and os.path.isdir(open_folder): + DEFAULT_OPEN_FOLDER = os.path.abspath(open_folder) +else: DEFAULT_OPEN_FOLDER = PATH_APP - SAS_OPENCL = config.SAS_OPENCL + #DEFAULT_STYLE = config.DEFAULT_STYLE From b11146e3ad4a15161b4d143d378dff08577aef25 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 15:22:39 +0100 Subject: [PATCH 32/82] Removed printEVT --- src/sas/config_system/config.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 0d1eedfcea..da9c975f2d 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -255,20 +255,5 @@ def __init__(self): # self.finalise() - def printEVT(self, message): - if self.__EVT_DEBUG__: - """ - :TODO - Need method doc string - """ - print("%g: %s" % (time.clock(), message)) - - if self.__EVT_DEBUG_2_FILE__: - out = open(self.__EVT_DEBUG_FILENAME__, 'a') - out.write("%10g: %s\n" % (time.clock(), message)) - out.close() - - - - From 86b8745884bfdb79545730bd4f8ae349fe919494 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 16:12:29 +0100 Subject: [PATCH 33/82] Config loading and saving properly implemented --- src/sas/__init__.py | 4 ++++ src/sas/config_system/config_meta.py | 31 +++++++++++++++++++++----- src/sas/qtgui/MainWindow/GuiManager.py | 5 +---- test/config/utest_config.py | 8 +++---- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/sas/__init__.py b/src/sas/__init__.py index d2133d3999..a41c7ecb5f 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -6,6 +6,10 @@ __all__ = ['get_app_dir', 'get_user_dir', 'config'] +# Load the config file +config.load() + + _APP_DIR = None def get_app_dir(): """ diff --git a/src/sas/config_system/config_meta.py b/src/sas/config_system/config_meta.py index eb72c17796..a25c61961c 100644 --- a/src/sas/config_system/config_meta.py +++ b/src/sas/config_system/config_meta.py @@ -1,9 +1,11 @@ -from typing import Optional, Dict, Any, List, Set -import json +from typing import Dict, Any, List +import os import logging -from sas.config_system.schema_elements import create_schema_element, CoercionError, SchemaElement +import json from copy import deepcopy + import sas +from sas.config_system.schema_elements import create_schema_element, CoercionError, SchemaElement logger = logging.getLogger("sas.config_system") @@ -39,7 +41,9 @@ def __init__(self): self._schema: Dict[str, SchemaElement] = {} self._defaults: Dict[str, SchemaElement] = {} self._deleted_attributes: List[str] = [] - self._meta_attributes = ["_locked", "_schema", "_defaults", "_deleted_attributes", "_meta_attributes"] + self._write_disabled = False + self._meta_attributes = ["_locked", "_schema", "_defaults", + "_deleted_attributes", "_meta_attributes", "_write_disabled"] def finalise(self): """ Call this at the end of the config to make this class 'final' @@ -71,7 +75,15 @@ def update(self, data: Dict[str, Any]): else: logger.error(f"Unknown config key: '{key}', skipping") - def save(self, file): + def save(self): + if self._write_disabled: + logger.error("Write disabled, this is probably because it will overwrite an outdated config.") + return + + with open("config.json", 'w') as file: + self.save_to_file_object(file) + + def save_to_file_object(self, file): """ Save config file Only changed variables will be included in the saved file @@ -89,7 +101,13 @@ def save(self, file): json.dump(output_data, file) - def load(self, file): + def load(self): + filename = "config.json" + if os.path.exists(filename): + with open("config.json", 'r') as file: + self.load_from_file_object(file) + + def load_from_file_object(self, file): """ Load config file """ data = json.load(file) @@ -119,6 +137,7 @@ def load(self, file): if int(file_major_version) != int(sasview_major_version): logger.warning(f"Attempting to used outdated config file (config is" f" for {file_version}, this SasView version is {sas.__version__})") + self._write_disabled = True self.update(data["config_data"]) diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index a2ecba6ce1..0360d522f7 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1300,10 +1300,7 @@ def saveCustomConfig(self): """ Save the config file based on current session values """ - # TODO: Decide what to do with config locations - logger.warning("Config paths have not yet been set up") - with open("config.json", 'w') as file: - config.save(file) + config.save() def customSavePaths(self, config_content): """ diff --git a/test/config/utest_config.py b/test/config/utest_config.py index b02d72f94b..5be7a5ec45 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -133,7 +133,7 @@ def test_save_basics(self): # Check saving with no changes, should be empty and config = Config() - config.save(file) + config.save_to_file_object(file) file.seek(0) @@ -156,7 +156,7 @@ def test_save_changes(self): file = StringIO() config = Config() config.update({key: test_dict[key]}) - config.save(file) + config.save_to_file_object(file) file.seek(0) observed = json.load(file) @@ -189,7 +189,7 @@ def test_only_save_actual_changes(self): config.update({key: test_dict[key]}) config.update({key: getattr(backup, key)}) - config.save(file) + config.save_to_file_object(file) file.seek(0) observed = json.load(file) @@ -211,7 +211,7 @@ def test_bad_config_version(self): with self.assertLogs('sas.config_system', level="WARN") as cm: # Try the bad value - config.load(file) + config.load_from_file_object(file) self.assertTrue(cm.output[0].startswith("WARNING:sas.config_system:")) From 85b300e01a9cc687a25aef9d784c27a5f25b6613 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 16:43:08 +0100 Subject: [PATCH 34/82] Removed some more things --- src/sas/config_system/config.py | 5 ----- src/sas/qtgui/MainWindow/GuiManager.py | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index da9c975f2d..82eeacec79 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -158,11 +158,6 @@ def __init__(self): self.__EVT_DEBUG_2_FILE__ = False self.__EVT_DEBUG_FILENAME__ = "debug.log" - # About box info - self._do_aboutbox = True - self._do_acknowledge = True - self._do_tutorial = True - self.icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images")) # logging.info("icon path: %s" % icon_path) self.media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 0360d522f7..e6c0ecd177 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1317,6 +1317,7 @@ def customSavePaths(self, config_content): changed = True return changed + def customSaveOpenCL(self, config_content): """ Update the config module with current session OpenCL choice From 72680b92f9125a2e030d6749354b35bcc64addcd Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 17:03:32 +0100 Subject: [PATCH 35/82] GuiUtils now duplicates variables, removing some --- run.py | 2 +- src/sas/config_system/config.py | 15 ++++++--------- src/sas/qtgui/Utilities/GuiUtils.py | 16 +++------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/run.py b/run.py index 11563f3c27..bc24a79b0c 100644 --- a/run.py +++ b/run.py @@ -122,7 +122,7 @@ def prepare(): root = abspath(dirname(realpath(sys.argv[0]))) addpath(joinpath(root, 'src')) - addpath(joinpath(root, joinpath('..', 'sasmodels'))) # dependency (for loading custom_config.py during log setup) + # addpath(joinpath(root, joinpath('..', 'sasmodels'))) # dependency (for loading custom_config.py during log setup) #from sas.logger_config import SetupLogger #logger = SetupLogger(__name__).config_development() diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 82eeacec79..9887c2d54f 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -163,20 +163,18 @@ def __init__(self): self.media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) self.test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test")) - - self._corner_image = os.path.join(self.icon_path, "angles_flat.png") - self._welcome_image = os.path.join(self.icon_path, "SVwelcome.png") - # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' self.APPLICATION_STATE_EXTENSION = '.svs' self.GUIFRAME_WIDTH = 1150 self.GUIFRAME_HEIGHT = 840 self.PLUGIN_STATE_EXTENSIONS = ['.fitv', '.inv', '.prv', '.crf'] - self.PLUGINS_WLIST = ['Fitting files (*.fitv)|*.fitv', - 'Invariant files (*.inv)|*.inv', - 'P(r) files (*.prv)|*.prv', - 'Corfunc files (*.crf)|*.crf'] + self.PLUGINS_WLIST = [ + 'Fitting files (*.fitv)|*.fitv', + 'Invariant files (*.inv)|*.inv', + 'P(r) files (*.prv)|*.prv', + 'Corfunc files (*.crf)|*.crf'] + self.PLOPANEL_WIDTH = 415 self.PLOPANEL_HEIGTH = 370 self.DATAPANEL_WIDTH = 235 @@ -184,7 +182,6 @@ def __init__(self): self.SPLASH_SCREEN_PATH = os.path.join(self.icon_path, "SVwelcome_mini.png") self.TUTORIAL_PATH = os.path.join(self.media_path, "Tutorial.pdf") - self.DEFAULT_STYLE = 64 self.SPLASH_SCREEN_WIDTH = 512 self.SPLASH_SCREEN_HEIGHT = 366 diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 8b1c64ff84..3360c0791f 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -137,24 +137,14 @@ def _find_local_config(confg_file, path): #read some constants from config -APPLICATION_STATE_EXTENSION = config.APPLICATION_STATE_EXTENSION -APPLICATION_NAME = config.__appname__ -SPLASH_SCREEN_PATH = config.SPLASH_SCREEN_PATH -WELCOME_PANEL_ON = config.WELCOME_PANEL_ON SPLASH_SCREEN_WIDTH = config.SPLASH_SCREEN_WIDTH SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME -if not WELCOME_PANEL_ON: - WELCOME_PANEL_SHOW = False -else: - WELCOME_PANEL_SHOW = True - DATALOADER_SHOW = config.DATALOADER_SHOW TOOLBAR_SHOW = config.TOOLBAR_SHOW FIXED_PANEL = config.FIXED_PANEL -if WELCOME_PANEL_ON: - WELCOME_PANEL_SHOW = config.WELCOME_PANEL_SHOW + PLOPANEL_WIDTH = config.PLOPANEL_WIDTH DATAPANEL_WIDTH = config.DATAPANEL_WIDTH GUIFRAME_WIDTH = config.GUIFRAME_WIDTH @@ -179,8 +169,8 @@ def _find_local_config(confg_file, path): VIEW_MENU = config.VIEW_MENU EDIT_MENU = config.EDIT_MENU extension_list = [] -if APPLICATION_STATE_EXTENSION is not None: - extension_list.append(APPLICATION_STATE_EXTENSION) +if config.APPLICATION_STATE_EXTENSION is not None: + extension_list.append(config.APPLICATION_STATE_EXTENSION) EXTENSIONS = PLUGIN_STATE_EXTENSIONS + extension_list try: PLUGINS_WLIST = '|'.join(config.PLUGINS_WLIST) From de53a085673170693f380c467022445feb0295c8 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 17:05:59 +0100 Subject: [PATCH 36/82] Removed unused splash screen params from GuiUtils --- src/sas/qtgui/Utilities/GuiUtils.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 3360c0791f..6f1660ff9b 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -137,9 +137,6 @@ def _find_local_config(confg_file, path): #read some constants from config -SPLASH_SCREEN_WIDTH = config.SPLASH_SCREEN_WIDTH -SPLASH_SCREEN_HEIGHT = config.SPLASH_SCREEN_HEIGHT -SS_MAX_DISPLAY_TIME = config.SS_MAX_DISPLAY_TIME DATALOADER_SHOW = config.DATALOADER_SHOW TOOLBAR_SHOW = config.TOOLBAR_SHOW From 4ad188f0330c71a2f98bef8672e8b01a2cd84450 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 17:06:55 +0100 Subject: [PATCH 37/82] Removed more GuiUtil duplicates --- src/sas/qtgui/Utilities/GuiUtils.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 6f1660ff9b..f9ead8e9ae 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -138,10 +138,6 @@ def _find_local_config(confg_file, path): #read some constants from config -DATALOADER_SHOW = config.DATALOADER_SHOW -TOOLBAR_SHOW = config.TOOLBAR_SHOW -FIXED_PANEL = config.FIXED_PANEL - PLOPANEL_WIDTH = config.PLOPANEL_WIDTH DATAPANEL_WIDTH = config.DATAPANEL_WIDTH GUIFRAME_WIDTH = config.GUIFRAME_WIDTH From 533d08f7fe65d7b5d26b06c1f04235b1cb525609 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 17:12:09 +0100 Subject: [PATCH 38/82] Removed more unused variables from GuiUtils --- src/sas/qtgui/Utilities/GuiUtils.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index f9ead8e9ae..da18a9d395 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -138,14 +138,6 @@ def _find_local_config(confg_file, path): #read some constants from config -PLOPANEL_WIDTH = config.PLOPANEL_WIDTH -DATAPANEL_WIDTH = config.DATAPANEL_WIDTH -GUIFRAME_WIDTH = config.GUIFRAME_WIDTH -GUIFRAME_HEIGHT = config.GUIFRAME_HEIGHT -CONTROL_WIDTH = config.CONTROL_WIDTH -CONTROL_HEIGHT = config.CONTROL_HEIGHT -DEFAULT_PERSPECTIVE = config.DEFAULT_PERSPECTIVE -CLEANUP_PLOT = config.CLEANUP_PLOT SAS_OPENCL = config.SAS_OPENCL # custom open_path open_folder = config.DEFAULT_OPEN_FOLDER From 7f6d833cd14c60f23c6ecee4b26970a74f75de4a Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 12 Sep 2022 17:20:16 +0100 Subject: [PATCH 39/82] Removed more GuiUtil things, and some references to it from DataExplorer --- src/sas/config_system/config.py | 6 ++++++ src/sas/qtgui/MainWindow/DataExplorer.py | 17 +++++++---------- src/sas/qtgui/Utilities/GuiUtils.py | 3 +++ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 9887c2d54f..cd3cb3002e 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -175,6 +175,12 @@ def __init__(self): 'P(r) files (*.prv)|*.prv', 'Corfunc files (*.crf)|*.crf'] + self.ANALYSIS_TYPES = [ + 'Fitting files (*.fitv)', + 'Invariant files (*.inv)', + 'P(r) files (*.prv)', + 'Corfunc files (*.crf)'] + self.PLOPANEL_WIDTH = 415 self.PLOPANEL_HEIGTH = 370 self.DATAPANEL_WIDTH = 235 diff --git a/src/sas/qtgui/MainWindow/DataExplorer.py b/src/sas/qtgui/MainWindow/DataExplorer.py index 69af555f34..d2b830116c 100644 --- a/src/sas/qtgui/MainWindow/DataExplorer.py +++ b/src/sas/qtgui/MainWindow/DataExplorer.py @@ -30,10 +30,7 @@ from sas.qtgui.MainWindow.NameChanger import ChangeName import sas.qtgui.Perspectives as Perspectives - -DEFAULT_PERSPECTIVE = "Fitting" -ANALYSIS_TYPES = ['Fitting (*.fitv)', 'Inversion (*.pr)', 'Invariant (*.inv)', - 'Corfunc (*.crf)', 'All Files (*.*)'] +from sas import config logger = logging.getLogger(__name__) @@ -57,7 +54,7 @@ def __init__(self, parent=None, guimanager=None, manager=None): # Read in default locations self.default_save_location = None - self.default_load_location = GuiUtils.DEFAULT_OPEN_FOLDER + self.default_load_location = config.DEFAULT_OPEN_FOLDER self.default_project_location = None self.manager = manager if manager is not None else DataManager() @@ -196,7 +193,7 @@ def initPerspectives(self): self.cbFitting.addItems(available_perspectives) self.cbFitting.currentIndexChanged.connect(self.updatePerspectiveCombo) # Set the index so we see the default (Fitting) - self.cbFitting.setCurrentIndex(self.cbFitting.findText(DEFAULT_PERSPECTIVE)) + self.cbFitting.setCurrentIndex(self.cbFitting.findText(config.DEFAULT_PERSPECTIVE)) def _perspective(self): """ @@ -290,7 +287,7 @@ def loadAnalysis(self): """ Called when the "Open Analysis" menu item chosen. """ - file_filter = ';;'.join(ANALYSIS_TYPES) + file_filter = ';;'.join(config.ANALYSIS_TYPES + ['All Files (*.*)']) kwargs = { 'parent' : self, 'caption' : 'Open Analysis', @@ -506,7 +503,7 @@ def readProject(self, filename): logging.error("Project load failed with " + str(ex)) return cs_keys = [] - visible_perspective = DEFAULT_PERSPECTIVE + visible_perspective = config.DEFAULT_PERSPECTIVE for key, value in all_data.items(): if key == 'is_batch': self.chkBatch.setChecked(value == 'True') @@ -527,7 +524,7 @@ def readProject(self, filename): self.updatePerspectiveWithProperties(key, value) # Set to fitting perspective and load in Batch and C&S Pages self.cbFitting.setCurrentIndex( - self.cbFitting.findText(DEFAULT_PERSPECTIVE)) + self.cbFitting.findText(config.DEFAULT_PERSPECTIVE)) # See if there are any batch pages defined and create them, if so self.updateWithBatchPages(all_data) # Get the constraint dict and apply it @@ -581,7 +578,7 @@ def updatePerspectiveWithProperties(self, key, value): items = self.updateModelFromData(data_dict) if 'fit_params' in value: - self.cbFitting.setCurrentIndex(self.cbFitting.findText(DEFAULT_PERSPECTIVE)) + self.cbFitting.setCurrentIndex(self.cbFitting.findText(config.DEFAULT_PERSPECTIVE)) params = value['fit_params'] # Make the perspective read the rest of the read data if not isinstance(params, list): diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index da18a9d395..4f6a690625 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -146,6 +146,9 @@ def _find_local_config(confg_file, path): else: DEFAULT_OPEN_FOLDER = PATH_APP +if config.DEFAULT_OPEN_FOLDER != "": + config.DEFAULT_OPEN_FOLDER = PATH_APP + #DEFAULT_STYLE = config.DEFAULT_STYLE From d9650e7d6fb8615482c666e24fa3f78764e5e91b Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Tue, 13 Sep 2022 09:35:42 +0100 Subject: [PATCH 40/82] Fixed test --- test/config/utest_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config/utest_config.py b/test/config/utest_config.py index 5be7a5ec45..ecc03c624c 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -247,7 +247,7 @@ def test_bad_config_file_structure(self): file.seek(0) with self.assertRaises(MalformedFile): - config.load(file) + config.load_from_file_object(file) def test_schema_union(self): From 97cd81dc63ec419f41d2a15d1150dcaeb991f800 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Tue, 13 Sep 2022 11:30:10 +0100 Subject: [PATCH 41/82] Deleted _config --- src/sas/_config.py | 65 ---------------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 src/sas/_config.py diff --git a/src/sas/_config.py b/src/sas/_config.py deleted file mode 100644 index 99beda90e7..0000000000 --- a/src/sas/_config.py +++ /dev/null @@ -1,65 +0,0 @@ -# Setup and find Custom config dir -from __future__ import print_function - -import sys -import os -from os.path import exists, expanduser, dirname, realpath, join as joinpath -import logging -import shutil - -from sasmodels.custom import load_module_from_path - -logger = logging.getLogger(__name__) - -# TODO: REMOVE -def make_custom_config_path(user_dir): - raise RuntimeError("Tried to run make_custom_config_path - this is now forbidden") - # """ - # The location of the cusstom config file. - # - # Returns ~/.sasview/config/custom_config.py - # """ - # dirname = os.path.join(user_dir, 'config') - # # If the directory doesn't exist, create it - # if not os.path.exists(dirname): - # os.makedirs(dirname) - # path = os.path.join(dirname, "custom_config.py") - # return path - -def setup_custom_config(app_dir, user_dir): - raise RuntimeError("Tried to run setup_custom_config - this is now forbidden") - - # path = make_custom_config_path(user_dir) - # if not os.path.isfile(path): - # try: - # # if the custom config file does not exist, copy the default from - # # the app dir - # shutil.copyfile(os.path.join(app_dir, "custom_config.py"), path) - # except Exception: - # logger.error("Could not copy default custom config.") - # - # #Adding SAS_OPENCL if it doesn't exist in the config file - # # - to support backcompability - # if not "SAS_OPENCL" in open(path).read(): - # try: - # open(path, "a+").write("SAS_OPENCL = \"None\"\n") - # except Exception: - # logger.error("Could not update custom config with SAS_OPENCL.") - # - # custom_config = load_custom_config(path) - # return custom_config - - -def load_custom_config(path): - raise RuntimeError("Tried to call load_custom_config - this is now forbidden") - # if os.path.exists(path): - # try: - # module = load_module_from_path('sas.custom_config', path) - # #logger.info("GuiManager loaded %s", path) - # return module - # except Exception as exc: - # logger.error("Error loading %s: %s", path, exc) - # - # from sas.sasview import custom_config - # logger.info("GuiManager custom_config defaults to sas.sasview.custom_config") - # return custom_config \ No newline at end of file From 19af85e2c9a78eba30967a6d2ad36ea80e9dc8af Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Tue, 13 Sep 2022 11:34:39 +0100 Subject: [PATCH 42/82] Removed unused config variables --- src/sas/config_system/config.py | 17 ++--------------- src/sas/qtgui/MainWindow/GuiManager.py | 2 +- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index cd3cb3002e..8e0fe9bf5a 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -189,12 +189,7 @@ def __init__(self): self.TUTORIAL_PATH = os.path.join(self.media_path, "Tutorial.pdf") - self.SPLASH_SCREEN_WIDTH = 512 - self.SPLASH_SCREEN_HEIGHT = 366 - self.SS_MAX_DISPLAY_TIME = 2000 - self.WELCOME_PANEL_ON = True - self.WELCOME_PANEL_SHOW = False - self.CLEANUP_PLOT = False + self.SHOW_WELCOME_PANEL = False # OPEN and SAVE project menu self.OPEN_SAVE_PROJECT_MENU = True # VIEW MENU @@ -202,15 +197,9 @@ def __init__(self): # EDIT MENU self.EDIT_MENU = True - self.SetupIconFile_win = os.path.join(self.icon_path, "ball.ico") - self.SetupIconFile_mac = os.path.join(self.icon_path, "ball.icns") - self.DefaultGroupName = "." - self.OutputBaseFilename = "setupSasView" self.FIXED_PANEL = True self.DATALOADER_SHOW = True - self.CLEANUP_PLOT = False - self.WELCOME_PANEL_SHOW = False # Show or hide toolbar at the start up self.TOOLBAR_SHOW = True # set a default perspective @@ -231,11 +220,9 @@ def __init__(self): self.GUIFRAME_WIDTH = -1 self.CONTROL_WIDTH = -1 self.CONTROL_HEIGHT = -1 - self.DEFAULT_OPEN_FOLDER = None - self.WELCOME_PANEL_SHOW = False + self.DEFAULT_OPEN_FOLDER = "" self.TOOLBAR_SHOW = True self.DEFAULT_PERSPECTIVE = "Fitting" - self.SAS_OPENCL = "None" # Logging options self.FILTER_DEBUG_LOGS = True diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index e6c0ecd177..e711b7bc06 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -601,7 +601,7 @@ def showWelcomeMessage(self): # Assure the welcome screen is requested show_welcome_widget = True - if config.WELCOME_PANEL_SHOW: + if config.SHOW_WELCOME_PANEL: self.actionWelcome() def addCallbacks(self): From 36ed14da84bafd05dcb1da00d6f9bd75b94c18c1 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Tue, 13 Sep 2022 11:36:48 +0100 Subject: [PATCH 43/82] Removed more unused config items --- src/sas/config_system/config.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 8e0fe9bf5a..00bd6c5cf3 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -166,8 +166,6 @@ def __init__(self): # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' self.APPLICATION_STATE_EXTENSION = '.svs' - self.GUIFRAME_WIDTH = 1150 - self.GUIFRAME_HEIGHT = 840 self.PLUGIN_STATE_EXTENSIONS = ['.fitv', '.inv', '.prv', '.crf'] self.PLUGINS_WLIST = [ 'Fitting files (*.fitv)|*.fitv', @@ -200,13 +198,7 @@ def __init__(self): self.FIXED_PANEL = True self.DATALOADER_SHOW = True - # Show or hide toolbar at the start up - self.TOOLBAR_SHOW = True - # set a default perspective - self.DEFAULT_PERSPECTIVE = 'None' - # Time out for updating sasview - self.UPDATE_TIMEOUT = 2 # OpenCL option self.SAS_OPENCL = None @@ -216,8 +208,6 @@ def __init__(self): self.FIXED_PANEL = True self.PLOPANEL_WIDTH = -1 self.DATALOADER_SHOW = True - self.GUIFRAME_HEIGHT = -1 - self.GUIFRAME_WIDTH = -1 self.CONTROL_WIDTH = -1 self.CONTROL_HEIGHT = -1 self.DEFAULT_OPEN_FOLDER = "" From 4b7ec882db69deab2127b8ece77637a38a769789 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Tue, 13 Sep 2022 11:37:30 +0100 Subject: [PATCH 44/82] Removed further config items --- src/sas/config_system/config.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index 00bd6c5cf3..a900748b80 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -158,11 +158,6 @@ def __init__(self): self.__EVT_DEBUG_2_FILE__ = False self.__EVT_DEBUG_FILENAME__ = "debug.log" - self.icon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "images")) - # logging.info("icon path: %s" % icon_path) - self.media_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "media")) - self.test_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "test")) - # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' self.APPLICATION_STATE_EXTENSION = '.svs' @@ -183,9 +178,6 @@ def __init__(self): self.PLOPANEL_HEIGTH = 370 self.DATAPANEL_WIDTH = 235 self.DATAPANEL_HEIGHT = 700 - self.SPLASH_SCREEN_PATH = os.path.join(self.icon_path, "SVwelcome_mini.png") - self.TUTORIAL_PATH = os.path.join(self.media_path, "Tutorial.pdf") - self.SHOW_WELCOME_PANEL = False # OPEN and SAVE project menu From 11a1ef2fb231d6b1c0b456bb998b63616f806dff Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Tue, 13 Sep 2022 16:38:37 +0100 Subject: [PATCH 45/82] Moved some packages, started on environment variable interface --- setup.py | 5 ++- src/sas/__init__.py | 2 +- src/sas/config_system/config.py | 16 +------ src/sas/qtgui/MainWindow/GuiManager.py | 32 -------------- src/sas/qtgui/MainWindow/MainWindow.py | 3 +- .../qtgui/Perspectives/Fitting/GPUOptions.py | 3 ++ src/sas/system/environment.py | 42 +++++++++++++++++++ src/sas/{logging.ini => system/log.ini} | 0 src/sas/{logger_config.py => system/log.py} | 6 +-- src/sas/version.py | 5 --- 10 files changed, 55 insertions(+), 59 deletions(-) create mode 100644 src/sas/system/environment.py rename src/sas/{logging.ini => system/log.ini} (100%) rename src/sas/{logger_config.py => system/log.py} (94%) delete mode 100644 src/sas/version.py diff --git a/setup.py b/setup.py index 7ad66afad4..c841501d48 100644 --- a/setup.py +++ b/setup.py @@ -242,7 +242,6 @@ def run(self): "sas.qtgui.Plotting.Slicers", "sas.qtgui.Plotting.Masks"]) # SasView -package_data['sas'] = ['logging.ini'] package_data['sas.sasview'] = ['images/*', 'media/*'] @@ -260,6 +259,10 @@ def run(self): 'upcoming_formats/*', ] packages.append("sas.sasview") + +package_data["sas.system"] = ["*"] +packages.append("sas.system") + package_data['sas.qtgui'] = ['Calculators/UI/*', 'MainWindow/UI/*', 'Perspectives/Corfunc/UI/*', diff --git a/src/sas/__init__.py b/src/sas/__init__.py index a41c7ecb5f..2d8785e921 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -1,10 +1,10 @@ -from sas.version import __version__ import os import sys from sas.config_system import configuration as config __all__ = ['get_app_dir', 'get_user_dir', 'config'] +__version__ = "5.0.5" # Load the config file config.load() diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index a900748b80..b75252eebc 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -174,11 +174,6 @@ def __init__(self): 'P(r) files (*.prv)', 'Corfunc files (*.crf)'] - self.PLOPANEL_WIDTH = 415 - self.PLOPANEL_HEIGTH = 370 - self.DATAPANEL_WIDTH = 235 - self.DATAPANEL_HEIGHT = 700 - self.SHOW_WELCOME_PANEL = False # OPEN and SAVE project menu self.OPEN_SAVE_PROJECT_MENU = True @@ -188,23 +183,14 @@ def __init__(self): self.EDIT_MENU = True - self.FIXED_PANEL = True - self.DATALOADER_SHOW = True - # OpenCL option self.SAS_OPENCL = None - self.DATAPANEL_WIDTH = -1 - self.CLEANUP_PLOT = False - self.FIXED_PANEL = True - self.PLOPANEL_WIDTH = -1 - self.DATALOADER_SHOW = True - self.CONTROL_WIDTH = -1 - self.CONTROL_HEIGHT = -1 self.DEFAULT_OPEN_FOLDER = "" self.TOOLBAR_SHOW = True self.DEFAULT_PERSPECTIVE = "Fitting" + # self.DEFAULT_PERSPECTIVE = "Corfunc" # Logging options self.FILTER_DEBUG_LOGS = True diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index e711b7bc06..d6ce27b609 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -1301,35 +1301,3 @@ def saveCustomConfig(self): Save the config file based on current session values """ config.save() - - def customSavePaths(self, config_content): - """ - Update the config module with current session paths - Returns True if update was done, False, otherwise - """ - changed = False - # Find load path - open_path = GuiUtils.DEFAULT_OPEN_FOLDER - defined_path = self.filesWidget.default_load_location - if open_path != defined_path: - # Replace the load path - config_content.DEFAULT_OPEN_FOLDER = defined_path - changed = True - return changed - - - def customSaveOpenCL(self, config_content): - """ - Update the config module with current session OpenCL choice - Returns True if update was done, False, otherwise - """ - changed = False - # Find load path - file_value = GuiUtils.SAS_OPENCL - session_value = os.environ.get("SAS_OPENCL", "") - if file_value != session_value: - # Replace the load path - config_content.SAS_OPENCL = session_value - changed = True - return changed - diff --git a/src/sas/qtgui/MainWindow/MainWindow.py b/src/sas/qtgui/MainWindow/MainWindow.py index ba4cb1d321..92fcbe3879 100644 --- a/src/sas/qtgui/MainWindow/MainWindow.py +++ b/src/sas/qtgui/MainWindow/MainWindow.py @@ -13,7 +13,6 @@ from PyQt5.QtCore import Qt # Local UI -from sas.qtgui.UI import main_resources_rc from .UI.MainWindowUI import Ui_SasView class MainSasViewWindow(QMainWindow, Ui_SasView): @@ -71,7 +70,7 @@ def run_sasview(): app = QApplication([]) #Initialize logger - from sas.logger_config import SetupLogger + from sas.system.log import SetupLogger SetupLogger(__name__).config_development() # initialize sasmodels settings diff --git a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py index 4b1fe584a9..8bd9a41bb5 100644 --- a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py +++ b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py @@ -108,6 +108,9 @@ def checked(self): else: self.sas_open_cl = None + logger.info(self.sas_open_cl) + print(self.sas_open_cl) + def set_sas_open_cl(self): """ Set SAS_OPENCL value when tests run or OK button clicked diff --git a/src/sas/system/environment.py b/src/sas/system/environment.py new file mode 100644 index 0000000000..9fa9d5d7c4 --- /dev/null +++ b/src/sas/system/environment.py @@ -0,0 +1,42 @@ +""" Interface for environmental variable access, + +This is intended to handle any conversion from the environment variable string to more natural types. +""" +import os +import logging + +class Envrironment: + + logger = logging.getLogger(__name__) + + @property + def sas_opencl(self) -> int: + """ + Get the value of the environment variable SAS_OPENCL, which specifies which OpenCL device + should be used. + + FAQ: Why use -1 to represent the no-device state, rather than None? Isn't None a better choice? + Ans: This helps keep the config files in order (see docs on that), as the type of -1 (the default) + can be inferred and checked online. + + """ + + string_value = os.environ.get("SAS_OPENCL", "None") + if string_value.lower() == "none": + return -1 + else: + try: + int_value = int(string_value) + return int_value + except ValueError: + self.logger.warning( + f"Failed to parse SAS_OPENCL environment variable, expected an integer or 'none', got {string_value}") + return -1 + + @sas_opencl.setter + def sas_opencl(self, value: int): + """ + Set the value of the environment variable SAS_OPENCL + """ + + os.environ["SAS_OPENCL"] = str(value) diff --git a/src/sas/logging.ini b/src/sas/system/log.ini similarity index 100% rename from src/sas/logging.ini rename to src/sas/system/log.ini diff --git a/src/sas/logger_config.py b/src/sas/system/log.py similarity index 94% rename from src/sas/logger_config.py rename to src/sas/system/log.py index de2f2ad73e..bd923d2856 100644 --- a/src/sas/logger_config.py +++ b/src/sas/system/log.py @@ -62,7 +62,7 @@ def _update_all_logs_to_debug(self, logger): for name, _ in logging.Logger.manager.loggerDict.items(): logging.getLogger(name).setLevel(logging.DEBUG) - def _find_config_file(self, filename="logging.ini"): + def _find_config_file(self, filename="log.ini"): ''' The config file is in: Debug ./sasview/ @@ -73,8 +73,8 @@ def _find_config_file(self, filename="logging.ini"): places_to_look_for_conf_file = [ os.path.join(os.path.abspath(os.path.dirname(__file__)), filename), filename, - os.path.join("sas", "sasview", filename), - os.path.join(os.getcwd(), "sas", "sasview", filename), + os.path.join("sas", "system", filename), + os.path.join(os.getcwd(), "sas", "system", filename), os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), filename) #For OSX app ] diff --git a/src/sas/version.py b/src/sas/version.py deleted file mode 100644 index 024bb246f3..0000000000 --- a/src/sas/version.py +++ /dev/null @@ -1,5 +0,0 @@ -""" This file is just for containing the version number, nothing else - -It is imported by sas.__init__ so that sas.__version__ exists too""" - -__version__ = "5.0.5" \ No newline at end of file From 3a755d004e96658b9fe74df1f3d21ac21394de72 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 10:38:31 +0100 Subject: [PATCH 46/82] Updated config variables --- run.py | 43 ++++--------------- .../qtgui/Perspectives/Fitting/GPUOptions.py | 26 +++++------ src/sas/system/__init__.py | 3 +- src/sas/system/{environment.py => env.py} | 7 ++- 4 files changed, 27 insertions(+), 52 deletions(-) rename src/sas/system/{environment.py => env.py} (89%) diff --git a/run.py b/run.py index bc24a79b0c..ed37b2ef6c 100644 --- a/run.py +++ b/run.py @@ -59,9 +59,6 @@ def prepare(): # Don't create *.pyc files sys.dont_write_bytecode = True - # Debug numpy warnings - #import numpy; numpy.seterr(all='raise') - # find the directories for the source and build from distutils.util import get_platform root = abspath(dirname(realpath(__file__))) @@ -73,15 +70,6 @@ def prepare(): # place than it otherwise would be. os.environ['SASVIEW_DOC_PATH'] = joinpath(build_path, "doc") - # Make sure that we have a private version of mplconfig - #mplconfig = joinpath(abspath(dirname(__file__)), '.mplconfig') - #os.environ['MPLCONFIGDIR'] = mplconfig - #if not os.path.exists(mplconfig): os.mkdir(mplconfig) - #import matplotlib - # matplotlib.use('Agg') - # print matplotlib.__file__ - #import pylab; pylab.hold(False) - # add periodictable to the path try: import periodictable except ImportError: @@ -92,28 +80,20 @@ def prepare(): except ImportError: addpath(joinpath(root, '..', 'bumps')) - # == no more C sources so no need to build project to run it == - ## Build project if the build directory does not already exist. - #if not os.path.exists(build_path): - # import subprocess - # with cd(root): - # subprocess.call((sys.executable, "setup.py", "build"), shell=False) - # Put the source trees on the path addpath(joinpath(root, 'src')) # sasmodels on the path addpath(joinpath(root, '../sasmodels/')) - # Note: only needed when running gui so suppress for now. - ## Run the UI conversion tool. - #import sas.qtgui.convertUI - - # initialize OpenCL setting - import sas - SAS_OPENCL = sas.config.SAS_OPENCL - if SAS_OPENCL and "SAS_OPENCL" not in os.environ: - os.environ["SAS_OPENCL"] = SAS_OPENCL + # If the SAS_OPENCL environment setting is set, set the config from it + # if it isn't set, set it from the config + from sas import config + from sas.system import env + if "SAS_OPENCL" in os.environ: + config.SAS_OPENCL = env.sas_opencl + else: + env.sas_opencl = config.SAS_OPENCL if __name__ == "__main__": @@ -122,13 +102,8 @@ def prepare(): root = abspath(dirname(realpath(sys.argv[0]))) addpath(joinpath(root, 'src')) - # addpath(joinpath(root, joinpath('..', 'sasmodels'))) # dependency (for loading custom_config.py during log setup) - - #from sas.logger_config import SetupLogger - #logger = SetupLogger(__name__).config_development() - - #logger.debug("Starting SASVIEW in debug mode.") prepare() + # Run the UI conversion tool when executed from script. This has to # happen after prepare() so that sas.qtgui is on the path. import sas.qtgui.convertUI diff --git a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py index 8bd9a41bb5..be323658d5 100644 --- a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py +++ b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py @@ -18,6 +18,9 @@ from sas.qtgui.Perspectives.Fitting.UI.GPUOptionsUI import Ui_GPUOptions from sas.qtgui.Perspectives.Fitting.UI.GPUTestResultsUI import Ui_GPUTestResults +from sas.system import env +from sas import config + try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: @@ -64,10 +67,10 @@ def addOpenCLOptions(self): """ # Get list of openCL options and add to GUI cl_tuple = _get_clinfo() - self.sas_open_cl = os.environ.get("SAS_OPENCL", "") + self.sas_open_cl = config.sas_opencl # Keys are the names in the form "platform: device". Corresponding values are the combined indices, e.g. - # "0:1", for setting the SAS_OPENCL env. + # "0:1", for setting the SAS_OPENCL env. TODO This appears not to be the case self.cl_options = {} for title, descr in cl_tuple: @@ -76,8 +79,7 @@ def addOpenCLOptions(self): check_box.setObjectName(_fromUtf8(descr)) check_box.setText(_translate("GPUOptions", descr, None)) self.optionsLayout.addWidget(check_box) - if (title == self.sas_open_cl) or ( - title == "None" and not self.clicked): + if (title == self.sas_open_cl) or (title == "None" and not self.clicked): check_box.click() self.clicked = True self.cl_options[descr] = title @@ -106,23 +108,15 @@ def checked(self): if hasattr(checked, "text"): self.sas_open_cl = self.cl_options[str(checked.text())] else: - self.sas_open_cl = None - - logger.info(self.sas_open_cl) - print(self.sas_open_cl) + self.sas_open_cl = -1 def set_sas_open_cl(self): """ Set SAS_OPENCL value when tests run or OK button clicked """ - no_opencl_msg = False - if self.sas_open_cl: - os.environ["SAS_OPENCL"] = self.sas_open_cl - if self.sas_open_cl.lower() == "none": - no_opencl_msg = True - else: - if "SAS_OPENCL" in os.environ: - del os.environ["SAS_OPENCL"] + no_opencl_msg = self.sas_open_cl == -1 + env.sas_opencl = self.sas_open_cl + # CRUFT: next version of reset_environment() will return env sasmodels.sasview_model.reset_environment() return no_opencl_msg diff --git a/src/sas/system/__init__.py b/src/sas/system/__init__.py index ecca45334f..c4b441ad04 100644 --- a/src/sas/system/__init__.py +++ b/src/sas/system/__init__.py @@ -1,4 +1,5 @@ from .web import web from .legal import legal +from .env import env -__all__ = ["web", "legal"] \ No newline at end of file +__all__ = ["web", "legal", "env"] \ No newline at end of file diff --git a/src/sas/system/environment.py b/src/sas/system/env.py similarity index 89% rename from src/sas/system/environment.py rename to src/sas/system/env.py index 9fa9d5d7c4..fe591e8d98 100644 --- a/src/sas/system/environment.py +++ b/src/sas/system/env.py @@ -39,4 +39,9 @@ def sas_opencl(self, value: int): Set the value of the environment variable SAS_OPENCL """ - os.environ["SAS_OPENCL"] = str(value) + if value == -1: + del os.environ["SAS_OPENCL"] + else: + os.environ["SAS_OPENCL"] = str(value) + +env = Envrironment() \ No newline at end of file From fe81a7f99fc695b371ec51ab10e93244f3bbd46f Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 10:54:46 +0100 Subject: [PATCH 47/82] Removing old config, adjusting CL state representation --- src/sas/__init__.py | 2 +- src/sas/config_system/config.py | 12 ------------ src/sas/qtgui/MainWindow/AboutBox.py | 2 +- src/sas/qtgui/MainWindow/GuiManager.py | 4 ++-- src/sas/qtgui/MainWindow/PackageGatherer.py | 2 +- src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py | 5 +++-- src/sas/system/env.py | 2 +- src/sas/system/log.py | 2 +- 8 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/sas/__init__.py b/src/sas/__init__.py index 2d8785e921..575abfd44e 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -1,10 +1,10 @@ +from sas.sasview import __version__ import os import sys from sas.config_system import configuration as config __all__ = ['get_app_dir', 'get_user_dir', 'config'] -__version__ = "5.0.5" # Load the config file config.load() diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index b75252eebc..ad38f79a06 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -143,21 +143,9 @@ class Config(ConfigBase, metaclass=ConfigMeta): def __init__(self): super().__init__() - # Version of the application - self.__appname__ = "SasView" - self.__version__ = sas.sasview.__version__ - self.__build__ = sas.sasview.__build__ - - # Debug message flag - self.__EVT_DEBUG__ = False - # Flag for automated testing self.__TEST__ = False - # Debug message should be written to a file? - self.__EVT_DEBUG_2_FILE__ = False - self.__EVT_DEBUG_FILENAME__ = "debug.log" - # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' self.APPLICATION_STATE_EXTENSION = '.svs' diff --git a/src/sas/qtgui/MainWindow/AboutBox.py b/src/sas/qtgui/MainWindow/AboutBox.py index 117d1f7f0f..f5378e9ad6 100644 --- a/src/sas/qtgui/MainWindow/AboutBox.py +++ b/src/sas/qtgui/MainWindow/AboutBox.py @@ -40,7 +40,7 @@ def addText(self):

- Build{config.__build__} + Build{sas.sasview.__build__}

{legal.copyright} diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index d6ce27b609..5960dee42c 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -65,6 +65,7 @@ from sas.qtgui.Utilities.ImageViewer import ImageViewer from sas.qtgui.Utilities.FileConverter import FileConverterWidget +import sas from sas import config from sas.system import web @@ -571,7 +572,7 @@ def processVersion(self, version_info): msg += " Please try again later." self.communicate.statusBarUpdateSignal.emit(msg) - elif version.__gt__(config.__version__): + elif version.__gt__(sas.__version__): msg = "Version %s is available! " % str(version) if "download_url" in version_info: webbrowser.open(version_info["download_url"]) @@ -580,7 +581,6 @@ def processVersion(self, version_info): self.communicate.statusBarUpdateSignal.emit(msg) else: msg = "You have the latest version" - msg += " of %s" % str(config.__appname__) self.communicate.statusBarUpdateSignal.emit(msg) except: msg = "guiframe: could not get latest application" diff --git a/src/sas/qtgui/MainWindow/PackageGatherer.py b/src/sas/qtgui/MainWindow/PackageGatherer.py index d6a447706d..e3bb4bdc04 100644 --- a/src/sas/qtgui/MainWindow/PackageGatherer.py +++ b/src/sas/qtgui/MainWindow/PackageGatherer.py @@ -69,7 +69,7 @@ def get_imported_packages(self): :returns: A dictionary with the package names as the key, with their respective version numbers as the value. :rtype: dict """ - package_versions_dict = {'python': sys.version, 'SasView': sas.sasview.__version__} + package_versions_dict = {'python': sys.version, 'SasView': sas.__version__} err_version_dict = {} no_version_list = [] # Generate a list of standard modules by looking at the local python library diff --git a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py index 42c51a5860..dc7ec47aef 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py @@ -7,6 +7,7 @@ from PyQt5 import QtCore from unittest.mock import MagicMock +import sas.sasview from sas import config from sas.system import web, legal @@ -44,7 +45,7 @@ def testVersion(self): """ version = self.widget.lblVersion self.assertIsInstance(version, QtWidgets.QLabel) - self.assertEqual(str(version.text()), str(config.__version__)) + self.assertEqual(str(version.text()), str(sas.__version__)) def testAbout(self): """ @@ -53,7 +54,7 @@ def testAbout(self): about = self.widget.lblAbout self.assertIsInstance(about, QtWidgets.QLabel) # build version - self.assertIn(str(config.__build__), about.text()) + self.assertIn(str(sas.sasview.__build__), about.text()) # License self.assertIn(str(legal.copyright), about.text()) # URLs diff --git a/src/sas/system/env.py b/src/sas/system/env.py index fe591e8d98..4a8c4c5af6 100644 --- a/src/sas/system/env.py +++ b/src/sas/system/env.py @@ -1,4 +1,4 @@ -""" Interface for environmental variable access, +""" Interface for environment variable access This is intended to handle any conversion from the environment variable string to more natural types. """ diff --git a/src/sas/system/log.py b/src/sas/system/log.py index bd923d2856..bfc4451220 100644 --- a/src/sas/system/log.py +++ b/src/sas/system/log.py @@ -90,5 +90,5 @@ def _find_config_file(self, filename="log.ini"): if os.path.exists(filepath): self.config_file = filepath return - print("ERROR: Logging.ini not found...") + print(f"'{filename}' not found.", file=sys.stderr) self.config_file = None From 8d91a0b011704c1eab869b5adbb599aa6dad70c9 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 14:40:05 +0100 Subject: [PATCH 48/82] GPU settings updated --- run.py | 8 -- src/sas/config_system/config.py | 4 +- src/sas/qtgui/MainWindow/MainWindow.py | 16 +++- .../qtgui/Perspectives/Fitting/GPUOptions.py | 74 +++++++++---------- src/sas/system/env.py | 29 ++------ 5 files changed, 55 insertions(+), 76 deletions(-) diff --git a/run.py b/run.py index ed37b2ef6c..74a88afeeb 100644 --- a/run.py +++ b/run.py @@ -86,14 +86,6 @@ def prepare(): # sasmodels on the path addpath(joinpath(root, '../sasmodels/')) - # If the SAS_OPENCL environment setting is set, set the config from it - # if it isn't set, set it from the config - from sas import config - from sas.system import env - if "SAS_OPENCL" in os.environ: - config.SAS_OPENCL = env.sas_opencl - else: - env.sas_opencl = config.SAS_OPENCL if __name__ == "__main__": diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index ad38f79a06..b0a6acbf71 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -172,8 +172,8 @@ def __init__(self): - # OpenCL option - self.SAS_OPENCL = None + # OpenCL option - should be a string, either, "none", a number, or pair of form "A:B" + self.SAS_OPENCL = "none" self.DEFAULT_OPEN_FOLDER = "" self.TOOLBAR_SHOW = True diff --git a/src/sas/qtgui/MainWindow/MainWindow.py b/src/sas/qtgui/MainWindow/MainWindow.py index 92fcbe3879..dbc9672dc2 100644 --- a/src/sas/qtgui/MainWindow/MainWindow.py +++ b/src/sas/qtgui/MainWindow/MainWindow.py @@ -1,9 +1,12 @@ # UNLESS EXEPTIONALLY REQUIRED TRY TO AVOID IMPORTING ANY MODULES HERE # ESPECIALLY ANYTHING IN SAS, SASMODELS NAMESPACE +import logging import os import sys from sas.sasview import __version__ as SASVIEW_VERSION +from sas import config +from sas.system import env from PyQt5.QtWidgets import QMainWindow from PyQt5.QtWidgets import QMdiArea @@ -74,13 +77,18 @@ def run_sasview(): SetupLogger(__name__).config_development() # initialize sasmodels settings - from sas import config, get_user_dir + from sas import get_user_dir if "SAS_DLL_PATH" not in os.environ: os.environ["SAS_DLL_PATH"] = os.path.join( get_user_dir(), "compiled_models") - SAS_OPENCL = config.SAS_OPENCL - if SAS_OPENCL and "SAS_OPENCL" not in os.environ: - os.environ["SAS_OPENCL"] = SAS_OPENCL + + # Set open cl config from environment variable, if it is set + if "SAS_OPENCL" in os.environ: + logging.getLogger(__name__).info("Getting OpenCL settings from environment variables") + config.SAS_OPENCL = env.sas_opencl + else: + logging.getLogger(__name__).info("Getting OpenCL settings from config") + env.sas_opencl = config.SAS_OPENCL # Make the event loop interruptable quickly import signal diff --git a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py index be323658d5..8abd142ff4 100644 --- a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py +++ b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py @@ -42,8 +42,6 @@ class GPUOptions(QtWidgets.QDialog, Ui_GPUOptions): OpenCL Dialog to select the desired OpenCL driver """ - clicked = False - sas_open_cl = None cl_options = None testingDoneSignal = QtCore.pyqtSignal(str) testingFailedSignal = QtCore.pyqtSignal(str) @@ -52,70 +50,64 @@ def __init__(self, parent=None): super(GPUOptions, self).__init__(parent) self.parent = parent self.setupUi(self) + + self.radio_buttons = [] + # disable the context help icon self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) - self.addOpenCLOptions() + self.add_options() self.progressBar.setVisible(False) self.progressBar.setFormat(" Test %v / %m") - self.createLinks() + + self.testButton.clicked.connect(self.testButtonClicked) + self.helpButton.clicked.connect(self.helpButtonClicked) self.testingDoneSignal.connect(self.testCompleted) self.testingFailedSignal.connect(self.testFailed) - def addOpenCLOptions(self): + + def add_options(self): """ Populate the window with a list of OpenCL options """ # Get list of openCL options and add to GUI cl_tuple = _get_clinfo() - self.sas_open_cl = config.sas_opencl - # Keys are the names in the form "platform: device". Corresponding values are the combined indices, e.g. - # "0:1", for setting the SAS_OPENCL env. TODO This appears not to be the case self.cl_options = {} + for title, descr in cl_tuple: + # Create an item for each openCL option - check_box = QtWidgets.QCheckBox() - check_box.setObjectName(_fromUtf8(descr)) - check_box.setText(_translate("GPUOptions", descr, None)) - self.optionsLayout.addWidget(check_box) - if (title == self.sas_open_cl) or (title == "None" and not self.clicked): - check_box.click() - self.clicked = True + radio_button = QtWidgets.QRadioButton() + radio_button.setObjectName(_fromUtf8(descr)) + radio_button.setText(_translate("GPUOptions", descr, None)) + self.optionsLayout.addWidget(radio_button) + if title.lower() == config.SAS_OPENCL.lower(): + + radio_button.setChecked(True) + self.cl_options[descr] = title + self.radio_buttons.append(radio_button) + self.openCLCheckBoxGroup.setMinimumWidth(self.optionsLayout.sizeHint().width()+10) - def createLinks(self): + def set_sas_open_cl(self): """ - Link user interactions to function calls + Set SAS_OPENCL value when tests run or OK button clicked """ - self.testButton.clicked.connect(self.testButtonClicked) - self.helpButton.clicked.connect(self.helpButtonClicked) - for item in self.openCLCheckBoxGroup.findChildren(QtWidgets.QCheckBox): - item.clicked.connect(self.checked) - def checked(self): - """ - Only allow a single check box to be selected. Uncheck others. - """ checked = None - for box in self.openCLCheckBoxGroup.findChildren(QtWidgets.QCheckBox): - if box.isChecked() and (self.cl_options[str(box.text())] == self.sas_open_cl or ( - str(box.text()) == "No OpenCL" and self.sas_open_cl == "")): - box.setChecked(False) - elif box.isChecked(): + for box in self.radio_buttons: + if box.isChecked(): checked = box - if hasattr(checked, "text"): - self.sas_open_cl = self.cl_options[str(checked.text())] - else: - self.sas_open_cl = -1 - def set_sas_open_cl(self): - """ - Set SAS_OPENCL value when tests run or OK button clicked - """ - no_opencl_msg = self.sas_open_cl == -1 - env.sas_opencl = self.sas_open_cl + if checked is None: + raise RuntimeError("Error: No radio button selected somehow") + + sas_open_cl = self.cl_options[str(checked.text())] + no_opencl_msg = sas_open_cl.lower() == "none" + env.sas_opencl = sas_open_cl + config.SAS_OPENCL = sas_open_cl # CRUFT: next version of reset_environment() will return env sasmodels.sasview_model.reset_environment() @@ -347,5 +339,5 @@ def _get_clinfo(): d_index += 1 p_index += 1 - clinfo.append(("None", "No OpenCL")) + clinfo.append(("none", "No OpenCL")) return clinfo diff --git a/src/sas/system/env.py b/src/sas/system/env.py index 4a8c4c5af6..e1063cc5bd 100644 --- a/src/sas/system/env.py +++ b/src/sas/system/env.py @@ -10,38 +10,25 @@ class Envrironment: logger = logging.getLogger(__name__) @property - def sas_opencl(self) -> int: + def sas_opencl(self) -> str: """ Get the value of the environment variable SAS_OPENCL, which specifies which OpenCL device should be used. - - FAQ: Why use -1 to represent the no-device state, rather than None? Isn't None a better choice? - Ans: This helps keep the config files in order (see docs on that), as the type of -1 (the default) - can be inferred and checked online. - """ - string_value = os.environ.get("SAS_OPENCL", "None") - if string_value.lower() == "none": - return -1 - else: - try: - int_value = int(string_value) - return int_value - except ValueError: - self.logger.warning( - f"Failed to parse SAS_OPENCL environment variable, expected an integer or 'none', got {string_value}") - return -1 + return os.environ.get("SAS_OPENCL", "none") + @sas_opencl.setter - def sas_opencl(self, value: int): + def sas_opencl(self, value: str): """ Set the value of the environment variable SAS_OPENCL """ - if value == -1: - del os.environ["SAS_OPENCL"] + if value.lower() == "none": + if "SAS_OPENCL" in os.environ: + del os.environ["SAS_OPENCL"] else: - os.environ["SAS_OPENCL"] = str(value) + os.environ["SAS_OPENCL"] = value env = Envrironment() \ No newline at end of file From fe8fb8f81cdad7084075ea970f8899769d079634 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 14:44:05 +0100 Subject: [PATCH 49/82] Disabled test flag to see if it breaks anything --- src/sas/config_system/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sas/config_system/config.py b/src/sas/config_system/config.py index b0a6acbf71..4381db468d 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/config_system/config.py @@ -144,7 +144,7 @@ def __init__(self): super().__init__() # Flag for automated testing - self.__TEST__ = False + # self.__TEST__ = False # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' From bffd91024005ff35721a6d911ebe3db915831838 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 15:38:29 +0100 Subject: [PATCH 50/82] Fixed file references for moved files --- installers/sasview.spec | 4 ++-- test/utest_sasview.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/installers/sasview.spec b/installers/sasview.spec index 749b52cc5a..b1e5371b23 100644 --- a/installers/sasview.spec +++ b/installers/sasview.spec @@ -19,8 +19,8 @@ datas = [ # ('../src/sas/sasview/local_config.py', '.'), # ('../src/sas/sasview/wxcruft.py', '.'), ('../src/sas/qtgui/Perspectives/Fitting/plugin_models', 'plugin_models'), - ('../src/sas/logger_config.py', '.'), - ('../src/sas/logging.ini', '.'), +# ('../src/sas/logger_config.py', '.'), + ('../src/sas/system/log.ini', '.'), ('../../sasmodels/sasmodels','sasmodels'), ('../docs/sphinx-docs/build/html','doc') ] diff --git a/test/utest_sasview.py b/test/utest_sasview.py index 08df8776aa..a5de8d4eb9 100755 --- a/test/utest_sasview.py +++ b/test/utest_sasview.py @@ -7,7 +7,7 @@ import logging import logging.config -LOGGER_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'logging.ini') +LOGGER_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'system', 'log.ini') logging.config.fileConfig(LOGGER_CONFIG_FILE) logger = logging.getLogger(__name__) From 658f2fa7fc151c418ccb42fe4b9c063e6fb69a72 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 16:43:30 +0100 Subject: [PATCH 51/82] Moved config_system to system.config --- setup.py | 4 ++-- src/sas/__init__.py | 2 +- src/sas/config_system/__init__.py | 1 - src/sas/system/config/__init__.py | 1 + .../{config_system => system/config}/config.py | 7 +------ .../config}/config_meta.py | 4 ++-- .../config}/schema_elements.py | 0 .../{config_system => system/config}/test_list | 0 .../{config_system => system/config}/util.py | 5 +---- test/config/utest_config.py | 18 +++++++++--------- 10 files changed, 17 insertions(+), 25 deletions(-) delete mode 100644 src/sas/config_system/__init__.py create mode 100644 src/sas/system/config/__init__.py rename src/sas/{config_system => system/config}/config.py (98%) rename src/sas/{config_system => system/config}/config_meta.py (98%) rename src/sas/{config_system => system/config}/schema_elements.py (100%) rename src/sas/{config_system => system/config}/test_list (100%) rename src/sas/{config_system => system/config}/util.py (51%) diff --git a/setup.py b/setup.py index c841501d48..d100e6a6ae 100644 --- a/setup.py +++ b/setup.py @@ -278,8 +278,8 @@ def run(self): ] packages.append("sas.qtgui") -package_data["sas.config_system"] = ["*"] -packages.append("sas.config_system") +package_data["sas.config"] = ["*"] +packages.append("sas.config") required = [ 'bumps>=0.7.5.9', 'periodictable>=1.5.0', 'pyparsing>=2.0.0', diff --git a/src/sas/__init__.py b/src/sas/__init__.py index 575abfd44e..a9348117ba 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -2,7 +2,7 @@ import os import sys -from sas.config_system import configuration as config +from sas.system.config import configuration as config __all__ = ['get_app_dir', 'get_user_dir', 'config'] diff --git a/src/sas/config_system/__init__.py b/src/sas/config_system/__init__.py deleted file mode 100644 index 715f89dab7..0000000000 --- a/src/sas/config_system/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from sas.config_system.util import configuration diff --git a/src/sas/system/config/__init__.py b/src/sas/system/config/__init__.py new file mode 100644 index 0000000000..49e067a2a3 --- /dev/null +++ b/src/sas/system/config/__init__.py @@ -0,0 +1 @@ +from sas.system.config.util import configuration diff --git a/src/sas/config_system/config.py b/src/sas/system/config/config.py similarity index 98% rename from src/sas/config_system/config.py rename to src/sas/system/config/config.py index 4381db468d..a8915e2036 100644 --- a/src/sas/config_system/config.py +++ b/src/sas/system/config/config.py @@ -130,12 +130,7 @@ different configs difficult. """ -from sas.config_system.config_meta import ConfigBase, ConfigMeta - -import sas.sasview -import os -import time -import logging +from sas.system.config.config_meta import ConfigBase, ConfigMeta class Config(ConfigBase, metaclass=ConfigMeta): diff --git a/src/sas/config_system/config_meta.py b/src/sas/system/config/config_meta.py similarity index 98% rename from src/sas/config_system/config_meta.py rename to src/sas/system/config/config_meta.py index a25c61961c..0485e60842 100644 --- a/src/sas/config_system/config_meta.py +++ b/src/sas/system/config/config_meta.py @@ -5,9 +5,9 @@ from copy import deepcopy import sas -from sas.config_system.schema_elements import create_schema_element, CoercionError, SchemaElement +from sas.system.config.schema_elements import create_schema_element, CoercionError, SchemaElement -logger = logging.getLogger("sas.config_system") +logger = logging.getLogger("sas.config") class MalformedFile(Exception): diff --git a/src/sas/config_system/schema_elements.py b/src/sas/system/config/schema_elements.py similarity index 100% rename from src/sas/config_system/schema_elements.py rename to src/sas/system/config/schema_elements.py diff --git a/src/sas/config_system/test_list b/src/sas/system/config/test_list similarity index 100% rename from src/sas/config_system/test_list rename to src/sas/system/config/test_list diff --git a/src/sas/config_system/util.py b/src/sas/system/config/util.py similarity index 51% rename from src/sas/config_system/util.py rename to src/sas/system/config/util.py index 0260719051..c44ce82348 100644 --- a/src/sas/config_system/util.py +++ b/src/sas/system/config/util.py @@ -1,8 +1,5 @@ -from sas.config_system.config import Config +from sas.system.config.config import Config -import sys -import os -import os def get_config() -> Config: return Config() diff --git a/test/config/utest_config.py b/test/config/utest_config.py index ecc03c624c..ddc1380857 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -8,11 +8,11 @@ import sas -from sas.config_system.config import Config +from sas.system.config import Config -from sas.config_system.config_meta import MalformedFile +from sas.system.config.config_meta import MalformedFile -from sas.config_system.schema_elements import \ +from sas.system.config import \ pairwise_schema_union, create_schema_element, \ SchemaBool, SchemaInt, SchemaFloat, SchemaStr, \ SchemaList, SchemaNonSpecified, \ @@ -93,9 +93,9 @@ def test_invalid_update_bad_name(self): name += "x" # try and set it - with self.assertLogs('sas.config_system', level="ERROR") as cm: + with self.assertLogs('sas.config', level="ERROR") as cm: config.update({name: None}) - self.assertTrue(cm.output[0].startswith("ERROR:sas.config_system:")) + self.assertTrue(cm.output[0].startswith("ERROR:sas.config:")) def test_invalid_update_bad_type(self): @@ -120,12 +120,12 @@ def test_invalid_update_bad_type(self): # Only test the ones that fail, i.e. cannot be coerced if pairwise_schema_union(test_value_schema, config._schema[key]) is None: - with self.assertLogs('sas.config_system', level="ERROR") as cm: + with self.assertLogs('sas.config', level="ERROR") as cm: # Try the bad value config.update({key: test_value}) - self.assertTrue(cm.output[0].startswith("ERROR:sas.config_system:")) + self.assertTrue(cm.output[0].startswith("ERROR:sas.config:")) def test_save_basics(self): @@ -209,11 +209,11 @@ def test_bad_config_version(self): file.seek(0) - with self.assertLogs('sas.config_system', level="WARN") as cm: + with self.assertLogs('sas.config', level="WARN") as cm: # Try the bad value config.load_from_file_object(file) - self.assertTrue(cm.output[0].startswith("WARNING:sas.config_system:")) + self.assertTrue(cm.output[0].startswith("WARNING:sas.config:")) def test_bad_config_file_structure(self): From 77d4a0048bf1284fcbd7cdc85dd58e0822a44fbf Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 17:06:27 +0100 Subject: [PATCH 52/82] Tweaked config layout and updated setup.py --- setup.py | 5 ++--- src/sas/__init__.py | 2 +- src/sas/system/__init__.py | 3 ++- src/sas/system/config/config.py | 1 + src/sas/system/config/test_list | 10 ---------- src/sas/system/config/util.py | 7 ------- 6 files changed, 6 insertions(+), 22 deletions(-) delete mode 100644 src/sas/system/config/test_list delete mode 100644 src/sas/system/config/util.py diff --git a/setup.py b/setup.py index d100e6a6ae..534c312f25 100644 --- a/setup.py +++ b/setup.py @@ -260,7 +260,8 @@ def run(self): ] packages.append("sas.sasview") -package_data["sas.system"] = ["*"] +package_data["sas.system"] = ["*", + "config/*"] packages.append("sas.system") package_data['sas.qtgui'] = ['Calculators/UI/*', @@ -278,8 +279,6 @@ def run(self): ] packages.append("sas.qtgui") -package_data["sas.config"] = ["*"] -packages.append("sas.config") required = [ 'bumps>=0.7.5.9', 'periodictable>=1.5.0', 'pyparsing>=2.0.0', diff --git a/src/sas/__init__.py b/src/sas/__init__.py index a9348117ba..eb37bca711 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -2,7 +2,7 @@ import os import sys -from sas.system.config import configuration as config +from sas.system import config __all__ = ['get_app_dir', 'get_user_dir', 'config'] diff --git a/src/sas/system/__init__.py b/src/sas/system/__init__.py index c4b441ad04..5b84646217 100644 --- a/src/sas/system/__init__.py +++ b/src/sas/system/__init__.py @@ -1,5 +1,6 @@ from .web import web from .legal import legal from .env import env +from .config.config import config -__all__ = ["web", "legal", "env"] \ No newline at end of file +__all__ = ["web", "legal", "env", "config"] \ No newline at end of file diff --git a/src/sas/system/config/config.py b/src/sas/system/config/config.py index a8915e2036..fc4dfe35fb 100644 --- a/src/sas/system/config/config.py +++ b/src/sas/system/config/config.py @@ -193,3 +193,4 @@ def __init__(self): +config = Config() \ No newline at end of file diff --git a/src/sas/system/config/test_list b/src/sas/system/config/test_list deleted file mode 100644 index fdb8513cbb..0000000000 --- a/src/sas/system/config/test_list +++ /dev/null @@ -1,10 +0,0 @@ -Places where config has been replaced - -AboutBox -GuiManger save state -DensityCalculatorTest -AboutBoxTest -WelcomePanel -ModelThread.Calc2D -FittingWidget -FittingWidgetTest \ No newline at end of file diff --git a/src/sas/system/config/util.py b/src/sas/system/config/util.py deleted file mode 100644 index c44ce82348..0000000000 --- a/src/sas/system/config/util.py +++ /dev/null @@ -1,7 +0,0 @@ -from sas.system.config.config import Config - - -def get_config() -> Config: - return Config() - -configuration = get_config() \ No newline at end of file From d908dbcf537c0c2b926bb38b161f55c6fa169224 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 17:19:54 +0100 Subject: [PATCH 53/82] Changed bad package name --- src/sas/system/config/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sas/system/config/__init__.py b/src/sas/system/config/__init__.py index 49e067a2a3..e69de29bb2 100644 --- a/src/sas/system/config/__init__.py +++ b/src/sas/system/config/__init__.py @@ -1 +0,0 @@ -from sas.system.config.util import configuration From 741febe99dea2618968c26e798c96543fb8654e8 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 17:35:17 +0100 Subject: [PATCH 54/82] Fixed bad imports in utest --- test/config/utest_config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/config/utest_config.py b/test/config/utest_config.py index ddc1380857..b78aa138af 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -8,11 +8,11 @@ import sas -from sas.system.config import Config +from sas.system.config.config import Config from sas.system.config.config_meta import MalformedFile -from sas.system.config import \ +from sas.system.config.schema_elements import \ pairwise_schema_union, create_schema_element, \ SchemaBool, SchemaInt, SchemaFloat, SchemaStr, \ SchemaList, SchemaNonSpecified, \ From e3c41e003de41a87b18b3da033a4f406f4fb04db Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 14 Sep 2022 18:14:56 +0100 Subject: [PATCH 55/82] Updated .gitignore to miss config.json --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8990c97167..82466c2068 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ *.so *.exe -/.vagrant /build /dist sasview.egg-info @@ -39,6 +38,7 @@ default_categories.json /setup.cfg **/UI/*.py !**/UI/__init__.py +config.json # doc build /docs/sphinx-docs/build From 0c9fba32c81e2572f5d8b4905becac6d246b53d7 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 14:30:17 +0100 Subject: [PATCH 56/82] Cleaned up __init__s, made user, version, and zenodo files in system --- run.py | 4 +- src/sas/__init__.py | 84 +------------------ src/sas/qtgui/MainWindow/AboutBox.py | 6 +- src/sas/qtgui/MainWindow/Acknowledgements.py | 6 +- src/sas/qtgui/MainWindow/DataManager.py | 2 +- src/sas/qtgui/MainWindow/GuiManager.py | 8 +- src/sas/qtgui/MainWindow/MainWindow.py | 4 +- src/sas/qtgui/MainWindow/PackageGatherer.py | 5 +- .../MainWindow/UnitTesting/AboutBoxTest.py | 5 +- .../UnitTesting/DataExplorerTest.py | 2 +- src/sas/qtgui/MainWindow/WelcomePanel.py | 6 +- .../Perspectives/Fitting/ReportPageLogic.py | 2 +- src/sas/qtgui/Utilities/FileConverter.py | 2 +- src/sas/qtgui/Utilities/Reports/reports.py | 5 +- src/sas/sascalc/fit/models.py | 2 +- src/sas/sascalc/fit/pagestate.py | 2 +- src/sas/sasview/__init__.py | 8 -- src/sas/system/config/config_meta.py | 7 +- src/sas/system/user.py | 24 ++++++ src/sas/system/version.py | 7 ++ src/sas/system/zenodo.py | 1 + test/config/utest_config.py | 13 +-- 22 files changed, 79 insertions(+), 126 deletions(-) delete mode 100644 src/sas/sasview/__init__.py create mode 100644 src/sas/system/user.py create mode 100644 src/sas/system/version.py create mode 100644 src/sas/system/zenodo.py diff --git a/run.py b/run.py index 74a88afeeb..55626da346 100644 --- a/run.py +++ b/run.py @@ -20,6 +20,8 @@ from os.path import abspath, dirname, realpath, join as joinpath from contextlib import contextmanager +import sas.system.user + PLUGIN_MODEL_DIR = 'plugin_models' def addpath(path): @@ -52,7 +54,7 @@ def setup_sasmodels(): """ # Set SAS_MODELPATH so sasmodels can find our custom models import sas - plugin_dir = os.path.join(sas.get_user_dir(), PLUGIN_MODEL_DIR) + plugin_dir = os.path.join(sas.system.user.get_user_dir(), PLUGIN_MODEL_DIR) os.environ['SAS_MODELPATH'] = plugin_dir def prepare(): diff --git a/src/sas/__init__.py b/src/sas/__init__.py index eb37bca711..f0cd9a8647 100644 --- a/src/sas/__init__.py +++ b/src/sas/__init__.py @@ -1,87 +1,9 @@ -from sas.sasview import __version__ +from sas.system.version import __version__ -import os -import sys -from sas.system import config +from sas.system import config, user -__all__ = ['get_app_dir', 'get_user_dir', 'config'] +__all__ = ['config'] # Load the config file config.load() - -_APP_DIR = None -def get_app_dir(): - """ - The directory where the sasview application is found. - - Returns the path to sasview if running in place or installed with setup. - If the application is frozen, returns the parent directory of the - application resources such as test files and images. - """ - global _APP_DIR - if not _APP_DIR: - _APP_DIR = find_app_dir() - return _APP_DIR - -# TODO: Replace with more idomatic version -def dirn(path, n): - """ - Return the directory n up from the current path - """ - path = os.path.realpath(path) - for _ in range(n): - path = os.path.dirname(path) - return path - - -def find_app_dir(): - """ - Locate the parent directory of the sasview resources. For the normal - application this will be the directory containing sasview.py. For the - frozen application this will be the path where the resources are installed. - """ - # We are starting out with the following info: - # __file__ = .../sas/__init__.pyc - # Check if the path .../sas/sasview exists, and use it as the - # app directory. This will only be the case if the app is not frozen. - path = os.path.join(os.path.dirname(__file__), 'sasview') - if os.path.exists(path): - return path - - # If we are running frozen, then root is a parent directory - if sys.platform == 'darwin': - # Here is the path to the file on the mac: - # .../Sasview.app/Contents/Resources/lib/python2.7/site-packages.zip/sas/__init__.pyc - # We want the path to the Resources directory. - path = dirn(__file__, 5) - elif os.name == 'nt': - # Here is the path to the file on windows: - # ../Sasview/library.zip/sas/__init__.pyc - # We want the path to the Sasview directory. - path = dirn(__file__, 3) - else: - raise RuntimeError("Couldn't find the app directory") - return path - -def make_user_dir(): - """ - Create the user directory ~/.sasview if it doesn't already exist. - """ - path = os.path.join(os.path.expanduser("~"),'.sasview') - if not os.path.exists(path): - os.mkdir(path) - return path - - -_USER_DIR = None -def get_user_dir(): - """ - The directory where the per-user configuration is stored. - - Returns ~/.sasview, creating it if it does not already exist. - """ - global _USER_DIR - if not _USER_DIR: - _USER_DIR = make_user_dir() - return _USER_DIR diff --git a/src/sas/qtgui/MainWindow/AboutBox.py b/src/sas/qtgui/MainWindow/AboutBox.py index f5378e9ad6..fac573d81b 100644 --- a/src/sas/qtgui/MainWindow/AboutBox.py +++ b/src/sas/qtgui/MainWindow/AboutBox.py @@ -3,6 +3,7 @@ import sas.sasview import sas.qtgui.Utilities.GuiUtils as GuiUtils +import sas.system.version from sas.qtgui.UI import images_rc from sas.qtgui.UI import main_resources_rc @@ -28,7 +29,7 @@ def addText(self): """ Modify the labels so the text corresponds to the current version """ - version = sas.sasview.__version__ + version = sas.system.version.__version__ self.lblVersion.setText(str(version)) lbl_font = self.font() @@ -39,9 +40,6 @@ def addText(self): -

- Build{sas.sasview.__build__} -

{legal.copyright}

diff --git a/src/sas/qtgui/MainWindow/Acknowledgements.py b/src/sas/qtgui/MainWindow/Acknowledgements.py index e14f41cc05..69bfb23215 100644 --- a/src/sas/qtgui/MainWindow/Acknowledgements.py +++ b/src/sas/qtgui/MainWindow/Acknowledgements.py @@ -2,6 +2,8 @@ from PyQt5 import QtWidgets, QtCore import sas.sasview +import sas.system.version +import sas.system.zenodo from .UI.AcknowledgementsUI import Ui_Acknowledgements @@ -19,8 +21,8 @@ def addText(self): """ Modify the labels so the text corresponds to the current version """ - version = sas.sasview.__version__ - doi = sas.sasview.__DOI__ + version = sas.system.version.__version__ + doi = sas.system.zenodo.__DOI__ acknowledgement_text_1 = "This work benefited from the use of the SasView application, originally developed " \ "under NSF Award DMR - 0520547. SasView also contains code developed with funding" \ " from the EU Horizon 2020 programme under the SINE2020 project Grant No 654000." diff --git a/src/sas/qtgui/MainWindow/DataManager.py b/src/sas/qtgui/MainWindow/DataManager.py index d5d4671fd0..b07bdc2b45 100755 --- a/src/sas/qtgui/MainWindow/DataManager.py +++ b/src/sas/qtgui/MainWindow/DataManager.py @@ -42,7 +42,7 @@ # used for import/export from sasdata.dataloader.data_info import Sample, Source, Vector -from sas.sasview import __version__ as SASVIEW_VERSION +from sas.system.version import __version__ as SASVIEW_VERSION class DataManager(object): diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 5960dee42c..8f4563cd0b 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -12,10 +12,12 @@ from PyQt5.QtCore import Qt, QLocale import matplotlib as mpl + +import sas.system.version + mpl.use("Qt5Agg") -from sas.sasview import __version__ as SASVIEW_VERSION -from sas.sasview import __release_date__ as SASVIEW_RELEASE_DATE +from sas.system.version import __version__ as SASVIEW_VERSION, __release_date__ as SASVIEW_RELEASE_DATE from twisted.internet import reactor # General SAS imports @@ -572,7 +574,7 @@ def processVersion(self, version_info): msg += " Please try again later." self.communicate.statusBarUpdateSignal.emit(msg) - elif version.__gt__(sas.__version__): + elif version.__gt__(sas.system.version.__version__): msg = "Version %s is available! " % str(version) if "download_url" in version_info: webbrowser.open(version_info["download_url"]) diff --git a/src/sas/qtgui/MainWindow/MainWindow.py b/src/sas/qtgui/MainWindow/MainWindow.py index dbc9672dc2..44eb6b9fe9 100644 --- a/src/sas/qtgui/MainWindow/MainWindow.py +++ b/src/sas/qtgui/MainWindow/MainWindow.py @@ -4,7 +4,7 @@ import os import sys -from sas.sasview import __version__ as SASVIEW_VERSION +from ...system.version import __version__ as SASVIEW_VERSION from sas import config from sas.system import env @@ -77,7 +77,7 @@ def run_sasview(): SetupLogger(__name__).config_development() # initialize sasmodels settings - from sas import get_user_dir + from sas.system.user import get_user_dir if "SAS_DLL_PATH" not in os.environ: os.environ["SAS_DLL_PATH"] = os.path.join( get_user_dir(), "compiled_models") diff --git a/src/sas/qtgui/MainWindow/PackageGatherer.py b/src/sas/qtgui/MainWindow/PackageGatherer.py index e3bb4bdc04..be7d7ef968 100644 --- a/src/sas/qtgui/MainWindow/PackageGatherer.py +++ b/src/sas/qtgui/MainWindow/PackageGatherer.py @@ -4,6 +4,7 @@ import pathlib import sas +import sas.system.version logger = logging.getLogger(__name__) @@ -69,7 +70,7 @@ def get_imported_packages(self): :returns: A dictionary with the package names as the key, with their respective version numbers as the value. :rtype: dict """ - package_versions_dict = {'python': sys.version, 'SasView': sas.__version__} + package_versions_dict = {'python': sys.version, 'SasView': sas.system.version.__version__} err_version_dict = {} no_version_list = [] # Generate a list of standard modules by looking at the local python library @@ -146,7 +147,7 @@ def get_imported_packages(self): if hasattr(package, '__version__'): # Module has __version__ attribute try: - package_versions_dict[package_name] = package.__version__ + package_versions_dict[package_name] = sas.system.version.__version__ continue except Exception as e: # Unable to access module diff --git a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py index dc7ec47aef..e5f7c5311e 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py @@ -8,6 +8,7 @@ from unittest.mock import MagicMock import sas.sasview +import sas.system.version from sas import config from sas.system import web, legal @@ -45,7 +46,7 @@ def testVersion(self): """ version = self.widget.lblVersion self.assertIsInstance(version, QtWidgets.QLabel) - self.assertEqual(str(version.text()), str(sas.__version__)) + self.assertEqual(str(version.text()), str(sas.system.version.__version__)) def testAbout(self): """ @@ -53,8 +54,6 @@ def testAbout(self): """ about = self.widget.lblAbout self.assertIsInstance(about, QtWidgets.QLabel) - # build version - self.assertIn(str(sas.sasview.__build__), about.text()) # License self.assertIn(str(legal.copyright), about.text()) # URLs diff --git a/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py b/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py index b6f6acf9e6..430d0e9bae 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py @@ -27,7 +27,7 @@ from sas.qtgui.Plotting.Plotter2D import Plotter2D import sas.qtgui.Plotting.PlotHelper as PlotHelper -from sas.sasview import __version__ as SASVIEW_VERSION +from sas.system.version import __version__ as SASVIEW_VERSION if not QApplication.instance(): app = QApplication(sys.argv) diff --git a/src/sas/qtgui/MainWindow/WelcomePanel.py b/src/sas/qtgui/MainWindow/WelcomePanel.py index 729761c4a6..e5d694041b 100644 --- a/src/sas/qtgui/MainWindow/WelcomePanel.py +++ b/src/sas/qtgui/MainWindow/WelcomePanel.py @@ -1,6 +1,7 @@ from PyQt5 import QtWidgets import sas.sasview +import sas.system.version from sas import config from sas.system import legal @@ -14,10 +15,9 @@ def __init__(self, parent=None): self.setWindowTitle("Welcome") - version = sas.sasview.__version__ # TODO: Make consistent with other version references - build = sas.sasview.__build__ # TODO: Make consistent with other build references + version = sas.system.version.__version__ # TODO: Make consistent with other version references - ver = "\nSasView %s\nBuild: %s\n%s" % (version, build, legal.copyright) + ver = "\nSasView %s\n%s" % (version, legal.copyright) self.lblVersion.setText(ver) diff --git a/src/sas/qtgui/Perspectives/Fitting/ReportPageLogic.py b/src/sas/qtgui/Perspectives/Fitting/ReportPageLogic.py index 73a7ceb859..70e63dc6a4 100644 --- a/src/sas/qtgui/Perspectives/Fitting/ReportPageLogic.py +++ b/src/sas/qtgui/Perspectives/Fitting/ReportPageLogic.py @@ -18,7 +18,7 @@ from sas.qtgui.Plotting.PlotterBase import PlotterBase from sas.qtgui.Utilities.Reports.reportdata import ReportData -from sas.sasview import __version__ as SASVIEW_VERSION +from sas.system.version import __version__ as SASVIEW_VERSION from sasmodels import __version__ as SASMODELS_VERSION # TODO: Integrate with other reports diff --git a/src/sas/qtgui/Utilities/FileConverter.py b/src/sas/qtgui/Utilities/FileConverter.py index 5b7e0ef7d1..97b82161eb 100644 --- a/src/sas/qtgui/Utilities/FileConverter.py +++ b/src/sas/qtgui/Utilities/FileConverter.py @@ -23,7 +23,7 @@ import sas.qtgui.Utilities.GuiUtils as GuiUtils from sas.qtgui.Utilities.FrameSelect import FrameSelect -from sas.sasview import __version__ as SASVIEW_VERSION +from ...system.version import __version__ as SASVIEW_VERSION from .UI.FileConverterUI import Ui_FileConverterUI diff --git a/src/sas/qtgui/Utilities/Reports/reports.py b/src/sas/qtgui/Utilities/Reports/reports.py index 5d256e10b1..a2e0b2414f 100644 --- a/src/sas/qtgui/Utilities/Reports/reports.py +++ b/src/sas/qtgui/Utilities/Reports/reports.py @@ -20,6 +20,7 @@ from xhtml2pdf import pisa import sas.sasview +import sas.system.version import sasmodels import logging @@ -97,7 +98,7 @@ def __init__(self, with self._html_doc.head: meta(http_equiv="Content-Type", content="text/html; charset=utf-8") - meta(name="Generator", content=f"SasView {sas.sasview.__version__}") + meta(name="Generator", content=f"SasView {sas.system.version.__version__}") if style_link is not None: link(rel="stylesheet", href=style_link) @@ -113,7 +114,7 @@ def __init__(self, h1(title) p(datetime.datetime.now().strftime("%I:%M%p, %B %d, %Y")) with div(id="version-info"): - p(f"sasview {sas.sasview.__version__}, sasmodels {sasmodels.__version__}", cls="sasview-details") + p(f"sasview {sas.system.version.__version__}, sasmodels {sasmodels.__version__}", cls="sasview-details") div(id="perspective") with div(id="data"): diff --git a/src/sas/sascalc/fit/models.py b/src/sas/sascalc/fit/models.py index a5dd930bea..22e0dda92e 100644 --- a/src/sas/sascalc/fit/models.py +++ b/src/sas/sascalc/fit/models.py @@ -17,7 +17,7 @@ from sasmodels.sasview_model import load_custom_model, load_standard_models -from sas import get_user_dir +from sas.system.user import get_user_dir # Explicitly import from the pluginmodel module so that py2exe # places it in the distribution. The Model1DPlugin class is used diff --git a/src/sas/sascalc/fit/pagestate.py b/src/sas/sascalc/fit/pagestate.py index 3dc1853d81..fedd825f7b 100644 --- a/src/sas/sascalc/fit/pagestate.py +++ b/src/sas/sascalc/fit/pagestate.py @@ -28,7 +28,7 @@ from sasmodels import convert import sasmodels.weights -from sas.sasview import __version__ as SASVIEW_VERSION +from sas.system.version import __version__ as SASVIEW_VERSION import sasdata.dataloader from sasdata.dataloader.readers.cansas_reader import Reader as CansasReader diff --git a/src/sas/sasview/__init__.py b/src/sas/sasview/__init__.py deleted file mode 100644 index e451e2feb2..0000000000 --- a/src/sas/sasview/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from distutils.version import StrictVersion -# The version number must follow StrictVersion rules as outlined -# in http://epydoc.sourceforge.net/stdlib/distutils.version.StrictVersion-class.html -__version__ = "5.0.5" -StrictVersion(__version__) -__DOI__ = "Zenodo, 10.5281/zenodo.6331344" -__release_date__ = "2022" -__build__ = "GIT_COMMIT" diff --git a/src/sas/system/config/config_meta.py b/src/sas/system/config/config_meta.py index 0485e60842..63157cc0be 100644 --- a/src/sas/system/config/config_meta.py +++ b/src/sas/system/config/config_meta.py @@ -5,6 +5,7 @@ from copy import deepcopy import sas +import sas.system.version from sas.system.config.schema_elements import create_schema_element, CoercionError, SchemaElement logger = logging.getLogger("sas.config") @@ -96,7 +97,7 @@ def save_to_file_object(self, file): data[key] = new_value output_data = { - "sasview_version": sas.__version__, + "sasview_version": sas.system.version.__version__, "config_data": data} json.dump(output_data, file) @@ -132,11 +133,11 @@ def load_from_file_object(self, file): # Check major version file_version = data["sasview_version"] file_major_version = file_version.split(".")[0] - sasview_major_version = sas.__version__.split(".")[0] + sasview_major_version = sas.system.version.__version__.split(".")[0] if int(file_major_version) != int(sasview_major_version): logger.warning(f"Attempting to used outdated config file (config is" - f" for {file_version}, this SasView version is {sas.__version__})") + f" for {file_version}, this SasView version is {sas.system.version.__version__})") self._write_disabled = True self.update(data["config_data"]) diff --git a/src/sas/system/user.py b/src/sas/system/user.py new file mode 100644 index 0000000000..4fda655def --- /dev/null +++ b/src/sas/system/user.py @@ -0,0 +1,24 @@ +import os + +_USER_DIR = None + +def make_user_dir(): + """ + Create the user directory ~/.sasview if it doesn't already exist. + """ + path = os.path.join(os.path.expanduser("~"),'.sasview') + if not os.path.exists(path): + os.mkdir(path) + return path + + +def get_user_dir(): + """ + The directory where the per-user configuration is stored. + + Returns ~/.sasview, creating it if it does not already exist. + """ + global _USER_DIR + if not _USER_DIR: + _USER_DIR = make_user_dir() + return _USER_DIR diff --git a/src/sas/system/version.py b/src/sas/system/version.py new file mode 100644 index 0000000000..755d4128c3 --- /dev/null +++ b/src/sas/system/version.py @@ -0,0 +1,7 @@ +from distutils.version import StrictVersion + +__version__ = "5.0.5" +__release_date__ = "2022" + + +StrictVersion(__version__) \ No newline at end of file diff --git a/src/sas/system/zenodo.py b/src/sas/system/zenodo.py new file mode 100644 index 0000000000..c93f5ed1bf --- /dev/null +++ b/src/sas/system/zenodo.py @@ -0,0 +1 @@ +__DOI__ = "Zenodo, 10.5281/zenodo.6331344" diff --git a/test/config/utest_config.py b/test/config/utest_config.py index b78aa138af..2bbb029344 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -7,6 +7,7 @@ import json import sas +import sas.system.version from sas.system.config.config import Config @@ -140,7 +141,7 @@ def test_save_basics(self): observed = json.load(file) empty_file = { - "sasview_version": sas.__version__, + "sasview_version": sas.system.version.__version__, "config_data": {} } @@ -162,7 +163,7 @@ def test_save_changes(self): observed = json.load(file) expected = { - "sasview_version": sas.__version__, + "sasview_version": sas.system.version.__version__, "config_data": {key: test_dict[key]} } @@ -176,7 +177,7 @@ def test_only_save_actual_changes(self): # (3) Check empty_file = { - "sasview_version": sas.__version__, + "sasview_version": sas.system.version.__version__, "config_data": {} } @@ -221,7 +222,7 @@ def test_bad_config_file_structure(self): bad_structures = [ { - "sasview_version": sas.__version__, + "sasview_version": sas.system.version.__version__, "quanfig_data": {} }, { @@ -229,11 +230,11 @@ def test_bad_config_file_structure(self): "config_data": {} }, { - "sassy_verberry": sas.__version__, + "sassy_verberry": sas.system.version.__version__, "config_data": {} }, { - "sasview_version": sas.__version__, + "sasview_version": sas.system.version.__version__, "config_data": [] }, {} From c18428ad9fa28d61c3b7aa9d7c6940456cd30b24 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 14:49:06 +0100 Subject: [PATCH 57/82] Update release automation script for new structure --- build_tools/release_automation.py | 41 +++++++++++++++++-------------- src/sas/system/version.py | 3 +-- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/build_tools/release_automation.py b/build_tools/release_automation.py index 2d495632c1..73b5943f34 100644 --- a/build_tools/release_automation.py +++ b/build_tools/release_automation.py @@ -135,29 +135,34 @@ def generate_zenodo(sasview_data, zenodo_api_key): "and attach to Zenodo release record.\n- Publish Zenodo record") return newDOI -def update_sasview_init(version, doi): - """ +version_template = \ +""" +from distutils.version import StrictVersion - :return: +__version__ = "%s" +__release_date__ = "%i" + +StrictVersion(__version__) +""" + +zenodo_template = '__DOI__ = "%s"' + +def update_sasview_metadata(version, doi): + """ + Update version and zenodo DOI """ - init_file = os.path.join('sasview','src', 'sas', 'sasview', '__init__.py') - output_lines = [] + system_directory = "sasview/src/sas/system" + version_filename = os.path.join(system_directory, "version.py") + zenodo_filename = os.path.join(system_directory, "zenodo.py") + year = datetime.datetime.now().year - with open(init_file, 'r') as f: - for line in f.readlines(): - if line[:11] in '__version__': - output_lines.append('__version__ = \"'+version+'\"\n') - elif line[:7] in '__DOI__' : - output_lines.append('__DOI__ = \"Zenodo, ' + str(doi) + '\"\n') - elif line[:16] in '__release_date__': - output_lines.append('__release_date__ = \"' + str(year) + '\"\n') - else: - output_lines.append(line) - with open(init_file, 'w') as f: - f.writelines(output_lines) + with open(version_filename, 'w') as file: + file.write(version_template % (version, year)) + with open(zenodo_filename, 'w') as file: + file.write(zenodo_template % doi) def update_sasmodels_init(version): """ @@ -241,7 +246,7 @@ def prepare_release_notes(issues_list, repository, username, password): zenodo_api_key = args.zenodo new_doi = generate_zenodo(sasview_data, zenodo_api_key) - update_sasview_init(sasview_version, new_doi) + update_sasview_metadata(sasview_version, new_doi) update_sasmodels_init(sasmodels_version) year = datetime.datetime.now().year diff --git a/src/sas/system/version.py b/src/sas/system/version.py index 755d4128c3..f6c31d1a75 100644 --- a/src/sas/system/version.py +++ b/src/sas/system/version.py @@ -3,5 +3,4 @@ __version__ = "5.0.5" __release_date__ = "2022" - -StrictVersion(__version__) \ No newline at end of file +StrictVersion(__version__) From 93cb3bcc13416f9998fd1a1a1bdd40d3c109b32a Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 14:55:46 +0100 Subject: [PATCH 58/82] Removed commented datas --- installers/sasview.spec | 5 ----- 1 file changed, 5 deletions(-) diff --git a/installers/sasview.spec b/installers/sasview.spec index b1e5371b23..d55f1c044c 100644 --- a/installers/sasview.spec +++ b/installers/sasview.spec @@ -9,17 +9,12 @@ import sys block_cipher = None PYTHON_LOC = sys.exec_prefix -#TODO: Removed commented lines datas = [ ('../src/sas/sasview/images', 'images'), ('../src/sas/sasview/media', 'media'), ('../src/sas/example_data', 'example_data'), ('../src/sas/qtgui/Utilities/Reports/report_style.css', 'sas/qtgui/Utilities/Reports'), -# ('../src/sas/sasview/custom_config.py', '.'), -# ('../src/sas/sasview/local_config.py', '.'), -# ('../src/sas/sasview/wxcruft.py', '.'), ('../src/sas/qtgui/Perspectives/Fitting/plugin_models', 'plugin_models'), -# ('../src/sas/logger_config.py', '.'), ('../src/sas/system/log.ini', '.'), ('../../sasmodels/sasmodels','sasmodels'), ('../docs/sphinx-docs/build/html','doc') From db8ef6439e1561e908243d24f0003531da6e0c0c Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 15:04:39 +0100 Subject: [PATCH 59/82] Cleaning up GuiUtils --- src/sas/qtgui/Utilities/GuiUtils.py | 55 ++----------------- .../Utilities/UnitTesting/GuiUtilsTest.py | 6 -- 2 files changed, 6 insertions(+), 55 deletions(-) diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 4f6a690625..1a1d8b546b 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -44,6 +44,7 @@ from sas.sascalc.fit.AbstractFitEngine import FitData1D, FitData2D from sasmodels.sasview_model import SasviewModel +import sas from sas import config from sasdata.dataloader.loader import Loader @@ -68,7 +69,7 @@ logger = logging.getLogger(__name__) -def get_app_dir(): +def get_sensible_default_open_directory(): """ :returns: app_path - the path to the application directory """ @@ -77,55 +78,14 @@ def get_app_dir(): if os.path.isfile(app_path): return os.path.dirname(app_path) - # - # # Next, try the current working directory - # if os.path.isfile(os.path.join(os.getcwd(), "custom_config.py")): - # #logging.info("Using application path: %s", os.getcwd()) - # return os.path.abspath(os.getcwd()) + # if this fails, use try the directory of the sasview module + return os.path.dirname(sas.__file__) - # Finally, try the directory of the sasview module - # TODO: gui_manager will have to know about sasview until we - # clean all these module variables and put them into a config class - # that can be passed by sasview.py. - # logging.info(sys.executable) - # logging.info(str(sys.argv)) - from sas import sasview as sasview - app_path = os.path.dirname(sasview.__file__) - # logging.info("Using application path: %s", app_path) - return app_path - -def get_user_directory(): - """ - Returns the user's home directory - """ - userdir = os.path.join(os.path.expanduser("~"), ".sasview") - if not os.path.isdir(userdir): - os.makedirs(userdir) - return userdir - -def _find_local_config(confg_file, path): - """ - Find configuration file for the current application - """ - config_module = None - fObj = None - try: - fObj, path_config, descr = imp.find_module(confg_file, [path]) - config_module = imp.load_module(confg_file, fObj, path_config, descr) - except ImportError: - pass - except ValueError: - print("Value error") - pass - finally: - if fObj is not None: - fObj.close() - return config_module # Get APP folder -PATH_APP = get_app_dir() -DATAPATH = PATH_APP +PATH_APP = get_sensible_default_open_directory() + # Read in the local config, which can either be with the main # application or in the installation directory # config = _find_local_config('local_config', PATH_APP) @@ -150,10 +110,7 @@ def _find_local_config(confg_file, path): config.DEFAULT_OPEN_FOLDER = PATH_APP -#DEFAULT_STYLE = config.DEFAULT_STYLE - PLUGIN_STATE_EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS -OPEN_SAVE_MENU = config.OPEN_SAVE_PROJECT_MENU VIEW_MENU = config.VIEW_MENU EDIT_MENU = config.EDIT_MENU extension_list = [] diff --git a/src/sas/qtgui/Utilities/UnitTesting/GuiUtilsTest.py b/src/sas/qtgui/Utilities/UnitTesting/GuiUtilsTest.py index 1736cff5d8..dbd55ed011 100644 --- a/src/sas/qtgui/Utilities/UnitTesting/GuiUtilsTest.py +++ b/src/sas/qtgui/Utilities/UnitTesting/GuiUtilsTest.py @@ -46,12 +46,6 @@ def testGetAppDir(self): """ pass - def testGetUserDirectory(self): - """ - Simple test of user directory getter - """ - home_dir = os.path.expanduser("~") - self.assertIn(home_dir, get_user_directory()) def testCommunicate(self): """ From 92da71d27e9b3a68715e220421d056aa658113f0 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 15:22:32 +0100 Subject: [PATCH 60/82] Cleaned some of GuiUtils and removed more config entries --- src/sas/qtgui/MainWindow/DataExplorer.py | 6 ++- src/sas/qtgui/Plotting/SlicerParameters.py | 3 +- src/sas/qtgui/Utilities/GuiUtils.py | 50 ++-------------------- src/sas/system/config/config.py | 8 ---- 4 files changed, 10 insertions(+), 57 deletions(-) diff --git a/src/sas/qtgui/MainWindow/DataExplorer.py b/src/sas/qtgui/MainWindow/DataExplorer.py index d2b830116c..2b39df65dd 100644 --- a/src/sas/qtgui/MainWindow/DataExplorer.py +++ b/src/sas/qtgui/MainWindow/DataExplorer.py @@ -1312,7 +1312,11 @@ def readData(self, path): for index, p_file in enumerate(path): basename = os.path.basename(p_file) _, extension = os.path.splitext(basename) - if extension.lower() in GuiUtils.EXTENSIONS: + extension_list = config.PLUGIN_STATE_EXTENSIONS + if config.APPLICATION_STATE_EXTENSION is not None: + extension_list.append(config.APPLICATION_STATE_EXTENSION) + + if extension.lower() in extension_list: any_error = True log_msg = "Data Loader cannot " log_msg += "load: %s\n" % str(p_file) diff --git a/src/sas/qtgui/Plotting/SlicerParameters.py b/src/sas/qtgui/Plotting/SlicerParameters.py index e1ee338dd5..b1bca0945f 100644 --- a/src/sas/qtgui/Plotting/SlicerParameters.py +++ b/src/sas/qtgui/Plotting/SlicerParameters.py @@ -21,6 +21,7 @@ from sasdata.file_converter.nxcansas_writer import NXcanSASWriter # Local UI from sas.qtgui.Plotting.UI.SlicerParametersUI import Ui_SlicerParametersUI +from sas import config class SlicerParameters(QtWidgets.QDialog, Ui_SlicerParametersUI): @@ -44,7 +45,7 @@ def __init__(self, parent=None, self.model = model self.validate_method = validate_method self.active_plots = active_plots - self.save_location = GuiUtils.DEFAULT_OPEN_FOLDER + self.save_location = config.DEFAULT_OPEN_FOLDER self.communicator = communicator # Initially, Apply is disabled diff --git a/src/sas/qtgui/Utilities/GuiUtils.py b/src/sas/qtgui/Utilities/GuiUtils.py index 1a1d8b546b..cfe7670ba0 100644 --- a/src/sas/qtgui/Utilities/GuiUtils.py +++ b/src/sas/qtgui/Utilities/GuiUtils.py @@ -48,9 +48,6 @@ from sas import config from sasdata.dataloader.loader import Loader -from sasdata.file_converter.nxcansas_writer import NXcanSASWriter - -from sas.qtgui.Utilities import CustomDir if os.path.splitext(sys.argv[0])[1].lower() != ".py": HELP_DIRECTORY_LOCATION = "doc" @@ -82,51 +79,10 @@ def get_sensible_default_open_directory(): return os.path.dirname(sas.__file__) - -# Get APP folder -PATH_APP = get_sensible_default_open_directory() - -# Read in the local config, which can either be with the main -# application or in the installation directory -# config = _find_local_config('local_config', PATH_APP) -# -# if config is None: -# config = _find_local_config('local_config', os.getcwd()) -# else: -# pass - - -#read some constants from config - -SAS_OPENCL = config.SAS_OPENCL # custom open_path -open_folder = config.DEFAULT_OPEN_FOLDER -if open_folder is not None and os.path.isdir(open_folder): - DEFAULT_OPEN_FOLDER = os.path.abspath(open_folder) -else: - DEFAULT_OPEN_FOLDER = PATH_APP - -if config.DEFAULT_OPEN_FOLDER != "": - config.DEFAULT_OPEN_FOLDER = PATH_APP - - -PLUGIN_STATE_EXTENSIONS = config.PLUGIN_STATE_EXTENSIONS -VIEW_MENU = config.VIEW_MENU -EDIT_MENU = config.EDIT_MENU -extension_list = [] -if config.APPLICATION_STATE_EXTENSION is not None: - extension_list.append(config.APPLICATION_STATE_EXTENSION) -EXTENSIONS = PLUGIN_STATE_EXTENSIONS + extension_list -try: - PLUGINS_WLIST = '|'.join(config.PLUGINS_WLIST) -except AttributeError: - PLUGINS_WLIST = '' -APPLICATION_WLIST = config.APPLICATION_WLIST -IS_WIN = True -IS_LINUX = False -CLOSE_SHOW = True -TIME_FACTOR = 2 -NOT_SO_GRAPH_LIST = ["BoxSum"] +if config.DEFAULT_OPEN_FOLDER == "" or not os.path.isdir(config.DEFAULT_OPEN_FOLDER): + config.DEFAULT_OPEN_FOLDER = get_sensible_default_open_directory() + class Communicate(QtCore.QObject): diff --git a/src/sas/system/config/config.py b/src/sas/system/config/config.py index fc4dfe35fb..98cc0ed26f 100644 --- a/src/sas/system/config/config.py +++ b/src/sas/system/config/config.py @@ -138,8 +138,6 @@ class Config(ConfigBase, metaclass=ConfigMeta): def __init__(self): super().__init__() - # Flag for automated testing - # self.__TEST__ = False # edit the list of file state your plugin can read self.APPLICATION_WLIST = 'SasView files (*.svs)|*.svs' @@ -158,12 +156,6 @@ def __init__(self): 'Corfunc files (*.crf)'] self.SHOW_WELCOME_PANEL = False - # OPEN and SAVE project menu - self.OPEN_SAVE_PROJECT_MENU = True - # VIEW MENU - self.VIEW_MENU = True - # EDIT MENU - self.EDIT_MENU = True From c9a070d5d7222c61cc94900789e1ab789cd67176 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 15:25:30 +0100 Subject: [PATCH 61/82] Removed CustomDir.py --- src/sas/qtgui/Utilities/CustomDir.py | 56 ---------------------------- 1 file changed, 56 deletions(-) delete mode 100755 src/sas/qtgui/Utilities/CustomDir.py diff --git a/src/sas/qtgui/Utilities/CustomDir.py b/src/sas/qtgui/Utilities/CustomDir.py deleted file mode 100755 index 8ca8ebe4b2..0000000000 --- a/src/sas/qtgui/Utilities/CustomDir.py +++ /dev/null @@ -1,56 +0,0 @@ -# Setup and find Custom config dir -import os.path -from sas import config - -def _find_usersasview_dir(): - """ - Find and return user/.sasview dir - """ - return os.path.join(os.path.expanduser("~"), ("." + config.APPLICATION_NAME)) - -def _find_customconf_dir(): - """ - Find path of the config directory. - The plugin directory is located in the user's home directory. - """ - u_dir = _find_usersasview_dir() - return os.path.join(u_dir, config.CONF_DIR) - -def setup_conf_dir(path): - raise RuntimeError("Tried to call setup_conf_dir") - # """ - # Setup the custom config dir and cat file - # """ - # conf_dir = _find_customconf_dir() - # # If the plugin directory doesn't exist, create it - # if not os.path.isdir(conf_dir): - # os.makedirs(conf_dir) - # config_file = os.path.join(conf_dir, "custom_config.py") - # - # # Place example user models as needed - # try: - # if not os.path.isfile(config_file): - # shutil.copyfile(os.path.join(path, "custom_config.py"), config_file) - # - # #Adding SAS_OPENCL if it doesn't exist in the config file - # # - to support backcompability - # if not "SAS_OPENCL" in open(config_file).read(): - # open(config_file,"a+").write("SAS_OPENCL = \"None\"\n") - # except: - # # Check for data path next to exe/zip file. - # #Look for maximum n_dir up of the current dir to find plugins dir - # n_dir = 12 - # is_dir = False - # f_dir = path - # for i in range(n_dir): - # if i > 1: - # f_dir, _ = os.path.split(f_dir) - # temp_path = os.path.join(f_dir, "custom_config.py") - # if os.path.isfile(temp_path): - # shutil.copyfile(temp_path, config_file) - # is_dir = True - # break - # if not is_dir: - # raise - # return conf_dir - # From 4780943191d53150f242dc439ae11e8dba045ff7 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 15:44:10 +0100 Subject: [PATCH 62/82] Update web links --- src/sas/system/web.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sas/system/web.py b/src/sas/system/web.py index feb442666d..bd1b9afd0e 100644 --- a/src/sas/system/web.py +++ b/src/sas/system/web.py @@ -1,6 +1,6 @@ class WebLinks: def __init__(self): - self.nist_url = "https://www.nist.gov/" + self.nist_url = "https://www.nist.gov/ncnr" self.umd_url = "https://www.umd.edu/" self.sns_url = "https://neutrons.ornl.gov/" self.nsf_url = "https://www.nsf.gov" @@ -14,7 +14,7 @@ def __init__(self): self.diamond_url = "http://www.diamond.ac.uk" self.homepage_url = "https://www.sasview.org" - self.download_url = 'https://github.com/SasView/sasview/releases' + self.download_url = 'https://github.com/SasView/sasview/releases/latest' self.marketplace_url = "http://marketplace.sasview.org/" self.update_url = 'https://www.sasview.org/latestversion.json' From b7a6b2e187ba4460f6e720c3fb8e90cd87c4f8a4 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 15:59:03 +0100 Subject: [PATCH 63/82] Fixed build number issues --- .github/workflows/docs.yml | 2 +- .github/workflows/installers.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- build_tools/release_automation.py | 1 + src/sas/system/version.py | 1 + 6 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 1536843af9..ba524e15bc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -93,7 +93,7 @@ jobs: run: | # SET SASVIEW GITHASH githash=$( git rev-parse HEAD ) - sed -i.bak s/GIT_COMMIT/$githash/g src/sas/sasview/__init__.py + sed -i.bak s/GIT_COMMIT/$githash/g src/sas/system/version.py # BUILD SASVIEW python setup.py clean python setup.py build diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml index e1200344dc..77fcd44b58 100644 --- a/.github/workflows/installers.yml +++ b/.github/workflows/installers.yml @@ -144,7 +144,7 @@ jobs: run: | # SET SASVIEW GITHASH githash=$( git rev-parse HEAD ) - sed -i.bak s/GIT_COMMIT/$githash/g src/sas/sasview/__init__.py + sed -i.bak s/GIT_COMMIT/$githash/g src/sas/system/version.py # BUILD SASVIEW python setup.py clean python setup.py build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f86936993..c962b2a21b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -146,7 +146,7 @@ jobs: run: | # SET SASVIEW GITHASH githash=$( git rev-parse HEAD ) - sed -i.bak s/GIT_COMMIT/$githash/g src/sas/sasview/__init__.py + sed -i.bak s/GIT_COMMIT/$githash/g src/sas/system/version.py # BUILD SASVIEW python setup.py clean python setup.py build diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d67f169b2e..ca2fda6cde 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -107,7 +107,7 @@ jobs: run: | # SET SASVIEW GITHASH githash=$( git rev-parse HEAD ) - sed -i.bak s/GIT_COMMIT/$githash/g src/sas/sasview/__init__.py + sed -i.bak s/GIT_COMMIT/$githash/g src/sas/system/version.py # BUILD SASVIEW python setup.py clean python setup.py build diff --git a/build_tools/release_automation.py b/build_tools/release_automation.py index 73b5943f34..cfb8508ad5 100644 --- a/build_tools/release_automation.py +++ b/build_tools/release_automation.py @@ -141,6 +141,7 @@ def generate_zenodo(sasview_data, zenodo_api_key): __version__ = "%s" __release_date__ = "%i" +__build__ = "GIT_COMMIT" StrictVersion(__version__) """ diff --git a/src/sas/system/version.py b/src/sas/system/version.py index f6c31d1a75..0ca23f807f 100644 --- a/src/sas/system/version.py +++ b/src/sas/system/version.py @@ -2,5 +2,6 @@ __version__ = "5.0.5" __release_date__ = "2022" +__build__ = "GIT_COMMIT" StrictVersion(__version__) From 69d1d9551795be2f846b800d8791c698a5675104 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Thu, 15 Sep 2022 16:05:08 +0100 Subject: [PATCH 64/82] Fixed version location in setup --- setup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 534c312f25..8bb1cb7fbc 100644 --- a/setup.py +++ b/setup.py @@ -14,13 +14,14 @@ from setuptools import setup # Manage version number ###################################### -with open(os.path.join("src", "sas", "sasview", "__init__.py")) as fid: +version_file = os.path.join("src", "sas", "system", "version.py") +with open(version_file) as fid: for line in fid: if line.startswith('__version__'): VERSION = line.split('"')[1] break else: - raise ValueError("Could not find version in src/sas/sasview/__init__.py") + raise ValueError(f"Could not find version in {version_file}") ############################################################## package_dir = {} From 6b6527af2a409d6ebb3e97ed44d466ee73e730f3 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Fri, 16 Sep 2022 09:43:19 +0100 Subject: [PATCH 65/82] Removed hide toolbar text --- src/sas/qtgui/MainWindow/GuiManager.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sas/qtgui/MainWindow/GuiManager.py b/src/sas/qtgui/MainWindow/GuiManager.py index 8f4563cd0b..3727b7df83 100644 --- a/src/sas/qtgui/MainWindow/GuiManager.py +++ b/src/sas/qtgui/MainWindow/GuiManager.py @@ -181,8 +181,7 @@ def addWidgets(self): self.results_panel.windowClosedSignal.connect(lambda: self.results_frame.setVisible(False)) self._workspace.toolBar.setVisible(config.TOOLBAR_SHOW) - self._workspace.actionHide_Toolbar.setText("Show Toolbar") - + # Add calculators - floating for usability self.SLDCalculator = SldPanel(self) self.DVCalculator = DensityPanel(self) From 7ca5d50f32f10b87d1cd2579d859b6746f7e9541 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 26 Sep 2022 08:50:14 +0100 Subject: [PATCH 66/82] Fixed version --- src/sas/qtgui/MainWindow/PackageGatherer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sas/qtgui/MainWindow/PackageGatherer.py b/src/sas/qtgui/MainWindow/PackageGatherer.py index be7d7ef968..b5fc3159b5 100644 --- a/src/sas/qtgui/MainWindow/PackageGatherer.py +++ b/src/sas/qtgui/MainWindow/PackageGatherer.py @@ -147,7 +147,7 @@ def get_imported_packages(self): if hasattr(package, '__version__'): # Module has __version__ attribute try: - package_versions_dict[package_name] = sas.system.version.__version__ + package_versions_dict[package_name] = package.__version__ continue except Exception as e: # Unable to access module From 576eacc0ed545b13a251d6666a841cb6b0f848d2 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 26 Sep 2022 08:52:05 +0100 Subject: [PATCH 67/82] Delft URL --- src/sas/system/web.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sas/system/web.py b/src/sas/system/web.py index bd1b9afd0e..ae09f4f126 100644 --- a/src/sas/system/web.py +++ b/src/sas/system/web.py @@ -9,7 +9,8 @@ def __init__(self): self.ill_url = "https://www.ill.eu/" self.ansto_url = "https://www.ansto.gov.au/" self.bam_url = "http://www.bam.de/" - self.delft_url = "http://www.tudelft.nl/en/tnw/business/facilities/reactor-instituut-delft/" + self.delft_url = \ + "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" self.inst_url = "https://www.utk.edu" self.diamond_url = "http://www.diamond.ac.uk" From 6656884e046ecb6ce52030c46c6e665239436a9d Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 26 Sep 2022 08:55:09 +0100 Subject: [PATCH 68/82] Moved sas.system.user import --- run.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/run.py b/run.py index 55626da346..065b80c37a 100644 --- a/run.py +++ b/run.py @@ -20,8 +20,6 @@ from os.path import abspath, dirname, realpath, join as joinpath from contextlib import contextmanager -import sas.system.user - PLUGIN_MODEL_DIR = 'plugin_models' def addpath(path): @@ -54,6 +52,7 @@ def setup_sasmodels(): """ # Set SAS_MODELPATH so sasmodels can find our custom models import sas + import sas.system.user plugin_dir = os.path.join(sas.system.user.get_user_dir(), PLUGIN_MODEL_DIR) os.environ['SAS_MODELPATH'] = plugin_dir From 38957fe0459d133103103e8630c3c51ca58260f5 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 26 Sep 2022 08:56:48 +0100 Subject: [PATCH 69/82] Changed import again --- run.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/run.py b/run.py index 065b80c37a..9c1aa05819 100644 --- a/run.py +++ b/run.py @@ -51,9 +51,9 @@ def setup_sasmodels(): Prepare sasmodels for running within sasview. """ # Set SAS_MODELPATH so sasmodels can find our custom models - import sas - import sas.system.user - plugin_dir = os.path.join(sas.system.user.get_user_dir(), PLUGIN_MODEL_DIR) + + from sas.system.user import get_user_dir + plugin_dir = os.path.join(get_user_dir(), PLUGIN_MODEL_DIR) os.environ['SAS_MODELPATH'] = plugin_dir def prepare(): From ea5ce84bdb24750ff2c0f22fa7da1161466f28ae Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 26 Sep 2022 09:01:43 +0100 Subject: [PATCH 70/82] Removed strict version requirement - isn't really necessary --- build_tools/release_automation.py | 4 ---- run.py | 2 +- src/sas/system/version.py | 3 --- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/build_tools/release_automation.py b/build_tools/release_automation.py index cfb8508ad5..06377e3a8e 100644 --- a/build_tools/release_automation.py +++ b/build_tools/release_automation.py @@ -137,13 +137,9 @@ def generate_zenodo(sasview_data, zenodo_api_key): version_template = \ """ -from distutils.version import StrictVersion - __version__ = "%s" __release_date__ = "%i" __build__ = "GIT_COMMIT" - -StrictVersion(__version__) """ zenodo_template = '__DOI__ = "%s"' diff --git a/run.py b/run.py index 9c1aa05819..4fd65f4c53 100644 --- a/run.py +++ b/run.py @@ -51,7 +51,7 @@ def setup_sasmodels(): Prepare sasmodels for running within sasview. """ # Set SAS_MODELPATH so sasmodels can find our custom models - + from sas.system.user import get_user_dir plugin_dir = os.path.join(get_user_dir(), PLUGIN_MODEL_DIR) os.environ['SAS_MODELPATH'] = plugin_dir diff --git a/src/sas/system/version.py b/src/sas/system/version.py index 0ca23f807f..1cd06c4312 100644 --- a/src/sas/system/version.py +++ b/src/sas/system/version.py @@ -1,7 +1,4 @@ -from distutils.version import StrictVersion - __version__ = "5.0.5" __release_date__ = "2022" __build__ = "GIT_COMMIT" -StrictVersion(__version__) From a6f233998c7587e19f73ea2a6efa6174d8020116 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 26 Sep 2022 09:06:59 +0100 Subject: [PATCH 71/82] Attempt to fix images issue --- setup.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup.py b/setup.py index 8bb1cb7fbc..3e1519f978 100644 --- a/setup.py +++ b/setup.py @@ -230,6 +230,11 @@ def run(self): "src", "sas", "qtgui", "Perspectives", "Corfunc", "UI") packages.extend(["sas.qtgui.Perspectives.Corfunc", "sas.qtgui.Perspectives.Corfunc.UI"]) + +package_dir["sas.qtgui.images"] = os.path.join( + "src", "sas", "qtgui", "images") +packages.append("sas.qtgui.images") + ## Plotting package_dir["sas.qtgui.Plotting"] = os.path.join( "src", "sas", "qtgui", "Plotting") From 0323f5f03c1fc0c8e06b831014da139b2202cc4d Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 28 Sep 2022 09:44:56 +0100 Subject: [PATCH 72/82] Rename web._licence to something not totally weird --- src/sas/qtgui/MainWindow/AboutBox.py | 2 +- src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py | 2 +- src/sas/system/web.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sas/qtgui/MainWindow/AboutBox.py b/src/sas/qtgui/MainWindow/AboutBox.py index fac573d81b..582e633c6f 100644 --- a/src/sas/qtgui/MainWindow/AboutBox.py +++ b/src/sas/qtgui/MainWindow/AboutBox.py @@ -50,7 +50,7 @@ def addText(self):

Comments? Bugs? Requests?
- Send us a ticket + Send us a ticket


diff --git a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py index e5f7c5311e..8363b0b053 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/AboutBoxTest.py @@ -59,7 +59,7 @@ def testAbout(self): # URLs self.assertIn(str(web.homepage_url), about.text()) self.assertIn(str(config.download_url), about.text()) - self.assertIn(str(config._license), about.text()) + self.assertIn(str(config.help_email), about.text()) # Are links enabled? self.assertTrue(about.openExternalLinks()) diff --git a/src/sas/system/web.py b/src/sas/system/web.py index ae09f4f126..bfdf4cc200 100644 --- a/src/sas/system/web.py +++ b/src/sas/system/web.py @@ -19,7 +19,7 @@ def __init__(self): self.marketplace_url = "http://marketplace.sasview.org/" self.update_url = 'https://www.sasview.org/latestversion.json' - self._license = "help@sasview.org" # TODO: Rename + self.help_email = "help@sasview.org" web = WebLinks() From 488540bbc421b0ee1ef4a55ef2fc9699d9b48ae1 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 28 Sep 2022 09:47:57 +0100 Subject: [PATCH 73/82] __version__ import fix --- src/sas/qtgui/MainWindow/MainWindow.py | 6 ++---- src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py | 3 --- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/sas/qtgui/MainWindow/MainWindow.py b/src/sas/qtgui/MainWindow/MainWindow.py index 44eb6b9fe9..330c66aace 100644 --- a/src/sas/qtgui/MainWindow/MainWindow.py +++ b/src/sas/qtgui/MainWindow/MainWindow.py @@ -4,9 +4,8 @@ import os import sys -from ...system.version import __version__ as SASVIEW_VERSION from sas import config -from sas.system import env +from sas.system import env, version from PyQt5.QtWidgets import QMainWindow from PyQt5.QtWidgets import QMdiArea @@ -26,8 +25,7 @@ def __init__(self, screen_resolution, parent=None): self.setupUi(self) # Add the version number to window title - self.setWindowTitle(f"SasView {SASVIEW_VERSION}") - + self.setWindowTitle(f"SasView {version.__version__}") # define workspace for dialogs. self.workspace = QMdiArea(self) # some perspectives are fixed size. diff --git a/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py b/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py index 48a01eb0a4..f4190c42ae 100644 --- a/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py +++ b/src/sas/qtgui/MainWindow/UnitTesting/GuiManagerTest.py @@ -10,9 +10,6 @@ from PyQt5 import QtCore from unittest.mock import MagicMock -# set up import paths -import path_prepare - # Local from sas.qtgui.MainWindow.DataExplorer import DataExplorerWindow from sas.qtgui.MainWindow.AboutBox import AboutBox From f26c4bc50bbe2120068c39cdefa3f86045a85fe6 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 28 Sep 2022 09:55:41 +0100 Subject: [PATCH 74/82] Changed version import --- src/sas/qtgui/Utilities/FileConverter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sas/qtgui/Utilities/FileConverter.py b/src/sas/qtgui/Utilities/FileConverter.py index 97b82161eb..bcca50d41d 100644 --- a/src/sas/qtgui/Utilities/FileConverter.py +++ b/src/sas/qtgui/Utilities/FileConverter.py @@ -23,7 +23,7 @@ import sas.qtgui.Utilities.GuiUtils as GuiUtils from sas.qtgui.Utilities.FrameSelect import FrameSelect -from ...system.version import __version__ as SASVIEW_VERSION +from sas.system import version from .UI.FileConverterUI import Ui_FileConverterUI @@ -284,7 +284,7 @@ def readMetadata(self): 'detector': [self.getDetectorMetadata()], 'sample': self.getSampleMetadata(), 'source': self.getSourceMetadata(), - 'notes': [f'Data file generated by SasView v{SASVIEW_VERSION}'], + 'notes': [f'Data file generated by SasView v{version.__version__}'], } self.metadata = metadata From 5b172b836b30b23edf88dfecc46b9e4369c1c821 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 10 Oct 2022 10:32:46 +0100 Subject: [PATCH 75/82] Weaker config requirements, pretty print --- src/sas/system/config/config_meta.py | 36 +++++++++++++++------------- src/sas/system/log.py | 2 -- src/sas/system/user.py | 5 ++-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/sas/system/config/config_meta.py b/src/sas/system/config/config_meta.py index 63157cc0be..86efcc311b 100644 --- a/src/sas/system/config/config_meta.py +++ b/src/sas/system/config/config_meta.py @@ -1,4 +1,4 @@ -from typing import Dict, Any, List +from typing import Dict, Any, List, Set import os import logging import json @@ -6,6 +6,7 @@ import sas import sas.system.version +from sas.system import user from sas.system.config.schema_elements import create_schema_element, CoercionError, SchemaElement logger = logging.getLogger("sas.config") @@ -42,9 +43,15 @@ def __init__(self): self._schema: Dict[str, SchemaElement] = {} self._defaults: Dict[str, SchemaElement] = {} self._deleted_attributes: List[str] = [] - self._write_disabled = False + self._bad_entries: Dict[str, Any] = {} self._meta_attributes = ["_locked", "_schema", "_defaults", - "_deleted_attributes", "_meta_attributes", "_write_disabled"] + "_deleted_attributes", "_meta_attributes", + "_bad_keys"] + + def config_filename(self, create_if_nonexistent=False): + """Filename for saving config items""" + version_parts = sas.system.version.__version__.split(".") + return os.path.join(user.get_user_dir(create_if_nonexistent), f"config-{version_parts[0]}.json") def finalise(self): """ Call this at the end of the config to make this class 'final' @@ -61,6 +68,7 @@ def update(self, data: Dict[str, Any]): # Skip over any deleted attributes if key in self._deleted_attributes: + self._bad_entries[key] = data[key] continue # Check the variable is in the schema @@ -74,20 +82,17 @@ def update(self, data: Dict[str, Any]): logger.error(f"Cannot set set variable '{key}', improper type ({e.message})") else: - logger.error(f"Unknown config key: '{key}', skipping") + logger.warning(f"Unknown config key: '{key}', skipping") + self._bad_entries[key] = data[key] def save(self): - if self._write_disabled: - logger.error("Write disabled, this is probably because it will overwrite an outdated config.") - return - - with open("config.json", 'w') as file: + with open(self.config_filename(True), 'w') as file: self.save_to_file_object(file) def save_to_file_object(self, file): """ Save config file - Only changed variables will be included in the saved file + Only changed and unknown variables will be included in the saved file """ data = {} for key in self._defaults: @@ -96,16 +101,18 @@ def save_to_file_object(self, file): if new_value != old_value: data[key] = new_value + data.update(self._bad_entries) + output_data = { "sasview_version": sas.system.version.__version__, "config_data": data} - json.dump(output_data, file) + json.dump(output_data, file, indent=2) def load(self): - filename = "config.json" + filename = self.config_filename(False) if os.path.exists(filename): - with open("config.json", 'r') as file: + with open(filename, 'r') as file: self.load_from_file_object(file) def load_from_file_object(self, file): @@ -138,7 +145,6 @@ def load_from_file_object(self, file): if int(file_major_version) != int(sasview_major_version): logger.warning(f"Attempting to used outdated config file (config is" f" for {file_version}, this SasView version is {sas.system.version.__version__})") - self._write_disabled = True self.update(data["config_data"]) @@ -176,8 +182,6 @@ def __setattr__(self, key, value): if key not in self.__dict__: raise ConfigLocked("New attribute attempt") - - super().__setattr__(key, value) diff --git a/src/sas/system/log.py b/src/sas/system/log.py index bfc4451220..c16840d8db 100644 --- a/src/sas/system/log.py +++ b/src/sas/system/log.py @@ -8,8 +8,6 @@ import pkg_resources -from sas import config - ''' Module that manages the global logging ''' diff --git a/src/sas/system/user.py b/src/sas/system/user.py index 4fda655def..96cc6b9f40 100644 --- a/src/sas/system/user.py +++ b/src/sas/system/user.py @@ -12,13 +12,14 @@ def make_user_dir(): return path -def get_user_dir(): +def get_user_dir(create_if_nonexistent=True): """ The directory where the per-user configuration is stored. Returns ~/.sasview, creating it if it does not already exist. """ global _USER_DIR - if not _USER_DIR: + if create_if_nonexistent and not _USER_DIR: _USER_DIR = make_user_dir() return _USER_DIR + From 554567f6573900a129371d8abb43e2820f414da9 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 10 Oct 2022 10:33:50 +0100 Subject: [PATCH 76/82] Removed config entries from logger --- src/sas/system/log.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/sas/system/log.py b/src/sas/system/log.py index c16840d8db..77dabb0362 100644 --- a/src/sas/system/log.py +++ b/src/sas/system/log.py @@ -38,15 +38,9 @@ def config_development(self): logger = logging.getLogger(self.name) self._update_all_logs_to_debug(logger) logging.captureWarnings(True) - self._disable_debug_from_config() logging.getLogger('matplotlib').setLevel(logging.WARN) return logger - def _disable_debug_from_config(self): - '''disable DEBUG logs as per user configuration (DEBUG logs disabled by default)''' - if config.FILTER_DEBUG_LOGS: - logging.disable(logging.DEBUG) - def _read_config_file(self): if self.config_file is not None: logging.config.fileConfig(self.config_file) From 728e21098907d191776948a2daf9e5ea86dcad7d Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 10 Oct 2022 10:46:34 +0100 Subject: [PATCH 77/82] Bugfix --- src/sas/system/config/config_meta.py | 12 ++++++++++-- src/sas/system/config/schema_elements.py | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/sas/system/config/config_meta.py b/src/sas/system/config/config_meta.py index 86efcc311b..ea0809cf99 100644 --- a/src/sas/system/config/config_meta.py +++ b/src/sas/system/config/config_meta.py @@ -46,12 +46,16 @@ def __init__(self): self._bad_entries: Dict[str, Any] = {} self._meta_attributes = ["_locked", "_schema", "_defaults", "_deleted_attributes", "_meta_attributes", - "_bad_keys"] + "_bad_entries"] def config_filename(self, create_if_nonexistent=False): """Filename for saving config items""" version_parts = sas.system.version.__version__.split(".") - return os.path.join(user.get_user_dir(create_if_nonexistent), f"config-{version_parts[0]}.json") + user_dir = user.get_user_dir(create_if_nonexistent) + if user_dir is None: + return None + else: + return os.path.join(user_dir, f"config-{version_parts[0]}.json") def finalise(self): """ Call this at the end of the config to make this class 'final' @@ -111,6 +115,10 @@ def save_to_file_object(self, file): def load(self): filename = self.config_filename(False) + + if filename is None: + return + if os.path.exists(filename): with open(filename, 'r') as file: self.load_from_file_object(file) diff --git a/src/sas/system/config/schema_elements.py b/src/sas/system/config/schema_elements.py index 3154b3c03b..51f7ec0382 100644 --- a/src/sas/system/config/schema_elements.py +++ b/src/sas/system/config/schema_elements.py @@ -177,7 +177,7 @@ def create_schema_element(name: str, value, recursion_depth: int=10) -> SchemaEl return SchemaStr() else: - raise SchemaError(f"Config element is not a bool, int, float, str, or a homogeneous list thereof ({value})") + raise SchemaError(f"Config element is not a bool, int, float, str, or a homogeneous list thereof ({name}={value})") def schema_union(elements: List[SchemaElement]): From 9e8f789fadcd6d49ab29d73b024985742b6154fd Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 10 Oct 2022 11:40:29 +0100 Subject: [PATCH 78/82] Save to user dir --- src/sas/qtgui/MainWindow/MainWindow.py | 3 ++- .../qtgui/Perspectives/Fitting/GPUOptions.py | 3 +++ src/sas/system/config/config_meta.py | 11 ++++------- src/sas/system/env.py | 12 ++++++++---- src/sas/system/user.py | 17 +++++------------ 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/sas/qtgui/MainWindow/MainWindow.py b/src/sas/qtgui/MainWindow/MainWindow.py index 330c66aace..6a81d6bcce 100644 --- a/src/sas/qtgui/MainWindow/MainWindow.py +++ b/src/sas/qtgui/MainWindow/MainWindow.py @@ -83,7 +83,8 @@ def run_sasview(): # Set open cl config from environment variable, if it is set if "SAS_OPENCL" in os.environ: logging.getLogger(__name__).info("Getting OpenCL settings from environment variables") - config.SAS_OPENCL = env.sas_opencl + if env.SAS_OPENCL != "none": + config.SAS_OPENCL = env.sas_opencl else: logging.getLogger(__name__).info("Getting OpenCL settings from config") env.sas_opencl = config.SAS_OPENCL diff --git a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py index 8abd142ff4..e972f71bf6 100644 --- a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py +++ b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py @@ -82,6 +82,9 @@ def add_options(self): radio_button.setObjectName(_fromUtf8(descr)) radio_button.setText(_translate("GPUOptions", descr, None)) self.optionsLayout.addWidget(radio_button) + + print(title, config.SAS_OPENCL) + if title.lower() == config.SAS_OPENCL.lower(): radio_button.setChecked(True) diff --git a/src/sas/system/config/config_meta.py b/src/sas/system/config/config_meta.py index ea0809cf99..22ce37cf1e 100644 --- a/src/sas/system/config/config_meta.py +++ b/src/sas/system/config/config_meta.py @@ -52,10 +52,7 @@ def config_filename(self, create_if_nonexistent=False): """Filename for saving config items""" version_parts = sas.system.version.__version__.split(".") user_dir = user.get_user_dir(create_if_nonexistent) - if user_dir is None: - return None - else: - return os.path.join(user_dir, f"config-{version_parts[0]}.json") + return os.path.join(user_dir, f"config-{version_parts[0]}.json") def finalise(self): """ Call this at the end of the config to make this class 'final' @@ -116,13 +113,13 @@ def save_to_file_object(self, file): def load(self): filename = self.config_filename(False) - if filename is None: - return - if os.path.exists(filename): with open(filename, 'r') as file: self.load_from_file_object(file) + else: + logger.warning(f"No config file found - one will be created when sasview exits") + def load_from_file_object(self, file): """ Load config file """ data = json.load(file) diff --git a/src/sas/system/env.py b/src/sas/system/env.py index e1063cc5bd..9ff4018666 100644 --- a/src/sas/system/env.py +++ b/src/sas/system/env.py @@ -4,28 +4,32 @@ """ import os import logging +from typing import Optional class Envrironment: logger = logging.getLogger(__name__) @property - def sas_opencl(self) -> str: + def sas_opencl(self) -> Optional[str]: """ Get the value of the environment variable SAS_OPENCL, which specifies which OpenCL device should be used. """ - return os.environ.get("SAS_OPENCL", "none") + if "SAS_OPENCL" in os.environ: + return os.environ.get("SAS_OPENCL", "none") + else: + return None @sas_opencl.setter - def sas_opencl(self, value: str): + def sas_opencl(self, value: Optional[str]): """ Set the value of the environment variable SAS_OPENCL """ - if value.lower() == "none": + if value is None or value.lower() == "none": if "SAS_OPENCL" in os.environ: del os.environ["SAS_OPENCL"] else: diff --git a/src/sas/system/user.py b/src/sas/system/user.py index 96cc6b9f40..86df6c3a54 100644 --- a/src/sas/system/user.py +++ b/src/sas/system/user.py @@ -1,15 +1,6 @@ import os -_USER_DIR = None - -def make_user_dir(): - """ - Create the user directory ~/.sasview if it doesn't already exist. - """ - path = os.path.join(os.path.expanduser("~"),'.sasview') - if not os.path.exists(path): - os.mkdir(path) - return path +_USER_DIR = os.path.join(os.path.expanduser("~"), '.sasview') def get_user_dir(create_if_nonexistent=True): @@ -19,7 +10,9 @@ def get_user_dir(create_if_nonexistent=True): Returns ~/.sasview, creating it if it does not already exist. """ global _USER_DIR - if create_if_nonexistent and not _USER_DIR: - _USER_DIR = make_user_dir() + + if create_if_nonexistent and not os.path.exists(_USER_DIR): + os.mkdir(_USER_DIR) + return _USER_DIR From 45ad22a3a442787d78ef4c5a08d1fbc89f4decf2 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 10 Oct 2022 11:50:41 +0100 Subject: [PATCH 79/82] Updated utest to reflect change in logging level --- test/config/utest_config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/config/utest_config.py b/test/config/utest_config.py index 2bbb029344..87bedc448c 100644 --- a/test/config/utest_config.py +++ b/test/config/utest_config.py @@ -82,7 +82,7 @@ def test_valid_update(self): def test_invalid_update_bad_name(self): - """ Check that an error is logged when there is a bad name in the config""" + """ Check that a warning is logged when there is a bad name in the config""" config = Config() @@ -94,9 +94,9 @@ def test_invalid_update_bad_name(self): name += "x" # try and set it - with self.assertLogs('sas.config', level="ERROR") as cm: + with self.assertLogs('sas.config', level="WARNING") as cm: config.update({name: None}) - self.assertTrue(cm.output[0].startswith("ERROR:sas.config:")) + self.assertTrue(cm.output[0].startswith("WARNING:sas.config:")) def test_invalid_update_bad_type(self): From d06a9f08fe4f3736f5b44f49821c73db4c27c9a2 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Mon, 10 Oct 2022 15:11:14 +0100 Subject: [PATCH 80/82] Removed debugging print statement --- src/sas/qtgui/Perspectives/Fitting/GPUOptions.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py index e972f71bf6..0297630002 100644 --- a/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py +++ b/src/sas/qtgui/Perspectives/Fitting/GPUOptions.py @@ -83,8 +83,6 @@ def add_options(self): radio_button.setText(_translate("GPUOptions", descr, None)) self.optionsLayout.addWidget(radio_button) - print(title, config.SAS_OPENCL) - if title.lower() == config.SAS_OPENCL.lower(): radio_button.setChecked(True) From 74bbe1245d90c4ae83a828324a8aa3e6a92c072e Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Tue, 11 Oct 2022 14:52:17 +0100 Subject: [PATCH 81/82] Updated web links to https --- src/sas/system/web.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sas/system/web.py b/src/sas/system/web.py index bfdf4cc200..50d8040b20 100644 --- a/src/sas/system/web.py +++ b/src/sas/system/web.py @@ -8,7 +8,7 @@ def __init__(self): self.ess_url = "https://europeanspallationsource.se/" self.ill_url = "https://www.ill.eu/" self.ansto_url = "https://www.ansto.gov.au/" - self.bam_url = "http://www.bam.de/" + self.bam_url = "https://www.bam.de/" self.delft_url = \ "https://www.tudelft.nl/en/faculty-of-applied-sciences/business/facilities/reactor-institute-delft" self.inst_url = "https://www.utk.edu" @@ -16,7 +16,7 @@ def __init__(self): self.homepage_url = "https://www.sasview.org" self.download_url = 'https://github.com/SasView/sasview/releases/latest' - self.marketplace_url = "http://marketplace.sasview.org/" + self.marketplace_url = "https://marketplace.sasview.org/" self.update_url = 'https://www.sasview.org/latestversion.json' self.help_email = "help@sasview.org" From db897fbdd5cbb8b19102708f805e4b97f0ac04e9 Mon Sep 17 00:00:00 2001 From: lucas-wilkins Date: Wed, 12 Oct 2022 12:19:27 +0100 Subject: [PATCH 82/82] Updated MainWindow config-env stuff --- src/sas/qtgui/MainWindow/MainWindow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sas/qtgui/MainWindow/MainWindow.py b/src/sas/qtgui/MainWindow/MainWindow.py index 6a81d6bcce..875332ea1f 100644 --- a/src/sas/qtgui/MainWindow/MainWindow.py +++ b/src/sas/qtgui/MainWindow/MainWindow.py @@ -81,10 +81,10 @@ def run_sasview(): get_user_dir(), "compiled_models") # Set open cl config from environment variable, if it is set - if "SAS_OPENCL" in os.environ: + + if env.sas_opencl is not None: logging.getLogger(__name__).info("Getting OpenCL settings from environment variables") - if env.SAS_OPENCL != "none": - config.SAS_OPENCL = env.sas_opencl + config.SAS_OPENCL = env.sas_opencl else: logging.getLogger(__name__).info("Getting OpenCL settings from config") env.sas_opencl = config.SAS_OPENCL