Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion BlockServer/config/configuration.py
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.
Expand All @@ -16,16 +16,17 @@

"""Contains all the code for defining a configuration or component"""

from collections import OrderedDict
from typing import Dict

from BlockServer.config.block import Block
from BlockServer.config.globalmacros import Globalmacro
from BlockServer.config.group import Group
from BlockServer.config.ioc import IOC
from BlockServer.config.metadata import MetaData
from BlockServer.core.constants import GRP_NONE
from server_common.helpers import PVPREFIX_MACRO
from server_common.utilities import print_and_log

Check failure on line 29 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (I001)

BlockServer\config\configuration.py:19:1: I001 Import block is un-sorted or un-formatted


class Configuration:
Expand All @@ -39,9 +40,10 @@
meta (MetaData): The meta-data for the configuration
components (OrderedDict): The components which are part of the configuration
is_component (bool): Whether it is actually a component
globalmacros (OrderedDict): The globalmacros for the configuration
"""

def __init__(self, macros: Dict):

Check failure on line 46 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (ANN204)

BlockServer\config\configuration.py:46:9: ANN204 Missing return type annotation for special method `__init__`
"""Constructor.

Args:
Expand All @@ -55,8 +57,9 @@
self.meta = MetaData("")
self.components = OrderedDict()
self.is_component = False
self.globalmacros = OrderedDict()

def add_block(self, name: str, pv: str, group: str = GRP_NONE, local: bool = True, **kwargs):

Check failure on line 62 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (ANN003)

BlockServer\config\configuration.py:62:88: ANN003 Missing type annotation for `**kwargs`

Check failure on line 62 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (ANN201)

BlockServer\config\configuration.py:62:9: ANN201 Missing return type annotation for public function `add_block`
"""Add a block to the configuration.

Args:
Expand All @@ -82,7 +85,7 @@
self.groups[group.lower()] = Group(group)
self.groups[group.lower()].blocks.append(name)

def add_ioc(

Check failure on line 88 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (ANN201)

BlockServer\config\configuration.py:88:9: ANN201 Missing return type annotation for public function `add_ioc`
self,
name: str,
component: str = None,
Expand All @@ -92,7 +95,7 @@
pvs: Dict = None,
pvsets: Dict = None,
simlevel: str = None,
remotePvPrefix: str = None,

Check failure on line 98 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (N803)

BlockServer\config\configuration.py:98:9: N803 Argument name `remotePvPrefix` should be lowercase
):
"""Add an IOC to the configuration.

Expand Down Expand Up @@ -128,10 +131,33 @@
self.meta.name.decode("utf-8") if isinstance(self.meta.name, bytes) else self.meta.name
)

def set_name(self, name: str):

Check failure on line 134 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (ANN201)

BlockServer\config\configuration.py:134:9: ANN201 Missing return type annotation for public function `set_name`
"""Sets the configuration's name.

Args:
name: The new name for the configuration
"""
self.meta.name = name

def add_globalmacro(

Check failure on line 142 in BlockServer/config/configuration.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (ANN201)

BlockServer\config\configuration.py:142:9: ANN201 Missing return type annotation for public function `add_globalmacro`
self,
name: str,
macros: Dict,
):
"""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 self.globalmacros.keys():
print_and_log(
f"Warning: IOC '{name}' is already part of the configuration. Not adding it again."
)
else:
print_and_log(
f"Info: Global macros for IOC '{name}' is being added to the configuration."
)
self.globalmacros[name.upper()] = Globalmacro(name, macros)
119 changes: 119 additions & 0 deletions BlockServer/config/globalmacros.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# 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 typing import Any, Dict, List, Union

Check failure on line 18 in BlockServer/config/globalmacros.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (F401)

BlockServer\config\globalmacros.py:18:37: F401 `typing.Union` imported but unused
from collections import OrderedDict

Check failure on line 19 in BlockServer/config/globalmacros.py

View workflow job for this annotation

GitHub Actions / call-workflow / ruff

Ruff (I001)

BlockServer\config\globalmacros.py:17:1: I001 Import block is un-sorted or un-formatted


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],
):
"""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, 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,
}

def get(self, name):
return self.__getattribute__(name)

def __getitem__(self, name):
return self.__getattribute__(name)


class GlobalmacroHelper:
"""Converts global macro data to Globalmacro Object.

Consists of static methods only.
"""

@staticmethod
def row_to_globalmacro(globalmacros: Dict, row: str):
"""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 = IOC_SEPARATOR
# 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
macro = ioc_macro

if ioc in globalmacros:
to_add_ioc = globalmacros[ioc]
to_add_ioc[macro] = value.strip()
globalmacros[ioc] = to_add_ioc
6 changes: 5 additions & 1 deletion BlockServer/core/config_holder.py
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.
Expand Down Expand Up @@ -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):
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(),
Expand Down
3 changes: 2 additions & 1 deletion BlockServer/core/constants.py
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.
Expand Down Expand Up @@ -79,5 +79,6 @@
FILENAME_META = "meta.xml"
FILENAME_SCREENS = "screens.xml"
FILENAME_BANNER = "banner.xml"
FILENAME_GLOBALS = "globals.txt"

SCHEMA_FOR = [FILENAME_BLOCKS, FILENAME_GROUPS, FILENAME_IOCS, FILENAME_COMPONENTS, FILENAME_META]
16 changes: 15 additions & 1 deletion BlockServer/fileIO/file_manager.py
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.
Expand All @@ -21,6 +21,7 @@

from BlockServer.config.configuration import Configuration, MetaData
from BlockServer.config.group import Group
from BlockServer.config.globalmacros import Globalmacro, GlobalmacroHelper
from BlockServer.config.xml_converter import ConfigurationXmlConverter
from BlockServer.core.constants import (
DEFAULT_COMPONENT,
Expand All @@ -32,6 +33,7 @@
FILENAME_IOCS,
FILENAME_META,
GRP_NONE,
FILENAME_GLOBALS,
)
from server_common.file_path_manager import FILEPATH_MANAGER
from BlockServer.fileIO.schema_checker import (
Expand Down Expand Up @@ -161,12 +163,24 @@ def load_config(self, name, macros, is_component):
"Files missing in " + name + " (%s)" % ",".join(list(config_files_missing))
)

# Import the Global macros
globals_path = os.path.join(FILEPATH_MANAGER.config_root_dir, FILENAME_GLOBALS)
globalmacros = {}
if os.path.isfile(globals_path):
with open(globals_path, "r") as file:
for line in file:
GlobalmacroHelper.row_to_globalmacro(globalmacros, line.strip())

# Set properties in the config
configuration.blocks = blocks
configuration.groups = groups
configuration.iocs = iocs
configuration.components = components
configuration.meta = meta
# configuration.globalmacros = globalmacros
for key, value in globalmacros.items():
configuration.add_globalmacro(key, value)

print_and_log(f"Configuration ('{name}') loaded.")
return configuration

Expand Down
Loading