fix message window a path errors

This commit is contained in:
Désiré Werner Menrath 2025-05-07 20:25:09 +02:00
parent c56b42df3e
commit f4a51f0050
7 changed files with 724 additions and 299 deletions

View File

@ -1,7 +1,5 @@
""" Classes Method and Functions for lx Apps """
import gettext
import locale
import os
import shutil
import signal
@ -20,6 +18,7 @@ import requests
# Translate
_ = AppConfig.setup_translations()
class Create:
"""
This class is for the creation of the folders and files
@ -43,7 +42,9 @@ class Create:
else:
sett.touch()
sett.write_text("[UPDATES]\non\n[THEME]\nlight\n[TOOLTIP]\nTrue\n[AUTOSTART ON]\noff\n")
sett.write_text(
"[UPDATES]\non\n[THEME]\nlight\n[TOOLTIP]\nTrue\n[AUTOSTART ON]\noff\n"
)
if AppConfig.KEYS_FILE.exists():
pass
@ -66,9 +67,11 @@ class Create:
else:
wg_ser.touch()
wg_ser.write_text("[Unit]\nDescription=Automatic Tunnel Start\nAfter=network-online.target\n\n[Service]\n"
"Type=oneshot\nExecStartPre=/bin/sleep 5\nExecStart=/usr/local/bin/start_wg.py\n[Install]"
"\nWantedBy=default.target")
wg_ser.write_text(
"[Unit]\nDescription=Automatic Tunnel Start\nAfter=network-online.target\n\n[Service]\n"
"Type=oneshot\nExecStartPre=/bin/sleep 5\nExecStart=/usr/local/bin/start_wg.py\n[Install]"
"\nWantedBy=default.target"
)
check_call(["systemctl", "--user", "enable", "wg_start.service"])
@staticmethod
@ -85,8 +88,12 @@ class Create:
"""
Starts SSL dencrypt
"""
process: CompletedProcess[str] = subprocess.run(["pkexec", "/usr/local/bin/ssl_decrypt.py"],
stdout=subprocess.PIPE, text=True, check=True)
process: CompletedProcess[str] = subprocess.run(
["pkexec", "/usr/local/bin/ssl_decrypt.py"],
stdout=subprocess.PIPE,
text=True,
check=True,
)
path: Path = Path.home() / ".config/wire_py/"
file_in_path: list[Path] = list(path.rglob("*.dat"))
if file_in_path:
@ -102,8 +109,12 @@ class Create:
"""
Starts SSL encryption
"""
process: CompletedProcess[str] = subprocess.run(["pkexec", "/usr/local/bin/ssl_encrypt.py"],
stdout=subprocess.PIPE, text=True, check=True)
process: CompletedProcess[str] = subprocess.run(
["pkexec", "/usr/local/bin/ssl_encrypt.py"],
stdout=subprocess.PIPE,
text=True,
check=True,
)
print(process.stdout)
if process.returncode == 0:
print("All Files successfully encrypted...")
@ -134,7 +145,8 @@ class LxTools(tk.Tk):
# First attempt: Try to use GDK if available (works on both X11 and Wayland)
try:
import gi
gi.require_version('Gdk', '3.0')
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
display = Gdk.Display.get_default()
@ -155,7 +167,10 @@ class LxTools(tk.Tk):
# Second attempt: Try xrandr for X11
try:
import subprocess
output = subprocess.check_output(["xrandr", "--query"], universal_newlines=True)
output = subprocess.check_output(
["xrandr", "--query"], universal_newlines=True
)
# Parse the output to find the primary monitor
primary_info = None
@ -193,7 +208,9 @@ class LxTools(tk.Tk):
# Try to make an educated guess for multi-monitor setups
# If screen width is much larger than height, assume multiple monitors side by side
if screen_width > screen_height * 1.8: # Heuristic for detecting multiple monitors
if (
screen_width > screen_height * 1.8
): # Heuristic for detecting multiple monitors
# Assume primary monitor is on the left half
screen_width = screen_width // 2
@ -201,7 +218,6 @@ class LxTools(tk.Tk):
y = (screen_height - height) // 2
window.geometry(f"{width}x{height}+{x}+{y}")
@staticmethod
def get_file_name(path: Path, i: int = 5) -> List[str]:
"""
@ -253,8 +269,14 @@ class LxTools(tk.Tk):
Path.unlink(file)
@staticmethod
def msg_window(image_path: Path, image_path2: Path, w_title: str, w_txt: str, txt2: Optional[str] = None,
com: Optional[str] = None) -> None:
def msg_window(
image_path: Path,
image_path2: Path,
w_title: str,
w_txt: str,
txt2: Optional[str] = None,
com: Optional[str] = None,
) -> None:
"""
Creates message windows
@ -269,29 +291,44 @@ class LxTools(tk.Tk):
msg.resizable(width=False, height=False)
msg.title(w_title)
msg.configure(pady=15, padx=15)
msg.img = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_info"])
msg.i_window = tk.Label(msg, image=msg.img)
# Lade das erste Bild für das Fenster
try:
msg.img = tk.PhotoImage(file=image_path)
msg.i_window = tk.Label(msg, image=msg.img)
except Exception as e:
print(f"Fehler beim Laden des Fensterbildes: {e}")
msg.i_window = tk.Label(msg, text="Bild nicht gefunden")
label: tk.Label = tk.Label(msg, text=w_txt)
label.grid(column=1, row=0)
if txt2 is not None and com is not None:
label.config(font=("Ubuntu", 11), padx=15, justify="left")
msg.i_window.grid(column=0, row=0, sticky="nw")
button2: ttk.Button = ttk.Button(msg, text=f"{txt2}", command=com, padding=4)
button2: ttk.Button = ttk.Button(
msg, text=f"{txt2}", command=com, padding=4
)
button2.grid(column=0, row=1, sticky="e", columnspan=2)
button: ttk.Button = ttk.Button(msg, text="OK", command=msg.destroy, padding=4)
button: ttk.Button = ttk.Button(
msg, text="OK", command=msg.destroy, padding=4
)
button.grid(column=0, row=1, sticky="w", columnspan=2)
else:
label.config(font=("Ubuntu", 11), padx=15)
msg.i_window.grid(column=0, row=0)
button: ttk.Button = ttk.Button(msg, text="OK", command=msg.destroy, padding=4)
button: ttk.Button = ttk.Button(
msg, text="OK", command=msg.destroy, padding=4
)
button.grid(column=0, columnspan=2, row=1)
AppConfig.IMAGE_PATHS["icon_vpn"]: tk.PhotoImage = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_vpn"])
msg.iconphoto(True, AppConfig.IMAGE_PATHS["icon_vpn"])
# Lade das Icon für das Fenster
try:
icon = tk.PhotoImage(file=image_path2)
msg.iconphoto(True, icon)
except Exception as e:
print(f"Fehler beim Laden des Fenstericons: {e}")
msg.columnconfigure(0, weight=1)
msg.rowconfigure(0, weight=1)
msg.winfo_toplevel()
@ -317,15 +354,22 @@ class LxTools(tk.Tk):
NoReturn since the function either exits the program or continues execution
"""
signals_to_names_dict: Dict[int, str] = dict((getattr(signal, n), n) for n in dir(signal)
if n.startswith("SIG") and "_" not in n)
signals_to_names_dict: Dict[int, str] = dict(
(getattr(signal, n), n)
for n in dir(signal)
if n.startswith("SIG") and "_" not in n
)
signal_name: str = signals_to_names_dict.get(signum, f"Unnamed signal: {signum}")
signal_name: str = signals_to_names_dict.get(
signum, f"Unnamed signal: {signum}"
)
# End program for certain signals, report to others only reception
if signum in (signal.SIGINT, signal.SIGTERM):
exit_code: int = 1
print(f"\nSignal {signal_name} {signum} received. => Aborting with exit code {exit_code}.")
print(
f"\nSignal {signal_name} {signum} received. => Aborting with exit code {exit_code}."
)
LxTools.clean_files(file_path, file)
print("Breakdown by user...")
sys.exit(exit_code)
@ -344,6 +388,7 @@ class Tunnel:
"""
Class of Methods for Wire-Py
"""
@classmethod
def con_to_dict(cls, file: TextIO) -> Tuple[str, str, str, Optional[str]]:
"""
@ -394,7 +439,11 @@ class Tunnel:
"""
Shows the Active Tunnel
"""
active = (os.popen('nmcli con show --active | grep -iPo "(.*)(wireguard)"').read().split())
active = (
os.popen('nmcli con show --active | grep -iPo "(.*)(wireguard)"')
.read()
.split()
)
if not active:
active = ""
else:
@ -413,8 +462,14 @@ class Tunnel:
return wg_s
@staticmethod
def export(image_path: Path = None, image_path2: Path = None, image_path3: Path = None, image_path4: Path = None,
title: Dict = None, window_msg: Dict = None) -> None:
def export(
image_path: Path = None,
image_path2: Path = None,
image_path3: Path = None,
image_path4: Path = None,
title: Dict = None,
window_msg: Dict = None,
) -> None:
"""
This will export the tunnels.
A zipfile with the current date and time is created
@ -439,15 +494,30 @@ class Tunnel:
with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf:
if len(zf.namelist()) != 0:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_vpn"], Msg.STR["exp_succ"], Msg.STR["exp_in_home"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_vpn"],
Msg.STR["exp_succ"],
Msg.STR["exp_in_home"],
)
else:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["exp_err"], Msg.STR["exp_try"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["exp_err"],
Msg.STR["exp_try"],
)
else:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["sel_tl"], Msg.STR["tl_first"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"],
Msg.STR["tl_first"],
)
except TypeError:
pass
@ -459,6 +529,7 @@ class ConfigManager:
Universal class for managing configuration files with caching.
Can be reused in different projects.
"""
_config = None
_config_file = None
@ -475,18 +546,19 @@ class ConfigManager:
try:
lines = Path(cls._config_file).read_text(encoding="utf-8").splitlines()
cls._config = {
'updates': lines[1].strip(),
'theme': lines[3].strip(),
'tooltips': lines[5].strip() == "True", # is converted here to boolean!!!
'autostart': lines[7].strip() if len(lines) > 7 else 'off'
"updates": lines[1].strip(),
"theme": lines[3].strip(),
"tooltips": lines[5].strip()
== "True", # is converted here to boolean!!!
"autostart": lines[7].strip() if len(lines) > 7 else "off",
}
except (IndexError, FileNotFoundError):
# DeDefault values in case of error
cls._config = {
'updates': 'on',
'theme': 'light',
'tooltips': "True", # Default Value as string !
'autostart': 'off'
"updates": "on",
"theme": "light",
"tooltips": "True", # Default Value as string !
"autostart": "off",
}
return cls._config
@ -495,16 +567,16 @@ class ConfigManager:
"""Save the config to the config file"""
if cls._config:
lines = [
'# Configuration\n',
"# Configuration\n",
f"{cls._config['updates']}\n",
'# Theme\n',
"# Theme\n",
f"{cls._config['theme']}\n",
'# Tooltips\n',
"# Tooltips\n",
f"{str(cls._config['tooltips'])}\n",
'# Autostart\n',
f"{cls._config['autostart']}\n"
"# Autostart\n",
f"{cls._config['autostart']}\n",
]
Path(cls._config_file).write_text(''.join(lines), encoding="utf-8")
Path(cls._config_file).write_text("".join(lines), encoding="utf-8")
@classmethod
def set(cls, key, value):
@ -579,8 +651,14 @@ class GiteaUpdate:
return "Invalid API Response"
@staticmethod
def download(urld: str, res: str, image_path: Path = None, image_path2: Path = None, image_path3: Path = None,
image_path4: Path = None) -> None:
def download(
urld: str,
res: str,
image_path: Path = None,
image_path2: Path = None,
image_path3: Path = None,
image_path4: Path = None,
) -> None:
"""
Downloads new version of wirepy
@ -600,22 +678,37 @@ class GiteaUpdate:
wt: str = _("Download Successful")
msg_t: str = _("Your zip file is in home directory")
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_vpn"], wt, msg_t)
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_vpn"],
wt,
msg_t,
)
else:
wt: str = _("Download error")
msg_t: str = _("Download failed! Please try again")
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"], wt, msg_t)
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
wt,
msg_t,
)
except subprocess.CalledProcessError:
wt: str = _("Download error")
msg_t: str = _("Download failed! No internet connection!")
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"], wt, msg_t)
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
wt,
msg_t,
)
class Tooltip():
class Tooltip:
"""Class for Tooltip
from common_tools.py import Tooltip
example: Tooltip(label, "Show tooltip on label")
@ -627,8 +720,15 @@ class Tooltip():
NOTE: When using with state_var, pass the tk.BooleanVar object directly,
NOT its value. For example: use state_var=my_bool_var, NOT state_var=my_bool_var.get()
"""
def __init__(self, widget: Any, text: str, state_var: Optional[tk.BooleanVar] = None,
x_offset: int = 65, y_offset: int = 40) -> None:
def __init__(
self,
widget: Any,
text: str,
state_var: Optional[tk.BooleanVar] = None,
x_offset: int = 65,
y_offset: int = 40,
) -> None:
"""Tooltip Class"""
self.widget: Any = widget
self.text: str = text
@ -674,8 +774,14 @@ class Tooltip():
tw.wm_geometry(f"+{x}+{y}")
label: tk.Label = tk.Label(
tw, text=self.text, background="lightgreen", foreground="black",
relief="solid", borderwidth=1, padx=5, pady=5
tw,
text=self.text,
background="lightgreen",
foreground="black",
relief="solid",
borderwidth=1,
padx=5,
pady=5,
)
label.grid()
@ -686,5 +792,3 @@ class Tooltip():
if self.tooltip_window:
self.tooltip_window.destroy()
self.tooltip_window = None

