Merge branch 'coretk' of https://github.com/coreemu/core into coretk
This commit is contained in:
commit
2586a5ad6f
8 changed files with 119 additions and 58 deletions
|
@ -3,6 +3,7 @@ Incorporate grpc into python tkinter GUI
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
from core.api.grpc import client, core_pb2
|
from core.api.grpc import client, core_pb2
|
||||||
from coretk.dialogs.mobilityplayer import MobilityPlayerDialog
|
from coretk.dialogs.mobilityplayer import MobilityPlayerDialog
|
||||||
|
@ -164,8 +165,8 @@ class CoreClient:
|
||||||
)
|
)
|
||||||
|
|
||||||
def join_session(self, session_id, query_location=True):
|
def join_session(self, session_id, query_location=True):
|
||||||
self.master.config(cursor="watch")
|
# self.master.config(cursor="watch")
|
||||||
self.master.update()
|
# self.master.update()
|
||||||
|
|
||||||
# update session and title
|
# update session and title
|
||||||
self.session_id = session_id
|
self.session_id = session_id
|
||||||
|
@ -225,12 +226,36 @@ class CoreClient:
|
||||||
# draw session
|
# draw session
|
||||||
self.app.canvas.reset_and_redraw(session)
|
self.app.canvas.reset_and_redraw(session)
|
||||||
|
|
||||||
# draw tool bar appropritate with session state
|
# get node service config and file config
|
||||||
|
for node in session.nodes:
|
||||||
|
self.created_nodes.add(node.id)
|
||||||
|
for link in session.links:
|
||||||
|
self.created_links.add(tuple(sorted([link.node_one_id, link.node_two_id])))
|
||||||
|
for node in session.nodes:
|
||||||
|
if node.type == core_pb2.NodeType.DEFAULT:
|
||||||
|
for service in node.services:
|
||||||
|
response = self.client.get_node_service(
|
||||||
|
self.session_id, node.id, service
|
||||||
|
)
|
||||||
|
if node.id not in self.service_configs:
|
||||||
|
self.service_configs[node.id] = {}
|
||||||
|
self.service_configs[node.id][service] = response.service
|
||||||
|
for file in response.service.configs:
|
||||||
|
response = self.client.get_node_service_file(
|
||||||
|
self.session_id, node.id, service, file
|
||||||
|
)
|
||||||
|
if node.id not in self.file_configs:
|
||||||
|
self.file_configs[node.id] = {}
|
||||||
|
if service not in self.file_configs[node.id]:
|
||||||
|
self.file_configs[node.id][service] = {}
|
||||||
|
self.file_configs[node.id][service][file] = response.data
|
||||||
|
|
||||||
if self.is_runtime():
|
if self.is_runtime():
|
||||||
self.app.toolbar.runtime_frame.tkraise()
|
self.app.toolbar.runtime_frame.tkraise()
|
||||||
else:
|
else:
|
||||||
self.app.toolbar.design_frame.tkraise()
|
self.app.toolbar.design_frame.tkraise()
|
||||||
self.master.config(cursor="")
|
# self.master.config(cursor="")
|
||||||
|
self.app.statusbar.progress_bar.stop()
|
||||||
|
|
||||||
def is_runtime(self):
|
def is_runtime(self):
|
||||||
return self.state == core_pb2.SessionState.RUNTIME
|
return self.state == core_pb2.SessionState.RUNTIME
|
||||||
|
@ -315,6 +340,8 @@ class CoreClient:
|
||||||
emane_config = {x: self.emane_config[x].value for x in self.emane_config}
|
emane_config = {x: self.emane_config[x].value for x in self.emane_config}
|
||||||
else:
|
else:
|
||||||
emane_config = None
|
emane_config = None
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
response = self.client.start_session(
|
response = self.client.start_session(
|
||||||
self.session_id,
|
self.session_id,
|
||||||
nodes,
|
nodes,
|
||||||
|
@ -328,12 +355,17 @@ class CoreClient:
|
||||||
service_configs,
|
service_configs,
|
||||||
file_configs,
|
file_configs,
|
||||||
)
|
)
|
||||||
|
process_time = time.time() - start
|
||||||
logging.debug("start session(%s), result: %s", self.session_id, response.result)
|
logging.debug("start session(%s), result: %s", self.session_id, response.result)
|
||||||
|
self.app.statusbar.start_session_callback(process_time)
|
||||||
|
|
||||||
def stop_session(self, session_id=None):
|
def stop_session(self, session_id=None):
|
||||||
if not session_id:
|
if not session_id:
|
||||||
session_id = self.session_id
|
session_id = self.session_id
|
||||||
|
start = time.time()
|
||||||
response = self.client.stop_session(session_id)
|
response = self.client.stop_session(session_id)
|
||||||
|
process_time = time.time() - start
|
||||||
|
self.app.statusbar.stop_session_callback(process_time)
|
||||||
logging.debug("stopped session(%s), result: %s", session_id, response.result)
|
logging.debug("stopped session(%s), result: %s", session_id, response.result)
|
||||||
|
|
||||||
def launch_terminal(self, node_id):
|
def launch_terminal(self, node_id):
|
||||||
|
|
|
@ -197,8 +197,9 @@ class NodeConfigDialog(Dialog):
|
||||||
self.node.name = self.name.get()
|
self.node.name = self.name.get()
|
||||||
if NodeUtils.is_image_node(self.node.type):
|
if NodeUtils.is_image_node(self.node.type):
|
||||||
self.node.image = self.container_image.get()
|
self.node.image = self.container_image.get()
|
||||||
if NodeUtils.is_container_node(self.node.type):
|
server = self.server.get()
|
||||||
self.node.server = self.server.get()
|
if NodeUtils.is_container_node(self.node.type) and server != "localhost":
|
||||||
|
self.node.server = server
|
||||||
|
|
||||||
# update canvas node
|
# update canvas node
|
||||||
self.canvas_node.image = self.image
|
self.canvas_node.image = self.image
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
import threading
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
|
||||||
|
@ -146,7 +147,11 @@ class SessionsDialog(Dialog):
|
||||||
logging.error("querysessiondrawing.py invalid state")
|
logging.error("querysessiondrawing.py invalid state")
|
||||||
|
|
||||||
def join_session(self, session_id):
|
def join_session(self, session_id):
|
||||||
self.app.core.join_session(session_id)
|
self.app.statusbar.progress_bar.start(5)
|
||||||
|
thread = threading.Thread(
|
||||||
|
target=self.app.core.join_session, args=([session_id])
|
||||||
|
)
|
||||||
|
thread.start()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
|
||||||
def on_selected(self, event):
|
def on_selected(self, event):
|
||||||
|
|
|
@ -7,7 +7,16 @@ import tkinter as tk
|
||||||
from coretk.images import ImageEnum, Images
|
from coretk.images import ImageEnum, Images
|
||||||
from coretk.nodeutils import NodeUtils
|
from coretk.nodeutils import NodeUtils
|
||||||
|
|
||||||
CANVAS_COMPONENT_TAGS = ["edge", "node", "nodename", "wallpaper", "linkinfo"]
|
CANVAS_COMPONENT_TAGS = [
|
||||||
|
"edge",
|
||||||
|
"node",
|
||||||
|
"nodename",
|
||||||
|
"wallpaper",
|
||||||
|
"linkinfo",
|
||||||
|
"antenna",
|
||||||
|
"wireless",
|
||||||
|
"selectednodes",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class GraphHelper:
|
class GraphHelper:
|
||||||
|
|
|
@ -3,6 +3,8 @@ The actions taken when each menubar option is clicked
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
import webbrowser
|
import webbrowser
|
||||||
from tkinter import filedialog, messagebox
|
from tkinter import filedialog, messagebox
|
||||||
|
|
||||||
|
@ -27,7 +29,16 @@ class MenuAction:
|
||||||
self.master = master
|
self.master = master
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
def prompt_save_running_session(self):
|
def cleanup_old_session(self, quitapp=False):
|
||||||
|
start = time.time()
|
||||||
|
self.app.core.stop_session()
|
||||||
|
self.app.core.delete_session()
|
||||||
|
process_time = time.time() - start
|
||||||
|
self.app.statusbar.stop_session_callback(process_time)
|
||||||
|
if quitapp:
|
||||||
|
self.app.quit()
|
||||||
|
|
||||||
|
def prompt_save_running_session(self, quitapp=False):
|
||||||
"""
|
"""
|
||||||
Prompt use to stop running session before application is closed
|
Prompt use to stop running session before application is closed
|
||||||
|
|
||||||
|
@ -43,13 +54,20 @@ class MenuAction:
|
||||||
or state == core_pb2.SessionState.DEFINITION
|
or state == core_pb2.SessionState.DEFINITION
|
||||||
):
|
):
|
||||||
self.app.core.delete_session()
|
self.app.core.delete_session()
|
||||||
|
if quitapp:
|
||||||
|
self.app.quit()
|
||||||
else:
|
else:
|
||||||
msgbox = messagebox.askyesnocancel("stop", "Stop the running session?")
|
msgbox = messagebox.askyesnocancel("stop", "Stop the running session?")
|
||||||
|
|
||||||
if msgbox or msgbox is False:
|
if msgbox or msgbox is False:
|
||||||
if msgbox:
|
if msgbox:
|
||||||
self.app.core.stop_session()
|
self.app.statusbar.progress_bar.start(5)
|
||||||
self.app.core.delete_session()
|
thread = threading.Thread(
|
||||||
|
target=self.cleanup_old_session, args=([quitapp])
|
||||||
|
)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
# self.app.core.stop_session()
|
||||||
|
# self.app.core.delete_session()
|
||||||
|
|
||||||
def on_quit(self, event=None):
|
def on_quit(self, event=None):
|
||||||
"""
|
"""
|
||||||
|
@ -57,8 +75,8 @@ class MenuAction:
|
||||||
|
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
self.prompt_save_running_session()
|
self.prompt_save_running_session(quitapp=True)
|
||||||
self.app.quit()
|
# self.app.quit()
|
||||||
|
|
||||||
def file_save_as_xml(self, event=None):
|
def file_save_as_xml(self, event=None):
|
||||||
logging.info("menuaction.py file_save_as_xml()")
|
logging.info("menuaction.py file_save_as_xml()")
|
||||||
|
@ -81,7 +99,10 @@ class MenuAction:
|
||||||
if file_path:
|
if file_path:
|
||||||
logging.info("opening xml: %s", file_path)
|
logging.info("opening xml: %s", file_path)
|
||||||
self.prompt_save_running_session()
|
self.prompt_save_running_session()
|
||||||
self.app.core.open_xml(file_path)
|
self.app.statusbar.progress_bar.start(5)
|
||||||
|
thread = threading.Thread(target=self.app.core.open_xml, args=([file_path]))
|
||||||
|
thread.start()
|
||||||
|
# self.app.core.open_xml(file_path)
|
||||||
|
|
||||||
def gui_preferences(self):
|
def gui_preferences(self):
|
||||||
dialog = PreferencesDialog(self.app, self.app)
|
dialog = PreferencesDialog(self.app, self.app)
|
||||||
|
|
|
@ -27,7 +27,10 @@ class CanvasComponentManagement:
|
||||||
if canvas_node.id not in self.selected:
|
if canvas_node.id not in self.selected:
|
||||||
x0, y0, x1, y1 = self.canvas.bbox(canvas_node.id)
|
x0, y0, x1, y1 = self.canvas.bbox(canvas_node.id)
|
||||||
bbox_id = self.canvas.create_rectangle(
|
bbox_id = self.canvas.create_rectangle(
|
||||||
(x0 - 6, y0 - 6, x1 + 6, y1 + 6), activedash=True, dash="-"
|
(x0 - 6, y0 - 6, x1 + 6, y1 + 6),
|
||||||
|
activedash=True,
|
||||||
|
dash="-",
|
||||||
|
tags="selectednodes",
|
||||||
)
|
)
|
||||||
self.selected[canvas_node.id] = bbox_id
|
self.selected[canvas_node.id] = bbox_id
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"status bar"
|
"status bar"
|
||||||
import time
|
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
|
||||||
|
@ -11,6 +10,7 @@ class StatusBar(ttk.Frame):
|
||||||
|
|
||||||
self.status = None
|
self.status = None
|
||||||
self.statusvar = tk.StringVar()
|
self.statusvar = tk.StringVar()
|
||||||
|
self.progress_bar = None
|
||||||
self.zoom = None
|
self.zoom = None
|
||||||
self.cpu_usage = None
|
self.cpu_usage = None
|
||||||
self.memory = None
|
self.memory = None
|
||||||
|
@ -19,26 +19,35 @@ class StatusBar(ttk.Frame):
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
self.columnconfigure(0, weight=8)
|
self.columnconfigure(0, weight=1)
|
||||||
self.columnconfigure(1, weight=1)
|
self.columnconfigure(1, weight=7)
|
||||||
self.columnconfigure(2, weight=1)
|
self.columnconfigure(2, weight=1)
|
||||||
self.columnconfigure(3, weight=1)
|
self.columnconfigure(3, weight=1)
|
||||||
|
self.columnconfigure(4, weight=1)
|
||||||
|
|
||||||
|
self.progress_bar = ttk.Progressbar(
|
||||||
|
self, orient="horizontal", mode="indeterminate"
|
||||||
|
)
|
||||||
|
self.progress_bar.grid(row=0, column=0, sticky="nsew")
|
||||||
self.status = ttk.Label(self, textvariable=self.statusvar)
|
self.status = ttk.Label(self, textvariable=self.statusvar)
|
||||||
self.statusvar.set("status")
|
self.statusvar.set("status")
|
||||||
self.status.grid(row=0, column=0)
|
self.status.grid(row=0, column=1, sticky="nsew")
|
||||||
self.zoom = ttk.Label(self, text="zoom")
|
self.zoom = ttk.Label(self, text="zoom")
|
||||||
self.zoom.grid(row=0, column=1)
|
self.zoom.grid(row=0, column=2)
|
||||||
self.cpu_usage = ttk.Label(self, text="cpu usage")
|
self.cpu_usage = ttk.Label(self, text="cpu usage")
|
||||||
self.cpu_usage.grid(row=0, column=2)
|
self.cpu_usage.grid(row=0, column=3)
|
||||||
self.emulation_light = ttk.Label(self, text="emulation light")
|
self.emulation_light = ttk.Label(self, text="emulation light")
|
||||||
self.emulation_light.grid(row=0, column=3)
|
self.emulation_light.grid(row=0, column=4)
|
||||||
|
|
||||||
def processing(self):
|
def start_session_callback(self, process_time):
|
||||||
texts = ["Processing.", "Processing..", "Processing...", "Processing...."]
|
num_nodes = len(self.app.core.canvas_nodes)
|
||||||
i = 0
|
num_links = len(self.app.core.links)
|
||||||
while self.running:
|
self.progress_bar.stop()
|
||||||
self.statusvar.set(texts[i % 4])
|
self.statusvar.set(
|
||||||
self.master.update()
|
"Network topology instantiated in %s seconds (%s node(s) and %s link(s))"
|
||||||
i = i + 1
|
% ("%.3f" % process_time, num_nodes, num_links)
|
||||||
time.sleep(0.002)
|
)
|
||||||
print("thread finish")
|
|
||||||
|
def stop_session_callback(self, cleanup_time):
|
||||||
|
self.progress_bar.stop()
|
||||||
|
self.statusvar.set("Cleanup completed in %s seconds" % "%.3f" % cleanup_time)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
import time
|
import threading
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
@ -196,25 +196,11 @@ class Toolbar(ttk.Frame):
|
||||||
|
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
self.app.statusbar.running = True
|
self.app.statusbar.progress_bar.start(5)
|
||||||
# thread = threading.Thread(target=self.app.statusbar.processing)
|
|
||||||
# thread.start()
|
|
||||||
self.master.config(cursor="watch")
|
|
||||||
self.master.update()
|
|
||||||
self.app.canvas.mode = GraphMode.SELECT
|
self.app.canvas.mode = GraphMode.SELECT
|
||||||
start = time.time()
|
thread = threading.Thread(target=self.app.core.start_session)
|
||||||
self.app.core.start_session()
|
thread.start()
|
||||||
dur = time.time() - start
|
|
||||||
self.runtime_frame.tkraise()
|
self.runtime_frame.tkraise()
|
||||||
self.master.config(cursor="")
|
|
||||||
nodes_num = len(self.app.core.canvas_nodes)
|
|
||||||
links_num = len(self.app.core.links)
|
|
||||||
self.app.statusbar.statusvar.set(
|
|
||||||
"Network topology instantiated in %s seconds (%s node(s) and %s link(s))"
|
|
||||||
% ("%.3f" % dur, nodes_num, links_num)
|
|
||||||
)
|
|
||||||
# self.app.statusbar.running = False
|
|
||||||
# print("done")
|
|
||||||
|
|
||||||
def click_link(self):
|
def click_link(self):
|
||||||
logging.debug("Click LINK button")
|
logging.debug("Click LINK button")
|
||||||
|
@ -367,14 +353,9 @@ class Toolbar(ttk.Frame):
|
||||||
|
|
||||||
:return: nothing
|
:return: nothing
|
||||||
"""
|
"""
|
||||||
logging.debug("Click on STOP button ")
|
self.app.statusbar.progress_bar.start(5)
|
||||||
# self.status_thread.join()
|
thread = threading.Thread(target=self.app.core.stop_session)
|
||||||
start = time.time()
|
thread.start()
|
||||||
self.app.core.stop_session()
|
|
||||||
dur = time.time() - start
|
|
||||||
self.app.statusbar.statusvar.set(
|
|
||||||
"Cleanup completed in %s seconds" % "%.3f" % dur
|
|
||||||
)
|
|
||||||
self.app.canvas.delete("wireless")
|
self.app.canvas.delete("wireless")
|
||||||
self.design_frame.tkraise()
|
self.design_frame.tkraise()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue