diff --git a/.vscode/settings.json b/.vscode/settings.json index 0c64554..34dfa2f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { "workbench.settings.openDefaultSettings": true + "workbench.startupEditor": "none" + "update.showReleaseNotes": false + "terminal.integrated.fontSize": 22 } \ No newline at end of file diff --git a/__pycache__/cls_mth_fc.cpython-312.pyc b/__pycache__/cls_mth_fc.cpython-312.pyc index b250738..d1ce123 100644 Binary files a/__pycache__/cls_mth_fc.cpython-312.pyc and b/__pycache__/cls_mth_fc.cpython-312.pyc differ diff --git a/__pycache__/wp_app_config.cpython-312.pyc b/__pycache__/wp_app_config.cpython-312.pyc index a42c96c..6fb4bf5 100644 Binary files a/__pycache__/wp_app_config.cpython-312.pyc and b/__pycache__/wp_app_config.cpython-312.pyc differ diff --git a/cls_mth_fc.py b/cls_mth_fc.py index cb89a1d..ba9cb42 100755 --- a/cls_mth_fc.py +++ b/cls_mth_fc.py @@ -169,18 +169,6 @@ class LxTools(tk.Tk): if file is not None: Path.unlink(file) - @staticmethod - def if_tip(path: Path) -> bool: - """ - method that writes in file whether tooltip is displayed or not - """ - lines = Path(path).read_text(encoding="utf-8") - if "False\n" in lines: - tip = False - else: - tip = True - return tip - @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: @@ -382,6 +370,82 @@ class Tunnel: pass +# ConfigManager with caching +class ConfigManager: + """ + Universal class for managing configuration files with caching. + Can be reused in different projects. + """ + _config = None + _config_file = None + + @classmethod + def init(cls, config_file): + """Initial the Configmanager with the given config file""" + cls._config_file = config_file + cls._config = None # Reset the cache + + @classmethod + def load(cls): + """Load the config file and return the config as dict""" + if not cls._config: + 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', + '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, + 'autostart': 'off' + } + return cls._config + + @classmethod + def save(cls): + """Save the config to the config file""" + if cls._config: + lines = [ + '# Configuration\n', + f"{cls._config['updates']}\n", + '# Theme\n', + f"{cls._config['theme']}\n", + '# Tooltips\n', + f"{str(cls._config['tooltips'])}\n", + '# Autostart\n', + f"{cls._config['autostart']}\n" + ] + Path(cls._config_file).write_text(''.join(lines), encoding="utf-8") + + @classmethod + def set(cls, key, value): + """Sets a configuration value and saves the change""" + cls.load() + cls._config[key] = value + cls.save() + + @classmethod + def get(cls, key, default=None): + """Returns a configuration value""" + config = cls.load() + return config.get(key, default) + + +class ThemeManager: + @staticmethod + def change_theme(root, theme_in_use, theme_name=None): + """Change application theme centrally""" + root.tk.call("set_theme", theme_in_use) + if theme_in_use == theme_name: + ConfigManager.set("theme", theme_in_use) + + class GiteaUpdate: """ Calling download requests the download URL of the running script, @@ -390,35 +454,46 @@ class GiteaUpdate: """ @staticmethod - def api_down(update_api_url: str, version: str, file: Optional[Path] = None) -> str: + def api_down(update_api_url: str, version: str, update_setting: str = None) -> str: """ Checks for updates via API - + Args: update_api_url: Update API URL version: Current version - file: Optional - Configuration file + update_setting: Update setting from ConfigManager (on/off) Returns: New version or status message """ + # If updates are disabled, return immediately + if update_setting != "on": + return "False" + try: response: requests.Response = requests.get(update_api_url, timeout=10) - response_dict: Any = response.json() - response_dict: Dict[str, Any] = response_dict[0] - with open(file, "r", encoding="utf-8") as set_f: - set_f = set_f.read() - if "on\n" in set_f: - if version[3:] != response_dict["tag_name"]: - req: str = response_dict["tag_name"] - else: - req: str = "No Updates" - else: - req: str = "False" - return req + response.raise_for_status() # Raise exception for HTTP errors + + response_data = response.json() + if not response_data: + return "No Updates" + + latest_version = response_data[0].get("tag_name") + if not latest_version: + return "Invalid API Response" + + # Compare versions (strip 'v. ' prefix if present) + current_version = version[3:] if version.startswith("v. ") else version + + if current_version != latest_version: + return latest_version + else: + return "No Updates" + except requests.exceptions.RequestException: - req: str = "No Internet Connection!" - return req + return "No Internet Connection!" + except (ValueError, KeyError, IndexError): + return "Invalid API Response" @staticmethod def download(urld: str, res: str, image_path: Path = None, image_path2: Path = None, image_path3: Path = None, diff --git a/wirepy.py b/wirepy.py index 101e3f8..181d298 100755 --- a/wirepy.py +++ b/wirepy.py @@ -14,17 +14,13 @@ from pathlib import Path from subprocess import check_call from tkinter import TclError, filedialog, ttk -from cls_mth_fc import (Create, GiteaUpdate, Tunnel, Tooltip, LxTools) +from cls_mth_fc import (ConfigManager, ThemeManager, Create, GiteaUpdate, Tunnel, Tooltip, LxTools) from wp_app_config import AppConfig, Msg LxTools.uos() Create.dir_and_files() Create.make_dir() Create.decrypt() -# 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) class Wirepy(tk.Tk): """ @@ -43,22 +39,17 @@ class Wirepy(tk.Tk): self.geometry(f"{self.x_width}x{self.y_height}+{self.monitor_center_x}+{self.monitor_center_y}") self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) - self.style = ttk.Style(self) self.tk.call("source", f"{AppConfig.SYSTEM_PATHS["tcl_path"]}/water.tcl") - lines = AppConfig.SETTINGS_FILE.read_text() - if "light\n" in lines: - self.tk.call("set_theme", "light") - else: - self.tk.call("set_theme", "dark") - + ConfigManager.init(AppConfig.SETTINGS_FILE) + theme = ConfigManager.get("theme") + ThemeManager.change_theme(self, theme) # Load the image file from the disk self.wg_icon = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_vpn"]) # Set it as the window icon self.iconphoto(True, self.wg_icon) - tips = LxTools.if_tip(AppConfig.SETTINGS_FILE) - FrameWidgets(self, tips_enabled=tips).grid() + FrameWidgets(self).grid() class FrameWidgets(ttk.Frame): @@ -68,47 +59,59 @@ class FrameWidgets(ttk.Frame): def __init__(self, container, tips_enabled=None, **kwargs): super().__init__(container, **kwargs) - self.tunnel = Tunnel() self.lb_tunnel = None self.btn_stst = None self.endpoint = None self.dns = None self.address = None self.auto_con = None + self.tips_enabled = tips_enabled + self.style = ttk.Style() 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"]) - self.tips_enabled = tips_enabled if tips_enabled is not None else LxTools.if_tip(AppConfig.SETTINGS_FILE) + self.tips_enabled = tips_enabled if tips_enabled is not None else ConfigManager.get("tooltip") + # StringVar-Variables initialization + self.update_label = tk.StringVar() + self.update_tooltip = tk.StringVar() + self.update_foreground = tk.StringVar(value="red") + # Frame for Menu self.menu_frame = ttk.Frame(self) self.menu_frame.configure(relief="flat") self.menu_frame.grid(column=0, row=0, columnspan=4, sticky="w") # App Menu - self.version_lb = ttk.Label(self.menu_frame, text=VERSION) + self.version_lb = ttk.Label(self.menu_frame, text=AppConfig.VERSION) 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: {VERSION[2:]}", self.tips_enabled) + Tooltip(self.version_lb, f"Version: {AppConfig.VERSION[2:]}", self.tips_enabled) self.options_btn = ttk.Menubutton(self.menu_frame, text=_("Options")) self.options_btn.grid(column=1, columnspan=1, row=0) Tooltip(self.options_btn, _("Click for Settings"), self.tips_enabled) - set_update = tk.IntVar() - set_tip = tk.BooleanVar() + self.set_update = tk.IntVar() + self.set_tip = tk.BooleanVar() 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(set_update.get()), variable=set_update) - self.settings.add_checkbutton(label=_("Disable Tooltips"), - command=lambda: self.tooltip(set_tip.get()), variable=set_tip) - self.settings.add_command(label=_("Light"), command=self.theme_change_light) - self.settings.add_command(label=_("Dark"), command=self.theme_change_dark) + command=lambda: self.update_setting(self.set_update.get()), variable=self.set_update) + self.settings.add_command(label=_("Disable Tooltips"), + command=lambda: self.tooltip(self.set_tip.get()), variable=self.set_tip) + + self.updates_lb = ttk.Label(self.menu_frame) + res = GiteaUpdate.api_down(AppConfig.UPDATE_URL, AppConfig.VERSION, ConfigManager.get("updates")) + self.update_ui_for_update(res) + # 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) # About BTN Menu / Label self.about_btn = ttk.Button( @@ -116,49 +119,10 @@ class FrameWidgets(ttk.Frame): self.about_btn.grid(column=2, columnspan=2, row=0) self.readme = tk.Menu(self) - # Update and Tooltip Label - self.updates_lb = ttk.Label(self.menu_frame) - self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) # View Checkbox to enable or disable Tooltip - if tips: - set_tip.set(value=False) - else: - set_tip.set(value=True) + self.set_tip.set(value=not self.tips_enabled) - # View Checkbox for enable or disable Updates - if res == "False": - set_update.set(value=1) - self.updates_lb.configure(text=_("Update search off")) - - Tooltip(self.updates_lb, _("Updates you have disabled"), self.tips_enabled) - - elif res == "No Internet Connection!": - self.updates_lb.configure(text=_("No Server Connection!"), foreground="red") - elif res == "No Updates": - self.updates_lb.configure(text=_("No Updates")) - - Tooltip(self.updates_lb, _("Congratulations! Wire-Py is up to date"), self.tips_enabled) - - else: - set_update.set(value=0) - text = f"Update {res} {_("available!")}" - - # Update BTN Menu - self.update_btn = ttk.Menubutton(self.menu_frame, text=text) - self.update_btn.grid(column=4, columnspan=3, row=0, padx=0) - - Tooltip(self.update_btn, _("Click to download new version"), self.tips_enabled) - - self.download = tk.Menu(self, relief="flat") - - self.update_btn.configure(menu=self.download, style="Toolbutton") - self.download.add_command( - label=_("Download"), - command=lambda: GiteaUpdate.download(f"https://git.ilunix.de/punix/Wire-Py/archive/{res}.zip", - res, AppConfig.IMAGE_PATHS["icon_info"], AppConfig.IMAGE_PATHS["icon_vpn"], AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"])) - - # Show active Tunnel self.a = Tunnel.active() # Label Frame 1 @@ -254,8 +218,11 @@ class FrameWidgets(ttk.Frame): # 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"], + 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) if self.l_box.size() == 0: @@ -304,40 +271,97 @@ class FrameWidgets(ttk.Frame): self.on_off() - - @staticmethod - def update_setting(update_res) -> None: - """ - write off or on in file - Args: - update_res (int): argument that is passed contains 0 or 1 - """ - if update_res == 1: - lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True) - lines[1] = 'off\n' - Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8") - + # Update the labels based on the result + def update_ui_for_update(self, res): + """Update UI elements based on update check result""" + if res == "False": + self.set_update.set(value=1) + self.update_label.set(_("Update search off")) + self.update_tooltip.set(_("Updates you have disabled")) + self.update_foreground.set("red") + + # Remove update button if it exists + if hasattr(self, 'update_btn'): + self.update_btn.grid_forget() + + # Display the label + self.updates_lb.configure( + textvariable=self.update_label, + foreground=self.update_foreground.get() + ) + self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) + Tooltip(self.updates_lb, self.update_tooltip.get(), self.tips_enabled) + + elif res == "No Internet Connection!": + self.update_label.set(_("No Server Connection!")) + self.update_foreground.set("red") + + # Remove update button if it exists + if hasattr(self, 'update_btn'): + self.update_btn.grid_forget() + + # Display the label + self.updates_lb.configure( + textvariable=self.update_label, + foreground=self.update_foreground.get() + ) + self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) + + elif res == "No Updates": + self.update_label.set(_("No Updates")) + self.update_tooltip.set(_("Congratulations! Wire-Py is up to date")) + self.update_foreground.set("black") + + # Remove update button if it exists + if hasattr(self, 'update_btn'): + self.update_btn.grid_forget() + + # Display the label + self.updates_lb.configure( + textvariable=self.update_label, + foreground=self.update_foreground.get() + ) + self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) + Tooltip(self.updates_lb, self.update_tooltip.get(), self.tips_enabled) + else: - lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True) - lines[1] = 'on\n' - Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8") - - @staticmethod - def tooltip(tip) -> None: + self.set_update.set(value=0) + update_text = f"Update {res} {_('available!')}" + + # Remove the label if displayed + self.updates_lb.grid_forget() + + # Create or update the update button + if not hasattr(self, 'update_btn'): + # Create the update button if it doesn't exist yet + 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.tips_enabled) + + self.download = tk.Menu(self, relief="flat") + self.update_btn.configure(menu=self.download, style="Toolbutton") + self.download.add_command( + label=_("Download"), + command=lambda: GiteaUpdate.download( + f"{AppConfig.DOWNLOAD_URL}/{res}.zip", + res, + AppConfig.IMAGE_PATHS["icon_info"], + AppConfig.IMAGE_PATHS["icon_vpn"], + AppConfig.IMAGE_PATHS["icon_error"], + AppConfig.IMAGE_PATHS["icon_msg"] + ) + ) +} + def tooltip(self, tip) -> None: """ - write True or False in a file + Aktualisiert die Tooltip-Einstellung im ConfigManager Args: - tip (bool): argument that is passed contains True or False + tip (bool): True zum Deaktivieren, False zum Aktivieren von Tooltips """ - if tip: - lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True) - lines[5] = 'False\n' - Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8") - - else: - lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True) - lines[5] = 'True\n' - Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8") + # Beachten Sie die umgekehrte Logik: tip=True bedeutet Tooltips deaktivieren + ConfigManager.set("tooltip", not tip) + # Aktualisieren Sie die lokale Variable für sofortige Wirkung + self.tips_enabled = not tip @staticmethod def about() -> None: @@ -354,27 +378,163 @@ class FrameWidgets(ttk.Frame): LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_vpn"], AppConfig.IMAGE_PATHS["icon_vpn"], _("Info"), msg_t, _("Go to Wire-Py git"), link_btn) - def theme_change_light(self) -> None: - """ - Set a light theme - """ - if self.tk.call("ttk::style", "theme", "use") == "water-dark": - self.tk.call("set_theme", "light") - lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True) # (keepends=True) = not changed - lines[3] = 'light\n' - Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8") - self.color_label() + def update_ui_for_update_status(self, res): + """Update UI elements based on update check result""" + print(f"Updating UI for result: {res}") # Debug output + + # First, clean up any existing UI elements + if hasattr(self, 'update_btn') and self.update_btn.winfo_exists(): + self.update_btn.grid_forget() + + # Reset all variables to ensure fresh state + self.update_label.set("") + self.update_tooltip.set("") + self.update_foreground.set("black") + + if res == "False": + self.set_update.set(value=1) + self.update_label.set(_("Update search off")) + self.update_tooltip.set(_("Updates you have disabled")) + self.update_foreground.set("red") + + # Display the label + self.updates_lb.configure( + textvariable=self.update_label, + foreground=self.update_foreground.get() + ) + self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) + Tooltip(self.updates_lb, self.update_tooltip.get(), self.tips_enabled) + + elif res == "No Internet Connection!": + self.update_label.set(_("No Server Connection!")) + self.update_foreground.set("red") + + # Display the label + self.updates_lb.configure( + textvariable=self.update_label, + foreground=self.update_foreground.get() + ) + self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) + + elif res == "No Updates": + self.update_label.set(_("No Updates")) + self.update_tooltip.set(_("Congratulations! Wire-Py is up to date")) + self.update_foreground.set("black") + + # Display the label + self.updates_lb.configure( + textvariable=self.update_label, + foreground=self.update_foreground.get() + ) + self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) + Tooltip(self.updates_lb, self.update_tooltip.get(), self.tips_enabled) + + else: + # We have an update available + self.set_update.set(value=0) + update_text = f"Update {res} {_('available!')}" + + # Hide the label if it's visible + if self.updates_lb.winfo_ismapped(): + self.updates_lb.grid_forget() + + # Create or update the update button + if not hasattr(self, 'update_btn') or not self.update_btn.winfo_exists(): + # Create the update button if it doesn't exist yet + 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.tips_enabled) + + self.download = tk.Menu(self, relief="flat") + self.update_btn.configure(menu=self.download, style="Toolbutton") + self.download.add_command( + label=_("Download"), + command=lambda: GiteaUpdate.download( + f"{AppConfig.DOWNLOAD_URL}/{res}.zip", + res, + AppConfig.IMAGE_PATHS["icon_info"], + AppConfig.IMAGE_PATHS["icon_vpn"], + AppConfig.IMAGE_PATHS["icon_error"], + AppConfig.IMAGE_PATHS["icon_msg"] + ) + ) + else: + # Update the existing update button + self.update_btn.configure(text=update_text) + # Make sure it's visible + self.update_btn.grid(column=4, columnspan=3, row=0, padx=0) + + # Update the download command + if hasattr(self, 'download'): + self.download.entryconfigure( + 0, # First entry in the menu + command=lambda: GiteaUpdate.download( + f"{AppConfig.DOWNLOAD_URL}/{res}.zip", + res, + AppConfig.IMAGE_PATHS["icon_info"], + AppConfig.IMAGE_PATHS["icon_vpn"], + AppConfig.IMAGE_PATHS["icon_error"], + AppConfig.IMAGE_PATHS["icon_msg"] + ) + ) - def theme_change_dark(self) -> None: + def update_setting(self, update_res) -> None: + """write off or on in file + Args: + update_res (int): argument that is passed contains 0 or 1 """ - Set a dark theme - """ - if not self.tk.call("ttk::style", "theme", "use") == "water-dark": - self.tk.call("set_theme", "dark") - lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True) - lines[3] = 'dark\n' - Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8") - self.color_label() + if update_res == 1: + # Disable updates + ConfigManager.set("updates", "off") + # When updates are disabled, we know the result should be "False" + self.update_ui_for_update_status("False") + else: + # Enable updates + ConfigManager.set("updates", "on") + # 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") + print(f"API returned: {res}") # Debug output + + # Make sure UI is updated regardless of previous state + if hasattr(self, 'update_btn'): + self.update_btn.grid_forget() + if hasattr(self, 'updates_lb'): + self.updates_lb.grid_forget() + + # Now update the UI with the fresh result + self.update_ui_for_update_status(res) + except Exception as e: + print(f"Error checking for updates: {e}") + # Fallback to a default message if there's an error + self.update_ui_for_update_status("No Internet Connection!") + + def update_tooletip_label(self) -> str: + """Update the theme label based on current theme""" + current_value = ConfigManager.get("tooletip") + if current_value == "True": + self.set_tip.set(_("Enable Tooltips")) + else: + self.set_tip.set(_("Disable Tooltips")) + + def update_theme_label(self) -> str: + """Update the theme label based on current theme""" + current_theme = ConfigManager.get("theme") + if current_theme == "light": + self.theme_label.set(_("Dark")) + else: + self.theme_label.set(_("Light")) + + def on_theme_toggle(self) -> None: + """Toggle between light and dark theme""" + current_theme = ConfigManager.get("theme") + new_theme = "dark" if current_theme == "light" else "light" + ThemeManager.change_theme(self, new_theme, new_theme) + self.color_label() + self.update_theme_label() # Update the theme label + # Update Menulfield + self.settings.entryconfigure(2, label=self.theme_label.get()) def start(self) -> None: """ @@ -410,8 +570,8 @@ class FrameWidgets(ttk.Frame): """ View activ Tunnel in the color green or yellow """ - lines = AppConfig.SETTINGS_FILE.read_text() - if "light\n" in lines: + if ConfigManager.get("theme") == "light": + self.lb_tunnel = ttk.Label(self, textvariable=self.str_var, foreground="green") else: @@ -727,54 +887,6 @@ class FrameWidgets(ttk.Frame): except EOFError as e: print(e) - def activate_tunnel(self, tunnel_name): - """Activates a tunnel after a delay""" - try: - # First check if the tunnel exists in NetworkManager - nm_connections = subprocess.run( - ["nmcli", "-t", "-f", "NAME", "connection", "show"], - check=True, - stdout=subprocess.PIPE, - text=True - ).stdout.strip().split('\n') - - # Find the actual connection name (it might have been modified) - actual_name = None - for conn in nm_connections: - if tunnel_name in conn: - actual_name = conn - break - - if actual_name: - # Use the actual connection name - subprocess.run(["nmcli", "connection", "up", actual_name], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - else: - # Use the original name as fallback - subprocess.run(["nmcli", "connection", "up", tunnel_name], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - - # After successful activation, update the display - self.a = Tunnel.active() - self.str_var.set(self.a) - self.color_label() - - # Try to load the tunnel data - try: - data = self.handle_tunnel_data(self.a) - self.init_and_report(data) - self.show_data() - self.stop() - except Exception as e: - print(f"Error loading tunnel data: {e}") - - except subprocess.CalledProcessError as e: - print(f"Error activating tunnel: {e}", "hier simma") - def init_and_report(self, data=None) -> None: """ Displays the value address, DNS and peer in the labels @@ -881,7 +993,6 @@ class FrameWidgets(ttk.Frame): if __name__ == "__main__": _ = AppConfig.setup_translations() - tips = LxTools.if_tip(AppConfig.SETTINGS_FILE) LxTools.sigi(AppConfig.TEMP_DIR, AppConfig.USER_FILE) window = Wirepy() """ diff --git a/wp_app_config.py b/wp_app_config.py index 26cc313..aa68942 100644 --- a/wp_app_config.py +++ b/wp_app_config.py @@ -24,6 +24,12 @@ class AppConfig: KEYS_FILE: Path = CONFIG_DIR / "keys" AUTOSTART_SERVICE: Path = Path.home() / ".config/systemd/user/wg_start.service" + # Updates + # 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year + VERSION: str = "v. 2.04.1725" + 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" + # Default settings DEFAULT_SETTINGS: Dict[str, Any] = { "updates": "on",