View File

@ -1,15 +0,0 @@
#!/usr/bin/python3
from pathlib import Path
from subprocess import check_call
from tkinter import filedialog, ttk
from common_tools import Create, LxTools
from wp_app_config import AppConfig, Msg
import gettext
import locale
import os
import shutil
import subprocess
from typing import Optional, Dict, Any, NoReturn, TextIO, Tuple, List
# Translate
_ = AppConfig.setup_translations()

View File

@ -12,11 +12,24 @@ uname: Path = Path("/tmp/.log_user")
log_name = Path(uname).read_text(encoding="utf-8")
keyfile: Path = Path(f"/home/{log_name}/.config/wire_py/pbwgk.pem")
#PKEYFILE: Path = "/usr/local/etc/ssl/pwgk.pem"
# PKEYFILE: Path = "/usr/local/etc/ssl/pwgk.pem"
if not keyfile.is_file():
check_call(["openssl", "rsa", "-in", AppConfig.SYSTEM_PATHS["pkey_path"], "-out", keyfile, "-outform", "PEM", "-pubout"])
check_call(
[
"openssl",
"rsa",
"-in",
AppConfig.SYSTEM_PATHS["pkey_path"],
"-out",
keyfile,
"-outform",
"PEM",
"-pubout",
]
)
shutil.chown(keyfile, 1000, 1000)
AppConfig.TEMP_DIR2 = f"/home/{log_name}/.config/wire_py/"
@ -29,6 +42,17 @@ if os.path.exists(f"{AppConfig.TEMP_DIR2}pbwgk.pem"):
for detunnels in detl:
tlname2 = f"{detunnels[:-4]}.conf"
extpath = f"{AppConfig.TEMP_DIR}/{tlname2}"
check_call(["openssl", "pkeyutl", "-decrypt", "-inkey", AppConfig.SYSTEM_PATHS["pkey_path"], "-in", detunnels,
"-out", extpath])
check_call(
[
"openssl",
"pkeyutl",
"-decrypt",
"-inkey",
AppConfig.SYSTEM_PATHS["pkey_path"],
"-in",
detunnels,
"-out",
extpath,
]
)
shutil.chown(extpath, 1000, 1000)

