-
Notifications
You must be signed in to change notification settings - Fork 3
Ticket3396 show global macros #450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
d0964b1
ae34053
9a64ced
2fb2aa5
964a846
f7246bd
5cc6e1a
71873df
17776be
f4aa705
615ff30
7aa2e58
58a35af
e01cebb
6521e05
7d6e2af
6e3aa66
7b09e37
cd5551d
4d471c7
06ce22e
38771f7
3f33243
60c3e35
60e0e91
5da0e16
9c5963e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| # This file is part of the ISIS IBEX application. | ||
| # Copyright (C) 2012-2025 Science & Technology Facilities Council. | ||
| # All rights reserved. | ||
| # | ||
| # This program is distributed in the hope that it will be useful. | ||
| # This program and the accompanying materials are made available under the | ||
| # terms of the Eclipse Public License v1.0 which accompanies this distribution. | ||
| # EXCEPT AS EXPRESSLY SET FORTH IN THE ECLIPSE PUBLIC LICENSE V1.0, THE PROGRAM | ||
| # AND ACCOMPANYING MATERIALS ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES | ||
| # OR CONDITIONS OF ANY KIND. See the Eclipse Public License v1.0 for more details. | ||
| # | ||
| # You should have received a copy of the Eclipse Public License v1.0 | ||
| # along with this program; if not, you can obtain a copy from | ||
| # https://www.eclipse.org/org/documents/epl-v10.php or | ||
| # http://opensource.org/licenses/eclipse-1.0.php | ||
|
|
||
| import copy | ||
| from collections import OrderedDict | ||
| from typing import Any | ||
|
|
||
| from server_common.utilities import print_and_log | ||
|
|
||
|
|
||
| class Globalmacro: | ||
| """Represents an IOC with its global macros. | ||
|
|
||
| Attributes: | ||
| name (string): The name of the IOC | ||
| macros (dict): The IOC's macros | ||
| """ | ||
|
|
||
| def __init__( | ||
| self, | ||
| name: str, | ||
| macros: dict[str, str] | None, | ||
| ) -> None: | ||
| """Constructor. | ||
|
|
||
| Args: | ||
| name: The name of the IOC | ||
| macros: The IOC's macros | ||
| """ | ||
| self.name = name | ||
|
|
||
| if macros is None: | ||
| self.macros = {} | ||
| else: | ||
| self.macros = macros | ||
|
|
||
| @staticmethod | ||
| def _dict_to_list(in_dict: dict[str, Any]) -> list[Any]: | ||
| """Converts into a format better for the GUI to parse, namely a list. | ||
|
|
||
| Args: | ||
| in_dict: The dictionary to be converted | ||
|
|
||
| Returns: | ||
| The newly created list | ||
| """ | ||
| out_list = [] | ||
| if in_dict: | ||
| for k, v in in_dict.items(): | ||
| # Take a copy as we do not want to modify the original | ||
| c = copy.deepcopy(v) | ||
| c["name"] = k | ||
| out_list.append(c) | ||
| return out_list | ||
|
|
||
| def __str__(self) -> str: | ||
| return f"{self.__class__.__name__}(name={self.name})" | ||
|
|
||
| def to_dict(self) -> dict[str, str | dict[str, str]]: | ||
| """Puts the IOC-globalmacro's details into a dictionary. | ||
|
|
||
| Returns: | ||
| The IOC-Global Macros' details | ||
| """ | ||
| return { | ||
| "name": self.name, | ||
| "macros": self.macros, | ||
| } | ||
|
|
||
|
|
||
| class GlobalmacroHelper: | ||
|
Contributor
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. nit: does it need to be a class with one method at all - can it just be a free function?
Contributor
Author
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. It is a helper class, now with two methods |
||
| """Converts global macro data to Globalmacro Object.""" | ||
|
|
||
| globalmacros = OrderedDict() | ||
|
|
||
| @staticmethod | ||
| def row_to_globalmacro(globalmacros: dict, row: str) -> None: | ||
| """converts a row from the globals file to globalmacro data. | ||
|
|
||
| Args: | ||
| globalmacros: The current list of global macros | ||
| row: The IOC's (or All IOCs) global macro record | ||
| """ | ||
| ioc_separator = "__" | ||
| equal_to = "=" | ||
| all_iocs = "<ALL IOCS>" | ||
| # Each record is of the form IOC__MACRO=VALUE | ||
| # Where there is no __ the Macro is applicable for all IOCs | ||
| if equal_to in row: | ||
| ioc_macro, value = row.rsplit(equal_to, maxsplit=1) | ||
| to_add_ioc = {} | ||
| if ioc_separator in ioc_macro: | ||
| ioc, macro = ioc_macro.split(ioc_separator, maxsplit=1) | ||
| else: | ||
| ioc = all_iocs | ||
|
Contributor
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. should: We seem to have a "special" key of
Contributor
Author
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. Changes done |
||
| macro = ioc_macro | ||
|
|
||
| if ioc in globalmacros: | ||
| to_add_ioc = globalmacros[ioc] | ||
| to_add_ioc[macro] = value.strip() | ||
| globalmacros[ioc] = to_add_ioc | ||
|
|
||
| @staticmethod | ||
| def add_globalmacro(name: str, macros: dict) -> None: | ||
| """Add an IOC with its global macros to the configuration. | ||
|
|
||
| Args: | ||
| name (string): The name of the IOC to add | ||
| macros: The macro sets relating to the IOC | ||
|
|
||
| """ | ||
| # Only add it if it has not been added before | ||
| if name.upper() in GlobalmacroHelper.globalmacros.keys(): | ||
| print_and_log( | ||
| f"Warning: IOC '{name}' is already part of the configuration. Not adding it again." | ||
| ) | ||
| else: | ||
| GlobalmacroHelper.globalmacros[name.upper()] = Globalmacro(name, macros) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # This file is part of the ISIS IBEX application. | ||
| # Copyright (C) 2012-2016 Science & Technology Facilities Council. | ||
| # Copyright (C) 2012-2025 Science & Technology Facilities Council. | ||
| # All rights reserved. | ||
| # | ||
| # This program is distributed in the hope that it will be useful. | ||
|
|
@@ -16,20 +16,20 @@ | |
|
|
||
| """Contains the code for the ConfigHolder class""" | ||
|
|
||
| # ruff: noqa: I001 | ||
| import copy | ||
| import re | ||
| from collections import OrderedDict | ||
| from typing import Any, Dict, List | ||
|
|
||
| from server_common.file_path_manager import FILEPATH_MANAGER | ||
| from server_common.helpers import PVPREFIX_MACRO | ||
| from server_common.utilities import print_and_log | ||
|
|
||
| from BlockServer.config.configuration import Configuration | ||
| from BlockServer.config.group import Group | ||
| from BlockServer.config.metadata import MetaData | ||
| from BlockServer.core.constants import DEFAULT_COMPONENT, GRP_NONE | ||
| from BlockServer.fileIO.file_manager import ConfigurationFileManager | ||
| from server_common.file_path_manager import FILEPATH_MANAGER | ||
| from server_common.helpers import PVPREFIX_MACRO | ||
| from server_common.utilities import print_and_log | ||
|
|
||
|
|
||
| class ConfigHolder: | ||
|
|
@@ -127,7 +127,7 @@ def get_blocknames(self) -> List[str]: | |
| names.append(block.name) | ||
| return names | ||
|
|
||
| def get_block_details(self): | ||
| def get_block_details(self) -> OrderedDict: | ||
| """Get the configuration details for all the blocks including any in components. | ||
|
|
||
| Returns: | ||
|
|
@@ -183,7 +183,7 @@ def get_group_details(self) -> Dict[str, Group]: | |
|
|
||
| return groups | ||
|
|
||
| def _set_group_details(self, redefinition) -> None: | ||
| def _set_group_details(self, redefinition: List) -> None: | ||
|
Contributor
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. there's a few in here that use |
||
| # Any redefinition only affects the main configuration | ||
| homeless_blocks = self.get_blocknames() | ||
| for grp in redefinition: | ||
|
|
@@ -245,15 +245,15 @@ def get_ioc_names(self, include_base: bool = False) -> List[str]: | |
| iocs.extend(cv.iocs) | ||
| return iocs | ||
|
|
||
| def get_ioc_details(self): | ||
| def get_ioc_details(self) -> OrderedDict: | ||
| """Get the details of the IOCs in the configuration. | ||
|
|
||
| Returns: | ||
| A copy of all the configuration IOC details | ||
| """ | ||
| return copy.deepcopy(self._config.iocs) | ||
|
|
||
| def get_component_ioc_details(self): | ||
| def get_component_ioc_details(self) -> Dict: | ||
| """Get the details of the IOCs in any components. | ||
|
|
||
| Returns: | ||
|
|
@@ -266,7 +266,7 @@ def get_component_ioc_details(self): | |
| iocs[ioc_name] = ioc | ||
| return iocs | ||
|
|
||
| def get_all_ioc_details(self): | ||
| def get_all_ioc_details(self) -> Dict: | ||
| """Get the details of the IOCs in the configuration and any components. | ||
|
|
||
| Returns: | ||
|
|
@@ -325,13 +325,17 @@ def _add_ioc( | |
| f"Can't add IOC '{name}' to component '{component}': component does not exist" | ||
| ) | ||
|
|
||
| def _globalmacros_to_list(self) -> List[Any]: | ||
| return [globalmacro.to_dict() for globalmacro in self._config.globalmacros.values()] | ||
|
|
||
| def get_config_details(self) -> Dict[str, Any]: | ||
| """Get the details of the configuration. | ||
|
|
||
| Returns: | ||
| A dictionary containing all the details of the configuration | ||
| """ | ||
| return { | ||
| "globalmacros": self._globalmacros_to_list(), | ||
| "blocks": self._blocks_to_list(True), | ||
| "groups": self._groups_to_list(), | ||
| "iocs": self._iocs_to_list(), | ||
|
|
@@ -364,22 +368,22 @@ def is_dynamic(self) -> bool: | |
| """ | ||
| return self._config.meta.isDynamic | ||
|
|
||
| def configures_block_gateway_and_archiver(self): | ||
| def configures_block_gateway_and_archiver(self) -> bool: | ||
| """ | ||
| Returns: | ||
| (bool): Whether this config has a gwblock.pvlist and block_config.xml to configure the | ||
| block gateway and archiver with. | ||
| """ | ||
| return self._config.meta.configuresBlockGWAndArchiver | ||
|
|
||
| def _comps_to_list(self): | ||
| def _comps_to_list(self) -> List: | ||
| comps = [] | ||
| for component_name, component_value in self._components.items(): | ||
| if component_name.lower() != DEFAULT_COMPONENT.lower(): | ||
| comps.append({"name": component_value.get_name()}) | ||
| return comps | ||
|
|
||
| def _blocks_to_list(self, expand_macro: bool = False): | ||
| def _blocks_to_list(self, expand_macro: bool = False) -> List: | ||
| blocks = self.get_block_details() | ||
| blks = [] | ||
| if blocks is not None: | ||
|
|
@@ -391,7 +395,7 @@ def _blocks_to_list(self, expand_macro: bool = False): | |
| blks.append(b) | ||
| return blks | ||
|
|
||
| def _groups_to_list(self): | ||
| def _groups_to_list(self) -> List: | ||
| groups = self.get_group_details() | ||
| grps = [] | ||
| if groups is not None: | ||
|
|
@@ -404,18 +408,18 @@ def _groups_to_list(self): | |
| grps.append(groups[GRP_NONE.lower()].to_dict()) | ||
| return grps | ||
|
|
||
| def _iocs_to_list(self): | ||
| def _iocs_to_list(self) -> List: | ||
| return [ioc.to_dict() for ioc in self._config.iocs.values()] | ||
|
|
||
| def _iocs_to_list_with_components(self): | ||
| def _iocs_to_list_with_components(self) -> List: | ||
| ioc_list = self._iocs_to_list() | ||
|
|
||
| for component in self._components.values(): | ||
| for ioc in component.iocs.values(): | ||
| ioc_list.append(ioc.to_dict()) | ||
| return ioc_list | ||
|
|
||
| def _to_dict(self, data_list): | ||
| def _to_dict(self, data_list: List) -> dict | None: | ||
| return None if data_list is None else {item["name"]: item for item in data_list} | ||
|
|
||
| def set_config(self, config: Configuration, is_component: bool = False) -> None: | ||
|
|
||
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.
should:
macrosnot type-hinted as being able to be set to None.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.
Changes done