pygui: update title to show xml file when one is opened, fixed issue creating nodes/links when not runtime due to refactoring, removed xml_file from coreclient and depend on the grpc GetSession wrapped data, grpc: added opened file information to GetSession call
This commit is contained in:
parent
04f7bc561b
commit
fc44ad6fe8
7 changed files with 48 additions and 47 deletions
|
@ -229,7 +229,7 @@ def get_config_options(
|
|||
"""
|
||||
results = {}
|
||||
for configuration in configurable_options.configurations():
|
||||
value = config[configuration.id]
|
||||
value = config.get(configuration.id, configuration.default)
|
||||
config_option = common_pb2.ConfigOption(
|
||||
label=configuration.label,
|
||||
name=configuration.id,
|
||||
|
|
|
@ -597,6 +597,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
config_service_configs=config_service_configs,
|
||||
mobility_configs=mobility_configs,
|
||||
metadata=session.metadata,
|
||||
file=session.file_name,
|
||||
)
|
||||
return core_pb2.GetSessionResponse(session=session_proto)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ from core.api.grpc import (
|
|||
wlan_pb2,
|
||||
)
|
||||
from core.gui import appconfig
|
||||
from core.gui.appconfig import CoreServer, Observer
|
||||
from core.gui.appconfig import XMLS_PATH, CoreServer, Observer
|
||||
from core.gui.dialogs.emaneinstall import EmaneInstallDialog
|
||||
from core.gui.dialogs.error import ErrorDialog
|
||||
from core.gui.dialogs.mobilityplayer import MobilityPlayer
|
||||
|
@ -98,8 +98,6 @@ class CoreClient:
|
|||
self.handling_throughputs: Optional[grpc.Future] = None
|
||||
self.handling_cpu_usage: Optional[grpc.Future] = None
|
||||
self.handling_events: Optional[grpc.Future] = None
|
||||
self.xml_dir: Optional[str] = None
|
||||
self.xml_file: Optional[str] = None
|
||||
|
||||
@property
|
||||
def client(self) -> client.CoreGrpcClient:
|
||||
|
@ -311,7 +309,8 @@ class CoreClient:
|
|||
response = self.client.get_session(session_id)
|
||||
self.session = Session.from_proto(response.session)
|
||||
self.client.set_session_user(self.session.id, self.user)
|
||||
self.master.title(f"CORE Session({self.session.id})")
|
||||
title_file = self.session.file.name if self.session.file else ""
|
||||
self.master.title(f"CORE Session({self.session.id}) {title_file}")
|
||||
self.handling_events = self.client.events(
|
||||
self.session.id, self.handle_events
|
||||
)
|
||||
|
@ -586,10 +585,18 @@ class CoreClient:
|
|||
except grpc.RpcError as e:
|
||||
self.app.show_grpc_exception("Node Terminal Error", e)
|
||||
|
||||
def save_xml(self, file_path: str) -> None:
|
||||
def get_xml_dir(self) -> str:
|
||||
return str(self.session.file.parent) if self.session.file else str(XMLS_PATH)
|
||||
|
||||
def save_xml(self, file_path: str = None) -> None:
|
||||
"""
|
||||
Save core session as to an xml file
|
||||
"""
|
||||
if not file_path and not self.session.file:
|
||||
logging.error("trying to save xml for session with no file")
|
||||
return
|
||||
if not file_path:
|
||||
file_path = str(self.session.file)
|
||||
try:
|
||||
if not self.is_runtime():
|
||||
logging.debug("Send session data to the daemon")
|
||||
|
@ -687,34 +694,17 @@ class CoreClient:
|
|||
"""
|
||||
self.client.set_session_state(self.session.id, SessionState.DEFINITION.value)
|
||||
for node in self.session.nodes.values():
|
||||
response = self.client.add_node(self.session.id, node.to_proto())
|
||||
response = self.client.add_node(
|
||||
self.session.id, node.to_proto(), source=GUI_SOURCE
|
||||
)
|
||||
logging.debug("created node: %s", response)
|
||||
asymmetric_links = []
|
||||
for edge in self.links.values():
|
||||
link = edge.link
|
||||
response = self.client.add_link(
|
||||
self.session.id,
|
||||
link.node1_id,
|
||||
link.node2_id,
|
||||
link.iface1,
|
||||
link.iface2,
|
||||
link.options,
|
||||
source=GUI_SOURCE,
|
||||
)
|
||||
logging.debug("created link: %s", response)
|
||||
self.add_link(edge.link)
|
||||
if edge.asymmetric_link:
|
||||
asymmetric_links.append(edge.asymmetric_link)
|
||||
for link in asymmetric_links:
|
||||
response = self.client.add_link(
|
||||
self.session.id,
|
||||
link.node1_id,
|
||||
link.node2_id,
|
||||
link.iface1,
|
||||
link.iface2,
|
||||
link.options,
|
||||
source=GUI_SOURCE,
|
||||
)
|
||||
logging.debug("created asymmetric link: %s", response)
|
||||
self.add_link(link)
|
||||
|
||||
def send_data(self) -> None:
|
||||
"""
|
||||
|
@ -1057,6 +1047,23 @@ class CoreClient:
|
|||
if response.session_id != -1:
|
||||
self.join_session(response.session_id)
|
||||
|
||||
def add_link(self, link: Link) -> None:
|
||||
iface1 = link.iface1.to_proto() if link.iface1 else None
|
||||
iface2 = link.iface2.to_proto() if link.iface2 else None
|
||||
options = link.options.to_proto() if link.options else None
|
||||
response = self.client.add_link(
|
||||
self.session.id,
|
||||
link.node1_id,
|
||||
link.node2_id,
|
||||
iface1,
|
||||
iface2,
|
||||
options,
|
||||
source=GUI_SOURCE,
|
||||
)
|
||||
logging.debug("added link: %s", response)
|
||||
if not response.result:
|
||||
logging.error("error adding link: %s", link)
|
||||
|
||||
def edit_link(self, link: Link) -> None:
|
||||
iface1_id = link.iface1.id if link.iface1 else None
|
||||
iface2_id = link.iface2.id if link.iface2 else None
|
||||
|
|
|
@ -181,8 +181,6 @@ class SessionsDialog(Dialog):
|
|||
|
||||
def join_session(self, session_id: int) -> None:
|
||||
self.destroy()
|
||||
if self.app.core.xml_file:
|
||||
self.app.core.xml_file = None
|
||||
task = ProgressTask(
|
||||
self.app, "Join", self.app.core.join_session, args=(session_id,)
|
||||
)
|
||||
|
|
|
@ -6,7 +6,6 @@ from functools import partial
|
|||
from tkinter import filedialog, messagebox
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from core.gui.appconfig import XMLS_PATH
|
||||
from core.gui.coreclient import CoreClient
|
||||
from core.gui.dialogs.about import AboutDialog
|
||||
from core.gui.dialogs.canvassizeandscale import SizeAndScaleDialog
|
||||
|
@ -265,16 +264,13 @@ class Menubar(tk.Menu):
|
|||
)
|
||||
|
||||
def click_save(self, _event=None) -> None:
|
||||
xml_file = self.core.xml_file
|
||||
if xml_file:
|
||||
self.core.save_xml(xml_file)
|
||||
if self.core.session.file:
|
||||
self.core.save_xml()
|
||||
else:
|
||||
self.click_save_xml()
|
||||
|
||||
def click_save_xml(self, _event: tk.Event = None) -> None:
|
||||
init_dir = self.core.xml_dir
|
||||
if not init_dir:
|
||||
init_dir = str(XMLS_PATH)
|
||||
init_dir = self.core.get_xml_dir()
|
||||
file_path = filedialog.asksaveasfilename(
|
||||
initialdir=init_dir,
|
||||
title="Save As",
|
||||
|
@ -284,12 +280,9 @@ class Menubar(tk.Menu):
|
|||
if file_path:
|
||||
self.add_recent_file_to_gui_config(file_path)
|
||||
self.core.save_xml(file_path)
|
||||
self.core.xml_file = file_path
|
||||
|
||||
def click_open_xml(self, _event: tk.Event = None) -> None:
|
||||
init_dir = self.core.xml_dir
|
||||
if not init_dir:
|
||||
init_dir = str(XMLS_PATH)
|
||||
init_dir = self.core.get_xml_dir()
|
||||
file_path = filedialog.askopenfilename(
|
||||
initialdir=init_dir,
|
||||
title="Open",
|
||||
|
@ -298,12 +291,10 @@ class Menubar(tk.Menu):
|
|||
if file_path:
|
||||
self.open_xml_task(file_path)
|
||||
|
||||
def open_xml_task(self, filename: str) -> None:
|
||||
self.add_recent_file_to_gui_config(filename)
|
||||
self.core.xml_file = filename
|
||||
self.core.xml_dir = str(os.path.dirname(filename))
|
||||
def open_xml_task(self, file_path: str) -> None:
|
||||
self.add_recent_file_to_gui_config(file_path)
|
||||
self.prompt_save_running_session()
|
||||
task = ProgressTask(self.app, "Open XML", self.core.open_xml, args=(filename,))
|
||||
task = ProgressTask(self.app, "Open XML", self.core.open_xml, args=(file_path,))
|
||||
task.start()
|
||||
|
||||
def execute_python(self) -> None:
|
||||
|
@ -357,7 +348,6 @@ class Menubar(tk.Menu):
|
|||
def click_new(self) -> None:
|
||||
self.prompt_save_running_session()
|
||||
self.core.create_new_session()
|
||||
self.core.xml_file = None
|
||||
|
||||
def click_find(self, _event: tk.Event = None) -> None:
|
||||
dialog = FindDialog(self.app)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Set, Tuple
|
||||
|
||||
from core.api.grpc import common_pb2, configservices_pb2, core_pb2, services_pb2
|
||||
|
@ -581,6 +582,7 @@ class Session:
|
|||
emane_models: List[str]
|
||||
emane_config: Dict[str, ConfigOption]
|
||||
metadata: Dict[str, str]
|
||||
file: Path
|
||||
|
||||
@classmethod
|
||||
def from_proto(cls, proto: core_pb2.Session) -> "Session":
|
||||
|
@ -616,6 +618,7 @@ class Session:
|
|||
for node_id, mapped_config in proto.mobility_configs.items():
|
||||
node = nodes[node_id]
|
||||
node.mobility_config = ConfigOption.from_dict(mapped_config.config)
|
||||
file_path = Path(proto.file) if proto.file else None
|
||||
return Session(
|
||||
id=proto.id,
|
||||
state=SessionState(proto.state),
|
||||
|
@ -629,6 +632,7 @@ class Session:
|
|||
emane_models=list(proto.emane_models),
|
||||
emane_config=ConfigOption.from_dict(proto.emane_config),
|
||||
metadata=dict(proto.metadata),
|
||||
file=file_path,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -726,6 +726,7 @@ message Session {
|
|||
repeated configservices.ConfigServiceConfig config_service_configs = 15;
|
||||
map<int32, common.MappedConfig> mobility_configs = 16;
|
||||
map<string, string> metadata = 17;
|
||||
string file = 18;
|
||||
}
|
||||
|
||||
message SessionSummary {
|
||||
|
|
Loading…
Reference in a new issue