View File

@ -8,15 +8,26 @@ from subprocess import check_call
from common_tools import LxTools
from wp_app_config import AppConfig
#uname: Path = Path("/tmp/.log_user")
#log_name = AppConfig.USER_FILE.read_text(encoding="utf-8")
keyfile: Path = Path(f"/home/{AppConfig.USER_FILE.read_text(encoding="utf-8")}/.config/wire_py/pbwgk.pem")
keyfile: Path = Path(
f"/home/{AppConfig.USER_FILE.read_text(encoding="utf-8")}/.config/wire_py/pbwgk.pem"
)
if not keyfile.is_file():
check_call(["openssl", "rsa", "-in", AppConfig.SYSTEM_PATHS["pkey_path"], "-out", keyfile, "-outform", "PEM", "-pubout"])
check_call(
[
"openssl",
"rsa",
"-in",
AppConfig.SYSTEM_PATHS["pkey_path"],
"-out",
keyfile,
"-outform",
"PEM",
"-pubout",
]
)
shutil.chown(keyfile, 1000, 1000)
if AppConfig.TEMP_DIR.exists():
@ -28,8 +39,20 @@ if not keyfile.is_file():
for tunnels in tl:
sourcetl: str = f"{AppConfig.TEMP_DIR}/{tunnels}"
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
tlname,])
check_call(
[
"openssl",
"pkeyutl",
"-encrypt",
"-inkey",
keyfile,
"-pubin",
"-in",
sourcetl,
"-out",
tlname,
]
)
else:
@ -42,5 +65,17 @@ else:
for tunnels in tl:
sourcetl: str = f"{AppConfig.TEMP_DIR}/{tunnels}"
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
tlname])
check_call(
[
"openssl",
"pkeyutl",
"-encrypt",
"-inkey",
keyfile,
"-pubin",
"-in",
sourcetl,
"-out",
tlname,
]
)

View File

@ -2,6 +2,7 @@
"""
This script belongs to wirepy and is for the auto start of the tunnel
"""
from pathlib import Path
from subprocess import check_call

454
wirepy.py
View File

