fix merge conflict

This commit is contained in:
Huy Pham 2019-11-01 08:56:35 -07:00
commit 22e773df1b
13 changed files with 396 additions and 281 deletions

View file

@ -40,7 +40,7 @@ class Application(tk.Frame):
def setup_app(self):
self.master.title("CORE")
self.master.geometry("1000x800")
image = Images.get(ImageEnum.CORE.value)
image = Images.get(ImageEnum.CORE)
self.master.tk.call("wm", "iconphoto", self.master._w, image)
self.pack(fill=tk.BOTH, expand=True)

View file

@ -0,0 +1,95 @@
import enum
import logging
import tkinter as tk
from tkinter import ttk
class ConfigType(enum.Enum):
STRING = 10
BOOL = 11
def create_config(master, config, padx=2, pady=2):
"""
Creates a scrollable canvas with an embedded window for displaying configuration
options. Will use grid layout to consume row 0 and columns 0-2.
:param master: master to add scrollable canvas to
:param dict config: config option mapping keys to config options
:param int padx: x padding for widgets
:param int pady: y padding for widgets
:return: widget value mapping
"""
master.rowconfigure(0, weight=1)
master.columnconfigure(0, weight=1)
master.columnconfigure(1, weight=1)
canvas = tk.Canvas(master, highlightthickness=0)
canvas.grid(row=0, columnspan=2, sticky="nsew", padx=padx, pady=pady)
canvas.columnconfigure(0, weight=1)
canvas.rowconfigure(0, weight=1)
scroll_y = tk.Scrollbar(master, orient="vertical", command=canvas.yview)
scroll_y.grid(row=0, column=2, sticky="ns")
frame = tk.Frame(canvas, padx=padx, pady=pady)
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=3)
values = {}
for index, key in enumerate(sorted(config)):
option = config[key]
label = tk.Label(frame, text=option.label)
label.grid(row=index, pady=pady, padx=padx, sticky="ew")
value = tk.StringVar()
config_type = ConfigType(option.type)
if config_type == ConfigType.BOOL:
select = tuple(option.select)
combobox = ttk.Combobox(frame, textvariable=value, values=select)
combobox.grid(row=index, column=1, sticky="ew", pady=pady)
if option.value == "1":
value.set("On")
else:
value.set("Off")
elif config_type == ConfigType.STRING:
entry = tk.Entry(frame, textvariable=value)
entry.grid(row=index, column=1, sticky="ew", pady=pady)
else:
logging.error("unhandled config option type: %s", config_type)
values[key] = value
frame_id = canvas.create_window(0, 0, anchor="nw", window=frame)
canvas.update_idletasks()
canvas.configure(scrollregion=canvas.bbox("all"), yscrollcommand=scroll_y.set)
frame.bind(
"<Configure>", lambda event: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.bind(
"<Configure>", lambda event: canvas.itemconfig(frame_id, width=event.width)
)
return values
def parse_config(options, values):
"""
Given a set of configurations, parse out values and transform them when needed.
:param dict options: option key mapping to configuration options
:param dict values: option key mapping to widget values
:return:
"""
config = {}
for key in options:
option = options[key]
value = values[key]
config_type = ConfigType(option.type)
config_value = value.get()
if config_type == ConfigType.BOOL:
if config_value == "On":
config_value = "1"
else:
config_value = "0"
config[key] = config_value
return config

View file

@ -6,8 +6,8 @@ import os
from collections import OrderedDict
from core.api.grpc import client, core_pb2
from coretk.dialogs.sessions import SessionsDialog
from coretk.linkinfo import Throughput
from coretk.querysessiondrawing import SessionTable
from coretk.wirelessconnection import WirelessConnection
@ -18,12 +18,9 @@ class CoreGrpc:
"""
self.core = client.CoreGrpcClient()
self.session_id = sid
self.node_ids = []
self.app = app
self.master = app.master
# self.set_up()
self.interface_helper = None
self.throughput_draw = Throughput(app.canvas, self)
self.wireless_draw = WirelessConnection(app.canvas, self)
@ -64,16 +61,6 @@ class CoreGrpc:
self.core.events(self.session_id, self.log_event)
# self.core.throughputs(self.log_throughput)
def query_existing_sessions(self, sessions):
"""
Query for existing sessions and prompt to join one
:param repeated core_pb2.SessionSummary sessions: summaries of all the existing sessions
:return: nothing
"""
SessionTable(self, self.master)
def delete_session(self, custom_sid=None):
if custom_sid is None:
sid = self.session_id
@ -102,18 +89,15 @@ class CoreGrpc:
:return: existing sessions
"""
self.core.connect()
response = self.core.get_sessions()
# logging.info("coregrpc.py: all sessions: %s", response)
# if there are no sessions, create a new session, else join a session
sessions = response.sessions
if len(sessions) == 0:
self.create_new_session()
else:
self.query_existing_sessions(sessions)
dialog = SessionsDialog(self.app, self.app)
dialog.show()
def get_session_state(self):
response = self.core.get_session(self.session_id)

View file

@ -594,7 +594,7 @@ class CoreMenubar(object):
session_menu.add_command(
label="Change sessions...",
command=action.session_change_sessions,
command=self.menu_action.session_change_sessions,
underline=0,
)
@ -620,7 +620,7 @@ class CoreMenubar(object):
underline=0,
)
session_menu.add_command(
label="Options...", command=action.session_options, underline=0
label="Options...", command=self.menu_action.session_options, underline=0
)
self.menubar.add_cascade(label="Session", menu=session_menu, underline=0)

View file

@ -200,55 +200,55 @@ class CoreToolbar(object):
def pick_router(self, main_button):
logging.debug("Pick router option")
self.network_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.ROUTER.value))
main_button.configure(image=Images.get(ImageEnum.ROUTER))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.ROUTER.value)
self.canvas.draw_node_image = Images.get(ImageEnum.ROUTER)
self.canvas.draw_node_name = "router"
def pick_host(self, main_button):
logging.debug("Pick host option")
self.network_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.HOST.value))
main_button.configure(image=Images.get(ImageEnum.HOST))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.HOST.value)
self.canvas.draw_node_image = Images.get(ImageEnum.HOST)
self.canvas.draw_node_name = "host"
def pick_pc(self, main_button):
logging.debug("Pick PC option")
self.network_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.PC.value))
main_button.configure(image=Images.get(ImageEnum.PC))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.PC.value)
self.canvas.draw_node_image = Images.get(ImageEnum.PC)
self.canvas.draw_node_name = "PC"
def pick_mdr(self, main_button):
logging.debug("Pick MDR option")
self.network_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.MDR.value))
main_button.configure(image=Images.get(ImageEnum.MDR))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.MDR.value)
self.canvas.draw_node_image = Images.get(ImageEnum.MDR)
self.canvas.draw_node_name = "mdr"
def pick_prouter(self, main_button):
logging.debug("Pick prouter option")
self.network_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.PROUTER.value))
main_button.configure(image=Images.get(ImageEnum.PROUTER))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.PROUTER.value)
self.canvas.draw_node_image = Images.get(ImageEnum.PROUTER)
self.canvas.draw_node_name = "prouter"
def pick_ovs(self, main_button):
logging.debug("Pick OVS option")
self.network_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.OVS.value))
main_button.configure(image=Images.get(ImageEnum.OVS))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.OVS.value)
self.canvas.draw_node_image = Images.get(ImageEnum.OVS)
self.canvas.draw_node_name = "OVS"
# TODO what graph node is this
def pick_editnode(self, main_button):
self.network_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.EDITNODE.value))
main_button.configure(image=Images.get(ImageEnum.EDITNODE))
logging.debug("Pick editnode option")
def draw_network_layer_options(self, network_layer_button):
@ -262,13 +262,13 @@ class CoreToolbar(object):
self.destroy_previous_frame()
option_frame = tk.Frame(self.master, padx=1, pady=1)
img_list = [
Images.get(ImageEnum.ROUTER.value),
Images.get(ImageEnum.HOST.value),
Images.get(ImageEnum.PC.value),
Images.get(ImageEnum.MDR.value),
Images.get(ImageEnum.PROUTER.value),
Images.get(ImageEnum.OVS.value),
Images.get(ImageEnum.EDITNODE.value),
Images.get(ImageEnum.ROUTER),
Images.get(ImageEnum.HOST),
Images.get(ImageEnum.PC),
Images.get(ImageEnum.MDR),
Images.get(ImageEnum.PROUTER),
Images.get(ImageEnum.OVS),
Images.get(ImageEnum.EDITNODE),
]
func_list = [
self.pick_router,
@ -312,7 +312,7 @@ class CoreToolbar(object):
:return: nothing
"""
router_image = Images.get(ImageEnum.ROUTER.value)
router_image = Images.get(ImageEnum.ROUTER)
network_layer_button = tk.Radiobutton(
self.edit_frame,
indicatoron=False,
@ -329,41 +329,41 @@ class CoreToolbar(object):
def pick_hub(self, main_button):
logging.debug("Pick link-layer node HUB")
self.link_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.HUB.value))
main_button.configure(image=Images.get(ImageEnum.HUB))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.HUB.value)
self.canvas.draw_node_image = Images.get(ImageEnum.HUB)
self.canvas.draw_node_name = "hub"
def pick_switch(self, main_button):
logging.debug("Pick link-layer node SWITCH")
self.link_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.SWITCH.value))
main_button.configure(image=Images.get(ImageEnum.SWITCH))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.SWITCH.value)
self.canvas.draw_node_image = Images.get(ImageEnum.SWITCH)
self.canvas.draw_node_name = "switch"
def pick_wlan(self, main_button):
logging.debug("Pick link-layer node WLAN")
self.link_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.WLAN.value))
main_button.configure(image=Images.get(ImageEnum.WLAN))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.WLAN.value)
self.canvas.draw_node_image = Images.get(ImageEnum.WLAN)
self.canvas.draw_node_name = "wlan"
def pick_rj45(self, main_button):
logging.debug("Pick link-layer node RJ45")
self.link_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.RJ45.value))
main_button.configure(image=Images.get(ImageEnum.RJ45))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.RJ45.value)
self.canvas.draw_node_image = Images.get(ImageEnum.RJ45)
self.canvas.draw_node_name = "rj45"
def pick_tunnel(self, main_button):
logging.debug("Pick link-layer node TUNNEL")
self.link_layer_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.TUNNEL.value))
main_button.configure(image=Images.get(ImageEnum.TUNNEL))
self.canvas.mode = GraphMode.PICKNODE
self.canvas.draw_node_image = Images.get(ImageEnum.TUNNEL.value)
self.canvas.draw_node_image = Images.get(ImageEnum.TUNNEL)
self.canvas.draw_node_name = "tunnel"
def pick_emane(self, main_button):
@ -431,7 +431,7 @@ class CoreToolbar(object):
:return: nothing
"""
hub_image = Images.get(ImageEnum.HUB.value)
hub_image = Images.get(ImageEnum.HUB)
link_layer_button = tk.Radiobutton(
self.edit_frame,
indicatoron=False,
@ -447,22 +447,22 @@ class CoreToolbar(object):
def pick_marker(self, main_button):
self.marker_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.MARKER.value))
main_button.configure(image=Images.get(ImageEnum.MARKER))
logging.debug("Pick MARKER")
def pick_oval(self, main_button):
self.marker_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.OVAL.value))
main_button.configure(image=Images.get(ImageEnum.OVAL))
logging.debug("Pick OVAL")
def pick_rectangle(self, main_button):
self.marker_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.RECTANGLE.value))
main_button.configure(image=Images.get(ImageEnum.RECTANGLE))
logging.debug("Pick RECTANGLE")
def pick_text(self, main_button):
self.marker_option_menu.destroy()
main_button.configure(image=Images.get(ImageEnum.TEXT.value))
main_button.configure(image=Images.get(ImageEnum.TEXT))
logging.debug("Pick TEXT")
def draw_marker_options(self, main_button):
@ -476,10 +476,10 @@ class CoreToolbar(object):
self.destroy_previous_frame()
option_frame = tk.Frame(self.master, padx=1, pady=1)
img_list = [
Images.get(ImageEnum.MARKER.value),
Images.get(ImageEnum.OVAL.value),
Images.get(ImageEnum.RECTANGLE.value),
Images.get(ImageEnum.TEXT.value),
Images.get(ImageEnum.MARKER),
Images.get(ImageEnum.OVAL),
Images.get(ImageEnum.RECTANGLE),
Images.get(ImageEnum.TEXT),
]
func_list = [
self.pick_marker,
@ -508,7 +508,7 @@ class CoreToolbar(object):
:return: nothing
"""
marker_image = Images.get(ImageEnum.MARKER.value)
marker_image = Images.get(ImageEnum.MARKER)
marker_main_button = tk.Radiobutton(
self.edit_frame,
indicatoron=False,
@ -530,13 +530,13 @@ class CoreToolbar(object):
"""
self.create_regular_button(
self.edit_frame,
Images.get(ImageEnum.START.value),
Images.get(ImageEnum.START),
self.click_start_session_tool,
"start the session",
)
self.create_radio_button(
self.edit_frame,
Images.get(ImageEnum.SELECT.value),
Images.get(ImageEnum.SELECT),
self.click_selection_tool,
self.radio_value,
1,
@ -544,7 +544,7 @@ class CoreToolbar(object):
)
self.create_radio_button(
self.edit_frame,
Images.get(ImageEnum.LINK.value),
Images.get(ImageEnum.LINK),
self.click_link_tool,
self.radio_value,
2,
@ -558,7 +558,7 @@ class CoreToolbar(object):
def create_observe_button(self):
menu_button = tk.Menubutton(
self.edit_frame,
image=Images.get(ImageEnum.OBSERVE.value),
image=Images.get(ImageEnum.OBSERVE),
width=self.width,
height=self.height,
direction=tk.RIGHT,
@ -615,13 +615,13 @@ class CoreToolbar(object):
def create_runtime_toolbar(self):
self.create_regular_button(
self.edit_frame,
Images.get(ImageEnum.STOP.value),
Images.get(ImageEnum.STOP),
self.click_stop_button,
"stop the session",
)
self.create_radio_button(
self.edit_frame,
Images.get(ImageEnum.SELECT.value),
Images.get(ImageEnum.SELECT),
self.click_selection_tool,
self.exec_radio_value,
1,
@ -630,7 +630,7 @@ class CoreToolbar(object):
self.create_observe_button()
self.create_radio_button(
self.edit_frame,
Images.get(ImageEnum.PLOT.value),
Images.get(ImageEnum.PLOT),
self.click_plot_button,
self.exec_radio_value,
2,
@ -638,7 +638,7 @@ class CoreToolbar(object):
)
self.create_radio_button(
self.edit_frame,
Images.get(ImageEnum.MARKER.value),
Images.get(ImageEnum.MARKER),
self.click_marker_button,
self.exec_radio_value,
3,
@ -646,16 +646,13 @@ class CoreToolbar(object):
)
self.create_radio_button(
self.edit_frame,
Images.get(ImageEnum.TWONODE.value),
Images.get(ImageEnum.TWONODE),
self.click_two_node_button,
self.exec_radio_value,
4,
"run command from one node to another",
)
self.create_regular_button(
self.edit_frame,
Images.get(ImageEnum.RUN.value),
self.click_run_button,
"run",
self.edit_frame, Images.get(ImageEnum.RUN), self.click_run_button, "run"
)
self.exec_radio_value.set(1)

View file

View file

@ -0,0 +1,24 @@
import tkinter as tk
from coretk.images import ImageEnum, Images
class Dialog(tk.Toplevel):
def __init__(self, master, app, title, modal=False):
super().__init__(master, padx=5, pady=5)
self.withdraw()
self.app = app
self.modal = modal
self.title(title)
self.protocol("WM_DELETE_WINDOW", self.destroy)
image = Images.get(ImageEnum.CORE)
self.tk.call("wm", "iconphoto", self._w, image)
def show(self):
self.transient(self.master)
self.focus_force()
if self.modal:
self.grab_set()
self.update()
self.deiconify()
self.wait_window()

View file

@ -0,0 +1,34 @@
import logging
import tkinter as tk
from coretk import configutils
from coretk.dialogs.dialog import Dialog
PAD_X = 2
PAD_Y = 2
class SessionOptionsDialog(Dialog):
def __init__(self, master, app):
super().__init__(master, app, "Session Options", modal=True)
self.options = None
self.values = None
self.save_button = tk.Button(self, text="Save", command=self.save)
self.cancel_button = tk.Button(self, text="Cancel", command=self.destroy)
self.draw()
def draw(self):
session_id = self.master.core_grpc.session_id
response = self.master.core_grpc.core.get_session_options(session_id)
logging.info("session options: %s", response)
self.options = response.config
self.values = configutils.create_config(self, self.options, PAD_X, PAD_Y)
self.save_button.grid(row=1, pady=PAD_Y, padx=PAD_X, sticky="ew")
self.cancel_button.grid(row=1, column=1, pady=PAD_Y, padx=PAD_X, sticky="ew")
def save(self):
config = configutils.parse_config(self.options, self.values)
session_id = self.master.core_grpc.session_id
response = self.master.core_grpc.core.set_session_options(session_id, config)
logging.info("saved session config: %s", response)
self.destroy()

View file

@ -0,0 +1,159 @@
import logging
import tkinter as tk
from tkinter.ttk import Scrollbar, Treeview
from core.api.grpc import core_pb2
from coretk.dialogs.dialog import Dialog
from coretk.images import ImageEnum, Images
class SessionsDialog(Dialog):
def __init__(self, master, app):
"""
create session table instance
:param coretk.coregrpc.CoreGrpc grpc: coregrpc
:param root.master master:
"""
super().__init__(master, app, "Sessions", modal=True)
self.selected = False
self.selected_id = None
self.tree = None
self.draw()
def draw(self):
self.columnconfigure(0, weight=1)
self.draw_description()
self.draw_tree()
self.draw_buttons()
def draw_description(self):
"""
write a short description
:return: nothing
"""
label = tk.Label(
self,
text="Below is a list of active CORE sessions. Double-click to \n"
"connect to an existing session. Usually, only sessions in \n"
"the RUNTIME state persist in the daemon, except for the \n"
"one you might be concurrently editting.",
)
label.grid(row=0, sticky="ew", pady=5)
def draw_tree(self):
self.tree = Treeview(self, columns=("id", "state", "nodes"), show="headings")
self.tree.grid(row=1, sticky="nsew")
self.tree.column("id", stretch=tk.YES)
self.tree.heading("id", text="ID")
self.tree.column("state", stretch=tk.YES)
self.tree.heading("state", text="State")
self.tree.column("nodes", stretch=tk.YES)
self.tree.heading("nodes", text="Node Count")
response = self.app.core_grpc.core.get_sessions()
logging.info("sessions: %s", response)
for index, session in enumerate(response.sessions):
state_name = core_pb2.SessionState.Enum.Name(session.state)
self.tree.insert(
"",
tk.END,
text=str(session.id),
values=(session.id, state_name, session.nodes),
)
self.tree.bind("<Double-1>", self.on_selected)
self.tree.bind("<<TreeviewSelect>>", self.click_select)
yscrollbar = Scrollbar(self, orient="vertical", command=self.tree.yview)
yscrollbar.grid(row=1, column=1, sticky="ns")
self.tree.configure(yscrollcommand=yscrollbar.set)
xscrollbar = Scrollbar(self, orient="horizontal", command=self.tree.xview)
xscrollbar.grid(row=2, sticky="ew", pady=5)
self.tree.configure(xscrollcommand=xscrollbar.set)
def draw_buttons(self):
frame = tk.Frame(self)
for i in range(4):
frame.columnconfigure(i, weight=1)
frame.grid(row=3, sticky="ew")
b = tk.Button(
frame,
image=Images.get(ImageEnum.DOCUMENTNEW),
text="New",
compound=tk.LEFT,
command=self.click_new,
)
b.grid(row=0, padx=2, sticky="ew")
b = tk.Button(
frame,
image=Images.get(ImageEnum.FILEOPEN),
text="Connect",
compound=tk.LEFT,
command=self.click_connect,
)
b.grid(row=0, column=1, padx=2, sticky="ew")
b = tk.Button(
frame,
image=Images.get(ImageEnum.EDITDELETE),
text="Shutdown",
compound=tk.LEFT,
command=self.click_shutdown,
)
b.grid(row=0, column=2, padx=2, sticky="ew")
b = tk.Button(frame, text="Cancel", command=self.click_new)
b.grid(row=0, column=3, padx=2, sticky="ew")
def click_new(self):
self.app.core_grpc.create_new_session()
self.destroy()
def click_select(self, event):
item = self.tree.selection()
session_id = int(self.tree.item(item, "text"))
self.selected = True
self.selected_id = session_id
def click_connect(self):
"""
if no session is selected yet, create a new one else join that session
:return: nothing
"""
if self.selected and self.selected_id is not None:
self.join_session(self.selected_id)
elif not self.selected and self.selected_id is None:
self.click_new()
else:
logging.error("sessions invalid state")
def click_shutdown(self):
"""
if no session is currently selected create a new session else shut the selected
session down.
:return: nothing
"""
if self.selected and self.selected_id is not None:
self.shutdown_session(self.selected_id)
elif not self.selected and self.selected_id is None:
self.click_new()
else:
logging.error("querysessiondrawing.py invalid state")
def join_session(self, session_id):
response = self.app.core_grpc.core.get_session(session_id)
self.app.core_grpc.session_id = session_id
self.app.core_grpc.core.events(session_id, self.app.core_grpc.log_event)
logging.info("entering session_id %s.... Result: %s", session_id, response)
self.destroy()
def on_selected(self, event):
item = self.tree.selection()
sid = int(self.tree.item(item, "text"))
self.join_session(sid)
def shutdown_session(self, sid):
self.app.core_grpc.terminate_session(sid)
self.click_new()
self.destroy()

View file

@ -94,7 +94,7 @@ class WlanAntennaManager:
x - 16 + self.offset,
y - 16,
anchor=tk.CENTER,
image=Images.get(ImageEnum.ANTENNA.value),
image=Images.get(ImageEnum.ANTENNA),
tags="antenna",
)
)

View file

@ -21,8 +21,8 @@ class Images:
cls.images[name] = tk_image
@classmethod
def get(cls, name):
return cls.images[name]
def get(cls, image):
return cls.images[image.value]
@classmethod
def convert_type_and_model_to_image(cls, node_type, node_model):
@ -35,30 +35,31 @@ class Images:
:return: the matching image and its name
"""
if node_type == core_pb2.NodeType.SWITCH:
return Images.get(ImageEnum.SWITCH.value), "switch"
return Images.get(ImageEnum.SWITCH), "switch"
if node_type == core_pb2.NodeType.HUB:
return Images.get(ImageEnum.HUB.value), "hub"
return Images.get(ImageEnum.HUB), "hub"
if node_type == core_pb2.NodeType.WIRELESS_LAN:
return Images.get(ImageEnum.WLAN.value), "wlan"
if node_type == core_pb2.NodeType.EMANE:
return Images.get(ImageEnum.EMANE.value), "emane"
if node_type == core_pb2.NodeType.RJ45:
return Images.get(ImageEnum.RJ45.value), "rj45"
return Images.get(ImageEnum.RJ45), "rj45"
if node_type == core_pb2.NodeType.TUNNEL:
return Images.get(ImageEnum.TUNNEL.value), "tunnel"
return Images.get(ImageEnum.TUNNEL), "tunnel"
if node_type == core_pb2.NodeType.DEFAULT:
if node_model == "router":
return Images.get(ImageEnum.ROUTER.value), "router"
return Images.get(ImageEnum.ROUTER), "router"
if node_model == "host":
return Images.get((ImageEnum.HOST.value)), "host"
return Images.get(ImageEnum.HOST), "host"
if node_model == "PC":
return Images.get(ImageEnum.PC.value), "PC"
return Images.get(ImageEnum.PC), "PC"
if node_model == "mdr":
return Images.get(ImageEnum.MDR.value), "mdr"
return Images.get(ImageEnum.MDR), "mdr"
if node_model == "prouter":
return Images.get(ImageEnum.PROUTER.value), "prouter"
return Images.get(ImageEnum.PROUTER), "prouter"
if node_model == "OVS":
return Images.get(ImageEnum.OVS.value), "ovs"
return Images.get(ImageEnum.OVS), "ovs"
else:
logging.debug("INVALID INPUT OR NOT CONSIDERED YET")

View file

@ -7,6 +7,8 @@ import webbrowser
from tkinter import filedialog, messagebox
from core.api.grpc import core_pb2
from coretk.dialogs.sessionoptions import SessionOptionsDialog
from coretk.dialogs.sessions import SessionsDialog
from coretk.setwallpaper import CanvasWallpaper
from coretk.sizeandscale import SizeAndScale
@ -290,10 +292,6 @@ def widgets_configure_throughput():
logging.debug("Click widgets configure throughput")
def session_change_sessions():
logging.debug("Click session change sessions")
def session_node_types():
logging.debug("Click session node types")
@ -314,10 +312,6 @@ def session_emulation_servers():
logging.debug("Click session emulation servers")
def session_options():
logging.debug("Click session options")
def help_about():
logging.debug("Click help About")
@ -429,3 +423,13 @@ class MenuAction:
def help_core_documentation(self):
webbrowser.open_new("http://coreemu.github.io/core/")
def session_options(self):
logging.debug("Click session options")
dialog = SessionOptionsDialog(self.application, self.application)
dialog.show()
def session_change_sessions(self):
logging.debug("Click session change sessions")
dialog = SessionsDialog(self.application, self.application)
dialog.show()

View file

@ -1,183 +0,0 @@
import logging
import tkinter as tk
from tkinter.ttk import Scrollbar, Treeview
from coretk.images import ImageEnum, Images
class SessionTable:
def __init__(self, grpc, master):
"""
create session table instance
:param coretk.coregrpc.CoreGrpc grpc: coregrpc
:param root.master master:
"""
self.grpc = grpc
self.selected = False
self.selected_sid = None
self.master = master
self.top = tk.Toplevel(self.master)
self.description_definition()
self.top.title("CORE sessions")
self.tree = Treeview(self.top)
# self.tree.pack(side=tk.TOP)
self.tree.grid(row=1, column=0, columnspan=2)
self.draw_scrollbar()
self.draw()
def description_definition(self):
"""
write a short description
:return: nothing
"""
lable = tk.Label(
self.top,
text="Below is a list of active CORE sessions. Double-click to "
"\nconnect to an existing session. Usually, only sessions in "
"\nthe RUNTIME state persist in the daemon, except for the "
"\none you might be concurrently editting.",
)
lable.grid(sticky=tk.W)
def column_definition(self):
# self.tree["columns"] = ("name", "nodecount", "filename", "date")
self.tree["columns"] = "nodecount"
self.tree.column("#0", width=300, minwidth=30)
# self.tree.column("name", width=72, miwidth=30)
self.tree.column("nodecount", width=300, minwidth=30)
# self.tree.column("filename", width=92, minwidth=30)
# self.tree.column("date", width=170, minwidth=30)
def draw_scrollbar(self):
yscrollbar = Scrollbar(self.top, orient="vertical", command=self.tree.yview)
yscrollbar.grid(row=1, column=3, sticky=tk.N + tk.S + tk.W)
self.tree.configure(yscrollcommand=yscrollbar.set)
xscrollbar = Scrollbar(self.top, orient="horizontal", command=self.tree.xview)
xscrollbar.grid(row=2, columnspan=2, sticky=tk.E + tk.W + tk.S)
self.tree.configure(xscrollcommand=xscrollbar.set)
def heading_definition(self):
self.tree.heading("#0", text="ID", anchor=tk.W)
# self.tree.heading("name", text="Name", anchor=tk.CENTER)
self.tree.heading("nodecount", text="Node Count", anchor=tk.W)
# self.tree.heading("filename", text="Filename", anchor=tk.CENTER)
# self.tree.heading("date", text="Date", anchor=tk.CENTER)
def enter_session(self, sid):
self.top.destroy()
response = self.grpc.core.get_session(sid)
self.grpc.session_id = sid
self.grpc.core.events(sid, self.grpc.log_event)
logging.info("Entering session_id %s.... Result: %s", sid, response)
def new_session(self):
self.top.destroy()
self.grpc.create_new_session()
def on_selected(self, event):
item = self.tree.selection()
sid = int(self.tree.item(item, "text"))
self.enter_session(sid)
def click_select(self, event):
# logging.debug("Click on %s ", event)
item = self.tree.selection()
sid = int(self.tree.item(item, "text"))
self.selected = True
self.selected_sid = sid
def session_definition(self):
response = self.grpc.core.get_sessions()
# logging.info("querysessiondrawing.py Get all sessions %s", response)
index = 1
for session in response.sessions:
self.tree.insert(
"", index, None, text=str(session.id), values=(str(session.nodes))
)
index = index + 1
self.tree.bind("<Double-1>", self.on_selected)
self.tree.bind("<<TreeviewSelect>>", self.click_select)
def click_connect(self):
"""
if no session is selected yet, create a new one else join that session
:return: nothing
"""
if self.selected and self.selected_sid is not None:
self.enter_session(self.selected_sid)
elif not self.selected and self.selected_sid is None:
self.new_session()
else:
logging.error("querysessiondrawing.py invalid state")
def shutdown_session(self, sid):
self.grpc.terminate_session(sid)
self.new_session()
self.top.destroy()
def click_shutdown(self):
"""
if no session is currently selected create a new session else shut the selected session down
:return: nothing
"""
if self.selected and self.selected_sid is not None:
self.shutdown_session(self.selected_sid)
elif not self.selected and self.selected_sid is None:
self.new_session()
else:
logging.error("querysessiondrawing.py invalid state")
# if self.selected and self.selected_sid is not None:
def draw_buttons(self):
f = tk.Frame(self.top)
f.grid(row=3, sticky=tk.W)
b = tk.Button(
f,
image=Images.get(ImageEnum.DOCUMENTNEW.value),
text="New",
compound=tk.LEFT,
command=self.new_session,
)
b.pack(side=tk.LEFT, padx=3, pady=4)
b = tk.Button(
f,
image=Images.get(ImageEnum.FILEOPEN.value),
text="Connect",
compound=tk.LEFT,
command=self.click_connect,
)
b.pack(side=tk.LEFT, padx=3, pady=4)
b = tk.Button(
f,
image=Images.get(ImageEnum.EDITDELETE.value),
text="Shutdown",
compound=tk.LEFT,
command=self.click_shutdown,
)
b.pack(side=tk.LEFT, padx=3, pady=4)
b = tk.Button(f, text="Cancel", command=self.new_session)
b.pack(side=tk.LEFT, padx=3, pady=4)
def center(self):
window_width = self.master.winfo_width()
window_height = self.master.winfo_height()
self.top.update()
top_level_width = self.top.winfo_width()
top_level_height = self.top.winfo_height()
x = window_width / 2 - top_level_width / 2
y = window_height / 2 - top_level_height / 2
self.top.geometry("+%d+%d" % (x, y))
def draw(self):
self.column_definition()
self.heading_definition()
self.session_definition()
self.draw_buttons()
self.center()
self.top.wait_window()