From b04da98f4480aefc5f8fb9880a8c1b38cab88b32 Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Tue, 21 Apr 2020 11:13:41 -0700 Subject: [PATCH] pygui updated config services to be associated with nodes directly and copyable --- daemon/core/gui/coreclient.py | 16 +++++---- .../core/gui/dialogs/configserviceconfig.py | 32 ++++++++++------- daemon/core/gui/dialogs/nodeconfigservice.py | 36 +++++++++---------- daemon/core/gui/graph/graph.py | 2 ++ daemon/core/gui/graph/node.py | 1 + 5 files changed, 49 insertions(+), 38 deletions(-) diff --git a/daemon/core/gui/coreclient.py b/daemon/core/gui/coreclient.py index e026b44b..7c69f954 100644 --- a/daemon/core/gui/coreclient.py +++ b/daemon/core/gui/coreclient.py @@ -91,7 +91,6 @@ class CoreClient: self.links = {} self.hooks = {} self.emane_config = None - self.config_service_configs = {} self.mobility_players = {} self.handling_throughputs = None self.handling_events = None @@ -341,10 +340,10 @@ class CoreClient: # get config service configurations response = self.client.get_node_config_service_configs(self.session_id) for config in response.configs: - node_configs = self.config_service_configs.setdefault( - config.node_id, {} + canvas_node = self.canvas_nodes[config.node_id] + service_config = canvas_node.config_service_configs.setdefault( + config.name, {} ) - service_config = node_configs.setdefault(config.name, {}) if config.templates: service_config["templates"] = config.templates if config.config: @@ -989,8 +988,13 @@ class CoreClient: self ) -> List[configservices_pb2.ConfigServiceConfig]: config_service_protos = [] - for node_id, node_config in self.config_service_configs.items(): - for name, service_config in node_config.items(): + for canvas_node in self.canvas_nodes.values(): + if not NodeUtils.is_container_node(canvas_node.core_node.type): + continue + if not canvas_node.config_service_configs: + continue + node_id = canvas_node.core_node.id + for name, service_config in canvas_node.config_service_configs.items(): config = service_config.get("config", {}) config_proto = configservices_pb2.ConfigServiceConfig( node_id=node_id, diff --git a/daemon/core/gui/dialogs/configserviceconfig.py b/daemon/core/gui/dialogs/configserviceconfig.py index 36c4ccfe..2239034e 100644 --- a/daemon/core/gui/dialogs/configserviceconfig.py +++ b/daemon/core/gui/dialogs/configserviceconfig.py @@ -16,21 +16,26 @@ from core.gui.widgets import CodeText, ConfigFrame, ListboxScroll if TYPE_CHECKING: from core.gui.app import Application + from core.gui.graph.node import CanvasNode class ConfigServiceConfigDialog(Dialog): def __init__( - self, master: Any, app: "Application", service_name: str, node_id: int + self, + master: Any, + app: "Application", + service_name: str, + canvas_node: "CanvasNode", + node_id: int, ): title = f"{service_name} Config Service" super().__init__(master, app, title, modal=True) self.master = master self.app = app self.core = app.core + self.canvas_node = canvas_node self.node_id = node_id self.service_name = service_name - self.service_configs = app.core.config_service_configs - self.radiovar = tk.IntVar() self.radiovar.set(2) self.directories = [] @@ -95,9 +100,9 @@ class ConfigServiceConfigDialog(Dialog): self.modes = sorted(x.name for x in response.modes) self.mode_configs = {x.name: x.config for x in response.modes} - node_configs = self.service_configs.get(self.node_id, {}) - service_config = node_configs.get(self.service_name, {}) - + service_config = self.canvas_node.config_service_configs.get( + self.service_name, {} + ) self.config = response.config self.default_config = {x.name: x.value for x in self.config.values()} custom_config = service_config.get("config") @@ -313,15 +318,15 @@ class ConfigServiceConfigDialog(Dialog): def click_apply(self): current_listbox = self.master.current.listbox if not self.is_custom(): - if self.node_id in self.service_configs: - self.service_configs[self.node_id].pop(self.service_name, None) + self.canvas_node.config_service_configs.pop(self.service_name, None) current_listbox.itemconfig(current_listbox.curselection()[0], bg="") self.destroy() return try: - node_config = self.service_configs.setdefault(self.node_id, {}) - service_config = node_config.setdefault(self.service_name, {}) + service_config = self.canvas_node.config_service_configs.setdefault( + self.service_name, {} + ) if self.config_frame: self.config_frame.parse_config() service_config["config"] = { @@ -365,9 +370,10 @@ class ConfigServiceConfigDialog(Dialog): return has_custom_templates or has_custom_config def click_defaults(self): - if self.node_id in self.service_configs: - node_config = self.service_configs.get(self.node_id, {}) - node_config.pop(self.service_name, None) + self.canvas_node.config_service_configs.pop(self.service_name, None) + logging.info( + "cleared config service config: %s", self.canvas_node.config_service_configs + ) self.temp_service_files = dict(self.original_service_files) filename = self.templates_combobox.get() self.template_text.text.delete(1.0, "end") diff --git a/daemon/core/gui/dialogs/nodeconfigservice.py b/daemon/core/gui/dialogs/nodeconfigservice.py index 8bdbc539..c86d8887 100644 --- a/daemon/core/gui/dialogs/nodeconfigservice.py +++ b/daemon/core/gui/dialogs/nodeconfigservice.py @@ -70,12 +70,10 @@ class NodeConfigServiceDialog(Dialog): label_frame.grid(row=0, column=2, sticky="nsew") label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) + self.current = ListboxScroll(label_frame) self.current.grid(sticky="nsew") - for service in sorted(self.current_services): - self.current.listbox.insert(tk.END, service) - if self.is_custom_service(service): - self.current.listbox.itemconfig(tk.END, bg="green") + self.draw_current_services() frame = ttk.Frame(self.top) frame.grid(stick="ew") @@ -108,24 +106,22 @@ class NodeConfigServiceDialog(Dialog): self.current_services.add(name) elif not var.get() and name in self.current_services: self.current_services.remove(name) - self.current.listbox.delete(0, tk.END) - for name in sorted(self.current_services): - self.current.listbox.insert(tk.END, name) - if self.is_custom_service(name): - self.current.listbox.itemconfig(tk.END, bg="green") + self.draw_current_services() self.canvas_node.core_node.config_services[:] = self.current_services def click_configure(self): current_selection = self.current.listbox.curselection() if len(current_selection): dialog = ConfigServiceConfigDialog( - master=self, - app=self.app, - service_name=self.current.listbox.get(current_selection[0]), - node_id=self.node_id, + self, + self.app, + self.current.listbox.get(current_selection[0]), + self.canvas_node, + self.node_id, ) if not dialog.has_error: dialog.show() + self.draw_current_services() else: messagebox.showinfo( "Config Service Configuration", @@ -133,6 +129,13 @@ class NodeConfigServiceDialog(Dialog): parent=self, ) + def draw_current_services(self): + self.current.listbox.delete(0, tk.END) + for name in sorted(self.current_services): + self.current.listbox.insert(tk.END, name) + if self.is_custom_service(name): + self.current.listbox.itemconfig(tk.END, bg="green") + def click_save(self): self.canvas_node.core_node.config_services[:] = self.current_services logging.info( @@ -156,9 +159,4 @@ class NodeConfigServiceDialog(Dialog): return def is_custom_service(self, service: str) -> bool: - node_configs = self.app.core.config_service_configs.get(self.node_id, {}) - service_config = node_configs.get(service) - if node_configs and service_config: - return True - else: - return False + return service in self.canvas_node.config_service_configs diff --git a/daemon/core/gui/graph/graph.py b/daemon/core/gui/graph/graph.py index 5d66667e..e4963f45 100644 --- a/daemon/core/gui/graph/graph.py +++ b/daemon/core/gui/graph/graph.py @@ -925,11 +925,13 @@ class CanvasGraph(tk.Canvas): # copy configurations and services node.core_node.services[:] = canvas_node.core_node.services + node.core_node.config_services[:] = canvas_node.core_node.config_services node.emane_model_configs = deepcopy(canvas_node.emane_model_configs) node.wlan_config = deepcopy(canvas_node.wlan_config) node.mobility_config = deepcopy(canvas_node.mobility_config) node.service_configs = deepcopy(canvas_node.service_configs) node.service_file_configs = deepcopy(canvas_node.service_file_configs) + node.config_service_configs = deepcopy(canvas_node.config_service_configs) # add new node to modified_service_nodes set if that set contains the # to_copy node diff --git a/daemon/core/gui/graph/node.py b/daemon/core/gui/graph/node.py index e788b584..90896284 100644 --- a/daemon/core/gui/graph/node.py +++ b/daemon/core/gui/graph/node.py @@ -64,6 +64,7 @@ class CanvasNode: self.mobility_config = {} self.service_configs = {} self.service_file_configs = {} + self.config_service_configs = {} self.setup_bindings() def setup_bindings(self):