fix merge conflict
This commit is contained in:
		
						commit
						95d36a1792
					
				
					 9 changed files with 224 additions and 42 deletions
				
			
		| 
						 | 
					@ -16,6 +16,7 @@ MOBILITY_PATH = HOME_PATH.joinpath("mobility")
 | 
				
			||||||
XMLS_PATH = HOME_PATH.joinpath("xmls")
 | 
					XMLS_PATH = HOME_PATH.joinpath("xmls")
 | 
				
			||||||
CONFIG_PATH = HOME_PATH.joinpath("gui.yaml")
 | 
					CONFIG_PATH = HOME_PATH.joinpath("gui.yaml")
 | 
				
			||||||
LOG_PATH = HOME_PATH.joinpath("gui.log")
 | 
					LOG_PATH = HOME_PATH.joinpath("gui.log")
 | 
				
			||||||
 | 
					SCRIPT_PATH = HOME_PATH.joinpath("scripts")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# local paths
 | 
					# local paths
 | 
				
			||||||
DATA_PATH = Path(__file__).parent.joinpath("data")
 | 
					DATA_PATH = Path(__file__).parent.joinpath("data")
 | 
				
			||||||
| 
						 | 
					@ -25,17 +26,16 @@ LOCAL_XMLS_PATH = DATA_PATH.joinpath("xmls").absolute()
 | 
				
			||||||
LOCAL_MOBILITY_PATH = DATA_PATH.joinpath("mobility").absolute()
 | 
					LOCAL_MOBILITY_PATH = DATA_PATH.joinpath("mobility").absolute()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# configuration data
 | 
					# configuration data
 | 
				
			||||||
TERMINALS = [
 | 
					TERMINALS = {
 | 
				
			||||||
    "$TERM",
 | 
					    "xterm": "xterm -e",
 | 
				
			||||||
    "gnome-terminal --window --",
 | 
					    "aterm": "aterm -e",
 | 
				
			||||||
    "lxterminal -e",
 | 
					    "eterm": "eterm -e",
 | 
				
			||||||
    "konsole -e",
 | 
					    "rxvt": "rxvt -e",
 | 
				
			||||||
    "xterm -e",
 | 
					    "konsole": "konsole -e",
 | 
				
			||||||
    "aterm -e",
 | 
					    "lxterminal": "lxterminal -e",
 | 
				
			||||||
    "eterm -e",
 | 
					    "xfce4-terminal": "xfce4-terminal -x",
 | 
				
			||||||
    "rxvt -e",
 | 
					    "gnome-terminal": "gnome-terminal --window --",
 | 
				
			||||||
    "xfce4-terminal -x",
 | 
					}
 | 
				
			||||||
]
 | 
					 | 
				
			||||||
