Remove tk ui
This commit is contained in:
parent
3f047c29b6
commit
4c44df62a2
|
@ -200,35 +200,6 @@ ssh = ["bcrypt (>=3.1.5)"]
|
|||
test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
|
||||
test-randomorder = ["pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
name = "customtkinter"
|
||||
version = "5.2.2"
|
||||
description = "Create modern looking GUIs with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "customtkinter-5.2.2-py3-none-any.whl", hash = "sha256:14ad3e7cd3cb3b9eb642b9d4e8711ae80d3f79fb82545ad11258eeffb2e6b37c"},
|
||||
{file = "customtkinter-5.2.2.tar.gz", hash = "sha256:fd8db3bafa961c982ee6030dba80b4c2e25858630756b513986db19113d8d207"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
darkdetect = "*"
|
||||
packaging = "*"
|
||||
|
||||
[[package]]
|
||||
name = "darkdetect"
|
||||
version = "0.8.0"
|
||||
description = "Detect OS Dark Mode from Python"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "darkdetect-0.8.0-py3-none-any.whl", hash = "sha256:a7509ccf517eaad92b31c214f593dbcf138ea8a43b2935406bbd565e15527a85"},
|
||||
{file = "darkdetect-0.8.0.tar.gz", hash = "sha256:b5428e1170263eb5dea44c25dc3895edd75e6f52300986353cd63533fe7df8b1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
macos-listener = ["pyobjc-framework-Cocoa"]
|
||||
|
||||
[[package]]
|
||||
name = "decorator"
|
||||
version = "5.1.1"
|
||||
|
@ -288,17 +259,6 @@ files = [
|
|||
{file = "invoke-2.2.0.tar.gz", hash = "sha256:ee6cbb101af1a859c7fe84f2a264c059020b0cb7fe3535f9424300ab568f6bd5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "24.0"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
|
||||
{file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paramiko"
|
||||
version = "3.4.0"
|
||||
|
@ -439,4 +399,4 @@ files = [
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "e01c9fdf03da702f9839b29039b9b141a079b40b4210d2a288b572d07481afa5"
|
||||
content-hash = "a6742759986eaac35d72d38a27ed349f010bf21820948b1c837749dfeea68af8"
|
||||
|
|
|
@ -10,7 +10,6 @@ readme = "README.md"
|
|||
python = "^3.11"
|
||||
fabric = "^3.2.2"
|
||||
attrs = "^23.2.0"
|
||||
customtkinter = "^5.2.2"
|
||||
cattrs = "^23.2.3"
|
||||
|
||||
|
||||
|
|
78
woven-ui.py
78
woven-ui.py
|
@ -1,78 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from sys import platform
|
||||
from argparse import ArgumentParser
|
||||
from contextlib import redirect_stdout
|
||||
from os import devnull
|
||||
from sys import stdout, stderr, exit
|
||||
from pathlib import Path
|
||||
from woven import WovenMesh
|
||||
from json import JSONDecodeError
|
||||
from cattrs.errors import ClassValidationError
|
||||
from tkinter.filedialog import askopenfilename
|
||||
from tkinter.messagebox import showerror
|
||||
import customtkinter as ctk
|
||||
|
||||
def load_config(config_path: str) -> WovenMesh | None:
|
||||
try:
|
||||
return WovenMesh.load_json_file(config_path)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
except JSONDecodeError as e:
|
||||
showerror("Invalid JSON Error", f"Invalid JSON encountered in configuration file: {e}")
|
||||
except ClassValidationError as e:
|
||||
details = "\n".join(f'{type(e).__name__}: {e}' for e in e.exceptions)
|
||||
showerror("Validation Error", f"The following validation errors occurred when loading the configuration file:\n{details}")
|
||||
return None
|
||||
|
||||
def start(config_path: str):
|
||||
ctk.set_appearance_mode("System")
|
||||
ctk.set_default_color_theme("dark-blue")
|
||||
|
||||
if platform != "darwin" and not platform.startswith("win"):
|
||||
ctk.set_widget_scaling(1.25)
|
||||
ctk.set_window_scaling(1.25)
|
||||
|
||||
root = ctk.CTk()
|
||||
root.geometry("1200x800")
|
||||
root.title("Woven")
|
||||
root.minsize(240, 240)
|
||||
root.grid_columnconfigure(0, weight = 1)
|
||||
root.grid_rowconfigure(1, weight = 1)
|
||||
|
||||
def update_config_handler():
|
||||
fn = askopenfilename(filetypes = [("JSON Files", "*.json")])
|
||||
if fn:
|
||||
update_config(load_config(fn))
|
||||
|
||||
load_config_button = ctk.CTkButton(master = root, text = "Load Config", width = 0, command = update_config_handler)
|
||||
load_config_button.grid(row = 0, padx = 20, pady = (20, 10), sticky = "w")
|
||||
save_config_button = ctk.CTkButton(master = root, text = "Save Config", width = 0, command = update_config_handler)
|
||||
save_config_button.grid(row = 0, padx = 20, pady = (20, 10), sticky = "e")
|
||||
|
||||
config_textbox = ctk.CTkTextbox(master = root)
|
||||
config_textbox.grid(row = 1, column = 0, padx = 20, pady = (10, 20), sticky = "nsew")
|
||||
|
||||
def update_config(config: WovenMesh | None):
|
||||
config_textbox.delete("0.0", "end")
|
||||
config_textbox.insert("0.0", "" if config is None else config.to_json_str())
|
||||
|
||||
update_config(load_config(config_path))
|
||||
|
||||
root.mainloop()
|
||||
|
||||
def main():
|
||||
parser = ArgumentParser("woven-ui")
|
||||
parser.add_argument("-q", "--quiet", action = "store_true", help = "decrease output verbosity")
|
||||
parser.add_argument("-c", "--config", default = "config.json", help = "The path to the config file")
|
||||
args = parser.parse_args()
|
||||
|
||||
with redirect_stdout(open(devnull, "w") if args.quiet else stdout):
|
||||
start(args.config)
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
exit(130)
|
||||
|
10
woven.py
10
woven.py
|
@ -51,7 +51,7 @@ def validator_range(min_value: T, max_value: T) -> Callable[[T], T]:
|
|||
return _validate
|
||||
|
||||
@define
|
||||
class WovenNode:
|
||||
class WovenMeshNode:
|
||||
address: IPv4Address | IPv6Address = field(converter = ip_address)
|
||||
gateway: IPv4Address | IPv6Address = field(converter = ip_address)
|
||||
interface: str
|
||||
|
@ -73,8 +73,8 @@ class WovenMesh:
|
|||
wireguard_config_ext: str = field(default = "conf", converter = lambda x: str(x).lstrip("."))
|
||||
table: Literal["auto", "off"] = field(default = "off", validator = validator_in(["auto", "off"]))
|
||||
allowed_ips: list[str] = field(factory = lambda: ["0.0.0.0/0", "::/0"])
|
||||
persistent_keepalive: int = field(default = 20, validator = validator_range(0, 1 << 31 - 1))
|
||||
mesh_nodes: dict[str, WovenNode] = field(factory = dict)
|
||||
keep_alive: int = field(default = 20, validator = validator_range(0, 1 << 31 - 1))
|
||||
mesh_nodes: dict[str, WovenMeshNode] = field(factory = dict)
|
||||
|
||||
def _surround(self, val: str) -> str:
|
||||
prefix_str = f"{self.tunnel_prefix}{self.tunnel_separator}" if self.tunnel_prefix else ""
|
||||
|
@ -200,7 +200,7 @@ class WovenMesh:
|
|||
allowed_ips = self.allowed_ips,
|
||||
endpoint_host = node_b.address,
|
||||
endpoint_port = port,
|
||||
persistent_keepalive = self.persistent_keepalive
|
||||
persistent_keepalive = self.keep_alive
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -227,7 +227,7 @@ class WovenMesh:
|
|||
allowed_ips = self.allowed_ips,
|
||||
endpoint_host = node_a.address,
|
||||
endpoint_port = port,
|
||||
persistent_keepalive = self.persistent_keepalive
|
||||
persistent_keepalive = self.keep_alive
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue