shape
|
@ -18,9 +18,10 @@ XML_PATH = HOME_PATH.joinpath("xml")
|
||||||
CONFIG_PATH = HOME_PATH.joinpath("gui.yaml")
|
CONFIG_PATH = HOME_PATH.joinpath("gui.yaml")
|
||||||
|
|
||||||
# local paths
|
# local paths
|
||||||
LOCAL_ICONS_PATH = Path(__file__).parent.joinpath("icons").absolute()
|
DATA_PATH = Path(__file__).parent.joinpath("data")
|
||||||
LOCAL_BACKGROUND_PATH = Path(__file__).parent.joinpath("backgrounds").absolute()
|
LOCAL_ICONS_PATH = DATA_PATH.joinpath("icons").absolute()
|
||||||
LOCAL_XMLS_PATH = Path(__file__).parent.joinpath("xmls").absolute()
|
LOCAL_BACKGROUND_PATH = DATA_PATH.joinpath("backgrounds").absolute()
|
||||||
|
LOCAL_XMLS_PATH = DATA_PATH.joinpath("xmls").absolute()
|
||||||
|
|
||||||
# configuration data
|
# configuration data
|
||||||
TERMINALS = [
|
TERMINALS = [
|
||||||
|
|
|
@ -141,15 +141,19 @@ class CoreClient:
|
||||||
else:
|
else:
|
||||||
logging.warning("unknown session event: %s", session_event)
|
logging.warning("unknown session event: %s", session_event)
|
||||||
elif event.HasField("node_event"):
|
elif event.HasField("node_event"):
|
||||||
node_event = event.node_event
|
self.handle_node_event(event.node_event)
|
||||||
node_id = node_event.node.id
|
|
||||||
x = node_event.node.position.x
|
|
||||||
y = node_event.node.position.y
|
|
||||||
canvas_node = self.canvas_nodes[node_id]
|
|
||||||
canvas_node.move(x, y)
|
|
||||||
else:
|
else:
|
||||||
logging.info("unhandled event: %s", event)
|
logging.info("unhandled event: %s", event)
|
||||||
|
|
||||||
|
def handle_node_event(self, event):
|
||||||
|
if event.source == "gui":
|
||||||
|
return
|
||||||
|
node_id = event.node.id
|
||||||
|
x = event.node.position.x
|
||||||
|
y = event.node.position.y
|
||||||
|
canvas_node = self.canvas_nodes[node_id]
|
||||||
|
canvas_node.move(x, y)
|
||||||
|
|
||||||
def handle_throughputs(self, event):
|
def handle_throughputs(self, event):
|
||||||
interface_throughputs = event.interface_throughputs
|
interface_throughputs = event.interface_throughputs
|
||||||
for i in interface_throughputs:
|
for i in interface_throughputs:
|
||||||
|
@ -164,9 +168,6 @@ 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.update()
|
|
||||||
|
|
||||||
# update session and title
|
# update session and title
|
||||||
self.session_id = session_id
|
self.session_id = session_id
|
||||||
self.master.title(f"CORE Session({self.session_id})")
|
self.master.title(f"CORE Session({self.session_id})")
|
||||||
|
@ -253,7 +254,6 @@ class CoreClient:
|
||||||
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.app.statusbar.progress_bar.stop()
|
self.app.statusbar.progress_bar.stop()
|
||||||
|
|
||||||
def is_runtime(self):
|
def is_runtime(self):
|
||||||
|
@ -321,8 +321,7 @@ class CoreClient:
|
||||||
|
|
||||||
def edit_node(self, node_id, x, y):
|
def edit_node(self, node_id, x, y):
|
||||||
position = core_pb2.Position(x=x, y=y)
|
position = core_pb2.Position(x=x, y=y)
|
||||||
response = self.client.edit_node(self.session_id, node_id, position)
|
self.client.edit_node(self.session_id, node_id, position, source="gui")
|
||||||
logging.info("updated node id %s: %s", node_id, response)
|
|
||||||
|
|
||||||
def start_session(self):
|
def start_session(self):
|
||||||
nodes = [x.core_node for x in self.canvas_nodes.values()]
|
nodes = [x.core_node for x in self.canvas_nodes.values()]
|
||||||
|
|
Before Width: | Height: | Size: 312 KiB After Width: | Height: | Size: 312 KiB |
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 230 B |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 635 B |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 1,006 B After Width: | Height: | Size: 1,006 B |
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 642 B After Width: | Height: | Size: 642 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 828 B After Width: | Height: | Size: 828 B |
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 259 B After Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 314 B After Width: | Height: | Size: 314 B |
Before Width: | Height: | Size: 799 B After Width: | Height: | Size: 799 B |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 719 B After Width: | Height: | Size: 719 B |
Before Width: | Height: | Size: 337 B After Width: | Height: | Size: 337 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 719 B After Width: | Height: | Size: 719 B |
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 744 B |
Before Width: | Height: | Size: 86 B After Width: | Height: | Size: 86 B |
Before Width: | Height: | Size: 724 B After Width: | Height: | Size: 724 B |
Before Width: | Height: | Size: 375 B After Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 174 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 160 B After Width: | Height: | Size: 160 B |
Before Width: | Height: | Size: 755 B After Width: | Height: | Size: 755 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 753 B |
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 925 B After Width: | Height: | Size: 925 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 127 B After Width: | Height: | Size: 127 B |
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 173 B |
|
@ -85,6 +85,13 @@ class CanvasGraph(tk.Canvas):
|
||||||
context.add_command(
|
context.add_command(
|
||||||
label="WLAN Config", command=canvas_node.show_wlan_config
|
label="WLAN Config", command=canvas_node.show_wlan_config
|
||||||
)
|
)
|
||||||
|
if self.master.core.is_runtime():
|
||||||
|
if canvas_node.core_node.id in self.master.core.mobility_players:
|
||||||
|
context.add_command(
|
||||||
|
label="Mobility Player",
|
||||||
|
command=canvas_node.show_mobility_player,
|
||||||
|
)
|
||||||
|
else:
|
||||||
context.add_command(
|
context.add_command(
|
||||||
label="Mobility Config", command=canvas_node.show_mobility_config
|
label="Mobility Config", command=canvas_node.show_mobility_config
|
||||||
)
|
)
|
||||||
|
@ -602,19 +609,20 @@ class CanvasNode:
|
||||||
old_y = self.core_node.position.y
|
old_y = self.core_node.position.y
|
||||||
x_offset = x - old_x
|
x_offset = x - old_x
|
||||||
y_offset = y - old_y
|
y_offset = y - old_y
|
||||||
self.core_node.position.x = x
|
self.core_node.position.x = int(x)
|
||||||
self.core_node.position.y = y
|
self.core_node.position.y = int(y)
|
||||||
for edge in self.edges:
|
|
||||||
x1, y1, x2, y2 = self.canvas.coords(edge.id)
|
|
||||||
if edge.src == self.id:
|
|
||||||
self.canvas.coords(edge.id, x_offset, y_offset, x2, y2)
|
|
||||||
else:
|
|
||||||
self.canvas.coords(edge.id, x1, y1, x_offset, y_offset)
|
|
||||||
edge.link_info.recalculate_info()
|
|
||||||
self.canvas.helper.update_wlan_connection(old_x, old_y, x, y, self.wlans)
|
|
||||||
self.canvas.move(self.id, x_offset, y_offset)
|
self.canvas.move(self.id, x_offset, y_offset)
|
||||||
self.canvas.move(self.text_id, x_offset, y_offset)
|
self.canvas.move(self.text_id, x_offset, y_offset)
|
||||||
self.antenna_draw.update_antennas_position(x_offset, y_offset)
|
self.antenna_draw.update_antennas_position(x_offset, y_offset)
|
||||||
|
self.canvas.canvas_management.node_drag(self, x_offset, y_offset)
|
||||||
|
for edge in self.edges:
|
||||||
|
x1, y1, x2, y2 = self.canvas.coords(edge.id)
|
||||||
|
if edge.src == self.id:
|
||||||
|
self.canvas.coords(edge.id, x, y, x2, y2)
|
||||||
|
else:
|
||||||
|
self.canvas.coords(edge.id, x1, y1, x, y)
|
||||||
|
edge.link_info.recalculate_info()
|
||||||
|
self.canvas.helper.update_wlan_connection(old_x, old_y, x, y, self.wlans)
|
||||||
|
|
||||||
def on_enter(self, event):
|
def on_enter(self, event):
|
||||||
if self.app.core.is_runtime() and self.app.core.observer:
|
if self.app.core.is_runtime() and self.app.core.observer:
|
||||||
|
@ -654,32 +662,7 @@ class CanvasNode:
|
||||||
if self.canvas.mode == GraphMode.EDGE:
|
if self.canvas.mode == GraphMode.EDGE:
|
||||||
return
|
return
|
||||||
x, y = self.canvas.canvas_xy(event)
|
x, y = self.canvas.canvas_xy(event)
|
||||||
moving_x, moving_y = self.moving
|
self.move(x, y)
|
||||||
offset_x, offset_y = x - moving_x, y - moving_y
|
|
||||||
self.moving = x, y
|
|
||||||
|
|
||||||
old_x, old_y = self.canvas.coords(self.id)
|
|
||||||
self.canvas.move(self.id, offset_x, offset_y)
|
|
||||||
self.canvas.move(self.text_id, offset_x, offset_y)
|
|
||||||
self.antenna_draw.update_antennas_position(offset_x, offset_y)
|
|
||||||
self.canvas.canvas_management.node_drag(self, offset_x, offset_y)
|
|
||||||
|
|
||||||
new_x, new_y = self.canvas.coords(self.id)
|
|
||||||
|
|
||||||
if self.canvas.core.is_runtime():
|
|
||||||
self.canvas.core.edit_node(self.core_node.id, int(new_x), int(new_y))
|
|
||||||
|
|
||||||
for edge in self.edges:
|
|
||||||
x1, y1, x2, y2 = self.canvas.coords(edge.id)
|
|
||||||
if x1 == old_x and y1 == old_y:
|
|
||||||
self.canvas.coords(edge.id, new_x, new_y, x2, y2)
|
|
||||||
else:
|
|
||||||
self.canvas.coords(edge.id, x1, y1, new_x, new_y)
|
|
||||||
edge.link_info.recalculate_info()
|
|
||||||
|
|
||||||
self.canvas.helper.update_wlan_connection(
|
|
||||||
old_x, old_y, new_x, new_y, self.wlans
|
|
||||||
)
|
|
||||||
|
|
||||||
def select_multiple(self, event):
|
def select_multiple(self, event):
|
||||||
self.canvas.canvas_management.node_select(self, True)
|
self.canvas.canvas_management.node_select(self, True)
|
||||||
|
@ -699,6 +682,9 @@ class CanvasNode:
|
||||||
dialog = MobilityConfigDialog(self.app, self.app, self)
|
dialog = MobilityConfigDialog(self.app, self.app, self)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
|
|
||||||
|
def show_mobility_player(self):
|
||||||
|
self.canvas.context = None
|
||||||
|
|
||||||
def show_emane_config(self):
|
def show_emane_config(self):
|
||||||
self.canvas.context = None
|
self.canvas.context = None
|
||||||
dialog = EmaneConfigDialog(self.app, self.app, self)
|
dialog = EmaneConfigDialog(self.app, self.app, self)
|
||||||
|
|
|
@ -35,7 +35,9 @@ class CanvasComponentManagement:
|
||||||
self.selected[canvas_node.id] = bbox_id
|
self.selected[canvas_node.id] = bbox_id
|
||||||
|
|
||||||
def node_drag(self, canvas_node, offset_x, offset_y):
|
def node_drag(self, canvas_node, offset_x, offset_y):
|
||||||
self.canvas.move(self.selected[canvas_node.id], offset_x, offset_y)
|
select_id = self.selected.get(canvas_node.id)
|
||||||
|
if select_id is not None:
|
||||||
|
self.canvas.move(select_id, offset_x, offset_y)
|
||||||
|
|
||||||
def delete_current_bbox(self):
|
def delete_current_bbox(self):
|
||||||
for bbid in self.selected.values():
|
for bbid in self.selected.values():
|
||||||
|
@ -76,8 +78,7 @@ class CanvasComponentManagement:
|
||||||
if neighbor.core_node.type != core_pb2.NodeType.WIRELESS_LAN:
|
if neighbor.core_node.type != core_pb2.NodeType.WIRELESS_LAN:
|
||||||
neighbor.antenna_draw.delete_antenna()
|
neighbor.antenna_draw.delete_antenna()
|
||||||
|
|
||||||
if canvas_node.core_node.id in node_to_wlink:
|
for link_tuple in node_to_wlink.get(canvas_node.core_node.id, []):
|
||||||
for link_tuple in node_to_wlink[canvas_node.core_node.id]:
|
|
||||||
nid_one, nid_two = link_tuple
|
nid_one, nid_two = link_tuple
|
||||||
if link_tuple in self.canvas.wireless_draw.map:
|
if link_tuple in self.canvas.wireless_draw.map:
|
||||||
self.canvas.delete(self.canvas.wireless_draw.map[link_tuple])
|
self.canvas.delete(self.canvas.wireless_draw.map[link_tuple])
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
"""
|
|
||||||
service file configuration
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceFileConfig:
|
|
||||||
def __init__(self):
|
|
||||||
# dict(node_id:dict(service:dict(filename, data)))
|
|
||||||
self.configurations = {}
|
|
||||||
|
|
||||||
# def set_service_configs(self, node_id, service_name, file_configs):
|
|
||||||
# """
|
|
||||||
# store file configs
|
|
||||||
#
|
|
||||||
# :param int node_id: node id
|
|
||||||
# :param str service_name: service name
|
|
||||||
# :param dict(str, str) file_configs: map of service file to its data
|
|
||||||
# :return: nothing
|
|
||||||
# """
|
|
||||||
# for key, value in file_configs.items():
|
|
||||||
# self.configurations[node_id][service_name][key] = value
|
|
||||||
|
|
||||||
def set_custom_service_file_config(self, node_id, service_name, file_name, data):
|
|
||||||
"""
|
|
||||||
store file config
|
|
||||||
|
|
||||||
:param int node_id: node id
|
|
||||||
:param str service_name: service name
|
|
||||||
:param str file_name: file name
|
|
||||||
:param str data: data
|
|
||||||
:return: nothing
|
|
||||||
"""
|
|
||||||
if node_id not in self.configurations:
|
|
||||||
self.configurations[node_id] = {}
|
|
||||||
if service_name not in self.configurations[node_id]:
|
|
||||||
self.configurations[node_id][service_name] = {}
|
|
||||||
self.configurations[node_id][service_name][file_name] = data
|
|
|
@ -1,85 +0,0 @@
|
||||||
"""
|
|
||||||
service node configuration
|
|
||||||
"""
|
|
||||||
import logging
|
|
||||||
from tkinter import messagebox
|
|
||||||
|
|
||||||
import grpc
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceNodeConfig:
|
|
||||||
def __init__(self, app):
|
|
||||||
self.app = app
|
|
||||||
# dict(node_id:dict(service:node_service_config_proto))
|
|
||||||
# maps node to all of its service configuration
|
|
||||||
self.configurations = {}
|
|
||||||
# dict(node_id:set(str))
|
|
||||||
# maps node to current configurations
|
|
||||||
self.current_services = {}
|
|
||||||
self.default_services = {}
|
|
||||||
|
|
||||||
# todo rewrite, no need self.default services
|
|
||||||
def node_default_services_configuration(self, node_id, node_model):
|
|
||||||
"""
|
|
||||||
set the default configurations for the default services of a node
|
|
||||||
|
|
||||||
:param coretk.graph.CanvasNode canvas_node: canvas node object
|
|
||||||
:return: nothing
|
|
||||||
"""
|
|
||||||
session_id = self.app.core.session_id
|
|
||||||
client = self.app.core.client
|
|
||||||
|
|
||||||
if len(self.default_services) == 0:
|
|
||||||
response = client.get_service_defaults(session_id)
|
|
||||||
logging.info("session default services: %s", response)
|
|
||||||
for default in response.defaults:
|
|
||||||
self.default_services[default.node_type] = default.services
|
|
||||||
|
|
||||||
self.configurations[node_id] = {}
|
|
||||||
|
|
||||||
self.current_services[node_id] = set()
|
|
||||||
for default in self.default_services[node_model]:
|
|
||||||
response = client.get_node_service(session_id, node_id, default)
|
|
||||||
logging.info(
|
|
||||||
"servicenodeconfig.py get node service (%s), result: %s",
|
|
||||||
node_id,
|
|
||||||
response,
|
|
||||||
)
|
|
||||||
self.configurations[node_id][default] = response.service
|
|
||||||
self.current_services[node_id].add(default)
|
|
||||||
|
|
||||||
def node_new_service_configuration(self, node_id, service_name):
|
|
||||||
"""
|
|
||||||
store node's configuration if a new service is added from the GUI
|
|
||||||
|
|
||||||
:param int node_id: node id
|
|
||||||
:param str service_name: service name
|
|
||||||
:return: nothing
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
config = self.app.core.get_node_service(node_id, service_name)
|
|
||||||
except grpc.RpcError:
|
|
||||||
messagebox.showerror("Service problem", "Service not found")
|
|
||||||
return False
|
|
||||||
if node_id not in self.configurations:
|
|
||||||
self.configurations[node_id] = {}
|
|
||||||
if node_id not in self.current_services:
|
|
||||||
self.current_services[node_id] = set()
|
|
||||||
if service_name not in self.configurations[node_id]:
|
|
||||||
self.configurations[node_id][service_name] = config
|
|
||||||
self.current_services[node_id].add(service_name)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def node_custom_service_configuration(self, node_id, service_name):
|
|
||||||
self.configurations[node_id][service_name] = self.app.core.get_node_service(
|
|
||||||
node_id, service_name
|
|
||||||
)
|
|
||||||
|
|
||||||
def node_service_custom_configuration(
|
|
||||||
self, node_id, service_name, startups, validates, shutdowns
|
|
||||||
):
|
|
||||||
self.app.core.set_node_service(
|
|
||||||
node_id, service_name, startups, validates, shutdowns
|
|
||||||
)
|
|
||||||
config = self.app.core.get_node_service(node_id, service_name)
|
|
||||||
self.configurations[node_id][service_name] = config
|
|
|
@ -428,7 +428,7 @@ class CoreGrpcClient:
|
||||||
request = core_pb2.GetNodeRequest(session_id=session_id, node_id=node_id)
|
request = core_pb2.GetNodeRequest(session_id=session_id, node_id=node_id)
|
||||||
return self.stub.GetNode(request)
|
return self.stub.GetNode(request)
|
||||||
|
|
||||||
def edit_node(self, session_id, node_id, position, icon=None):
|
def edit_node(self, session_id, node_id, position, icon=None, source=None):
|
||||||
"""
|
"""
|
||||||
Edit a node, currently only changes position.
|
Edit a node, currently only changes position.
|
||||||
|
|
||||||
|
@ -436,12 +436,17 @@ class CoreGrpcClient:
|
||||||
:param int node_id: node id
|
:param int node_id: node id
|
||||||
:param core_pb2.Position position: position to set node to
|
:param core_pb2.Position position: position to set node to
|
||||||
:param str icon: path to icon for gui to use for node
|
:param str icon: path to icon for gui to use for node
|
||||||
|
:param str source: application source editing node
|
||||||
:return: response with result of success or failure
|
:return: response with result of success or failure
|
||||||
:rtype: core_pb2.EditNodeResponse
|
:rtype: core_pb2.EditNodeResponse
|
||||||
:raises grpc.RpcError: when session or node doesn't exist
|
:raises grpc.RpcError: when session or node doesn't exist
|
||||||
"""
|
"""
|
||||||
request = core_pb2.EditNodeRequest(
|
request = core_pb2.EditNodeRequest(
|
||||||
session_id=session_id, node_id=node_id, position=position, icon=icon
|
session_id=session_id,
|
||||||
|
node_id=node_id,
|
||||||
|
position=position,
|
||||||
|
icon=icon,
|
||||||
|
source=source,
|
||||||
)
|
)
|
||||||
return self.stub.EditNode(request)
|
return self.stub.EditNode(request)
|
||||||
|
|
||||||
|
|
|
@ -504,7 +504,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
position=position,
|
position=position,
|
||||||
services=services,
|
services=services,
|
||||||
)
|
)
|
||||||
return core_pb2.NodeEvent(node=node_proto)
|
return core_pb2.NodeEvent(node=node_proto, source=event.source)
|
||||||
|
|
||||||
def _handle_link_event(self, event):
|
def _handle_link_event(self, event):
|
||||||
"""
|
"""
|
||||||
|
@ -800,7 +800,10 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
||||||
result = True
|
result = True
|
||||||
try:
|
try:
|
||||||
session.edit_node(node.id, options)
|
session.edit_node(node.id, options)
|
||||||
node_data = node.data(0)
|
source = None
|
||||||
|
if request.source:
|
||||||
|
source = request.source
|
||||||
|
node_data = node.data(0, source=source)
|
||||||
session.broadcast_node(node_data)
|
session.broadcast_node(node_data)
|
||||||
except CoreError:
|
except CoreError:
|
||||||
result = False
|
result = False
|
||||||
|
|
|
@ -76,6 +76,7 @@ NodeData = collections.namedtuple(
|
||||||
"altitude",
|
"altitude",
|
||||||
"icon",
|
"icon",
|
||||||
"opaque",
|
"opaque",
|
||||||
|
"source",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
NodeData.__new__.__defaults__ = (None,) * len(NodeData._fields)
|
NodeData.__new__.__defaults__ = (None,) * len(NodeData._fields)
|
||||||
|
|
|
@ -176,7 +176,7 @@ class NodeBase:
|
||||||
self.ifindex += 1
|
self.ifindex += 1
|
||||||
return ifindex
|
return ifindex
|
||||||
|
|
||||||
def data(self, message_type, lat=None, lon=None, alt=None):
|
def data(self, message_type, lat=None, lon=None, alt=None, source=None):
|
||||||
"""
|
"""
|
||||||
Build a data object for this node.
|
Build a data object for this node.
|
||||||
|
|
||||||
|
@ -184,6 +184,7 @@ class NodeBase:
|
||||||
:param str lat: latitude
|
:param str lat: latitude
|
||||||
:param str lon: longitude
|
:param str lon: longitude
|
||||||
:param str alt: altitude
|
:param str alt: altitude
|
||||||
|
:param str source: source of node data
|
||||||
:return: node data object
|
:return: node data object
|
||||||
:rtype: core.emulator.data.NodeData
|
:rtype: core.emulator.data.NodeData
|
||||||
"""
|
"""
|
||||||
|
@ -217,6 +218,7 @@ class NodeBase:
|
||||||
model=model,
|
model=model,
|
||||||
server=server,
|
server=server,
|
||||||
services=services,
|
services=services,
|
||||||
|
source=source,
|
||||||
)
|
)
|
||||||
|
|
||||||
return node_data
|
return node_data
|
||||||
|
|
|
@ -298,6 +298,7 @@ message Event {
|
||||||
|
|
||||||
message NodeEvent {
|
message NodeEvent {
|
||||||
Node node = 1;
|
Node node = 1;
|
||||||
|
string source = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LinkEvent {
|
message LinkEvent {
|
||||||
|
@ -378,6 +379,7 @@ message EditNodeRequest {
|
||||||
int32 node_id = 2;
|
int32 node_id = 2;
|
||||||
Position position = 3;
|
Position position = 3;
|
||||||
string icon = 4;
|
string icon = 4;
|
||||||
|
string source = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message EditNodeResponse {
|
message EditNodeResponse {
|
||||||
|
|