#!/usr/bin/python3 """App configuration for Wire-Py""" from logger import app_logger from pathlib import Path from subprocess import CompletedProcess, run from typing import Dict, Any from shared_libs.common_tools import Translate class AppConfig: """Central configuration and system setup manager for the Wire-Py application. This class serves as a singleton-like container for all global configuration data, including paths, UI settings, localization, versioning, and system-specific resources. It ensures that required directories, files, and services are created and configured before the application starts. Additionally, it provides tools for managing translations, default settings, and autostart functionality to maintain a consistent user experience. Key Responsibilities: - Centralizes all configuration values (paths, UI preferences, localization). - Ensures required directories and files exist on startup. - Handles translation setup via `gettext` for multilingual support. - Manages default settings file generation. - Configures autostart services using systemd for user-specific launch behavior. This class is used globally across the application to access configuration data consistently and perform system-level setup tasks. """ # Base paths BASE_DIR: Path = Path.home() CONFIG_DIR: Path = BASE_DIR / ".config/wire_py" TEMP_DIR: Path = Path("/tmp/tlecdcwg") PUBLICKEY: Path = CONFIG_DIR / "pbwgk.pem" # Configuration files SETTINGS_FILE: Path = CONFIG_DIR / "settings" SYSTEMD_USER_FOLDER: Path = Path.home() / ".config/systemd/user" AUTOSTART_SERVICE: Path = Path.home() / ".config/systemd/user/wg_start.service" DEFAULT_SETTINGS: Dict[str, str] = { "# Configuration": "on", "# Theme": "dark", "# Tooltips": True, "# Autostart": "off", } # Updates # 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year VERSION: str = "v. 2.08.1025" 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": "WirePy", "window_size": (590, 440), "font_family": "Ubuntu", "font_size": 11, "resizable_window": (True, True), } # System-dependent paths SYSTEM_PATHS: Dict[str, Path] = { "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", } @classmethod def ensure_directories(cls) -> None: """Ensures that all required directories exist""" if not cls.CONFIG_DIR.exists(): cls.CONFIG_DIR.mkdir(parents=True, exist_ok=True) cls.TEMP_DIR.mkdir(parents=True, exist_ok=True) @classmethod 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() ) cls.SETTINGS_FILE.write_text(content) @classmethod def get_autostart_content(cls) -> None: """Returns the content for an autostart service file""" systemd_file: list[str] = [ "[Unit]", "Description=Automatic Tunnel Start", "After=network-online.target", "", "[Service]", "Type=oneshot", "ExecStartPre=/bin/sleep 5", "ExecStart=/usr/local/bin/start_wg.py", "", "[Install]", "WantedBy=default.target", ] if not cls.SYSTEMD_USER_FOLDER.exists(): cls.SYSTEMD_USER_FOLDER.mkdir(parents=True, exist_ok=True) if not cls.AUTOSTART_SERVICE.is_file(): content = "\n".join([line for line in systemd_file]) cls.AUTOSTART_SERVICE.write_text(content) process: CompletedProcess[str] = run( ["systemctl", "--user", "enable", "wg_start.service"], capture_output=True, text=True, check=False, ) if process.returncode == 0: app_logger.log(process.stdout) if process.stderr: app_logger.log( f"{process.stderr}") # here is initializing the class for translation strings _ = Translate.setup_translations("wirepy") 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 "header_left_bottom": _("Simple GUI for Wireguard"), "header_right_top": _("Wireguard VPN Manager"), "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"), "exp_zip": _( "The error occurs because the zipfile module encountered an issue.\n" "Please verify that you have the latest version of WirePy installed.\n" "You can also contact the WirePy developer team to resolve this issue quickly.\n" ), "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"), "invalid_base64": _( "Invalid base64 format!\nPlease use a Config file with valid key." ), "options": _("Options"), "disable_updates": _("Disable Updates"), "about": _("About"), "lx_tools": _("Lx Tools Wire-Py"), "tunnels": _("Tunnels"), "active_tunnel": _("Active Tunnel"), "interface": _("Interface"), "peer": _("Peer"), "rename": _("Rename"), "max_chars": _("Max. 12 characters!"), "autoconnect_on": _("Autoconnect on:"), "no_autoconnect": _("no Autoconnect"), "update_search_off": _("Update search off"), "no_server_connection": _("No Server Connection!"), "no_updates": _("No Updates"), "about_msg": _( "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" ), "goto_git": _("Go to Wire-Py git"), "info": _("Info"), "disable_tooltips": _("Disable Tooltips"), "enable_tooltips": _("Enable Tooltips"), "dark": _("Dark"), "light": _("Light"), } TTIP: Dict[str, str] = { # 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" ), "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" ), "download": _("Click to download new version"), "updates_disabled": _("Updates you have disabled"), "no_server_conn_tt": _("Could not connect to update server"), "up_to_date": _("Congratulations! Wire-Py is up to date"), "install_new_version": _("Click to install new version"), "no_pillow": "Pillow library is not installed.\nInstall it for a better icon experience.", }