EDITORS = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"]
 | 
					EDITORS = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,6 +50,14 @@ def copy_files(current_path, new_path):
 | 
				
			||||||
        shutil.copy(current_file, new_file)
 | 
					        shutil.copy(current_file, new_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def find_terminal():
 | 
				
			||||||
 | 
					    for term in sorted(TERMINALS):
 | 
				
			||||||
 | 
					        cmd = TERMINALS[term]
 | 
				
			||||||
 | 
					        if shutil.which(term):
 | 
				
			||||||
 | 
					            return cmd
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_directory():
 | 
					def check_directory():
 | 
				
			||||||
    if HOME_PATH.exists():
 | 
					    if HOME_PATH.exists():
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
| 
						 | 
					@ -60,16 +68,14 @@ def check_directory():
 | 
				
			||||||
    ICONS_PATH.mkdir()
 | 
					    ICONS_PATH.mkdir()
 | 
				
			||||||
    MOBILITY_PATH.mkdir()
 | 
					    MOBILITY_PATH.mkdir()
 | 
				
			||||||
    XMLS_PATH.mkdir()
 | 
					    XMLS_PATH.mkdir()
 | 
				
			||||||
 | 
					    SCRIPT_PATH.mkdir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    copy_files(LOCAL_ICONS_PATH, ICONS_PATH)
 | 
					    copy_files(LOCAL_ICONS_PATH, ICONS_PATH)
 | 
				
			||||||
    copy_files(LOCAL_BACKGROUND_PATH, BACKGROUNDS_PATH)
 | 
					    copy_files(LOCAL_BACKGROUND_PATH, BACKGROUNDS_PATH)
 | 
				
			||||||
    copy_files(LOCAL_XMLS_PATH, XMLS_PATH)
 | 
					    copy_files(LOCAL_XMLS_PATH, XMLS_PATH)
 | 
				
			||||||
    copy_files(LOCAL_MOBILITY_PATH, MOBILITY_PATH)
 | 
					    copy_files(LOCAL_MOBILITY_PATH, MOBILITY_PATH)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if "TERM" in os.environ:
 | 
					    terminal = find_terminal()
 | 
				
			||||||
        terminal = TERMINALS[0]
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        terminal = TERMINALS[1]
 | 
					 | 
				
			||||||
    if "EDITOR" in os.environ:
 | 
					    if "EDITOR" in os.environ:
 | 
				
			||||||
        editor = EDITORS[0]
 | 
					        editor = EDITORS[0]
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import json
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					from tkinter import messagebox
 | 
				
			||||||
from typing import TYPE_CHECKING, Dict, List
 | 
					from typing import TYPE_CHECKING, Dict, List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import grpc
 | 
					import grpc
 | 
				
			||||||
| 
						 | 
					@ -38,17 +39,6 @@ OBSERVERS = {
 | 
				
			||||||
    "IPSec policies": "setkey -DP",
 | 
					    "IPSec policies": "setkey -DP",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEFAULT_TERMS = {
 | 
					 | 
				
			||||||
    "xterm": "xterm -e",
 | 
					 | 
				
			||||||
    "aterm": "aterm -e",
 | 
					 | 
				
			||||||
    "eterm": "eterm -e",
 | 
					 | 
				
			||||||
    "rxvt": "rxvt -e",
 | 
					 | 
				
			||||||
    "konsole": "konsole -e",
 | 
					 | 
				
			||||||
    "lxterminal": "lxterminal -e",
 | 
					 | 
				
			||||||
    "xfce4-terminal": "xfce4-terminal -x",
 | 
					 | 
				
			||||||
    "gnome-terminal": "gnome-terminal --window--",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CoreServer:
 | 
					class CoreServer:
 | 
				
			||||||
    def __init__(self, name: str, address: str, port: int):
 | 
					    def __init__(self, name: str, address: str, port: int):
 | 
				
			||||||
| 
						 | 
					@ -571,11 +561,15 @@ class CoreClient:
 | 
				
			||||||
    def launch_terminal(self, node_id: int):
 | 
					    def launch_terminal(self, node_id: int):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            terminal = self.app.guiconfig["preferences"]["terminal"]
 | 
					            terminal = self.app.guiconfig["preferences"]["terminal"]
 | 
				
			||||||
 | 
					            if not terminal:
 | 
				
			||||||
 | 
					                messagebox.showerror(
 | 
				
			||||||
 | 
					                    "Terminal Error",
 | 
				
			||||||
 | 
					                    "No terminal set, please set within the preferences menu",
 | 
				
			||||||
 | 
					                    parent=self.app,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
            response = self.client.get_node_terminal(self.session_id, node_id)
 | 
					            response = self.client.get_node_terminal(self.session_id, node_id)
 | 
				
			||||||
            output = os.popen(f"echo {terminal}").read()[:-1]
 | 
					            cmd = f"{terminal} {response.terminal} &"
 | 
				
			||||||
            if output in DEFAULT_TERMS:
 | 
					 | 
				
			||||||
                terminal = DEFAULT_TERMS[output]
 | 
					 | 
				
			||||||
            cmd = f'{terminal} "{response.terminal}" &'
 | 
					 | 
				
			||||||
            logging.info("launching terminal %s", cmd)
 | 
					            logging.info("launching terminal %s", cmd)
 | 
				
			||||||
            os.system(cmd)
 | 
					            os.system(cmd)
 | 
				
			||||||
        except grpc.RpcError as e:
 | 
					        except grpc.RpcError as e:
 | 
				
			||||||
| 
						 | 
					@ -1069,3 +1063,9 @@ class CoreClient:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def service_been_modified(self, node_id: int) -> bool:
 | 
					    def service_been_modified(self, node_id: int) -> bool:
 | 
				
			||||||
        return node_id in self.modified_service_nodes
 | 
					        return node_id in self.modified_service_nodes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def execute_script(self, script):
 | 
				
			||||||
 | 
					        response = self.client.execute_script(script)
 | 
				
			||||||
 | 
					        logging.info("execute python script %s", response)
 | 
				
			||||||
 | 
					        if response.session_id != -1:
 | 
				
			||||||
 | 
					            self.join_session(response.session_id)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										85
									
								
								daemon/core/gui/dialogs/executepython.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								daemon/core/gui/dialogs/executepython.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,85 @@
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					import tkinter as tk
 | 
				
			||||||
 | 
					from tkinter import filedialog, ttk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from core.gui.appconfig import SCRIPT_PATH
 | 
				
			||||||
 | 
					from core.gui.dialogs.dialog import Dialog
 | 
				
			||||||
 | 
					from core.gui.themes import FRAME_PAD, PADX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ExecutePythonDialog(Dialog):
 | 
				
			||||||
 | 
					    def __init__(self, master, app):
 | 
				
			||||||
 | 
					        super().__init__(master, app, "Execute Python Script", modal=True)
 | 
				
			||||||
 | 
					        self.app = app
 | 
				
			||||||
 | 
					        self.with_options = tk.IntVar(value=0)
 | 
				
			||||||
 | 
					        self.options = tk.StringVar(value="")
 | 
				
			||||||
 | 
					        self.option_entry = None
 | 
				
			||||||
 | 
					        self.file_entry = None
 | 
				
			||||||
 | 
					        self.draw()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def draw(self):
 | 
				
			||||||
 | 
					        i = 0
 | 
				
			||||||
 | 
					        frame = ttk.Frame(self.top, padding=FRAME_PAD)
 | 
				
			||||||
 | 
					        frame.columnconfigure(0, weight=1)
 | 
				
			||||||
 | 
					        frame.columnconfigure(1, weight=1)
 | 
				
			||||||
 | 
					        frame.grid(row=i, column=0, sticky="nsew")
 | 
				
			||||||
 | 
					        i = i + 1
 | 
				
			||||||
 | 
					        var = tk.StringVar(value="")
 | 
				
			||||||
 | 
					        self.file_entry = ttk.Entry(frame, textvariable=var)
 | 
				
			||||||
 | 
					        self.file_entry.grid(row=0, column=0, sticky="ew")
 | 
				
			||||||
 | 
					        button = ttk.Button(frame, text="...", command=self.select_file)
 | 
				
			||||||
 | 
					        button.grid(row=0, column=1, sticky="ew")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.top.columnconfigure(0, weight=1)
 | 
				
			||||||
 | 
					        button = ttk.Checkbutton(
 | 
				
			||||||
 | 
					            self.top,
 | 
				
			||||||
 | 
					            text="With Options",
 | 
				
			||||||
 | 
					            variable=self.with_options,
 | 
				
			||||||
 | 
					            command=self.add_options,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        button.grid(row=i, column=0, sticky="ew")
 | 
				
			||||||
 | 
					        i = i + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        label = ttk.Label(
 | 
				
			||||||
 | 
					            self.top, text="Any command-line options for running the Python script"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        label.grid(row=i, column=0, sticky="ew")
 | 
				
			||||||
 | 
					        i = i + 1
 | 
				
			||||||
 | 
					        self.option_entry = ttk.Entry(
 | 
				
			||||||
 | 
					            self.top, textvariable=self.options, state="disabled"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.option_entry.grid(row=i, column=0, sticky="ew")
 | 
				
			||||||
 | 
					        i = i + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        frame = ttk.Frame(self.top, padding=FRAME_PAD)
 | 
				
			||||||
 | 
					        frame.columnconfigure(0, weight=1)
 | 
				
			||||||
 | 
					        frame.columnconfigure(1, weight=1)
 | 
				
			||||||
 | 
					        frame.grid(row=i, column=0)
 | 
				
			||||||
 | 
					        button = ttk.Button(frame, text="Execute", command=self.script_execute)
 | 
				
			||||||
 | 
					        button.grid(row=0, column=0, sticky="ew", padx=PADX)
 | 
				
			||||||
 | 
					        button = ttk.Button(frame, text="Cancel", command=self.destroy)
 | 
				
			||||||
 | 
					        button.grid(row=0, column=1, sticky="ew", padx=PADX)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_options(self):
 | 
				
			||||||
 | 
					        if self.with_options.get():
 | 
				
			||||||
 | 
					            self.option_entry.configure(state="normal")
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.option_entry.configure(state="disabled")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def select_file(self):
 | 
				
			||||||
 | 
					        file = filedialog.askopenfilename(
 | 
				
			||||||
 | 
					            parent=self.top,
 | 
				
			||||||
 | 
					            initialdir=str(SCRIPT_PATH),
 | 
				
			||||||
 | 
					            title="Open python script",
 | 
				
			||||||
 | 
					            filetypes=((".py Files", "*.py"), ("All Files", "*")),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        if file:
 | 
				
			||||||
 | 
					            self.file_entry.delete(0, "end")
 | 
				
			||||||
 | 
					            self.file_entry.insert("end", file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def script_execute(self):
 | 
				
			||||||
 | 
					        file = self.file_entry.get()
 | 
				
			||||||
 | 
					        options = self.option_entry.get()
 | 
				
			||||||
 | 
					        logging.info("Execute %s with options %s", file, options)
 | 
				
			||||||
 | 
					        self.app.core.execute_script(file)
 | 
				
			||||||
 | 
					        self.destroy()
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,11 @@
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import tkinter as tk
 | 
					import tkinter as tk
 | 
				
			||||||
from functools import partial
 | 
					from functools import partial
 | 
				
			||||||
from tkinter import ttk
 | 
					from tkinter import messagebox, ttk
 | 
				
			||||||
from typing import TYPE_CHECKING
 | 
					from typing import TYPE_CHECKING
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import netaddr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from core.gui import nodeutils
 | 
					from core.gui import nodeutils
 | 
				
			||||||
from core.gui.appconfig import ICONS_PATH
 | 
					from core.gui.appconfig import ICONS_PATH
 | 
				
			||||||
from core.gui.dialogs.dialog import Dialog
 | 
					from core.gui.dialogs.dialog import Dialog
 | 
				
			||||||
| 
						 | 
					@ -18,6 +20,58 @@ if TYPE_CHECKING:
 | 
				
			||||||
    from core.gui.graph.node import CanvasNode
 | 
					    from core.gui.graph.node import CanvasNode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_ip6(parent, name: str, value: str) -> bool:
 | 
				
			||||||
 | 
					    title = f"IP6 Error for {name}"
 | 
				
			||||||
 | 
					    if not value:
 | 
				
			||||||
 | 
					        messagebox.showerror(title, "Empty Value", parent=parent)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    values = value.split("/")
 | 
				
			||||||
 | 
					    if len(values) != 2:
 | 
				
			||||||
 | 
					        messagebox.showerror(
 | 
				
			||||||
 | 
					            title, "Must be in the format address/prefix", parent=parent
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    addr, mask = values
 | 
				
			||||||
 | 
					    if not netaddr.valid_ipv6(addr):
 | 
				
			||||||
 | 
					        messagebox.showerror(title, "Invalid IP6 address", parent=parent)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        mask = int(mask)
 | 
				
			||||||
 | 
					        if not (0 <= mask <= 128):
 | 
				
			||||||
 | 
					            messagebox.showerror(title, "Mask must be between 0-128", parent=parent)
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					    except ValueError:
 | 
				
			||||||
 | 
					        messagebox.showerror(title, "Invalid Mask", parent=parent)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_ip4(parent, name: str, value: str) -> bool:
 | 
				
			||||||
 | 
					    title = f"IP4 Error for {name}"
 | 
				
			||||||
 | 
					    if not value:
 | 
				
			||||||
 | 
					        messagebox.showerror(title, "Empty Value", parent=parent)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    values = value.split("/")
 | 
				
			||||||
 | 
					    if len(values) != 2:
 | 
				
			||||||
 | 
					        messagebox.showerror(
 | 
				
			||||||
 | 
					            title, "Must be in the format address/prefix", parent=parent
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    addr, mask = values
 | 
				
			||||||
 | 
					    if not netaddr.valid_ipv4(addr):
 | 
				
			||||||
 | 
					        messagebox.showerror(title, "Invalid IP4 address", parent=parent)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        mask = int(mask)
 | 
				
			||||||
 | 
					        if not (0 <= mask <= 32):
 | 
				
			||||||
 | 
					            messagebox.showerror(title, "Mask must be between 0-32", parent=parent)
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					    except ValueError:
 | 
				
			||||||
 | 
					        messagebox.showerror(title, "Invalid mask", parent=parent)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mac_auto(is_auto: tk.BooleanVar, entry: ttk.Entry):
 | 
					def mac_auto(is_auto: tk.BooleanVar, entry: ttk.Entry):
 | 
				
			||||||
    logging.info("mac auto clicked")
 | 
					    logging.info("mac auto clicked")
 | 
				
			||||||
    if is_auto.get():
 | 
					    if is_auto.get():
 | 
				
			||||||
| 
						 | 
					@ -203,7 +257,6 @@ class NodeConfigDialog(Dialog):
 | 
				
			||||||
            label.grid(row=row, column=0, padx=PADX, pady=PADY)
 | 
					            label.grid(row=row, column=0, padx=PADX, pady=PADY)
 | 
				
			||||||
            ip4 = tk.StringVar(value=f"{interface.ip4}/{interface.ip4mask}")
 | 
					            ip4 = tk.StringVar(value=f"{interface.ip4}/{interface.ip4mask}")
 | 
				
			||||||
            entry = ttk.Entry(tab, textvariable=ip4)
 | 
					            entry = ttk.Entry(tab, textvariable=ip4)
 | 
				
			||||||
            entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
 | 
					 | 
				
			||||||
            entry.grid(row=row, column=1, columnspan=2, sticky="ew")
 | 
					            entry.grid(row=row, column=1, columnspan=2, sticky="ew")
 | 
				
			||||||
            row += 1
 | 
					            row += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,7 +264,6 @@ class NodeConfigDialog(Dialog):
 | 
				
			||||||
            label.grid(row=row, column=0, padx=PADX, pady=PADY)
 | 
					            label.grid(row=row, column=0, padx=PADX, pady=PADY)
 | 
				
			||||||
            ip6 = tk.StringVar(value=f"{interface.ip6}/{interface.ip6mask}")
 | 
					            ip6 = tk.StringVar(value=f"{interface.ip6}/{interface.ip6mask}")
 | 
				
			||||||
            entry = ttk.Entry(tab, textvariable=ip6)
 | 
					            entry = ttk.Entry(tab, textvariable=ip6)
 | 
				
			||||||
            entry.bind("<FocusOut>", self.app.validation.ip_focus_out)
 | 
					 | 
				
			||||||
            entry.grid(row=row, column=1, columnspan=2, sticky="ew")
 | 
					            entry.grid(row=row, column=1, columnspan=2, sticky="ew")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.interfaces[interface.id] = InterfaceData(is_auto, mac, ip4, ip6)
 | 
					            self.interfaces[interface.id] = InterfaceData(is_auto, mac, ip4, ip6)
 | 
				
			||||||
| 
						 | 
					@ -240,6 +292,8 @@ class NodeConfigDialog(Dialog):
 | 
				
			||||||
            self.image_file = file_path
 | 
					            self.image_file = file_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def config_apply(self):
 | 
					    def config_apply(self):
 | 
				
			||||||
 | 
					        error = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # update core node
 | 
					        # update core node
 | 
				
			||||||
        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):
 | 
				
			||||||
| 
						 | 
					@ -255,7 +309,29 @@ class NodeConfigDialog(Dialog):
 | 
				
			||||||
        # update canvas node
 | 
					        # update canvas node
 | 
				
			||||||
        self.canvas_node.image = self.image
 | 
					        self.canvas_node.image = self.image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # update node interface data
 | 
				
			||||||
 | 
					        for interface in self.canvas_node.interfaces:
 | 
				
			||||||
 | 
					            data = self.interfaces[interface.id]
 | 
				
			||||||
 | 
					            if check_ip4(self, interface.name, data.ip4.get()):
 | 
				
			||||||
 | 
					                ip4, ip4mask = data.ip4.get().split("/")
 | 
				
			||||||
 | 
					                interface.ip4 = ip4
 | 
				
			||||||
 | 
					                interface.ip4mask = int(ip4mask)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                error = True
 | 
				
			||||||
 | 
					                data.ip4.set(f"{interface.ip4}/{interface.ip4mask}")
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            if check_ip6(self, interface.name, data.ip6.get()):
 | 
				
			||||||
 | 
					                ip6, ip6mask = data.ip6.get().split("/")
 | 
				
			||||||
 | 
					                interface.ip6 = ip6
 | 
				
			||||||
 | 
					                interface.ip6mask = int(ip6mask)
 | 
				
			||||||
 | 
					                interface.mac = data.mac.get()
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                error = True
 | 
				
			||||||
 | 
					                data.ip6.set(f"{interface.ip6}/{interface.ip6mask}")
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # redraw
 | 
					        # redraw
 | 
				
			||||||
 | 
					        if not error:
 | 
				
			||||||
            self.canvas_node.redraw()
 | 
					            self.canvas_node.redraw()
 | 
				
			||||||
            self.destroy()
 | 
					            self.destroy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,9 +56,8 @@ class PreferencesDialog(Dialog):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        label = ttk.Label(frame, text="Terminal")
 | 
					        label = ttk.Label(frame, text="Terminal")
 | 
				
			||||||
        label.grid(row=2, column=0, pady=PADY, padx=PADX, sticky="w")
 | 
					        label.grid(row=2, column=0, pady=PADY, padx=PADX, sticky="w")
 | 
				
			||||||
        combobox = ttk.Combobox(
 | 
					        terminals = sorted(appconfig.TERMINALS.values())
 | 
				
			||||||
            frame, textvariable=self.terminal, values=appconfig.TERMINALS
 | 
					        combobox = ttk.Combobox(frame, textvariable=self.terminal, values=terminals)
 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        combobox.grid(row=2, column=1, sticky="ew")
 | 
					        combobox.grid(row=2, column=1, sticky="ew")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        label = ttk.Label(frame, text="3D GUI")
 | 
					        label = ttk.Label(frame, text="3D GUI")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,8 +107,7 @@ class CanvasEdge:
 | 
				
			||||||
        y = (y1 + y2) / 2
 | 
					        y = (y1 + y2) / 2
 | 
				
			||||||
        return x, y
 | 
					        return x, y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def draw_labels(self):
 | 
					    def create_labels(self):
 | 
				
			||||||
        x1, y1, x2, y2 = self.get_coordinates()
 | 
					 | 
				
			||||||
        label_one = None
 | 
					        label_one = None
 | 
				
			||||||
        if self.link.HasField("interface_one"):
 | 
					        if self.link.HasField("interface_one"):
 | 
				
			||||||
            label_one = (
 | 
					            label_one = (
 | 
				
			||||||
| 
						 | 
					@ -121,6 +120,11 @@ class CanvasEdge:
 | 
				
			||||||
                f"{self.link.interface_two.ip4}/{self.link.interface_two.ip4mask}\n"
 | 
					                f"{self.link.interface_two.ip4}/{self.link.interface_two.ip4mask}\n"
 | 
				
			||||||
                f"{self.link.interface_two.ip6}/{self.link.interface_two.ip6mask}\n"
 | 
					                f"{self.link.interface_two.ip6}/{self.link.interface_two.ip6mask}\n"
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					        return label_one, label_two
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def draw_labels(self):
 | 
				
			||||||
 | 
					        x1, y1, x2, y2 = self.get_coordinates()
 | 
				
			||||||
 | 
					        label_one, label_two = self.create_labels()
 | 
				
			||||||
        self.text_src = self.canvas.create_text(
 | 
					        self.text_src = self.canvas.create_text(
 | 
				
			||||||
            x1,
 | 
					            x1,
 | 
				
			||||||
            y1,
 | 
					            y1,
 | 
				
			||||||
| 
						 | 
					@ -138,6 +142,11 @@ class CanvasEdge:
 | 
				
			||||||
            tags=tags.LINK_INFO,
 | 
					            tags=tags.LINK_INFO,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def redraw(self):
 | 
				
			||||||
 | 
					        label_one, label_two = self.create_labels()
 | 
				
			||||||
 | 
					        self.canvas.itemconfig(self.text_src, text=label_one)
 | 
				
			||||||
 | 
					        self.canvas.itemconfig(self.text_dst, text=label_two)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update_labels(self):
 | 
					    def update_labels(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Move edge labels based on current position.
 | 
					        Move edge labels based on current position.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,6 +107,8 @@ class CanvasNode:
 | 
				
			||||||
    def redraw(self):
 | 
					    def redraw(self):
 | 
				
			||||||
        self.canvas.itemconfig(self.id, image=self.image)
 | 
					        self.canvas.itemconfig(self.id, image=self.image)
 | 
				
			||||||
        self.canvas.itemconfig(self.text_id, text=self.core_node.name)
 | 
					        self.canvas.itemconfig(self.text_id, text=self.core_node.name)
 | 
				
			||||||
 | 
					        for edge in self.edges:
 | 
				
			||||||
 | 
					            edge.redraw()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _get_label_y(self):
 | 
					    def _get_label_y(self):
 | 
				
			||||||
        image_box = self.canvas.bbox(self.id)
 | 
					        image_box = self.canvas.bbox(self.id)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ from typing import TYPE_CHECKING
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import core.gui.menuaction as action
 | 
					import core.gui.menuaction as action
 | 
				
			||||||
from core.gui.coreclient import OBSERVERS
 | 
					from core.gui.coreclient import OBSERVERS
 | 
				
			||||||
 | 
					from core.gui.dialogs.executepython import ExecutePythonDialog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if TYPE_CHECKING:
 | 
					if TYPE_CHECKING:
 | 
				
			||||||
    from core.gui.app import Application
 | 
					    from core.gui.app import Application
 | 
				
			||||||
| 
						 | 
					@ -69,7 +70,7 @@ class Menubar(tk.Menu):
 | 
				
			||||||
        menu.add_cascade(label="Recent files", menu=self.recent_menu)
 | 
					        menu.add_cascade(label="Recent files", menu=self.recent_menu)
 | 
				
			||||||
        menu.add_separator()
 | 
					        menu.add_separator()
 | 
				
			||||||
        menu.add_command(label="Export Python script...", state=tk.DISABLED)
 | 
					        menu.add_command(label="Export Python script...", state=tk.DISABLED)
 | 
				
			||||||
        menu.add_command(label="Execute XML or Python script...", state=tk.DISABLED)
 | 
					        menu.add_command(label="Execute Python script...", command=self.execute_python)
 | 
				
			||||||
        menu.add_command(
 | 
					        menu.add_command(
 | 
				
			||||||
            label="Execute Python script with options...", state=tk.DISABLED
 | 
					            label="Execute Python script with options...", state=tk.DISABLED
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					@ -443,6 +444,10 @@ class Menubar(tk.Menu):
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.menuaction.file_save_as_xml()
 | 
					            self.menuaction.file_save_as_xml()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def execute_python(self):
 | 
				
			||||||
 | 
					        dialog = ExecutePythonDialog(self.app, self.app)
 | 
				
			||||||
 | 
					        dialog.show()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def change_menubar_item_state(self, is_runtime: bool):
 | 
					    def change_menubar_item_state(self, is_runtime: bool):
 | 
				
			||||||
        for i in range(self.edit_menu.index("end")):
 | 
					        for i in range(self.edit_menu.index("end")):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ PATH="/sbin:/bin:/usr/sbin:/usr/bin"
 | 
				
			||||||
export PATH
 | 
					export PATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [ "z$1" = "z-d" ]; then
 | 
					if [ "z$1" = "z-d" ]; then
 | 
				
			||||||
    pypids=`pidof python python2`
 | 
					    pypids=`pidof python3 python`
 | 
				
			||||||
    for p in $pypids; do
 | 
					    for p in $pypids; do
 | 
				
			||||||
	grep -q core-daemon /proc/$p/cmdline
 | 
						grep -q core-daemon /proc/$p/cmdline
 | 
				
			||||||
	if [ $? = 0 ]; then
 | 
						if [ $? = 0 ]; then
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue