From 23116617350910c6cac38e73b271d66835a50e2d Mon Sep 17 00:00:00 2001 From: punix Date: Wed, 30 Apr 2025 23:24:00 +0200 Subject: [PATCH] part one more optimization with app_config file --- __pycache__/cls_mth_fc.cpython-312.pyc | Bin 24258 -> 25421 bytes __pycache__/wp_app_config.cpython-312.pyc | Bin 3612 -> 8883 bytes cls_mth_fc.py | 44 ++++--- wirepy.py | 95 +++++++-------- wp_app_config.py | 136 ++++++++++++++++++---- 5 files changed, 191 insertions(+), 84 deletions(-) diff --git a/__pycache__/cls_mth_fc.cpython-312.pyc b/__pycache__/cls_mth_fc.cpython-312.pyc index a8e736cfd3a37abd062f0a5165ae39e1a573da33..3e3e5a962e62f1b0c737f31e1a2cf8fc8c9c78af 100644 GIT binary patch delta 4351 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 delta 3196 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 diff --git a/cls_mth_fc.py b/cls_mth_fc.py index a184d87..6869907 100755 --- a/cls_mth_fc.py +++ b/cls_mth_fc.py @@ -14,16 +14,11 @@ from datetime import datetime from pathlib import Path from subprocess import check_call, CompletedProcess from tkinter import ttk, Toplevel -from wp_app_config import AppConfig +from wp_app_config import AppConfig, Msg import requests # Translate -AppConfig.APP_NAME -locale.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR) -gettext.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR) -gettext.textdomain(AppConfig.APP_NAME) -_ = gettext.gettext - +_ = AppConfig.setup_translations() class Create: """ @@ -80,7 +75,6 @@ class Create: def make_dir() -> None: """Folder Name "tlecdewg" = Tunnel Encrypt Decrypt Wireguard""" - AppConfig.TEMP_DIR: Path = Path("/tmp/tlecdcwg/") if AppConfig.TEMP_DIR.exists(): pass else: @@ -125,6 +119,31 @@ class LxTools(tk.Tk): def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + @staticmethod + def get_file_name(path: Path, i: int = 5) -> List[str]: + """ + Recursively searches the specified path for files and returns a list of filenames, + with the last 'i' characters of each filename removed. + + This method is useful for obtaining filenames without specific file extensions, + e.g., to remove '.conf' from Wireguard configuration files. + + Args: + path (Path): The directory path to search + i (int, optional): Number of characters to remove from the end of each filename. + Default is 5, which typically corresponds to the length of '.conf'. + + Returns: + List[str]: A list of filenames without the last 'i' characters + + Example: + If path contains files like 'tunnel1.conf', 'tunnel2.conf' and i=5, + the method returns ['tunnel1', 'tunnel2']. + """ + lists_file = list(path.rglob("*")) + lists_file = [conf_file.name[:-i] for conf_file in lists_file] + return lists_file + @staticmethod def uos() -> None: """ @@ -432,17 +451,15 @@ class Tunnel: with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf: if len(zf.namelist()) != 0: - msg_t: str = _("Your zip file is in home directory") - LxTools.msg_window(img_w, img_i, _("Export Successful"), msg_t) + LxTools.msg_window(img_w, img_i, Msg.STR["exp_succ"], Msg.STR["exp_in_home"]) else: - msg_t: str = _("Export failed! Please try again") - LxTools.msg_window(img_w2, img_i2, _("Export error"), msg_t) + LxTools.msg_window(img_w2, img_i2, Msg.STR["exp_err"], Msg.STR["exp_try"]) else: - LxTools.msg_window(img_w, img_i2, sl, pfit) + LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["tl_first"]) except TypeError: pass @@ -492,6 +509,7 @@ class Tooltip: label: tk.Label = tk.Label(tw, text=self.text, background="lightgreen", foreground="black", relief="solid", borderwidth=1, padx=5, pady=5) label.grid() + self.tooltip_window.after(2200, lambda: tw.destroy()) def hide_tooltip(self, event: Optional[Any] = None) -> None: """ diff --git a/wirepy.py b/wirepy.py index 46fff58..144ac7e 100755 --- a/wirepy.py +++ b/wirepy.py @@ -15,7 +15,7 @@ from subprocess import check_call from tkinter import TclError, filedialog, ttk from cls_mth_fc import (Create, GiteaUpdate, Tooltip, Tunnel, LxTools) -from wp_app_config import AppConfig +from wp_app_config import AppConfig, Msg LxTools.uos() Create.dir_and_files() @@ -24,28 +24,18 @@ Create.decrypt() tips = LxTools.if_tip(AppConfig.SETTINGS_FILE) - # 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year VERSION: str = "v. 2.04.1725" res = GiteaUpdate.api_down("https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases", VERSION, AppConfig.SETTINGS_FILE) # Translate -AppConfig.APP_NAME -locale.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR) -gettext.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR) -gettext.textdomain(AppConfig.APP_NAME) -_ = gettext.gettext +_ = AppConfig.setup_translations() img_w: str = r"/usr/share/icons/lx-icons/64/info.png" img_i: str = r"/usr/share/icons/lx-icons/48/wg_vpn.png" img_w2: str = r"/usr/share/icons/lx-icons/64/error.png" img_i2: str = r"/usr/share/icons/lx-icons/48/wg_msg.png" -sl: str = _("Select tunnel") -rnp: str = _("Renaming not possible") -ie:str = _("Import Error") -pfit: str = _("Please first import tunnel") -pstl: str = _("Please select a tunnel from the list") LxTools.sigi(AppConfig.TEMP_DIR, AppConfig.USER_FILE) @@ -71,7 +61,7 @@ class Wirepy(tk.Tk): LxTools.theme_change(self) # Load the image file from the disk - self.wg_icon = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn.png") + self.wg_icon = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_vpn"]) # Set it as the window icon self.iconphoto(True, self.wg_icon) @@ -92,12 +82,12 @@ class FrameWidgets(ttk.Frame): self.dns = None self.address = None self.auto_con = None - self.wg_vpn_start = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn-start.png") - self.wg_vpn_stop = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn-stop.png") - self.imp_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_import.png") - self.tr_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_trash.png") - self.exp_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_export.png") - self.warning_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/64/error.png") + self.wg_vpn_start = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_start"]) + self.wg_vpn_stop = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_stop"]) + self.imp_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_import"]) + self.tr_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_trash"]) + self.exp_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_export"]) + self.warning_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_error"]) # Frame for Menu self.menu_frame = ttk.Frame(self) @@ -271,7 +261,8 @@ class FrameWidgets(ttk.Frame): # Button Export self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic, - command=lambda: Tunnel.export(img_w, img_i, img_w2, img_i2, sl, pfit), padding=0) + command=lambda: Tunnel.export(img_w, img_i, img_w2, img_i2, + Msg.STR["sel_tl"], Msg.STR["tl_first"]), padding=0) self.btn_exp.grid(column=0, row=3, padx=15, pady=8) if self.l_box.size() == 0: @@ -309,14 +300,14 @@ class FrameWidgets(ttk.Frame): 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, _("To use the autostart, enable this Checkbox"), tips) + Tooltip(self.wg_autostart, Msg.TTIP["autostart"], tips) if self.l_box.size() == 0: - Tooltip(self.wg_autostart, _("You must have at least one\ntunnel in the list,to use the autostart"), tips) + Tooltip(self.wg_autostart, Msg.TTIP["autostart_info"], tips) else: - Tooltip(self.wg_autostart, _("To use the autostart, a tunnel must be selected from the list"), tips) + Tooltip(self.wg_autostart, Msg.TTIP["autostart"], tips) self.on_off() @@ -459,30 +450,34 @@ class FrameWidgets(ttk.Frame): if self.l_box.size() != 0: - LxTools.msg_window(img_w, img_i2, sl, pstl) + LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["sel_list"]) else: - LxTools.msg_window(img_w, img_i2, sl, pfit) + LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["tl_first"]) def tl_rename(self) -> None: """ method to rename a tunnel """ + name_of_file = LxTools.get_file_name(AppConfig.TEMP_DIR) special_characters = ["\\", "/", "{", "}", " "] if len(self.lb_rename.get()) > 12: - LxTools.msg_window(img_w, img_i2, rnp, _("The new name may contain only 12 characters")) + LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["sign_len"]) elif len(self.lb_rename.get()) == 0: - LxTools.msg_window(img_w, img_i2, rnp, _("At least one character must be entered")) + LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["zero_signs"]) elif any(ch in special_characters for ch in self.lb_rename.get()): - msg_t = _("No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n") - LxTools.msg_window(img_w, img_i2, rnp, msg_t) + LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["false_signs"]) + + elif self.lb_rename.get() in name_of_file: + + LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["is_in_use"]) else: @@ -491,7 +486,7 @@ class FrameWidgets(ttk.Frame): select_tl = self.l_box.get(self.select_tunnel[0]) # nmcli connection modify old connection.id iphone - check_call(["nmcli", "connection", "modify", select_tl, "connection.id", self.lb_rename.get()]) + 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) @@ -515,11 +510,14 @@ class FrameWidgets(ttk.Frame): except IndexError: - LxTools.msg_window(img_w, img_i2, rnp, pstl) + LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["sel_list"]) except subprocess.CalledProcessError: pass + except EOFError as e: + print(e) + def import_sl(self) -> None: """ validity check of wireguard config files @@ -543,18 +541,17 @@ 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: - msg_t = _("Tunnel already available!\nPlease use another file for import") - LxTools.msg_window(img_w2, img_i2, ie, msg_t) + LxTools.msg_window(img_w2, img_i2, Msg.STR["imp_err"], Msg.STR["tl_exist"]) else: 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, "/tmp/tlecdcwg/") + p1 = shutil.copy(filepath, AppConfig.TEMP_DIR) path_split = path_split1[len(path_split1) - 17:] - os.rename(p1, f"/tmp/tlecdcwg/{path_split}") - new_conf = f"/tmp/tlecdcwg/{path_split}" + os.rename(p1, f"{AppConfig.TEMP_DIR}/{path_split}") + new_conf = f"{AppConfig.TEMP_DIR}/{path_split}" if self.a != "": check_call(["nmcli", "connection", "down", self.a]) self.reset_fields() @@ -565,7 +562,7 @@ class FrameWidgets(ttk.Frame): Create.encrypt() else: - shutil.copy(filepath, "/tmp/tlecdcwg/") + shutil.copy(filepath, f"{AppConfig.TEMP_DIR}/") if self.a != "": check_call(["nmcli", "connection", "down", self.a]) self.reset_fields() @@ -583,16 +580,13 @@ class FrameWidgets(ttk.Frame): self.l_box.update() self.l_box.selection_set(0) - Tooltip(self.wg_autostart, _("To use the autostart, enable this Checkbox"), tips) + Tooltip(self.wg_autostart, Msg.TTIP["autostart"], tips) - Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!") - , tips,) + Tooltip(self.btn_tr, Msg.TTIP["trash_tl"], tips) - Tooltip(self.btn_exp, _(" Click to export all\nWireguard Tunnel to Zipfile") - , tips) + Tooltip(self.btn_exp, Msg.TTIP["export_tl"], tips) - Tooltip(self.btn_rename, _("To rename a tunnel, you need to\nselect a tunnel from" - " the list"), tips) + Tooltip(self.btn_rename, Msg.TTIP["rename_tl"], tips) self.lb_rename.insert(0, "Max. 12 characters!") self.str_var = tk.StringVar() @@ -606,8 +600,7 @@ class FrameWidgets(ttk.Frame): pass else: - msg_t = _("Oh... no valid Wireguard File!\nPlease select a valid Wireguard File") - LxTools.msg_window(img_w2, img_i2, ie, msg_t) + LxTools.msg_window(img_w2, img_i2, Msg.STR["imp_err"], Msg.STR["no_valid_file"]) except EOFError as e: print(e) @@ -738,7 +731,7 @@ class FrameWidgets(ttk.Frame): command=lambda: self.wg_switch("stop"), padding=0) self.btn_stst.grid(column=0, row=0, padx=5, pady=8) - Tooltip(self.btn_stst, _("Click to stop selected Wireguard Tunnel"), tips) + Tooltip(self.btn_stst, Msg.TTIP["stop_tl"], tips) def start(self) -> None: """ @@ -750,9 +743,9 @@ class FrameWidgets(ttk.Frame): tl = Tunnel.list() if len(tl) == 0: - Tooltip(self.btn_stst, _("No tunnels to start in the list"), tips) + Tooltip(self.btn_stst, Msg.TTIP["empty_list"], tips) else: - Tooltip(self.btn_stst, _("Click to start selected Wireguard Tunnel"), tips) + Tooltip(self.btn_stst, Msg.TTIP["start_tl"], tips) def color_label(self) -> None: """ @@ -789,11 +782,11 @@ class FrameWidgets(ttk.Frame): if self.l_box.size() != 0: - LxTools.msg_window(img_w, img_i2, sl, pstl) + LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["sel_list"]) else: - LxTools.msg_window(img_w, img_i2, sl, pfit) + LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["tl_first"]) def handle_connection_state(self, action: str, tunnel_name: str = None) -> None: """ diff --git a/wp_app_config.py b/wp_app_config.py index 3485c59..fc6dbc5 100644 --- a/wp_app_config.py +++ b/wp_app_config.py @@ -1,26 +1,31 @@ +#!/usr/bin/python3 +"""App configuration for Wire-Py""" + +import gettext +import locale from pathlib import Path from typing import Dict, Any class AppConfig: - """Central configuration class for the application""" - - # Base paths - BASE_DIR = Path.home() - CONFIG_DIR = BASE_DIR / ".config/wire_py" - TEMP_DIR = Path("/tmp/tlecdcwg") - USER_FILE = Path("/tmp/.log_user") - - # Configuration files - SETTINGS_FILE = CONFIG_DIR / "settings" - KEYS_FILE = CONFIG_DIR / "keys" - AUTOSTART_SERVICE = Path.home() / ".config/systemd/user/wg_start.service" + """Central configuration class for Wire-Py application""" # Localization - APP_NAME = "wirepy" - LOCALE_DIR = "/usr/share/locale/" + APP_NAME: str = "wirepy" + LOCALE_DIR: Path = Path("/usr/share/locale/") + + # Base paths + BASE_DIR: Path = Path.home() + CONFIG_DIR: Path = BASE_DIR / ".config/wire_py" + TEMP_DIR: Path = Path("/tmp/tlecdcwg") + USER_FILE: Path = Path("/tmp/.log_user") + + # Configuration files + SETTINGS_FILE: Path = CONFIG_DIR / "settings" + KEYS_FILE: Path = CONFIG_DIR / "keys" + AUTOSTART_SERVICE: Path = Path.home() / ".config/systemd/user/wg_start.service" # Default settings - DEFAULT_SETTINGS = { + DEFAULT_SETTINGS: Dict[str, Any] = { "updates": "on", "theme": "light", "tooltip": True, @@ -28,7 +33,7 @@ class AppConfig: } # UI configuration - UI_CONFIG = { + UI_CONFIG: Dict[str, Any] = { "window_title": "Wire-Py", "window_size": (600, 383), "font_family": "Ubuntu", @@ -37,12 +42,41 @@ class AppConfig: } # System-dependent paths - SYSTEM_PATHS = { + 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" + "tcl_path": "/usr/share/TK-Themes", + } + # Images and icons paths + IMAGE_PATHS: Dict[str, str] = { + "icon_vpn": "/usr/share/icons/lx-icons/48/wg_vpn.png", + "icon_msg": "/usr/share/icons/lx-icons/48/wg_msg.png", + "icon_import": "/usr/share/icons/lx-icons/48/wg_import.png", + "icon_export": "/usr/share/icons/lx-icons/48/wg_export.png", + "icon_trash": "/usr/share/icons/lx-icons/48/wg_trash.png", + "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" + + } + + @staticmethod + def setup_translations() -> gettext.gettext: + """ + Initialize translations and set the translation function + Special method for translating strings in this file + + Returns: + The gettext translation function + """ + locale.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR) + gettext.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR) + gettext.textdomain(AppConfig.APP_NAME) + return gettext.gettext + @classmethod def ensure_directories(cls) -> None: """Ensures that all required directories exist""" @@ -60,7 +94,7 @@ class AppConfig: def get_image_paths(cls) -> Dict[str, Path]: """Returns paths to UI images""" return { - "main_icon": cls.CONFIG_DIR / "images/main.png", + "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" @@ -78,4 +112,66 @@ Type=oneshot ExecStartPre=/bin/sleep 5 ExecStart=/usr/local/bin/start_wg.py [Install] -WantedBy=default.target""" \ No newline at end of file +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. + + This class contains a dictionary of message strings used throughout the Wire-Py application. + All strings are prepared for translation using gettext. The short key names make the code + more concise while maintaining readability. + + Attributes: + STR (dict): A dictionary mapping short keys to translated message strings. + Keys are abbreviated for brevity but remain descriptive. + + Usage: + Import this class and access messages using the dictionary: + `Msg.STR["sel_tl"]` returns the translated "Select tunnel" message. + + Note: + 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"), + "ren_err": _("Renaming not possible"), + "exp_succ": _("Export successful"), + "exp_in_home": _("Your zip file is in home directory"), + "imp_err": _("Import Error"), + "exp_err": _("Export Error"), + "exp_try": _("Export failed! Please try again"), + "tl_first": _("Please first import tunnel"), + "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"), + "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") + + } + TTIP: Dict[str, str] = { + #Strings for Tooltips + "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"), + "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"), + "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") + + } + \ No newline at end of file