@ -2,8 +2,6 @@
"""
this script is a simple GUI for managing Wireguard Tunnels
"""
import gettext
import locale
import os
import shutil
import subprocess
@ -14,7 +12,15 @@ from pathlib import Path
from subprocess import check_call
from tkinter import TclError, filedialog, ttk
from common_tools import (ConfigManager, ThemeManager, Create, GiteaUpdate, Tunnel, Tooltip, LxTools)
from common_tools import (
ConfigManager,
ThemeManager,
Create,
GiteaUpdate,
Tunnel,
Tooltip,
LxTools,
)
from wp_app_config import AppConfig, Msg
LxTools.uos()
@ -22,10 +28,12 @@ Create.dir_and_files()
Create.make_dir()
Create.decrypt()
class Wirepy(tk.Tk):
"""
Class Wirepy this is the Main Window of wirepy
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@ -38,8 +46,10 @@ class Wirepy(tk.Tk):
# Set the window size
self.geometry(f"{self.x_width}x{self.y_height}")
self.resizable(AppConfig.UI_CONFIG["resizable_window"][0],
AppConfig.UI_CONFIG["resizable_window"][1])
self.resizable(
AppConfig.UI_CONFIG["resizable_window"][0],
AppConfig.UI_CONFIG["resizable_window"][1],
)
self.title(AppConfig.UI_CONFIG["window_title"])
self.columnconfigure(0, weight=1)
@ -69,6 +79,7 @@ class FrameWidgets(ttk.Frame):
"""
ttk frame class for better structure
"""
def __init__(self, container, **kwargs):
super().__init__(container, **kwargs)
@ -101,13 +112,16 @@ class FrameWidgets(ttk.Frame):
# If it's a string or something else
self.tooltip_state.set(str(state) == "True")
self.tooltip_label = tk.StringVar() # StringVar-Variable for tooltip label for view Disabled/Enabled
self.tooltip_label = (
tk.StringVar()
) # StringVar-Variable for tooltip label for view Disabled/Enabled
self.tooltip_update_label()
self.update_label = tk.StringVar() # StringVar-Variable for update label
self.update_tooltip = tk.StringVar() # StringVar-Variable for update tooltip please not remove!
self.update_label = tk.StringVar() # StringVar-Variable for update label
self.update_tooltip = (
tk.StringVar()
) # StringVar-Variable for update tooltip please not remove!
self.update_foreground = tk.StringVar(value="red")
# Frame for Menu
self.menu_frame = ttk.Frame(self)
self.menu_frame.configure(relief="flat")
@ -118,7 +132,9 @@ class FrameWidgets(ttk.Frame):
self.version_lb.config(font=("Ubuntu", 11), foreground="#00c4ff")
self.version_lb.grid(column=0, row=0, rowspan=4, padx=10)
Tooltip(self.version_lb, f"Version: {AppConfig.VERSION[2:]}", self.tooltip_state)
Tooltip(
self.version_lb, f"Version: {AppConfig.VERSION[2:]}", self.tooltip_state
)
self.options_btn = ttk.Menubutton(self.menu_frame, text=_("Options"))
self.options_btn.grid(column=1, columnspan=1, row=0)
@ -128,27 +144,37 @@ class FrameWidgets(ttk.Frame):
self.set_update = tk.IntVar()
self.settings = tk.Menu(self, relief="flat")
self.options_btn.configure(menu=self.settings, style="Toolbutton")
self.settings.add_checkbutton(label=_("Disable Updates"),
command=lambda: self.update_setting(self.set_update.get()), variable=self.set_update)
self.settings.add_checkbutton(
label=_("Disable Updates"),
command=lambda: self.update_setting(self.set_update.get()),
variable=self.set_update,
)
self.updates_lb = ttk.Label(self.menu_frame, textvariable=self.update_label)
self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10)
self.updates_lb.grid_remove()
self.update_label.trace_add("write", self.update_label_display)
self.update_foreground.trace_add("write", self.update_label_display)
res = GiteaUpdate.api_down(AppConfig.UPDATE_URL, AppConfig.VERSION, ConfigManager.get("updates"))
res = GiteaUpdate.api_down(
AppConfig.UPDATE_URL, AppConfig.VERSION, ConfigManager.get("updates")
)
self.update_ui_for_update(res)
# Tooltip Menu
self.settings.add_command(label=self.tooltip_label.get(), command=self.tooltips_toggle)
self.settings.add_command(
label=self.tooltip_label.get(), command=self.tooltips_toggle
)
# Label show dark or light
self.theme_label = tk.StringVar()
self.update_theme_label()
self.settings.add_command(label=self.theme_label.get(), command=self.on_theme_toggle)
self.settings.add_command(
label=self.theme_label.get(), command=self.on_theme_toggle
)
# About BTN Menu / Label
self.about_btn = ttk.Button(
self.menu_frame, text=_("About"), style="Toolbutton", command=self.about)
self.menu_frame, text=_("About"), style="Toolbutton", command=self.about
)
self.about_btn.grid(column=2, columnspan=2, row=0)
self.readme = tk.Menu(self)
@ -172,7 +198,9 @@ class FrameWidgets(ttk.Frame):
# Bottom Frame 4
self.lb_frame3 = ttk.Frame(self)
self.lb_frame3.configure(relief="flat")
self.lb_frame3.grid(column=0, row=5, columnspan=4, sticky="snew", padx=2, pady=2)
self.lb_frame3.grid(
column=0, row=5, columnspan=4, sticky="snew", padx=2, pady=2
)
# Bottom Frame 5
self.lb_frame4 = ttk.Frame(self)
@ -205,7 +233,9 @@ class FrameWidgets(ttk.Frame):
self.l_box.grid(column=1, rowspan=4, row=0, sticky="ns")
self.l_box.event_add("<<ClickEvent>>", "<Button-1>")
self.l_box.bind("<<ClickEvent>>", self.enable_check_box)
self.scrollbar = ttk.Scrollbar(self.lb_frame_btn_lbox, orient="vertical", command=self.l_box.yview)
self.scrollbar = ttk.Scrollbar(
self.lb_frame_btn_lbox, orient="vertical", command=self.l_box.yview
)
self.scrollbar.grid(column=1, rowspan=4, row=0, sticky="nse")
self.l_box.configure(yscrollcommand=self.scrollbar.set)
@ -230,14 +260,24 @@ class FrameWidgets(ttk.Frame):
self.show_data()
# Button Import
self.btn_i = ttk.Button(self.lb_frame_btn_lbox, image=self.imp_pic, command=self.import_sl, padding=0)
self.btn_i = ttk.Button(
self.lb_frame_btn_lbox,
image=self.imp_pic,
command=self.import_sl,
padding=0,
)
self.btn_i.grid(column=0, row=1, padx=15, pady=8)
Tooltip(self.btn_i, Msg.TTIP["import_tl"], self.tooltip_state)
# Button Trash
self.btn_tr = ttk.Button(self.lb_frame_btn_lbox, image=self.tr_pic, command=self.delete, padding=0,
style="CButton.TButton")
self.btn_tr = ttk.Button(
self.lb_frame_btn_lbox,
image=self.tr_pic,
command=self.delete,
padding=0,
style="CButton.TButton",
)
self.btn_tr.grid(column=0, row=2, padx=15, pady=8)
if self.l_box.size() == 0:
@ -246,11 +286,19 @@ class FrameWidgets(ttk.Frame):
Tooltip(self.btn_tr, Msg.TTIP["trash_tl"], self.tooltip_state)
# Button Export
self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic,
command=lambda: Tunnel.export(AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_vpn"], AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"], Msg.STR["tl_first"]), padding=0)
self.btn_exp = ttk.Button(
self.lb_frame_btn_lbox,
image=self.exp_pic,
command=lambda: Tunnel.export(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_vpn"],
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"],
Msg.STR["tl_first"],
),
padding=0,
)
self.btn_exp.grid(column=0, row=3, padx=15, pady=8)
@ -266,13 +314,31 @@ class FrameWidgets(ttk.Frame):
self.lb_rename.config(state="disable")
if self.l_box.size() != 0:
Tooltip(self.lb_rename, Msg.TTIP["rename_tl"], self.tooltip_state, x_offset= -120, y_offset=-70)
Tooltip(
self.lb_rename,
Msg.TTIP["rename_tl"],
self.tooltip_state,
x_offset=-120,
y_offset=-70,
)
else:
Tooltip(self.lb_rename, Msg.TTIP["rename_tl_info"], self.tooltip_state, x_offset=-180, y_offset=-50)
Tooltip(
self.lb_rename,
Msg.TTIP["rename_tl_info"],
self.tooltip_state,
x_offset=-180,
y_offset=-50,
)
# Button Rename
self.btn_rename = ttk.Button(self.lb_frame4, text=_("Rename"), state="disable", command=self.tl_rename,
padding=4, style="RnButton.TButton")
self.btn_rename = ttk.Button(
self.lb_frame4,
text=_("Rename"),
state="disable",
command=self.tl_rename,
padding=4,
style="RnButton.TButton",
)
self.btn_rename.grid(column=3, row=0, padx=5, pady=10, sticky="ne")
# Check Buttons
@ -281,22 +347,46 @@ class FrameWidgets(ttk.Frame):
self.autoconnect_var.set(f"{self.auto_con}")
# Frame for Labels, Entry and Button
self.autoconnect = ttk.Label(self.lb_frame3, textvariable=self.autoconnect_var, width=15)
self.autoconnect = ttk.Label(
self.lb_frame3, textvariable=self.autoconnect_var, width=15
)
self.autoconnect.config(font=("Ubuntu", 11))
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
self.wg_autostart = ttk.Checkbutton(self.lb_frame3, text=_("Autoconnect on:"), variable=self.selected_option,
command=self.box_set)
self.wg_autostart = ttk.Checkbutton(
self.lb_frame3,
text=_("Autoconnect on:"),
variable=self.selected_option,
command=self.box_set,
)
self.wg_autostart.grid(column=0, row=0, pady=15, padx=15, sticky="nw")
if self.l_box.size() >= 1 and len(self.l_box.curselection()) >= 1:
Tooltip(self.wg_autostart, Msg.TTIP["autostart"], self.tooltip_state, x_offset=-10, y_offset=-40)
Tooltip(
self.wg_autostart,
Msg.TTIP["autostart"],
self.tooltip_state,
x_offset=-10,
y_offset=-40,
)
if self.l_box.size() == 0:
Tooltip(self.wg_autostart, Msg.TTIP["autostart_info"], self.tooltip_state, x_offset=30, y_offset=-50)
Tooltip(
self.wg_autostart,
Msg.TTIP["autostart_info"],
self.tooltip_state,
x_offset=30,
y_offset=-50,
)
else:
Tooltip(self.wg_autostart, Msg.TTIP["autostart"], self.tooltip_state, x_offset=-10, y_offset=-40)
Tooltip(
self.wg_autostart,
Msg.TTIP["autostart"],
self.tooltip_state,
x_offset=-10,
y_offset=-40,
)
self.on_off()
@ -316,9 +406,9 @@ class FrameWidgets(ttk.Frame):
def update_ui_for_update(self, res):
"""Update UI elements based on update check result"""
# First, remove the update button if it exists to avoid conflicts
if hasattr(self, 'update_btn'):
if hasattr(self, "update_btn"):
self.update_btn.grid_forget()
delattr(self, 'update_btn')
delattr(self, "update_btn")
if res == "False":
self.set_update.set(value=1)
@ -333,7 +423,11 @@ class FrameWidgets(ttk.Frame):
self.update_label.set(_("No Server Connection!"))
self.update_foreground.set("red")
# Set tooltip for "No Server Connection"
Tooltip(self.updates_lb, _("Could not connect to update server"), self.tooltip_state)
Tooltip(
self.updates_lb,
_("Could not connect to update server"),
self.tooltip_state,
)
elif res == "No Updates":
self.update_label.set(_("No Updates"))
@ -352,7 +446,9 @@ class FrameWidgets(ttk.Frame):
# Create the update button
self.update_btn = ttk.Menubutton(self.menu_frame, text=update_text)
self.update_btn.grid(column=4, columnspan=3, row=0, padx=0)
Tooltip(self.update_btn, _("Click to download new version"), self.tooltip_state)
Tooltip(
self.update_btn, _("Click to download new version"), self.tooltip_state
)
self.download = tk.Menu(self, relief="flat")
self.update_btn.configure(menu=self.download, style="Toolbutton")
@ -364,8 +460,8 @@ class FrameWidgets(ttk.Frame):
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_vpn"],
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"]
)
AppConfig.IMAGE_PATHS["icon_msg"],
),
)
@staticmethod
@ -373,15 +469,26 @@ class FrameWidgets(ttk.Frame):
"""
a tk.Toplevel window
"""
def link_btn() -> str | None:
webbrowser.open("https://git.ilunix.de/punix/Wire-Py")
msg_t = _("Wire-Py a simple Wireguard Gui for Linux systems.\n\n"
"Wire-Py is open source software written in Python.\n\n"
"Email: polunga40@unity-mail.de also likes for donation.\n\n"
"Use without warranty!\n")
msg_t = _(
"Wire-Py a simple Wireguard Gui for Linux systems.\n\n"
"Wire-Py is open source software written in Python.\n\n"
"Email: polunga40@unity-mail.de also likes for donation.\n\n"
"Use without warranty!\n"
)
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_vpn"],
AppConfig.IMAGE_PATHS["icon_vpn"],
_("Info"),
msg_t,
_("Go to Wire-Py git"),
link_btn,
)
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_vpn"], AppConfig.IMAGE_PATHS["icon_vpn"], _("Info"), msg_t, _("Go to Wire-Py git"), link_btn)
def update_setting(self, update_res) -> None:
"""write off or on in file
Args:
@ -398,12 +505,14 @@ class FrameWidgets(ttk.Frame):
# When enabling updates, we need to actually check for updates
try:
# Force a fresh check by passing "on" as the update setting
res = GiteaUpdate.api_down(AppConfig.UPDATE_URL, AppConfig.VERSION, "on")
res = GiteaUpdate.api_down(
AppConfig.UPDATE_URL, AppConfig.VERSION, "on"
)
# Make sure UI is updated regardless of previous state
if hasattr(self, 'update_btn'):
if hasattr(self, "update_btn"):
self.update_btn.grid_forget()
if hasattr(self, 'updates_lb'):
if hasattr(self, "updates_lb"):
self.updates_lb.grid_forget()
# Now update the UI with the fresh result
@ -461,8 +570,12 @@ class FrameWidgets(ttk.Frame):
"""
Start Button
"""
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_start,
command=lambda: self.wg_switch("start"), padding=0)
self.btn_stst = ttk.Button(
self.lb_frame_btn_lbox,
image=self.wg_vpn_start,
command=lambda: self.wg_switch("start"),
padding=0,
)
self.btn_stst.grid(column=0, row=0, padx=5, pady=8)
tl = LxTools.get_file_name(AppConfig.TEMP_DIR)
@ -491,12 +604,16 @@ class FrameWidgets(ttk.Frame):
"""
View activ Tunnel in the color green or yellow
"""
if ConfigManager.get("theme") == "light":
if ConfigManager.get("theme") == "light":
self.lb_tunnel = ttk.Label(self, textvariable=self.str_var, foreground="green")
self.lb_tunnel = ttk.Label(
self, textvariable=self.str_var, foreground="green"
)
else:
self.lb_tunnel = ttk.Label(self, textvariable=self.str_var, foreground="yellow")
self.lb_tunnel = ttk.Label(
self, textvariable=self.str_var, foreground="yellow"
)
self.lb_tunnel.config(font=("Ubuntu", 11, "bold"))
self.lb_tunnel.grid(column=2, padx=10, row=1)
@ -505,8 +622,12 @@ class FrameWidgets(ttk.Frame):
"""
Stop Button
"""
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_stop,
command=lambda: self.wg_switch("stop"), padding=0)
self.btn_stst = ttk.Button(
self.lb_frame_btn_lbox,
image=self.wg_vpn_stop,
command=lambda: self.wg_switch("stop"),
padding=0,
)
self.btn_stst.grid(column=0, row=0, padx=5, pady=8)
Tooltip(self.btn_stst, Msg.TTIP["stop_tl"], self.tooltip_state)
@ -527,7 +648,7 @@ class FrameWidgets(ttk.Frame):
filepath = filedialog.askopenfilename(
initialdir=f"{Path.home()}",
title=_("Select Wireguard config File"),
filetypes=[(_("WG config files"), "*.conf")]
filetypes=[(_("WG config files"), "*.conf")],
)
# Überprüfe, ob der Benutzer den Dialog abgebrochen hat
@ -541,7 +662,11 @@ class FrameWidgets(ttk.Frame):
path_split = filepath.split("/")
path_split1 = path_split[-1]
if "PrivateKey = " in read and "PublicKey = " in read and "Endpoint =" in read:
if (
"PrivateKey = " in read
and "PublicKey = " in read
and "Endpoint =" in read
):
with open(filepath, "r", encoding="utf-8") as file:
key = Tunnel.con_to_dict(file)
pre_key = key[3]
@ -550,14 +675,21 @@ class FrameWidgets(ttk.Frame):
p_key = AppConfig.KEYS_FILE.read_text(encoding="utf-8")
if pre_key in p_key or f"{pre_key}\n" in p_key:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["imp_err"], Msg.STR["tl_exist"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["imp_err"],
Msg.STR["tl_exist"],
)
else:
with open(AppConfig.KEYS_FILE, "a", encoding="utf-8") as keyfile:
with open(
AppConfig.KEYS_FILE, "a", encoding="utf-8"
) as keyfile:
keyfile.write(f"{pre_key}\r")
if len(path_split1) > 17:
p1 = shutil.copy(filepath, AppConfig.TEMP_DIR)
path_split = path_split1[len(path_split1) - 17:]
path_split = path_split1[len(path_split1) - 17 :]
os.rename(p1, f"{AppConfig.TEMP_DIR}/{path_split}")
new_conf = f"{AppConfig.TEMP_DIR}/{path_split}"
@ -565,7 +697,18 @@ class FrameWidgets(ttk.Frame):
check_call(["nmcli", "connection", "down", self.a])
self.reset_fields()
subprocess.check_output(["nmcli", "connection", "import", "type", "wireguard", "file", new_conf], text=True)
subprocess.check_output(
[
"nmcli",
"connection",
"import",
"type",
"wireguard",
"file",
new_conf,
],
text=True,
)
Create.encrypt()
else:
shutil.copy(filepath, f"{AppConfig.TEMP_DIR}/")
@ -574,7 +717,18 @@ class FrameWidgets(ttk.Frame):
check_call(["nmcli", "connection", "down", self.a])
self.reset_fields()
subprocess.check_output(["nmcli", "connection", "import", "type", "wireguard", "file", filepath], text=True)
subprocess.check_output(
[
"nmcli",
"connection",
"import",
"type",
"wireguard",
"file",
filepath,
],
text=True,
)
Create.encrypt()
self.str_var.set("")
@ -585,10 +739,18 @@ class FrameWidgets(ttk.Frame):
self.l_box.update()
self.l_box.selection_set(0)
Tooltip(self.wg_autostart, Msg.TTIP["autostart"], self.tooltip_state, x_offset=-10, y_offset=-40)
Tooltip(
self.wg_autostart,
Msg.TTIP["autostart"],
self.tooltip_state,
x_offset=-10,
y_offset=-40,
)
Tooltip(self.btn_tr, Msg.TTIP["trash_tl"], self.tooltip_state)
Tooltip(self.btn_exp, Msg.TTIP["export_tl"], self.tooltip_state)
Tooltip(self.btn_rename, Msg.TTIP["rename_tl"], self.tooltip_state)
Tooltip(
self.btn_rename, Msg.TTIP["rename_tl"], self.tooltip_state
)
self.lb_rename.insert(0, "Max. 12 characters!")
self.str_var = tk.StringVar()
@ -596,11 +758,25 @@ class FrameWidgets(ttk.Frame):
self.color_label()
self.stop()
data = self.handle_tunnel_data(self.a)
check_call(["nmcli", "con", "mod", self.a, "connection.autoconnect", "no"])
check_call(
[
"nmcli",
"con",
"mod",
self.a,
"connection.autoconnect",
"no",
]
)
elif ("PrivateKey = " in read) and ("Endpoint = " in read):
pass
else:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["imp_err"], Msg.STR["no_valid_file"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["imp_err"],
Msg.STR["no_valid_file"],
)
except EOFError as e:
print(e)
@ -618,15 +794,16 @@ class FrameWidgets(ttk.Frame):
try:
self.select_tunnel = self.l_box.curselection()
select_tl = self.l_box.get(self.select_tunnel[0])
with open(f"/tmp/tlecdcwg/{select_tl}.conf", "r+", encoding="utf-8") as file2:
with open(
f"/tmp/tlecdcwg/{select_tl}.conf", "r+", encoding="utf-8"
) as file2:
key = Tunnel.con_to_dict(file2)
pre_key = key[3]
check_call(["nmcli", "connection", "delete", select_tl])
self.l_box.delete(self.select_tunnel[0])
with open(AppConfig.SETTINGS_FILE, "r", encoding="utf-8") as set_f6:
lines6 = set_f6.readlines()
if (select_tl == lines6[7].strip()
and "off\n" not in lines6[7].strip()):
if select_tl == lines6[7].strip() and "off\n" not in lines6[7].strip():
lines6[7] = "off\n"
with open(AppConfig.SETTINGS_FILE, "w", encoding="utf-8") as set_f7:
set_f7.writelines(lines6)
@ -637,7 +814,9 @@ class FrameWidgets(ttk.Frame):
Path.unlink(f"{Path.home()}/.config/wire_py/{select_tl}.dat")
Path.unlink(f"/tmp/tlecdcwg/{select_tl}.conf")
with open(AppConfig.KEYS_FILE, "r", encoding="utf-8") as readfile:
with open(f"{Path.home()}/.config/wire_py/keys2", "w", encoding="utf-8") as writefile:
with open(
f"{Path.home()}/.config/wire_py/keys2", "w", encoding="utf-8"
) as writefile:
for line in readfile:
if pre_key not in line.strip("\n"):
writefile.write(line)
@ -650,8 +829,13 @@ class FrameWidgets(ttk.Frame):
if self.l_box.size() == 0:
self.wg_autostart.configure(state="disabled")
self.lb_rename.configure(state="disabled")
Tooltip(self.wg_autostart, Msg.TTIP["autostart_info"]
, self.tooltip_state, x_offset=30, y_offset=-50)
Tooltip(
self.wg_autostart,
Msg.TTIP["autostart_info"],
self.tooltip_state,
x_offset=30,
y_offset=-50,
)
Tooltip(self.btn_exp, Msg.TTIP["export_tl_info"], self.tooltip_state)
Tooltip(self.btn_stst, Msg.TTIP["empty_list"], self.tooltip_state)
@ -668,11 +852,21 @@ class FrameWidgets(ttk.Frame):
if self.l_box.size() != 0:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["sel_tl"], Msg.STR["sel_list"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"],
Msg.STR["sel_list"],
)
else:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["sel_tl"], Msg.STR["tl_first"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"],
Msg.STR["tl_first"],
)
def enable_check_box(self, _) -> None:
"""
@ -691,7 +885,11 @@ class FrameWidgets(ttk.Frame):
Set (on), the selected tunnel is displayed in the label.
At (off) the label is first emptied then filled with No Autoconnect
"""
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
lines = (
Path(AppConfig.SETTINGS_FILE)
.read_text(encoding="utf-8")
.splitlines(keepends=True)
)
if lines[7] != "off\n":
print(f"{lines[7]} starts automatically when the system starts.")
@ -707,7 +905,12 @@ class FrameWidgets(ttk.Frame):
self.autoconnect_var = tk.StringVar()
self.autoconnect_var.set(self.auto_con)
self.autoconnect = ttk.Label(self.lb_frame3, textvariable=self.autoconnect_var, foreground="#0071ff", width=15)
self.autoconnect = ttk.Label(
self.lb_frame3,
textvariable=self.autoconnect_var,
foreground="#0071ff",
width=15,
)
self.autoconnect.config(font=("Ubuntu", 11))
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
@ -727,9 +930,15 @@ class FrameWidgets(ttk.Frame):
select_tl = self.l_box.get(select_tunnel[0])
if self.selected_option.get() == 0:
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
lines[7] = 'off\n'
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
lines = (
Path(AppConfig.SETTINGS_FILE)
.read_text(encoding="utf-8")
.splitlines(keepends=True)
)
lines[7] = "off\n"
Path(AppConfig.SETTINGS_FILE).write_text(
"".join(lines), encoding="utf-8"
)
tl = LxTools.get_file_name(AppConfig.TEMP_DIR)
@ -737,9 +946,15 @@ class FrameWidgets(ttk.Frame):
self.wg_autostart.configure(state="disabled")
if self.selected_option.get() >= 1:
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
lines = (
Path(AppConfig.SETTINGS_FILE)
.read_text(encoding="utf-8")
.splitlines(keepends=True)
)
lines[7] = select_tl
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
Path(AppConfig.SETTINGS_FILE).write_text(
"".join(lines), encoding="utf-8"
)
except IndexError:
self.selected_option.set(1)
@ -755,19 +970,39 @@ class FrameWidgets(ttk.Frame):
if len(self.lb_rename.get()) > 12:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["ren_err"], Msg.STR["sign_len"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["ren_err"],
Msg.STR["sign_len"],
)
elif len(self.lb_rename.get()) == 0:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["ren_err"], Msg.STR["zero_signs"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["ren_err"],
Msg.STR["zero_signs"],
)
elif any(ch in special_characters for ch in self.lb_rename.get()):
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["ren_err"], Msg.STR["false_signs"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["ren_err"],
Msg.STR["false_signs"],
)
elif self.lb_rename.get() in name_of_file:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["ren_err"], Msg.STR["is_in_use"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["ren_err"],
Msg.STR["is_in_use"],
)
else:
@ -776,7 +1011,17 @@ class FrameWidgets(ttk.Frame):
select_tl = self.l_box.get(self.select_tunnel[0])
# nmcli connection modify old connection.id iphone
subprocess.check_output(["nmcli", "connection", "modify", select_tl, "connection.id", self.lb_rename.get()], text=True)
subprocess.check_output(
[
"nmcli",
"connection",
"modify",
select_tl,
"connection.id",
self.lb_rename.get(),
],
text=True,
)
source = Path(f"/tmp/tlecdcwg/{select_tl}.conf")
destination = source.with_name(f"{self.lb_rename.get()}.conf")
source.replace(destination)
@ -792,7 +1037,9 @@ class FrameWidgets(ttk.Frame):
lines5 = set_f5.readlines()
if select_tl == lines5[7].strip() and "off\n" not in lines5[7].strip():
lines5[7] = new_a_connect
with open(AppConfig.SETTINGS_FILE, "w", encoding="utf-8") as theme_set5:
with open(
AppConfig.SETTINGS_FILE, "w", encoding="utf-8"
) as theme_set5:
theme_set5.writelines(lines5)
self.autoconnect_var.set(value=new_a_connect)
self.update_connection_display()
@ -800,7 +1047,12 @@ class FrameWidgets(ttk.Frame):
except IndexError:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["ren_err"], Msg.STR["sel_list"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["ren_err"],
Msg.STR["sel_list"],
)
except subprocess.CalledProcessError:
pass
@ -826,7 +1078,9 @@ class FrameWidgets(ttk.Frame):
shows data in the label
"""
# Address Label
self.address = ttk.Label(self.lb_frame, textvariable=self.add, foreground="#0071ff")
self.address = ttk.Label(
self.lb_frame, textvariable=self.add, foreground="#0071ff"
)
self.address.grid(column=0, row=5, sticky="w", padx=10, pady=6)
self.address.config(font=("Ubuntu", 9))
@ -836,7 +1090,9 @@ class FrameWidgets(ttk.Frame):
self.dns.config(font=("Ubuntu", 9))
# Endpoint Label
self.endpoint = ttk.Label(self.lb_frame2, textvariable=self.enp, foreground="#0071ff")
self.endpoint = ttk.Label(
self.lb_frame2, textvariable=self.enp, foreground="#0071ff"
)
self.endpoint.grid(column=0, row=8, sticky="w", padx=10, pady=20)
self.endpoint.config(font=("Ubuntu", 9))
@ -861,11 +1117,21 @@ class FrameWidgets(ttk.Frame):
if self.l_box.size() != 0:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["sel_tl"], Msg.STR["sel_list"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"],
Msg.STR["sel_list"],
)
else:
LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_msg"], Msg.STR["sel_tl"], Msg.STR["tl_first"])
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"],
Msg.STR["tl_first"],
)
def handle_connection_state(self, action: str, tunnel_name: str = None) -> None:
"""

