custom nodes dialog works for creating, editing, and saving to config in basic case

This commit is contained in:
bharnden 2019-11-07 11:33:40 -08:00
parent 613568ca28
commit 2873c32c23
7 changed files with 78 additions and 21 deletions

View file

@ -42,7 +42,10 @@ def check_directory():
for background in LOCAL_BACKGROUND_PATH.glob("*"):
new_background = BACKGROUNDS_PATH.joinpath(background.name)
shutil.copy(background, new_background)
config = {"servers": [{"name": "example", "address": "127.0.0.1", "port": 50051}]}
config = {
"servers": [{"name": "example", "address": "127.0.0.1", "port": 50051}],
"nodes": [],
}
save_config(config)

View file

@ -8,6 +8,7 @@ from collections import OrderedDict
from core.api.grpc import client, core_pb2
from coretk.coretocanvas import CoreToCanvasMapping
from coretk.dialogs.sessions import SessionsDialog
from coretk.images import Images
from coretk.interface import Interface, InterfaceManager
from coretk.mobilitynodeconfig import MobilityNodeConfig
from coretk.wlannodeconfig import WlanNodeConfig
@ -65,9 +66,10 @@ class CoreServer:
class CustomNode:
def __init__(self, name, image, services):
def __init__(self, name, image, image_file, services):
self.name = name
self.image = image
self.image_file = image_file
self.services = services
@ -83,15 +85,11 @@ class CoreClient:
self.master = app.master
self.interface_helper = None
self.services = {}
self.custom_nodes = {}
# distributed server data
# loaded configuration data
self.servers = {}
for server_config in self.app.config["servers"]:
server = CoreServer(
server_config["name"], server_config["address"], server_config["port"]
)
self.servers[server.name] = server
self.custom_nodes = {}
self.read_config()
# data for managing the current session
self.nodes = {}
@ -106,6 +104,23 @@ class CoreClient:
self.mobilityconfig_management = MobilityNodeConfig()
self.emane_config = None
def read_config(self):
# read distributed server
for server_config in self.app.config["servers"]:
server = CoreServer(
server_config["name"], server_config["address"], server_config["port"]
)
self.servers[server.name] = server
# read custom nodes
for node in self.app.config["nodes"]:
image_file = node["image"]
image = Images.get_custom(image_file)
custom_node = CustomNode(
node["name"], image, image_file, set(node["services"])
)
self.custom_nodes[custom_node.name] = custom_node
def handle_events(self, event):
logging.info("event: %s", event)
if event.link_event is not None:

View file

@ -1,8 +1,11 @@
import logging
import tkinter as tk
from pathlib import Path
from coretk import appdirs
from coretk.coreclient import CustomNode
from coretk.dialogs.dialog import Dialog
from coretk.dialogs.nodeicon import IconDialog
from coretk.dialogs.icondialog import IconDialog
from coretk.widgets import CheckboxList, ListboxScroll
@ -86,6 +89,7 @@ class CustomNodesDialog(Dialog):
self.name = tk.StringVar()
self.image_button = None
self.image = None
self.image_file = None
self.services = set()
self.selected = None
self.selected_index = None
@ -145,17 +149,25 @@ class CustomNodesDialog(Dialog):
for i in range(2):
frame.columnconfigure(i, weight=1)
button = tk.Button(frame, text="Save", command=self.click_edit)
button = tk.Button(frame, text="Save", command=self.click_save)
button.grid(row=0, column=0, sticky="ew")
button = tk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew")
def reset_values(self):
self.name.set("")
self.image = None
self.image_file = None
self.services = set()
self.image_button.config(image="")
def click_icon(self):
dialog = IconDialog(self, self.app, self.name.get(), self.image)
dialog.show()
if dialog.image:
self.image = dialog.image
self.image_file = dialog.file_path.get()
self.image_button.config(image=self.image)
def click_services(self):
@ -164,22 +176,44 @@ class CustomNodesDialog(Dialog):
if dialog.current_services is not None:
self.services = dialog.current_services
def click_save(self):
self.app.config["nodes"].clear()
for name in sorted(self.app.core.custom_nodes):
custom_node = self.app.core.custom_nodes[name]
self.app.config["nodes"].append(
{
"name": custom_node.name,
"image": custom_node.image_file,
"services": list(custom_node.services),
}
)
logging.info("saving custom nodes: %s", self.app.config["nodes"])
appdirs.save_config(self.app.config)
def click_create(self):
name = self.name.get()
if name not in self.app.core.custom_nodes:
custom_node = CustomNode(name, self.image, self.services)
custom_node = CustomNode(
name, self.image, Path(self.image_file).name, set(self.services)
)
self.app.core.custom_nodes[name] = custom_node
self.nodes_list.listbox.insert(tk.END, name)
self.reset_values()
def reset_values(self):
self.name.set("")
self.image = None
self.services = set()
self.image_button.config(image="")
def click_edit(self):
pass
name = self.name.get()
if self.selected:
previous_name = self.selected
self.selected = name
custom_node = self.app.core.custom_nodes.pop(previous_name)
custom_node.name = name
custom_node.image = self.image
custom_node.image_file = Path(self.image_file).name
custom_node.services = self.services
self.app.core.custom_nodes[name] = custom_node
self.nodes_list.listbox.delete(self.selected_index)
self.nodes_list.listbox.insert(self.selected_index, name)
self.nodes_list.listbox.selection_set(self.selected_index)
def click_delete(self):
if self.selected and self.selected in self.app.core.custom_nodes:
@ -198,6 +232,7 @@ class CustomNodesDialog(Dialog):
self.name.set(custom_node.name)
self.services = custom_node.services
self.image = custom_node.image
self.image_file = custom_node.image_file
self.image_button.config(image=self.image)
self.edit_button.config(state=tk.NORMAL)
self.delete_button.config(state=tk.NORMAL)

View file

@ -2,7 +2,7 @@ import tkinter as tk
from tkinter import ttk
from coretk.dialogs.dialog import Dialog
from coretk.dialogs.nodeicon import IconDialog
from coretk.dialogs.icondialog import IconDialog
from coretk.dialogs.nodeservice import NodeServicesDialog
NETWORKNODETYPES = ["switch", "hub", "wlan", "rj45", "tunnel"]

View file

@ -5,7 +5,7 @@ wlan configuration
import tkinter as tk
from coretk.dialogs.dialog import Dialog
from coretk.dialogs.nodeicon import IconDialog
from coretk.dialogs.icondialog import IconDialog
class WlanConfigDialog(Dialog):

View file

@ -29,6 +29,10 @@ class Images:
def get(cls, image):
return cls.images[image.value]
@classmethod
def get_custom(cls, name):
return cls.images[name]
@classmethod
def convert_type_and_model_to_image(cls, node_type, node_model):
"""