From c1ed7f54d8980cea4a576c88ca68a95a308ca36a Mon Sep 17 00:00:00 2001 From: Huy Pham <42948410+hpham@users.noreply.github.com> Date: Tue, 22 Oct 2019 13:17:47 -0700 Subject: [PATCH] coretk --- coretk/coretk/coregrpc.py | 5 + coretk/coretk/coremenubar.py | 4 +- coretk/coretk/coretocanvas.py | 1 + coretk/coretk/grpcmanagement.py | 4 +- coretk/coretk/linkinfo.py | 174 ++++++++++++++++++++++++++++---- coretk/coretk/menuaction.py | 5 + coretk/coretk/sizeandscale.py | 86 ++++++++++++++++ 7 files changed, 259 insertions(+), 20 deletions(-) create mode 100644 coretk/coretk/sizeandscale.py diff --git a/coretk/coretk/coregrpc.py b/coretk/coretk/coregrpc.py index 3d2955dc..e3e98edd 100644 --- a/coretk/coretk/coregrpc.py +++ b/coretk/coretk/coregrpc.py @@ -35,6 +35,9 @@ class CoreGrpc: def log_throughput(self, event): interface_throughputs = event.interface_throughputs + # for i in interface_throughputs: + # print(i) + # return throughputs_belong_to_session = [] for if_tp in interface_throughputs: if if_tp.node_id in self.node_ids: @@ -245,6 +248,8 @@ class CoreGrpc: response = self.core.add_link(self.session_id, id1, id2, if1, if2) logging.info("created link: %s", response) + self.core.get_node_links(self.session_id, id1) + # def get_session(self): # response = self.core.get_session(self.session_id) # nodes = response.session.nodes diff --git a/coretk/coretk/coremenubar.py b/coretk/coretk/coremenubar.py index f08d18ed..353e0c8a 100644 --- a/coretk/coretk/coremenubar.py +++ b/coretk/coretk/coremenubar.py @@ -166,7 +166,9 @@ class CoreMenubar(object): canvas_menu.add_separator() - canvas_menu.add_command(label="Size/scale...", command=action.canvas_size_scale) + canvas_menu.add_command( + label="Size/scale...", command=self.menu_action.canvas_size_and_scale + ) canvas_menu.add_command(label="Wallpaper...", command=action.canvas_wallpaper) canvas_menu.add_separator() diff --git a/coretk/coretk/coretocanvas.py b/coretk/coretk/coretocanvas.py index f16c5306..e808735f 100644 --- a/coretk/coretk/coretocanvas.py +++ b/coretk/coretk/coretocanvas.py @@ -8,6 +8,7 @@ class CoreToCanvasMapping: def __init__(self): self.core_id_to_canvas_id = {} self.core_node_and_interface_to_canvas_edge = {} + # self.edge_id_to_canvas_token = {} def map_node_and_interface_to_canvas_edge(self, nid, iid, edge_token): self.core_node_and_interface_to_canvas_edge[tuple([nid, iid])] = edge_token diff --git a/coretk/coretk/grpcmanagement.py b/coretk/coretk/grpcmanagement.py index 2d5a9027..ebd34f6c 100644 --- a/coretk/coretk/grpcmanagement.py +++ b/coretk/coretk/grpcmanagement.py @@ -230,7 +230,7 @@ class GrpcManager: """ src_interface = None dst_interface = None - + print("create interface") self.interfaces_manager.new_subnet() src_node = self.nodes[src_canvas_id] @@ -263,6 +263,8 @@ class GrpcManager: edge.interface_1 = src_interface edge.interface_2 = dst_interface + print(src_interface) + print(dst_interface) return src_interface, dst_interface def add_edge(self, session_id, token, canvas_id_1, canvas_id_2): diff --git a/coretk/coretk/linkinfo.py b/coretk/coretk/linkinfo.py index 7480e004..c21a56b0 100644 --- a/coretk/coretk/linkinfo.py +++ b/coretk/coretk/linkinfo.py @@ -1,11 +1,23 @@ """ Link information, such as IPv4, IPv6 and throughput drawn in the canvas """ +import logging import math +WIRELESS_DEF = ["mdr", "wlan"] + class LinkInfo: def __init__(self, canvas, edge, ip4_src, ip6_src, ip4_dst, ip6_dst): + """ + create an instance of LinkInfo object + :param tkinter.Canvas canvas: canvas object + :param coretk.graph.CanvasEdge edge: canvas edge onject + :param ip4_src: + :param ip6_src: + :param ip4_dst: + :param ip6_dst: + """ self.canvas = canvas self.edge = edge # self.edge_id = edge.id @@ -20,13 +32,23 @@ class LinkInfo: self.id2 = self.create_edge_dst_info() def slope_src_dst(self): + """ + calculate slope of the line connecting source node to destination node + :rtype: float + :return: slope of line + """ x1, y1, x2, y2 = self.canvas.coords(self.edge.id) if x2 - x1 == 0: - return 9999 + return 9999.0 else: return (y2 - y1) / (x2 - x1) def create_edge_src_info(self): + """ + draw the ip address for source node + + :return: nothing + """ x1, y1, x2, _ = self.canvas.coords(self.edge.id) m = self.slope_src_dst() distance = math.cos(math.atan(m)) * self.radius @@ -39,6 +61,11 @@ class LinkInfo: return id1 def create_edge_dst_info(self): + """ + draw the ip address for destination node + + :return: nothing + """ x1, _, x2, y2 = self.canvas.coords(self.edge.id) m = self.slope_src_dst() distance = math.cos(math.atan(m)) * self.radius @@ -51,6 +78,11 @@ class LinkInfo: return id2 def recalculate_info(self): + """ + move the node info when the canvas node move + + :return: nothing + """ x1, y1, x2, y2 = self.canvas.coords(self.edge.id) m = self.slope_src_dst() distance = math.cos(math.atan(m)) * self.radius @@ -73,6 +105,11 @@ class LinkInfo: class Throughput: def __init__(self, canvas, grpc): + """ + create an instance of Throughput object + :param tkinter.Canvas canvas: canvas object + :param coretk.coregrpc,CoreGrpc grpc: grpc object + """ self.canvas = canvas self.core_grpc = grpc self.grpc_manager = canvas.grpc_manager @@ -83,6 +120,8 @@ class Throughput: # map an edge canvas id to a throughput canvas id self.map = {} + self.edge_id_to_token = {} + def load_throughput_info(self, interface_throughputs): """ load all interface throughouts from an event @@ -98,28 +137,119 @@ class Throughput: token = self.grpc_manager.core_mapping.get_token_from_node_and_interface( nid, iid ) + print(token) edge_id = self.canvas.edges[token].id + + self.edge_id_to_token[edge_id] = token + if edge_id not in self.tracker: self.tracker[edge_id] = tp else: temp = self.tracker[edge_id] self.tracker[edge_id] = (temp + tp) / 2 + def edge_is_wired(self, token): + """ + determine whether link is a WIRED link + + :param token: + :return: + """ + canvas_edge = self.canvas.edges[token] + canvas_src_id = canvas_edge.src + canvas_dst_id = canvas_edge.dst + src_node = self.canvas.nodes[canvas_src_id] + dst_node = self.canvas.nodes[canvas_dst_id] + + if src_node.node_type == "wlan": + if dst_node.node_type == "mdr": + return False + else: + logging.debug("linkinfo.py is_wired WARNING wlan only connected to mdr") + return True + if dst_node.node_type == "wlan": + if src_node.node_type == "mdr": + return False + else: + logging.debug("linkinfo.py is_wired WARNING wlan only connected to mdr") + return True + return True + + def draw_wired_throughput(self, edge_id): + + x1, y1, x2, y2 = self.canvas.coords(edge_id) + x = (x1 + x2) / 2 + y = (y1 + y2) / 2 + + if edge_id not in self.map: + tp_id = self.canvas.create_text( + x, y, text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]) + ) + self.map[edge_id] = tp_id + + # redraw throughput + else: + self.canvas.itemconfig( + self.map[edge_id], + text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]), + ) + + def draw_wireless_throughput(self, edge_id): + token = self.edge_id_to_token[edge_id] + canvas_edge = self.canvas.edges[token] + canvas_src_id = canvas_edge.src + canvas_dst_id = canvas_edge.dst + src_node = self.canvas.nodes[canvas_src_id] + dst_node = self.canvas.nodes[canvas_dst_id] + + # non_wlan_node = None + if src_node.node_type == "wlan": + non_wlan_node = dst_node + else: + non_wlan_node = src_node + + x, y = self.canvas.coords(non_wlan_node.id) + if edge_id not in self.map: + tp_id = self.canvas.create_text( + x + 50, + y + 25, + text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]), + ) + self.map[edge_id] = tp_id + + # redraw throughput + else: + self.canvas.itemconfig( + self.map[edge_id], + text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]), + ) + def draw_throughputs(self): for edge_id in self.tracker: - x1, y1, x2, y2 = self.canvas.coords(edge_id) - x = (x1 + x2) / 2 - y = (y1 + y2) / 2 - if edge_id not in self.map: - tp_id = self.canvas.create_text( - x, y, text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]) - ) - self.map[edge_id] = tp_id + if self.edge_is_wired(self.edge_id_to_token[edge_id]): + self.draw_wired_throughput(edge_id) else: - self.canvas.itemconfig( - self.map[edge_id], - text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]), - ) + self.draw_wireless_throughput(edge_id) + # draw wireless throughput + + # x1, y1, x2, y2 = self.canvas.coords(edge_id) + # x = (x1 + x2) / 2 + # y = (y1 + y2) / 2 + # + # print(self.is_wired(self.edge_id_to_token[edge_id])) + # # new throughput + # if edge_id not in self.map: + # tp_id = self.canvas.create_text( + # x, y, text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]) + # ) + # self.map[edge_id] = tp_id + # + # # redraw throughput + # else: + # self.canvas.itemconfig( + # self.map[edge_id], + # text="{0:.3f} kbps".format(0.001 * self.tracker[edge_id]), + # ) def process_grpc_throughput_event(self, interface_throughputs): self.load_throughput_info(interface_throughputs) @@ -127,8 +257,16 @@ class Throughput: def update_throughtput_location(self, edge): tp_id = self.map[edge.id] - x1, y1 = self.canvas.coords(edge.src) - x2, y2 = self.canvas.coords(edge.dst) - x = (x1 + x2) / 2 - y = (y1 + y2) / 2 - self.canvas.coords(tp_id, x, y) + if self.edge_is_wired(self.edge_id_to_token[edge.id]): + x1, y1 = self.canvas.coords(edge.src) + x2, y2 = self.canvas.coords(edge.dst) + x = (x1 + x2) / 2 + y = (y1 + y2) / 2 + self.canvas.coords(tp_id, x, y) + else: + if self.canvas.nodes[edge.src].node_type == "wlan": + x, y = self.canvas.coords(edge.dst) + self.canvas.coords(tp_id, x + 50, y + 20) + else: + x, y = self.canvas.coords(edge.src) + self.canvas.coords(tp_id, x + 50, y + 25) diff --git a/coretk/coretk/menuaction.py b/coretk/coretk/menuaction.py index 207a1f3a..e7e1aafc 100644 --- a/coretk/coretk/menuaction.py +++ b/coretk/coretk/menuaction.py @@ -7,6 +7,7 @@ import webbrowser from tkinter import filedialog, messagebox from core.api.grpc import core_pb2 +from coretk.sizeandscale import SizeAndScale SAVEDIR = "/home/ncs/Desktop/" @@ -153,6 +154,7 @@ def canvas_delete(): def canvas_size_scale(): logging.debug("Click canvas size/scale") + SizeAndScale() def canvas_wallpaper(): @@ -415,6 +417,9 @@ class MenuAction: # t1 = time.clock() # print(t1 - t0) + def canvas_size_and_scale(self): + SizeAndScale() + def help_core_github(self): webbrowser.open_new("https://github.com/coreemu/core") diff --git a/coretk/coretk/sizeandscale.py b/coretk/coretk/sizeandscale.py new file mode 100644 index 00000000..e9485892 --- /dev/null +++ b/coretk/coretk/sizeandscale.py @@ -0,0 +1,86 @@ +""" +size and scale +""" + +import tkinter as tk + + +class SizeAndScale: + def __init__(self): + self.top = tk.Toplevel() + self.top.title("Canvas Size and Scale") + self.size_chart() + + self.pixel_width_text = None + + def click_scrollbar(self, e1, e2, e3): + print(e1, e2, e3) + + def create_text_label(self, frame, text, row, column): + text_label = tk.Label(frame, text=text) + text_label.grid(row=row, column=column) + + def size_chart(self): + f = tk.Frame(self.top) + t = tk.Label(f, text="Size") + t.grid(row=0, column=0, sticky=tk.W) + + scrollbar = tk.Scrollbar(f, orient=tk.VERTICAL) + scrollbar.grid(row=1, column=1) + e = tk.Entry(f, text="1000", xscrollcommand=scrollbar.set) + e.focus() + e.grid(row=1, column=0) + scrollbar.config(command=self.click_scrollbar) + + # l = tk.Label(f, text="W") + # l.grid(row=1, column=2) + # l = tk.Label(f, text=" X ") + # l.grid(row=1, column=3) + self.create_text_label(f, "W", 1, 2) + self.create_text_label(f, " X ", 1, 3) + + hpixel_scrollbar = tk.Scrollbar(f, orient=tk.VERTICAL) + hpixel_scrollbar.grid(row=1, column=5) + + hpixel_entry = tk.Entry(f, text="750", xscrollcommand=hpixel_scrollbar.set) + hpixel_entry.focus() + hpixel_entry.grid(row=1, column=4) + + h_label = tk.Label(f, text="H") + h_label.grid(row=1, column=6) + + self.create_text_label(f, "pixels", 1, 7) + # pixel_label = tk.Label(f, text="pixels") + # pixel_label.grid(row=1, column=7) + + wmeter_scrollbar = tk.Scrollbar(f, orient=tk.VERTICAL) + wmeter_scrollbar.grid(row=2, column=2) + + wmeter_entry = tk.Entry(f, text="1500.0", xscrollcommand=wmeter_scrollbar.set) + wmeter_entry.focus() + wmeter_entry.grid(row=2, column=0, columnspan=2, sticky=tk.W + tk.E) + + # l = tk.Label(f, text=" X ") + # l.grid(row=2, column=3) + self.create_text_label(f, " X ", row=2, column=3) + + # f1 = tk.Frame(f) + hmeter_scrollbar = tk.Scrollbar(f, orient=tk.VERTICAL) + hmeter_scrollbar.grid(row=2, column=6) + + hmeter_entry = tk.Entry(f, text="1125.0", xscrollcommand=hmeter_scrollbar.set) + hmeter_entry.focus() + hmeter_entry.grid(row=2, column=4, columnspan=2, sticky=tk.W + tk.E) + + self.create_text_label(f, "pixels", 2, 7) + # pixel_label = tk.Label(f, text="pixels") + # pixel_label.grid(row=2, column=7) + # hmeter_entry.pack(side=tk.LEFT) + # + # hmeter_scrollbar = tk.Scrollbar(hmeter_entry, orient=tk.VERTICAL) + # hmeter_scrollbar.pack(side=tk.LEFT) + # f1.grid(row=2, column=4) + + f.grid() + + # def scale_chart(self):