From 1f4009f20318368d15e2072f1cdb97ad9ee3d3df Mon Sep 17 00:00:00 2001 From: "Sode, Adedamola (DLSLtd,RAL,LSCI)" Date: Mon, 12 Jan 2026 10:19:35 +0000 Subject: [PATCH 1/4] Added functionality to fetch files in action buttons in embedded screens to add to the JsonMap --- src/techui_builder/builder.py | 41 +++++++++++++++++++++++++- tests/test_builder.py | 16 +++++----- tests/test_files/test_bob_embedded.bob | 31 +++++++++++++++++++ 3 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 tests/test_files/test_bob_embedded.bob diff --git a/src/techui_builder/builder.py b/src/techui_builder/builder.py index 35da856..3ce0892 100644 --- a/src/techui_builder/builder.py +++ b/src/techui_builder/builder.py @@ -246,11 +246,41 @@ def create_screens(self): def _generate_json_map(self, screen_path: Path, dest_path: Path) -> JsonMap: """Recursively generate JSON map from .bob file tree""" +<<<<<<< HEAD # Create initial node at top of .bob file current_node = JsonMap( str(screen_path.relative_to(self._write_directory)), display_name=None, ) +======= + def _extract_action_button_file_from_embedded( + file_elem: ObjectifiedElement, + ) -> ObjectifiedElement: + file_path = Path(file_elem.text.strip() if file_elem.text else "") + file_path = dest_path.joinpath(file_path) + tree = objectify.parse(file_path.absolute()) + root: ObjectifiedElement = tree.getroot() + + # Find all elements + widgets = [ + w + for w in root.findall(".//widget") + if w.get("type", default=None) == "action_button" + ] + + for widget_elem in widgets: + open_display = _get_action_group(widget_elem) + if open_display is None: + continue + file_elem = open_display.file + return file_elem + return file_elem + + if visited is None: + visited = set() + + current_node = JsonMap(str(screen_path.relative_to(self._write_directory))) +>>>>>>> 1c5aaf5 (Added functionality to fetch files in action buttons in embedded screens to add to the JsonMap) abs_path = screen_path.absolute() @@ -270,7 +300,7 @@ def _generate_json_map(self, screen_path: Path, dest_path: Path) -> JsonMap: for w in root.findall(".//widget") if w.get("type", default=None) # in ["symbol", "embedded", "action_button"] - in ["symbol", "action_button"] + in ["symbol", "action_button", "embedded"] ] for widget_elem in widgets: @@ -284,6 +314,7 @@ def _generate_json_map(self, screen_path: Path, dest_path: Path) -> JsonMap: if open_display is None: continue +<<<<<<< HEAD # Use file, name, and macro elements file_elem = open_display.file name_elem = widget_elem.name.text @@ -292,6 +323,14 @@ def _generate_json_map(self, screen_path: Path, dest_path: Path) -> JsonMap: # case "embedded": # file_elem = widget_elem.file # macro_dict = _get_macros(widget_elem) +======= + macro_dict = _get_macros(open_display) + case "embedded": + file_elem = _extract_action_button_file_from_embedded( + widget_elem.file + ) + macro_dict = _get_macros(widget_elem) +>>>>>>> 1c5aaf5 (Added functionality to fetch files in action buttons in embedded screens to add to the JsonMap) case _: continue diff --git a/tests/test_builder.py b/tests/test_builder.py index 4ac5cbf..8e06b49 100644 --- a/tests/test_builder.py +++ b/tests/test_builder.py @@ -302,16 +302,14 @@ def test_generate_json_map(builder_with_test_files, example_json_map, test_files # TODO: write this test -# def test_generate_json_map_embedded_screen(builder, example_json_map): -# screen_path = Path("tests/test_files/test_bob.bob") -# dest_path = Path("tests/test_files/") +def test_generate_json_map_embedded_screen(builder_with_test_files, example_json_map): + screen_path = Path("tests/test_files/test_bob_embedded.bob").absolute() + dest_path = Path("tests/test_files/") -# # Set widget type to embedded -# ... - -# test_json_map = builder._generate_json_map(screen_path, dest_path) - -# assert test_json_map == example_json_map + test_json_map = builder_with_test_files._generate_json_map(screen_path, dest_path) + example_json_map.file = "test_bob_embedded.bob" + example_json_map.children.append(JsonMap("$(IOC)/pmacAxis.pvi.bob", exists=False)) + assert test_json_map == example_json_map def test_parse_display_name_with_name(builder): diff --git a/tests/test_files/test_bob_embedded.bob b/tests/test_files/test_bob_embedded.bob new file mode 100644 index 0000000..f734932 --- /dev/null +++ b/tests/test_files/test_bob_embedded.bob @@ -0,0 +1,31 @@ + + + + Display + + Detector + test_device + 60 + 150 + 50 + 50 + + + Open Display + test_child_bob.bob + replace + + + $(pv_name) +$(pv_value) +$(actions) + + + Embedded Display + motor_embed.bob + 150 + 120 + 160 + 80 + + From 5db5c12cc4b5a8be8e48907d6d33de828d879421 Mon Sep 17 00:00:00 2001 From: "Sode, Adedamola (DLSLtd,RAL,LSCI)" Date: Fri, 16 Jan 2026 15:19:14 +0000 Subject: [PATCH 2/4] moved function --- src/techui_builder/builder.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/techui_builder/builder.py b/src/techui_builder/builder.py index 3ce0892..a5845af 100644 --- a/src/techui_builder/builder.py +++ b/src/techui_builder/builder.py @@ -246,6 +246,7 @@ def create_screens(self): def _generate_json_map(self, screen_path: Path, dest_path: Path) -> JsonMap: """Recursively generate JSON map from .bob file tree""" +<<<<<<< HEAD <<<<<<< HEAD # Create initial node at top of .bob file current_node = JsonMap( @@ -276,6 +277,8 @@ def _extract_action_button_file_from_embedded( return file_elem return file_elem +======= +>>>>>>> 934c651 (moved function) if visited is None: visited = set() @@ -326,8 +329,8 @@ def _extract_action_button_file_from_embedded( ======= macro_dict = _get_macros(open_display) case "embedded": - file_elem = _extract_action_button_file_from_embedded( - widget_elem.file + file_elem = self._extract_action_button_file_from_embedded( + widget_elem.file, dest_path ) macro_dict = _get_macros(widget_elem) >>>>>>> 1c5aaf5 (Added functionality to fetch files in action buttons in embedded screens to add to the JsonMap) @@ -370,6 +373,7 @@ def _extract_action_button_file_from_embedded( return current_node +<<<<<<< HEAD def _get_macros(self, element: ObjectifiedElement): if hasattr(element, "macros"): macros = element.macros.getchildren() @@ -420,6 +424,30 @@ def _fix_duplicate_names(self, node: JsonMap) -> None: # Recursively fix children self._fix_duplicate_names(child) +======= + def _extract_action_button_file_from_embedded( + self, file_elem: ObjectifiedElement, dest_path: Path + ) -> ObjectifiedElement: + file_path = Path(file_elem.text.strip() if file_elem.text else "") + file_path = dest_path.joinpath(file_path) + tree = objectify.parse(file_path.absolute()) + root: ObjectifiedElement = tree.getroot() + + # Find all elements + widgets = [ + w + for w in root.findall(".//widget") + if w.get("type", default=None) == "action_button" + ] + + for widget_elem in widgets: + open_display = _get_action_group(widget_elem) + if open_display is None: + continue + file_elem = open_display.file + return file_elem + return file_elem +>>>>>>> 934c651 (moved function) def write_json_map( self, From 223a6d8321d0c10c4a39768ed47b17e1ae17f673 Mon Sep 17 00:00:00 2001 From: "Sode, Adedamola (DLSLtd,RAL,LSCI)" Date: Fri, 16 Jan 2026 15:36:37 +0000 Subject: [PATCH 3/4] updated to latest main --- src/techui_builder/builder.py | 91 ++++++++++------------------------- 1 file changed, 25 insertions(+), 66 deletions(-) diff --git a/src/techui_builder/builder.py b/src/techui_builder/builder.py index a5845af..6593f28 100644 --- a/src/techui_builder/builder.py +++ b/src/techui_builder/builder.py @@ -246,44 +246,11 @@ def create_screens(self): def _generate_json_map(self, screen_path: Path, dest_path: Path) -> JsonMap: """Recursively generate JSON map from .bob file tree""" -<<<<<<< HEAD -<<<<<<< HEAD # Create initial node at top of .bob file current_node = JsonMap( str(screen_path.relative_to(self._write_directory)), display_name=None, ) -======= - def _extract_action_button_file_from_embedded( - file_elem: ObjectifiedElement, - ) -> ObjectifiedElement: - file_path = Path(file_elem.text.strip() if file_elem.text else "") - file_path = dest_path.joinpath(file_path) - tree = objectify.parse(file_path.absolute()) - root: ObjectifiedElement = tree.getroot() - - # Find all elements - widgets = [ - w - for w in root.findall(".//widget") - if w.get("type", default=None) == "action_button" - ] - - for widget_elem in widgets: - open_display = _get_action_group(widget_elem) - if open_display is None: - continue - file_elem = open_display.file - return file_elem - return file_elem - -======= ->>>>>>> 934c651 (moved function) - if visited is None: - visited = set() - - current_node = JsonMap(str(screen_path.relative_to(self._write_directory))) ->>>>>>> 1c5aaf5 (Added functionality to fetch files in action buttons in embedded screens to add to the JsonMap) abs_path = screen_path.absolute() @@ -317,23 +284,17 @@ def _extract_action_button_file_from_embedded( if open_display is None: continue -<<<<<<< HEAD # Use file, name, and macro elements file_elem = open_display.file name_elem = widget_elem.name.text macro_dict = self._get_macros(open_display) - # case "embedded": - # file_elem = widget_elem.file - # macro_dict = _get_macros(widget_elem) -======= - macro_dict = _get_macros(open_display) case "embedded": file_elem = self._extract_action_button_file_from_embedded( widget_elem.file, dest_path ) - macro_dict = _get_macros(widget_elem) ->>>>>>> 1c5aaf5 (Added functionality to fetch files in action buttons in embedded screens to add to the JsonMap) + name_elem = widget_elem.name.text + macro_dict = self._get_macros(widget_elem) case _: continue @@ -373,7 +334,29 @@ def _extract_action_button_file_from_embedded( return current_node -<<<<<<< HEAD + def _extract_action_button_file_from_embedded( + self, file_elem: ObjectifiedElement, dest_path: Path + ) -> ObjectifiedElement: + file_path = Path(file_elem.text.strip() if file_elem.text else "") + file_path = dest_path.joinpath(file_path) + tree = objectify.parse(file_path.absolute()) + root: ObjectifiedElement = tree.getroot() + + # Find all elements + widgets = [ + w + for w in root.findall(".//widget") + if w.get("type", default=None) == "action_button" + ] + + for widget_elem in widgets: + open_display = _get_action_group(widget_elem) + if open_display is None: + continue + file_elem = open_display.file + return file_elem + return file_elem + def _get_macros(self, element: ObjectifiedElement): if hasattr(element, "macros"): macros = element.macros.getchildren() @@ -424,30 +407,6 @@ def _fix_duplicate_names(self, node: JsonMap) -> None: # Recursively fix children self._fix_duplicate_names(child) -======= - def _extract_action_button_file_from_embedded( - self, file_elem: ObjectifiedElement, dest_path: Path - ) -> ObjectifiedElement: - file_path = Path(file_elem.text.strip() if file_elem.text else "") - file_path = dest_path.joinpath(file_path) - tree = objectify.parse(file_path.absolute()) - root: ObjectifiedElement = tree.getroot() - - # Find all elements - widgets = [ - w - for w in root.findall(".//widget") - if w.get("type", default=None) == "action_button" - ] - - for widget_elem in widgets: - open_display = _get_action_group(widget_elem) - if open_display is None: - continue - file_elem = open_display.file - return file_elem - return file_elem ->>>>>>> 934c651 (moved function) def write_json_map( self, From bdd97765d46d15436a98959d01efa353cddafc38 Mon Sep 17 00:00:00 2001 From: "Sode, Adedamola (DLSLtd,RAL,LSCI)" Date: Fri, 16 Jan 2026 15:38:21 +0000 Subject: [PATCH 4/4] updated to latest main --- tests/test_builder.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_builder.py b/tests/test_builder.py index 8e06b49..d0cd973 100644 --- a/tests/test_builder.py +++ b/tests/test_builder.py @@ -308,7 +308,11 @@ def test_generate_json_map_embedded_screen(builder_with_test_files, example_json test_json_map = builder_with_test_files._generate_json_map(screen_path, dest_path) example_json_map.file = "test_bob_embedded.bob" - example_json_map.children.append(JsonMap("$(IOC)/pmacAxis.pvi.bob", exists=False)) + example_json_map.children.append( + JsonMap( + "$(IOC)/pmacAxis.pvi.bob", display_name="Embedded Display", exists=False + ) + ) assert test_json_map == example_json_map