From cd0827af07f980d45399112d366ef78609a4ebc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Wed, 19 Jun 2024 16:54:49 +0200 Subject: [PATCH] Fixed tree generation to include id and uuid on managed objects --- server/src/uds/core/ui/user_interface.py | 12 ++++++++---- server/src/uds/management/commands/tree.py | 10 ++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/server/src/uds/core/ui/user_interface.py b/server/src/uds/core/ui/user_interface.py index d72995ec1..671a6cba1 100644 --- a/server/src/uds/core/ui/user_interface.py +++ b/server/src/uds/core/ui/user_interface.py @@ -1713,17 +1713,21 @@ class UserInterface(metaclass=UserInterfaceType): # Values can contain invalid characters, so we log every single char # logger.info('Invalid serialization data on {0} {1}'.format(self, values.encode('hex'))) - def gui_description(self) -> list[types.ui.GuiElement]: + def gui_description(self, *, skip_init_gui: bool = False) -> list[types.ui.GuiElement]: """ This simple method generates the theGui description needed by the administration client, so it can represent it at user interface and manage it. Args: - obj: If any, object that will get its "initGui" invoked - This will only happen (not to be None) in Services. + skip_init_gui: If True, init_gui will not be called + + Note: + skip_init_gui is used to avoid calling init_gui when we are not going to use the result + This is used, for example, when exporting data, generating the tree, etc... """ - self.init_gui() # We give the "oportunity" to fill necesary theGui data before providing it to client + if not skip_init_gui: + self.init_gui() # We give the "oportunity" to fill necesary theGui data before providing it to client res: list[types.ui.GuiElement] = [] for key, val in self._gui.items(): diff --git a/server/src/uds/management/commands/tree.py b/server/src/uds/management/commands/tree.py index 460196084..4c16b0946 100644 --- a/server/src/uds/management/commands/tree.py +++ b/server/src/uds/management/commands/tree.py @@ -60,14 +60,14 @@ def get_serialized_from_managed_object( ) -> collections.abc.Mapping[str, typing.Any]: try: obj: 'Module' = mod.get_instance() - gui_types: dict[str, str] = {i['name']: str(i['gui']['type']) for i in obj.gui_description()} + gui_types: dict[str, str] = {i['name']: str(i['gui']['type']) for i in obj.gui_description(skip_init_gui=True)} values = obj.get_fields_as_dict() # Remove password fields for fld, fld_type in gui_types.items(): if fld_type == 'password': values[fld] = '********' # Some names are know "secret data" - for i in ('serverCertificate', 'privateKey'): + for i in ('serverCertificate', 'privateKey', 'server_certificate', 'private_key'): if i in values: values[i] = '********' # remove removable fields @@ -75,6 +75,8 @@ def get_serialized_from_managed_object( if i in values: del values[i] # Append type_name to list + values['id'] = mod.id + values['uuid'] = mod.uuid values['type_name'] = str(obj.type_name) values['comments'] = mod.comments @@ -166,8 +168,8 @@ class Command(BaseCommand): 'id': item.uuid, 'unique_id': item.unique_id, 'friendly_name': item.friendly_name, - 'state': types.states.State.from_str(item.state).localized, - 'os_state': types.states.State.from_str(item.os_state).localized, + 'state': str(types.states.State.from_str(item.state).localized), + 'os_state': str(types.states.State.from_str(item.os_state).localized), 'state_date': item.state_date, 'creation_date': item.creation_date, 'revision': item.publication and item.publication.revision or '',