pygui: changes around using session.nodes instead of canvas_nodes when possible
This commit is contained in:
parent
588afaad13
commit
27495cbda1
5 changed files with 58 additions and 67 deletions
|
@ -118,6 +118,12 @@ class CoreClient:
|
||||||
self.setup_cpu_usage()
|
self.setup_cpu_usage()
|
||||||
return self._client
|
return self._client
|
||||||
|
|
||||||
|
def set_canvas_node(self, node: Node, canvas_node: CanvasNode) -> None:
|
||||||
|
self.canvas_nodes[node.id] = canvas_node
|
||||||
|
|
||||||
|
def get_canvas_node(self, node_id: int) -> CanvasNode:
|
||||||
|
return self.canvas_nodes[node_id]
|
||||||
|
|
||||||
def reset(self) -> None:
|
def reset(self) -> None:
|
||||||
# helpers
|
# helpers
|
||||||
self.ifaces_manager.reset()
|
self.ifaces_manager.reset()
|
||||||
|
@ -231,18 +237,21 @@ class CoreClient:
|
||||||
|
|
||||||
def handle_node_event(self, event: NodeEvent) -> None:
|
def handle_node_event(self, event: NodeEvent) -> None:
|
||||||
logging.debug("node event: %s", event)
|
logging.debug("node event: %s", event)
|
||||||
|
node = event.node
|
||||||
if event.message_type == MessageType.NONE:
|
if event.message_type == MessageType.NONE:
|
||||||
canvas_node = self.canvas_nodes[event.node.id]
|
canvas_node = self.canvas_nodes[node.id]
|
||||||
x = event.node.position.x
|
x = node.position.x
|
||||||
y = event.node.position.y
|
y = node.position.y
|
||||||
canvas_node.move(x, y)
|
canvas_node.move(x, y)
|
||||||
elif event.message_type == MessageType.DELETE:
|
elif event.message_type == MessageType.DELETE:
|
||||||
canvas_node = self.canvas_nodes[event.node.id]
|
canvas_node = self.canvas_nodes[node.id]
|
||||||
self.app.canvas.clear_selection()
|
self.app.canvas.clear_selection()
|
||||||
self.app.canvas.select_object(canvas_node.id)
|
self.app.canvas.select_object(canvas_node.id)
|
||||||
self.app.canvas.delete_selected_objects()
|
self.app.canvas.delete_selected_objects()
|
||||||
elif event.message_type == MessageType.ADD:
|
elif event.message_type == MessageType.ADD:
|
||||||
self.app.canvas.add_core_node(event.node)
|
if node.id in self.session.nodes:
|
||||||
|
logging.error("core node already exists: %s", node)
|
||||||
|
self.app.canvas.add_core_node(node)
|
||||||
else:
|
else:
|
||||||
logging.warning("unknown node event: %s", event)
|
logging.warning("unknown node event: %s", event)
|
||||||
|
|
||||||
|
@ -463,10 +472,9 @@ class CoreClient:
|
||||||
|
|
||||||
def start_session(self) -> Tuple[bool, List[str]]:
|
def start_session(self) -> Tuple[bool, List[str]]:
|
||||||
self.ifaces_manager.reset_mac()
|
self.ifaces_manager.reset_mac()
|
||||||
nodes = [x.core_node.to_proto() for x in self.canvas_nodes.values()]
|
nodes = [x.to_proto() for x in self.session.nodes.values()]
|
||||||
links = []
|
links = []
|
||||||
for edge in self.links.values():
|
for link in self.session.links:
|
||||||
link = edge.link
|
|
||||||
if link.iface1 and not link.iface1.mac:
|
if link.iface1 and not link.iface1.mac:
|
||||||
link.iface1.mac = self.ifaces_manager.next_mac()
|
link.iface1.mac = self.ifaces_manager.next_mac()
|
||||||
if link.iface2 and not link.iface2.mac:
|
if link.iface2 and not link.iface2.mac:
|
||||||
|
@ -674,13 +682,12 @@ class CoreClient:
|
||||||
"""
|
"""
|
||||||
create nodes and links that have not been created yet
|
create nodes and links that have not been created yet
|
||||||
"""
|
"""
|
||||||
node_protos = [x.core_node.to_proto() for x in self.canvas_nodes.values()]
|
|
||||||
link_protos = [x.link.to_proto() for x in self.links.values()]
|
|
||||||
self.client.set_session_state(self.session.id, SessionState.DEFINITION.value)
|
self.client.set_session_state(self.session.id, SessionState.DEFINITION.value)
|
||||||
for node_proto in node_protos:
|
for node in self.session.nodes.values():
|
||||||
response = self.client.add_node(self.session.id, node_proto)
|
response = self.client.add_node(self.session.id, node.to_proto())
|
||||||
logging.debug("create node: %s", response)
|
logging.debug("created node: %s", response)
|
||||||
for link_proto in link_protos:
|
for link in self.session.links:
|
||||||
|
link_proto = link.to_proto()
|
||||||
response = self.client.add_link(
|
response = self.client.add_link(
|
||||||
self.session.id,
|
self.session.id,
|
||||||
link_proto.node1_id,
|
link_proto.node1_id,
|
||||||
|
@ -689,7 +696,7 @@ class CoreClient:
|
||||||
link_proto.iface2,
|
link_proto.iface2,
|
||||||
link_proto.options,
|
link_proto.options,
|
||||||
)
|
)
|
||||||
logging.debug("create link: %s", response)
|
logging.debug("created link: %s", response)
|
||||||
|
|
||||||
def send_data(self) -> None:
|
def send_data(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -762,7 +769,7 @@ class CoreClient:
|
||||||
"""
|
"""
|
||||||
i = 1
|
i = 1
|
||||||
while True:
|
while True:
|
||||||
if i not in self.canvas_nodes:
|
if i not in self.session.nodes:
|
||||||
break
|
break
|
||||||
i += 1
|
i += 1
|
||||||
return i
|
return i
|
||||||
|
@ -816,18 +823,20 @@ class CoreClient:
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
)
|
)
|
||||||
|
self.session.nodes[node.id] = node
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def deleted_graph_nodes(self, canvas_nodes: List[CanvasNode]) -> None:
|
def deleted_canvas_nodes(self, canvas_nodes: List[CanvasNode]) -> None:
|
||||||
"""
|
"""
|
||||||
remove the nodes selected by the user and anything related to that node
|
remove the nodes selected by the user and anything related to that node
|
||||||
such as link, configurations, interfaces
|
such as link, configurations, interfaces
|
||||||
"""
|
"""
|
||||||
for canvas_node in canvas_nodes:
|
for canvas_node in canvas_nodes:
|
||||||
node_id = canvas_node.core_node.id
|
node = canvas_node.core_node
|
||||||
del self.canvas_nodes[node_id]
|
del self.canvas_nodes[node.id]
|
||||||
|
del self.session.nodes[node.id]
|
||||||
|
|
||||||
def deleted_graph_edges(self, edges: Iterable[CanvasEdge]) -> None:
|
def deleted_canvas_edges(self, edges: Iterable[CanvasEdge]) -> None:
|
||||||
links = []
|
links = []
|
||||||
for edge in edges:
|
for edge in edges:
|
||||||
del self.links[edge.token]
|
del self.links[edge.token]
|
||||||
|
@ -861,20 +870,19 @@ class CoreClient:
|
||||||
"""
|
"""
|
||||||
src_node = canvas_src_node.core_node
|
src_node = canvas_src_node.core_node
|
||||||
dst_node = canvas_dst_node.core_node
|
dst_node = canvas_dst_node.core_node
|
||||||
|
|
||||||
# determine subnet
|
|
||||||
self.ifaces_manager.determine_subnets(canvas_src_node, canvas_dst_node)
|
self.ifaces_manager.determine_subnets(canvas_src_node, canvas_dst_node)
|
||||||
|
|
||||||
src_iface = None
|
src_iface = None
|
||||||
if NodeUtils.is_container_node(src_node.type):
|
if NodeUtils.is_container_node(src_node.type):
|
||||||
src_iface = self.create_iface(canvas_src_node)
|
src_iface = self.create_iface(canvas_src_node)
|
||||||
self.iface_to_edge[(src_node.id, src_iface.id)] = edge.token
|
self.iface_to_edge[(src_node.id, src_iface.id)] = edge.token
|
||||||
|
edge.src_iface = src_iface
|
||||||
|
canvas_src_node.ifaces[src_iface.id] = src_iface
|
||||||
dst_iface = None
|
dst_iface = None
|
||||||
if NodeUtils.is_container_node(dst_node.type):
|
if NodeUtils.is_container_node(dst_node.type):
|
||||||
dst_iface = self.create_iface(canvas_dst_node)
|
dst_iface = self.create_iface(canvas_dst_node)
|
||||||
self.iface_to_edge[(dst_node.id, dst_iface.id)] = edge.token
|
self.iface_to_edge[(dst_node.id, dst_iface.id)] = edge.token
|
||||||
|
edge.dst_iface = dst_iface
|
||||||
|
canvas_dst_node.ifaces[dst_iface.id] = dst_iface
|
||||||
link = Link(
|
link = Link(
|
||||||
type=LinkType.WIRED,
|
type=LinkType.WIRED,
|
||||||
node1_id=src_node.id,
|
node1_id=src_node.id,
|
||||||
|
@ -882,17 +890,9 @@ class CoreClient:
|
||||||
iface1=src_iface,
|
iface1=src_iface,
|
||||||
iface2=dst_iface,
|
iface2=dst_iface,
|
||||||
)
|
)
|
||||||
# assign after creating link proto, since interfaces are copied
|
|
||||||
if src_iface:
|
|
||||||
iface1 = link.iface1
|
|
||||||
edge.src_iface = iface1
|
|
||||||
canvas_src_node.ifaces[iface1.id] = iface1
|
|
||||||
if dst_iface:
|
|
||||||
iface2 = link.iface2
|
|
||||||
edge.dst_iface = iface2
|
|
||||||
canvas_dst_node.ifaces[iface2.id] = iface2
|
|
||||||
edge.set_link(link)
|
edge.set_link(link)
|
||||||
self.links[edge.token] = edge
|
self.links[edge.token] = edge
|
||||||
|
self.session.links.append(link)
|
||||||
logging.info("Add link between %s and %s", src_node.name, dst_node.name)
|
logging.info("Add link between %s and %s", src_node.name, dst_node.name)
|
||||||
|
|
||||||
def get_wlan_configs_proto(self) -> List[wlan_pb2.WlanConfig]:
|
def get_wlan_configs_proto(self) -> List[wlan_pb2.WlanConfig]:
|
||||||
|
|
|
@ -87,22 +87,19 @@ class FindDialog(Dialog):
|
||||||
"""
|
"""
|
||||||
node_name = self.find_text.get().strip()
|
node_name = self.find_text.get().strip()
|
||||||
self.clear_treeview_items()
|
self.clear_treeview_items()
|
||||||
for node_id, node in sorted(
|
for node in self.app.core.session.nodes.values():
|
||||||
self.app.core.canvas_nodes.items(), key=lambda x: x[0]
|
name = node.name
|
||||||
):
|
|
||||||
name = node.core_node.name
|
|
||||||
if not node_name or node_name == name:
|
if not node_name or node_name == name:
|
||||||
pos_x = round(node.core_node.position.x, 1)
|
pos_x = round(node.position.x, 1)
|
||||||
pos_y = round(node.core_node.position.y, 1)
|
pos_y = round(node.position.y, 1)
|
||||||
# TODO: I am not sure what to insert for Detail column
|
# TODO: I am not sure what to insert for Detail column
|
||||||
# leaving it blank for now
|
# leaving it blank for now
|
||||||
self.tree.insert(
|
self.tree.insert(
|
||||||
"",
|
"",
|
||||||
tk.END,
|
tk.END,
|
||||||
text=str(node_id),
|
text=str(node.id),
|
||||||
values=(node_id, name, f"<{pos_x}, {pos_y}>", ""),
|
values=(node.id, name, f"<{pos_x}, {pos_y}>", ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
results = self.tree.get_children("")
|
results = self.tree.get_children("")
|
||||||
if results:
|
if results:
|
||||||
self.tree.selection_set(results[0])
|
self.tree.selection_set(results[0])
|
||||||
|
@ -121,7 +118,7 @@ class FindDialog(Dialog):
|
||||||
if item:
|
if item:
|
||||||
self.app.canvas.delete("find")
|
self.app.canvas.delete("find")
|
||||||
node_id = int(self.tree.item(item, "text"))
|
node_id = int(self.tree.item(item, "text"))
|
||||||
canvas_node = self.app.core.canvas_nodes[node_id]
|
canvas_node = self.app.core.get_canvas_node(node_id)
|
||||||
|
|
||||||
x0, y0, x1, y1 = self.app.canvas.bbox(canvas_node.id)
|
x0, y0, x1, y1 = self.app.canvas.bbox(canvas_node.id)
|
||||||
dist = 5 * self.app.guiconfig.scale
|
dist = 5 * self.app.guiconfig.scale
|
||||||
|
|
|
@ -25,9 +25,9 @@ class RunToolDialog(Dialog):
|
||||||
"""
|
"""
|
||||||
store all CORE nodes (nodes that execute commands) from all existing nodes
|
store all CORE nodes (nodes that execute commands) from all existing nodes
|
||||||
"""
|
"""
|
||||||
for nid, node in self.app.core.canvas_nodes.items():
|
for node in self.app.core.session.nodes.values():
|
||||||
if NodeUtils.is_container_node(node.core_node.type):
|
if NodeUtils.is_container_node(node.type):
|
||||||
self.executable_nodes[node.core_node.name] = nid
|
self.executable_nodes[node.name] = node.id
|
||||||
|
|
||||||
def draw(self) -> None:
|
def draw(self) -> None:
|
||||||
self.top.rowconfigure(0, weight=1)
|
self.top.rowconfigure(0, weight=1)
|
||||||
|
|
|
@ -34,10 +34,8 @@ class EdgeInfoFrame(InfoFrameBase):
|
||||||
self.columnconfigure(0, weight=1)
|
self.columnconfigure(0, weight=1)
|
||||||
link = self.edge.link
|
link = self.edge.link
|
||||||
options = link.options
|
options = link.options
|
||||||
src_canvas_node = self.app.core.canvas_nodes[link.node1_id]
|
src_node = self.app.core.session.nodes[link.node1_id]
|
||||||
src_node = src_canvas_node.core_node
|
dst_node = self.app.core.session.nodes[link.node2_id]
|
||||||
dst_canvas_node = self.app.core.canvas_nodes[link.node2_id]
|
|
||||||
dst_node = dst_canvas_node.core_node
|
|
||||||
|
|
||||||
frame = DetailsFrame(self)
|
frame = DetailsFrame(self)
|
||||||
frame.grid(sticky="ew")
|
frame.grid(sticky="ew")
|
||||||
|
@ -81,9 +79,9 @@ class WirelessEdgeInfoFrame(InfoFrameBase):
|
||||||
|
|
||||||
def draw(self) -> None:
|
def draw(self) -> None:
|
||||||
link = self.edge.link
|
link = self.edge.link
|
||||||
src_canvas_node = self.app.core.canvas_nodes[link.node1_id]
|
src_canvas_node = self.app.canvas.nodes[self.edge.src]
|
||||||
src_node = src_canvas_node.core_node
|
src_node = src_canvas_node.core_node
|
||||||
dst_canvas_node = self.app.core.canvas_nodes[link.node2_id]
|
dst_canvas_node = self.app.canvas.nodes[self.edge.dst]
|
||||||
dst_node = dst_canvas_node.core_node
|
dst_node = dst_canvas_node.core_node
|
||||||
|
|
||||||
# find interface for each node connected to network
|
# find interface for each node connected to network
|
||||||
|
|
|
@ -311,10 +311,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
edge.middle_label_text(link.label)
|
edge.middle_label_text(link.label)
|
||||||
|
|
||||||
def add_core_node(self, core_node: Node) -> None:
|
def add_core_node(self, core_node: Node) -> None:
|
||||||
if core_node.id in self.core.canvas_nodes:
|
logging.debug("adding node: %s", core_node)
|
||||||
logging.error("core node already exists: %s", core_node)
|
|
||||||
return
|
|
||||||
logging.debug("adding node %s", core_node)
|
|
||||||
# if the gui can't find node's image, default to the "edit-node" image
|
# if the gui can't find node's image, default to the "edit-node" image
|
||||||
image = NodeUtils.node_image(core_node, self.app.guiconfig, self.app.app_scale)
|
image = NodeUtils.node_image(core_node, self.app.guiconfig, self.app.app_scale)
|
||||||
if not image:
|
if not image:
|
||||||
|
@ -323,7 +320,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
y = core_node.position.y
|
y = core_node.position.y
|
||||||
node = CanvasNode(self.app, x, y, core_node, image)
|
node = CanvasNode(self.app, x, y, core_node, image)
|
||||||
self.nodes[node.id] = node
|
self.nodes[node.id] = node
|
||||||
self.core.canvas_nodes[core_node.id] = node
|
self.core.set_canvas_node(core_node, node)
|
||||||
|
|
||||||
def draw_session(self, session: Session) -> None:
|
def draw_session(self, session: Session) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -336,12 +333,11 @@ class CanvasGraph(tk.Canvas):
|
||||||
if NodeUtils.is_ignore_node(core_node.type):
|
if NodeUtils.is_ignore_node(core_node.type):
|
||||||
continue
|
continue
|
||||||
self.add_core_node(core_node)
|
self.add_core_node(core_node)
|
||||||
|
|
||||||
# draw existing links
|
# draw existing links
|
||||||
for link in session.links:
|
for link in session.links:
|
||||||
logging.debug("drawing link: %s", link)
|
logging.debug("drawing link: %s", link)
|
||||||
canvas_node1 = self.core.canvas_nodes[link.node1_id]
|
canvas_node1 = self.core.get_canvas_node(link.node1_id)
|
||||||
canvas_node2 = self.core.canvas_nodes[link.node2_id]
|
canvas_node2 = self.core.get_canvas_node(link.node2_id)
|
||||||
if link.type == LinkType.WIRELESS:
|
if link.type == LinkType.WIRELESS:
|
||||||
self.add_wireless_edge(canvas_node1, canvas_node2, link)
|
self.add_wireless_edge(canvas_node1, canvas_node2, link)
|
||||||
else:
|
else:
|
||||||
|
@ -544,8 +540,8 @@ class CanvasGraph(tk.Canvas):
|
||||||
shape.delete()
|
shape.delete()
|
||||||
|
|
||||||
self.selection.clear()
|
self.selection.clear()
|
||||||
self.core.deleted_graph_nodes(nodes)
|
self.core.deleted_canvas_nodes(nodes)
|
||||||
self.core.deleted_graph_edges(edges)
|
self.core.deleted_canvas_edges(edges)
|
||||||
|
|
||||||
def delete_edge(self, edge: CanvasEdge) -> None:
|
def delete_edge(self, edge: CanvasEdge) -> None:
|
||||||
edge.delete()
|
edge.delete()
|
||||||
|
@ -564,7 +560,7 @@ class CanvasGraph(tk.Canvas):
|
||||||
dst_wireless = NodeUtils.is_wireless_node(dst_node.core_node.type)
|
dst_wireless = NodeUtils.is_wireless_node(dst_node.core_node.type)
|
||||||
if dst_wireless:
|
if dst_wireless:
|
||||||
src_node.delete_antenna()
|
src_node.delete_antenna()
|
||||||
self.core.deleted_graph_edges([edge])
|
self.core.deleted_canvas_edges([edge])
|
||||||
|
|
||||||
def zoom(self, event: tk.Event, factor: float = None) -> None:
|
def zoom(self, event: tk.Event, factor: float = None) -> None:
|
||||||
if not factor:
|
if not factor:
|
||||||
|
@ -750,8 +746,8 @@ class CanvasGraph(tk.Canvas):
|
||||||
image_file = self.node_draw.image_file
|
image_file = self.node_draw.image_file
|
||||||
self.node_draw.image = self.app.get_custom_icon(image_file, ICON_SIZE)
|
self.node_draw.image = self.app.get_custom_icon(image_file, ICON_SIZE)
|
||||||
node = CanvasNode(self.app, x, y, core_node, self.node_draw.image)
|
node = CanvasNode(self.app, x, y, core_node, self.node_draw.image)
|
||||||
self.core.canvas_nodes[core_node.id] = node
|
|
||||||
self.nodes[node.id] = node
|
self.nodes[node.id] = node
|
||||||
|
self.core.set_canvas_node(core_node, node)
|
||||||
|
|
||||||
def width_and_height(self) -> Tuple[int, int]:
|
def width_and_height(self) -> Tuple[int, int]:
|
||||||
"""
|
"""
|
||||||
|
@ -955,8 +951,8 @@ class CanvasGraph(tk.Canvas):
|
||||||
)
|
)
|
||||||
|
|
||||||
copy_map[canvas_node.id] = node.id
|
copy_map[canvas_node.id] = node.id
|
||||||
self.core.canvas_nodes[copy.id] = node
|
|
||||||
self.nodes[node.id] = node
|
self.nodes[node.id] = node
|
||||||
|
self.core.set_canvas_node(copy, node)
|
||||||
for edge in canvas_node.edges:
|
for edge in canvas_node.edges:
|
||||||
if edge.src not in self.to_copy or edge.dst not in self.to_copy:
|
if edge.src not in self.to_copy or edge.dst not in self.to_copy:
|
||||||
if canvas_node.id == edge.src:
|
if canvas_node.id == edge.src:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue