This repository has been archived by the owner on Mar 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 46
Config loaders #1116
Draft
stanislaw47
wants to merge
104
commits into
taurus-org:develop
Choose a base branch
from
stanislaw47:config_loaders
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Config loaders #1116
Changes from all commits
Commits
Show all changes
104 commits
Select commit
Hold shift + click to select a range
4e9d30d
Add main Taurus parser with common options and ability to load subcom…
0db8ad8
Rebuild testsuite laucnhing method to support it as a subcommand
6586b9b
Merge branch 'develop' of https://github.com/taurus-org/taurus into d…
4771f9a
Add skeleton for config loader
e0e5c92
Define interface of abstract class
938db8c
Move to use abstract class
88d733c
Implementation of JSON config loader
512a931
Delegate non-path strings to PyConfigLoader
9ab3ef4
Add implementation fo Python config loader
00a0c43
Add implementation of config loader from XML file
9e021a5
Specify proper section in XML
684ba73
Get in line with what XML file loads
9118498
Use helper function
445285e
Use helper function for Python config loader also
00e4139
Use config loader for most of configuration
81bf057
Allow setting deprecated Monitor widget
cce2f9a
Add filed with absolute path to config directory
1fb53f8
Load Sardana stuff from config files
b45c603
Cleanup xmlroot
ea2e634
Make loader more robust
5e83ae3
Delete function from unsucessful merge
7a27f2a
Use absolute paths for imports
4f213ff
Remove unused imports
d5e7d0f
Load monitor widget directly in config loader
072f025
Add some documentation
4ee3e72
Fix bugs when loading Python module
8b85750
PEP8
fb890ce
Use entrypoints to discover and load config loader plugins
5f7fc7f
Return default value when reading config from Python module
10394bd
Fix issues with entrypoints
6736212
Add launcher for manual testing of config loader
a6386b8
Add examples of configuration for Python and JSON file
402c829
Make quick launcher more structurized
d3af287
Add new moethod for indicitaing if loader supports condifuration
b5764a9
Implement supports method for all loaders
7e5ff0e
Make supports method static
ae83efc
Adapt getLoader emthod to support multiple loaders
9bf4b54
m, typo
5475327
Add prefix for config loaders entrypoints
1a3764d
Remove deprecated properties and Sardana-centred ones from mandatory …
9cd2178
Remove conf_dir from mandatory abstract API
5acc5c7
Use flexible dictionary with configuration instead of class fields
204a84d
Split logic responsible for loading data from formatting data
94ba5ab
Update loading values from configuration
d98275f
Add BckCompatConfigLoader
fc8d1e2
Add config loader for Sardana
435e250
Allow loading deprecated and Sardana-related config values
e48b285
Fix syntax
16a41b7
Add hooks list to abstract interface
42689ba
Add hooks for backward compatible changes
3b56644
Add Sardana custom laoder with hooks
5b59928
Update _loadCustomPanels method to laod panels from configuration or …
a97404e
Remove Sardana-related config loader methods
b883df6
Execute registered config loader hooks
b8910fb
PEP8
5be97c5
Add missing entry point for Sardana config loader
edda3b9
Fix typo
085e8af
Always try to laod Sardana config values
1f4247f
m, typos
deb7c9a
m, typo
55bab0b
Retiurn loaders list from loader function
1d08b0f
getLoader -> getLoaders
00a24d6
Move getLoaders function to its own module
edf38f6
USe variable with entry point name for easier testing
fd8b344
Create instrument panels completely in config loader hook
f8433f7
Protect against expections raised while executing config hooks
b0a09e8
Add new exception speicifc for hooks
21c5b95
Simplify handling of errors
c6a6a68
Import just Device
e0b6582
Move custom exceptions to util module
a4a5e1e
Remove unused import
fdff9cc
Provide concrete config loader classes for Python and XML configurati…
4a402e2
Add new Sardana config laoders to entry point
9bd06cd
Update docstring
2428a08
Refactor loading instruments from Pool
6bff4ed
PEP8
bc2ab07
Simplify printing configuration
5afc4e9
Add method to cast TaurusGuiComponent to dictionary
6b1622b
Cast description obejcts to dictionaries to simplify printing
a229e6c
Return dictionary, not result of 'update' call (None)
b10acbc
Fix printing description objects
372c8e5
Allow easy printing of ExternalApp objects
0123838
Merge branch 'develop' of https://github.com/taurus-org/taurus into d…
2431aeb
Merge branch 'develop' into config_loaders
87682d8
Merge branch 'config_loaders' of https://github.com/stanislaw47/tauru…
94f9030
Move default values to DEFAULT_CONFIG variable
5dee71a
Use unified way of refering to configuration fields
da9893d
Make conf private variable
cc9e428
Adapt loaders to new API
6e89719
Do not pass conf instance to hooks
4ccdf92
Fix extending CONFIG_VALUES list
c96d2eb
Add support for XML_CONFIG field
d41ccac
MAke GUI_NAME optional (default to confname)
c9b26e7
Addd list of all Description classes along with configuration sections
f3b9adf
Add helper method for generating pure Python dictionary from configur…
24b5651
Use existing DESCRIPTIONS list
19b22a0
Fix JSON loader
8dcca46
Add skeleton of tests for PYthon configuration
f352cba
Add new entrypoint for loading custom config properties
stanislaw47 eee6441
Remove redundant config loaders
stanislaw47 8cbb2bc
Get rid of hooks
stanislaw47 10de1a1
Add loading all extra config properties in TaurusGUI
stanislaw47 fbbd352
Remove SYNOPTIC from stadard config properties
stanislaw47 3b9e6d4
Merge branch 'develop' into config_loaders
stanislaw47 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
############################################################################# | ||
## | ||
# This file is part of Taurus | ||
## | ||
# http://taurus-scada.org | ||
## | ||
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain | ||
## | ||
# Taurus is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
## | ||
# Taurus is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
## | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with Taurus. If not, see <http://www.gnu.org/licenses/>. | ||
## | ||
########################################################################### | ||
|
||
""" | ||
""" | ||
|
||
from .util import getLoaders |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import sys | ||
from pprint import pprint | ||
|
||
from .util import getLoaders | ||
|
||
|
||
def main(conf): | ||
cfg = {} | ||
loaders = getLoaders(conf) | ||
for loader in loaders: | ||
cfg.update(loader.load()) | ||
|
||
cfg = loaders[0].to_dict(cfg) | ||
|
||
pprint(cfg) | ||
|
||
|
||
main(sys.argv[1]) | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
############################################################################# | ||
## | ||
# This file is part of Taurus | ||
## | ||
# http://taurus-scada.org | ||
## | ||
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain | ||
## | ||
# Taurus is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
## | ||
# Taurus is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
## | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with Taurus. If not, see <http://www.gnu.org/licenses/>. | ||
## | ||
########################################################################### | ||
|
||
"""""" | ||
import abc | ||
|
||
from taurus.qt.qtgui.taurusgui.utils import ( | ||
AppletDescription, | ||
ExternalApp, | ||
PanelDescription, | ||
ToolBarDescription, | ||
) | ||
|
||
# Python 2/3 compatibility | ||
if not hasattr(abc, "ABC"): | ||
setattr(abc, "ABC", abc.ABCMeta("ABC", (object,), {})) | ||
|
||
|
||
__all__ = ["AbstractConfigLoader"] | ||
|
||
|
||
class AbstractConfigLoader(abc.ABC): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this implementation even more than the one before! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great to hear it :) |
||
""" | ||
Abstract class for config loaders. | ||
It defines interface which has to be implemneted by subclass in | ||
order for it to be ConfigLoader | ||
""" | ||
|
||
CONFIG_VALUES = [ | ||
"GUI_NAME", | ||
"ORGANIZATION", | ||
"CUSTOM_LOGO", | ||
"ORGANIZATION_LOGO", | ||
"SINGLE_INSTANCE", | ||
"MANUAL_URI", | ||
"INIFILE", | ||
"EXTRA_CATALOG_WIDGETS", | ||
] | ||
|
||
DESCRIPTIONS = [ | ||
(AppletDescription, "AppletDescriptions"), | ||
(ExternalApp, "ExternalApps"), | ||
(PanelDescription, "PanelDescriptions"), | ||
(ToolBarDescription, "ToolBarDescriptions"), | ||
] | ||
|
||
def __init__(self, confname): | ||
self._confname = confname | ||
|
||
@abc.abstractmethod | ||
def supports(self, confname): | ||
""" | ||
Return True or False for support of specific configuration passed | ||
""" | ||
return None | ||
|
||
@abc.abstractmethod | ||
def load(self): | ||
""" | ||
This method is meant to load actual data from file on disk. | ||
Return dictionary with configuration. | ||
""" | ||
return {} | ||
|
||
def to_dict(self, conf): | ||
""" | ||
Generate pure Python dictionary from conf | ||
""" | ||
|
||
for _, section in self.DESCRIPTIONS: | ||
objs = [o.to_dict() for o in conf.get(section, [])] | ||
conf[section] = objs | ||
|
||
return conf |
69 changes: 69 additions & 0 deletions
69
lib/taurus/qt/qtgui/taurusgui/config_loader/examples/config.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
{ | ||
"GUI_NAME": "EXAMPLE 01", | ||
"ORGANIZATION": "Taurus", | ||
"MANUAL_URI": "http://www.taurus-scada.org", | ||
"SYNOPTIC": ["images/example01.jdw", "images/syn2.jdw"], | ||
"INSTRUMENTS_FROM_POOL": false, | ||
"PanelDescriptions": [ | ||
{ | ||
"name": "NeXus Browser", | ||
"classname": "taurus.qt.qtgui.extra_nexus.TaurusNeXusBrowser" | ||
}, | ||
{ | ||
"name": "BigInstrument", | ||
"classname": "taurus.qt.qtgui.panel.TaurusAttrForm", | ||
"model": "sys/tg_test/1" | ||
}, | ||
{ | ||
"name": "NeXus Browser", | ||
"classname": "taurus.qt.qtgui.extra_nexus.TaurusNeXusBrowser" | ||
}, | ||
{ | ||
"name": "instrument1", | ||
"classname": "taurus.qt.qtgui.panel.TaurusForm", | ||
"model": [ | ||
"sys/tg_test/1/double_scalar", | ||
"sys/tg_test/1/short_scalar_ro", | ||
"sys/tg_test/1/float_spectrum_ro", | ||
"sys/tg_test/1/double_spectrum" | ||
] | ||
}, | ||
{ | ||
"name": "instrument2", | ||
"classname": "taurus.qt.qtgui.panel.TaurusForm", | ||
"model": [ | ||
"sys/tg_test/1/wave", | ||
"sys/tg_test/1/boolean_scalar" | ||
] | ||
}, | ||
{ | ||
"name": "Selected Instrument", | ||
"classname": "taurus.external.qt.Qt.QLineEdit", | ||
"sharedDataRead": { | ||
"SelectedInstrument": "setText" | ||
}, | ||
"sharedDataWrite": { | ||
"SelectedInstrument": "textEdited" | ||
} | ||
} | ||
], | ||
"ToolBarDescriptions": [ | ||
{ | ||
"name": "Empty Toolbar", | ||
"classname": "taurus.external.qt.Qt.QToolBar" | ||
} | ||
], | ||
"ExternalApps": [ | ||
{ | ||
"name": "xterm", | ||
"cmdargs": ["xterm", "spock"], | ||
"text": "Spock", | ||
"icon": "utilities-terminal" | ||
} | ||
], | ||
"EXTRA_CATALOG_WIDGETS": [ | ||
["taurus.external.qt.Qt.QLineEdit", "logos:taurus.png"], | ||
["taurus.external.qt.Qt.QSpinBox", "images/syn2.jpg"], | ||
["taurus.external.qt.Qt.QLabel", null] | ||
] | ||
} |
70 changes: 70 additions & 0 deletions
70
lib/taurus/qt/qtgui/taurusgui/config_loader/examples/config.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
|
||
|
||
from taurus.qt.qtgui.taurusgui.utils import PanelDescription, ExternalApp, ToolBarDescription, AppletDescription | ||
|
||
GUI_NAME = 'EXAMPLE 01' | ||
ORGANIZATION = 'Taurus' | ||
|
||
MANUAL_URI = 'http://www.taurus-scada.org' | ||
|
||
SYNOPTIC = ['images/example01.jdw', 'images/syn2.jdw'] | ||
|
||
|
||
INSTRUMENTS_FROM_POOL = False | ||
|
||
|
||
nxbrowser = PanelDescription( | ||
'NeXus Browser', | ||
classname='taurus.qt.qtgui.extra_nexus.TaurusNeXusBrowser' | ||
) | ||
|
||
i0 = PanelDescription( | ||
'BigInstrument', | ||
classname='taurus.qt.qtgui.panel.TaurusAttrForm', | ||
model='sys/tg_test/1' | ||
) | ||
|
||
i1 = PanelDescription( | ||
'instrument1', | ||
classname='taurus.qt.qtgui.panel.TaurusForm', | ||
model=['sys/tg_test/1/double_scalar', | ||
'sys/tg_test/1/short_scalar_ro', | ||
'sys/tg_test/1/float_spectrum_ro', | ||
'sys/tg_test/1/double_spectrum'] | ||
) | ||
|
||
i2 = PanelDescription( | ||
'instrument2', | ||
classname='taurus.qt.qtgui.panel.TaurusForm', | ||
model=['sys/tg_test/1/wave', | ||
'sys/tg_test/1/boolean_scalar'] | ||
) | ||
|
||
trend = PanelDescription( | ||
'Trend', | ||
classname='taurus.qt.qtgui.plot.TaurusTrend', | ||
model=['sys/tg_test/1/double_scalar'] | ||
) | ||
|
||
connectionDemo = PanelDescription( | ||
'Selected Instrument', | ||
classname='taurus.external.qt.Qt.QLineEdit', # A pure Qt widget! | ||
sharedDataRead={'SelectedInstrument': 'setText'}, | ||
sharedDataWrite={'SelectedInstrument': 'textEdited'} | ||
) | ||
|
||
dummytoolbar = ToolBarDescription( | ||
'Empty Toolbar', | ||
classname='taurus.external.qt.Qt.QToolBar' | ||
) | ||
|
||
xterm = ExternalApp( | ||
cmdargs=['xterm', 'spock'], text="Spock", icon='utilities-terminal') | ||
hdfview = ExternalApp(["hdfview"]) | ||
pymca = ExternalApp(['pymca']) | ||
|
||
EXTRA_CATALOG_WIDGETS = [ | ||
('taurus.external.qt.Qt.QLineEdit', 'logos:taurus.png'), # a resource | ||
('taurus.external.qt.Qt.QSpinBox', 'images/syn2.jpg'), # relative | ||
# ('taurus.external.Qt.QTextEdit','/tmp/foo.png'), # absolute | ||
('taurus.external.qt.Qt.QLabel', None)] # none |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
############################################################################# | ||
## | ||
# This file is part of Taurus | ||
## | ||
# http://taurus-scada.org | ||
## | ||
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain | ||
## | ||
# Taurus is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU Lesser General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
## | ||
# Taurus is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Lesser General Public License for more details. | ||
## | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with Taurus. If not, see <http://www.gnu.org/licenses/>. | ||
## | ||
########################################################################### | ||
|
||
"""""" | ||
|
||
import json | ||
import os | ||
|
||
from taurus.qt.qtgui.taurusgui.config_loader.abstract import ( | ||
AbstractConfigLoader, | ||
) | ||
from taurus.qt.qtgui.taurusgui.config_loader.util import ConfigLoaderError | ||
|
||
__all__ = ["JsonConfigLoader"] | ||
|
||
|
||
class JsonConfigLoader(AbstractConfigLoader): | ||
""" | ||
Loads configuration for TaurusGui from JSON file | ||
""" | ||
|
||
def __init__(self, confname): | ||
super(JsonConfigLoader, self).__init__(confname) | ||
self._data = {} | ||
|
||
def _get_objects(self, klass, section): | ||
""" | ||
Helper function to get list of Python objects from dictionary | ||
""" | ||
objs = [] | ||
for o in self._data.get(section, []): | ||
if isinstance(o, dict): | ||
objs.append(klass(**o)) | ||
return objs | ||
|
||
@staticmethod | ||
def supports(confname): | ||
if os.path.isfile(confname): | ||
ext = os.path.splitext(confname)[-1] | ||
if ext == ".json": | ||
return True | ||
return False | ||
|
||
def _get_data(self): | ||
try: | ||
with open(self._confname, "r") as fp: | ||
self._data = json.load(fp) | ||
except IOError as e: | ||
raise ConfigLoaderError( | ||
"Problem with accessing config file: " + str(e) | ||
) | ||
except ValueError as e: | ||
raise ConfigLoaderError( | ||
"Problem with config file decoding: " + str(e) | ||
) | ||
|
||
def load(self): | ||
self._get_data() | ||
|
||
tmp = {} | ||
|
||
for v in self.CONFIG_VALUES: | ||
if v in self._data: | ||
tmp[v] = self._data[v] | ||
|
||
for klass, section in self.DESCRIPTIONS: | ||
tmp[section] = self._get_objects(klass, section) | ||
|
||
tmp["CONF_DIR"] = os.path.abspath( | ||
os.path.dirname(self._confname) | ||
) | ||
|
||
return tmp |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes more sense as a taurus gui option/subcommand. Also, I think that the helper functions are better provided as method(s) of the configloader object (this way different loaders can take care of printing their own stuff)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not know yet how exactly that would work. But I simplified this a lot since now there's internal dictionary instead of class.
To make it simply, I needed to introduce
to_dict
method for each*Description
class. In future, this could evolve to what was referenced asConfigWriter
.