View File

@ -6,6 +6,7 @@ import locale
from pathlib import Path
from typing import Dict, Any
class AppConfig:
"""Central configuration class for Wire-Py application"""
@ -30,23 +31,21 @@ class AppConfig:
UPDATE_URL: str = "https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases"
DOWNLOAD_URL: str = "https://git.ilunix.de/punix/Wire-Py/archive"
# UI configuration
UI_CONFIG: Dict[str, Any] = {
"window_title": "Wire-Py",
"window_size": (600, 383),
"font_family": "Ubuntu",
"font_size": 11,
"resizable_window": (False, False)
"resizable_window": (False, False),
}
# System-dependent paths
SYSTEM_PATHS: Dict[str, str]= {
SYSTEM_PATHS: Dict[str, str] = {
"ssl_decrypt": "/usr/local/bin/ssl_decrypt.py",
"ssl_encrypt": "/usr/local/bin/ssl_encrypt.py",
"tcl_path": "/usr/share/TK-Themes",
"pkey_path": "/usr/local/etc/ssl/pwgk.pem"
"pkey_path": "/usr/local/etc/ssl/pwgk.pem",
}
# Images and icons paths
@ -59,8 +58,7 @@ class AppConfig:
"icon_start": "/usr/share/icons/lx-icons/48/wg_vpn-start.png",
"icon_stop": "/usr/share/icons/lx-icons/48/wg_vpn-stop.png",
"icon_info": "/usr/share/icons/lx-icons/64/info.png",
"icon_error": "/usr/share/icons/lx-icons/64/error.png"
"icon_error": "/usr/share/icons/lx-icons/64/error.png",
}
@staticmethod
@ -87,7 +85,9 @@ class AppConfig:
def create_default_settings(cls) -> None:
"""Creates default settings if they don't exist"""
if not cls.SETTINGS_FILE.exists():
content = "\n".join(f"[{k.upper()}]\n{v}" for k, v in cls.DEFAULT_SETTINGS.items())
content = "\n".join(
f"[{k.upper()}]\n{v}" for k, v in cls.DEFAULT_SETTINGS.items()
)
cls.SETTINGS_FILE.write_text(content)
@classmethod
@ -97,14 +97,14 @@ class AppConfig:
"main_icon": cls.SYSTEM_PATHS["image_path"] / "48/wg_vpn.png",
"warning": cls.CONFIG_DIR / "images/warning.png",
"success": cls.CONFIG_DIR / "images/success.png",
"error": cls.CONFIG_DIR / "images/error.png"
"error": cls.CONFIG_DIR / "images/error.png",
}
@classmethod
def get_autostart_content(cls) -> str:
"""Returns the content for the autostart service file"""
return """[Unit]
Description=Automatic Tunnel Start
return """[Unit]Description=Automatic Tunnel Start
After=network-online.target
[Service]
@ -114,9 +114,11 @@ ExecStart=/usr/local/bin/start_wg.py
[Install]
WantedBy=default.target"""
# here is inizialize the class for translate strrings
_ = AppConfig.setup_translations()
class Msg:
"""
A utility class that provides centralized access to translated message strings.
@ -137,6 +139,7 @@ class Msg:
Ensure that gettext translation is properly initialized before
accessing these strings to ensure correct localization.
"""
STR: Dict[str, str] = {
# Strings for messages
"sel_tl": _("Select tunnel"),
@ -150,31 +153,38 @@ class Msg:
"sel_list": _("Please select a tunnel from the list"),
"sign_len": _("The new name may contain only 12 characters"),
"zero_signs": _("At least one character must be entered"),
"false signs": _("No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n"),
"false signs": _(
"No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n"
),
"is_in_use": _("The tunnel is already in use"),
"no_valid_file": _("Oh... no valid Wireguard File!\nPlease select a valid Wireguard File"),
"tl_exist": _("Tunnel already available!\nPlease use another file for import")
"no_valid_file": _(
"Oh... no valid Wireguard File!\nPlease select a valid Wireguard File"
),
"tl_exist": _("Tunnel already available!\nPlease use another file for import"),
}
TTIP: Dict[str, str] = {
#Strings for Tooltips
# Strings for Tooltips
"settings": _("Click for Settings"),
"import_tl": _("Click to import a Wireguard Tunnel"),
"start_tl": _("Click to start selected Wireguard Tunnel"),
"empty_list": _("No tunnels to start in the list"),
"stop_tl": _("Click to stop selected Wireguard Tunnel"),
"del_tl": _("Click to delete selected Wireguard Tunnel"),
"rename_tl": _("To rename a tunnel, you need to\nselect a tunnel from the list"),
"rename_tl": _(
"To rename a tunnel, you need to\nselect a tunnel from the list"
),
"export_tl": _(" Click to export all\nWireguard Tunnel to Zipfile"),
"trash_tl": _("Click to delete a Wireguard Tunnel\nSelect from the list!"),
"autostart": _("To use the autostart, enable this Checkbox"),
"autostart_info": _("You must have at least one\ntunnel in the list,to use the autostart"),
"autostart_info": _(
"You must have at least one\ntunnel in the list,to use the autostart"
),
"export_tl_info": _("No Tunnels in List for Export"),
"start_tl_info": _("Click to start selected Wireguard Tunnel"),
"rename_tl_info": _("To rename a tunnel, at least one must be in the list"),
"trash_tl_info": _("No tunnels to delete in the list"),
"list_auto_info": _("To use the autostart, a tunnel must be selected from the list"),
"download": _("Click to download new version")
"list_auto_info": _(
"To use the autostart, a tunnel must be selected from the list"
),
"download": _("Click to download new version"),
}