#!/usr/bin/python3 """ this script is a simple GUI for managing Wireguard Tunnels """ import gettext import locale import os import shutil import subprocess import sys import tkinter as tk import webbrowser from pathlib import Path from subprocess import check_call from tkinter import TclError, filedialog, ttk from cls_mth_fc import (Create, GiteaUpdate, Tooltip, Tunnel, LxTools) LxTools.uos() Create.dir_and_files() Create.make_dir() Create.decrypt() tcl_path: Path = Path("/usr/share/TK-Themes") set_file: Path = Path(Path.home() / ".config/wire_py/settings") tips = LxTools.if_tip(set_file) folder_path: Path = Path("/tmp/tlecdcwg/") user_file = Path("/tmp/.log_user") # 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, set_file) # Translate APP = "wirepy" LOCALE_DIR = "/usr/share/locale/" locale.bindtextdomain(APP, LOCALE_DIR) gettext.bindtextdomain(APP, LOCALE_DIR) gettext.textdomain(APP) _ = gettext.gettext 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(folder_path, user_file) class Wirepy(tk.Tk): """ Class Wirepy this is the Main Window of wirepy """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.my_tool_tip = None self.x_width = 600 self.y_height = 383 self.monitor_center_x = int(self.winfo_screenwidth() / 2 - (self.x_width / 2)) self.monitor_center_y = int(self.winfo_screenheight() / 2 - (self.y_height / 2)) self.resizable(width=False, height=False) self.title("Wire-Py") 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"{tcl_path}/water.tcl") with open(set_file, "r", encoding="utf-8") as read_file: lines = read_file.readlines() if "light\n" in lines: self.tk.call("set_theme", "light") else: self.tk.call("set_theme", "dark") # Load the image file from the disk self.wg_icon = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn.png") # Set it as the window icon self.iconphoto(True, self.wg_icon) FrameWidgets(self).grid() class FrameWidgets(ttk.Frame): """ ttk frame class for better structure """ def __init__(self, container, **kwargs): super().__init__(container, **kwargs) self.lb_tunnel = None self.btn_stst = None self.endpoint = None 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") def update(): """ Set on or off in file """ if set_update.get() == 1: with open(set_file, "r", encoding="utf-8") as set_f2: lines2 = set_f2.readlines() lines2[1] = "off\n" with open(set_file, "w", encoding="utf-8") as set_f2: set_f2.writelines(lines2) if set_update.get() == 0: with open(set_file, "r", encoding="utf-8") as set_f2: lines2 = set_f2.readlines() lines2[1] = "on\n" with open(set_file, "w", encoding="utf-8") as set_f2: set_f2.writelines(lines2) def theme_change_light(): """ Set a light theme """ if self.tk.call("ttk::style", "theme", "use") == "water-dark": self.tk.call("set_theme", "light") with open(set_file, "r", encoding="utf-8") as theme_set2: lines3 = theme_set2.readlines() lines3[3] = "light\n" with open(set_file, "w", encoding="utf-8") as theme_set2: theme_set2.writelines(lines3) self.color_label() def theme_change_dark(): """ Set a dark theme """ if not self.tk.call("ttk::style", "theme", "use") == "water-dark": self.tk.call("set_theme", "dark") with open(set_file, "r", encoding="utf-8") as theme_set2: lines4 = theme_set2.readlines() lines4[3] = "dark\n" with open(set_file, "w", encoding="utf-8") as theme_set2: theme_set2.writelines(lines4) self.color_label() def tooltip(): """ Set True or False in a file """ if set_tip.get(): with open(set_file, "r", encoding="utf-8") as set_f2: lines2 = set_f2.readlines() lines2[5] = "False\n" with open(set_file, "w", encoding="utf-8") as set_f2: set_f2.writelines(lines2) else: with open(set_file, "r", encoding="utf-8") as set_f2: lines2 = set_f2.readlines() lines2[5] = "True\n" with open(set_file, "w", encoding="utf-8") as set_f2: set_f2.writelines(lines2) def info(): def link_btn(): 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") LxTools.msg_window(img_i, img_i, _("Info"), msg_t, _("Go to Wire-Py git"), link_btn) # 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.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:]}", tips) 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"), tips) set_update = tk.IntVar() 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=update, variable=set_update) self.settings.add_checkbutton(label=_("Disable Tooltips"), command=tooltip, variable=set_tip) self.settings.add_command(label=_("Light"), command=theme_change_light) self.settings.add_command(label=_("Dark"), command=theme_change_dark) # About BTN Menu / Label self.about_btn = ttk.Button( self.menu_frame, text=_("About"), style="Toolbutton", command=info ) 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) # 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"), tips) 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"), tips) 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"), tips) 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, img_w, img_i, img_w2, img_i2)) # Show active Tunnel self.a = Tunnel.active() # Label Frame 1 self.lb_frame_btn_lbox = ttk.Frame(self) self.lb_frame_btn_lbox.configure(relief="flat") self.lb_frame_btn_lbox.grid(column=0, rowspan=3, row=1) # Label Frame 2 self.lb_frame = ttk.Frame(self) self.lb_frame.configure(relief="solid") self.lb_frame.grid(column=2, row=2, sticky="snew", padx=20, pady=5) # Label Frame 3 self.lb_frame2 = ttk.Frame(self) self.lb_frame2.configure(relief="solid") self.lb_frame2.grid(column=2, row=3, sticky="snew", padx=20, pady=5) # 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) # Bottom Frame 5 self.lb_frame4 = ttk.Frame(self) self.lb_frame4.configure(relief="flat") self.lb_frame4.grid(column=2, row=5, columnspan=3, sticky="e", padx=15) # Show active Label self.select_tunnel = None self.lb = ttk.Label(self, text=_("Active: ")) self.lb.config(font=("Ubuntu", 11, "bold")) self.lb.grid(column=2, row=1, padx=15, pady=4, sticky="w") # Label to Show active Tunnel self.str_var = tk.StringVar(value=self.a) self.color_label() # Interface Label self.interface = ttk.Label(self.lb_frame, text=_("Interface")) self.interface.grid(column=0, row=3, sticky="we", padx=120) self.interface.config(font=("Ubuntu", 9)) # Peer Label self.peer = ttk.Label(self.lb_frame2, text=_("Peer")) self.peer.config(font=("Ubuntu", 9)) self.peer.grid(column=0, row=4, sticky="we", padx=130) def enable_check_box(_): """ checkbox for enable autostart Tunnel """ Create.files_for_autostart() if self.l_box.size() != 0: self.wg_autostart.configure(state="normal") self.lb_rename.config(state="normal") self.lb_rename.delete(0, tk.END) self.btn_rename.config(state="normal") # Listbox with Scrollbar self.l_box = tk.Listbox(self.lb_frame_btn_lbox, selectmode="single") self.l_box.config(relief="ridge", font=("Ubuntu", 12, "bold")) self.l_box.grid(column=1, rowspan=4, row=0, sticky="ns") self.l_box.event_add("<>", "") self.l_box.bind("<>", enable_check_box) 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) # Tunnel List self.tl = Tunnel.list() for tunnels in self.tl: self.l_box.insert("end", tunnels[:-5]) self.l_box.update() # Button Vpn if self.a != "": self.stop() data = self.handle_tunnel_data(self.a) else: self.start() # Address Label self.add = tk.StringVar() self.DNS = tk.StringVar() self.enp = tk.StringVar() self.reset_fields() 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.grid(column=0, row=1, padx=15, pady=8) Tooltip(self.btn_i, _("Click to import a Wireguard Tunnel"), tips) def delete(): """ delete Wireguard Tunnel """ 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: 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(set_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() ): lines6[7] = "off\n" with open(set_file, "w", encoding="utf-8") as set_f7: set_f7.writelines(lines6) self.selected_option.set(0) self.autoconnect_var.set(_("no Autoconnect")) is_encrypt = Path.home() / f".config/wire_py/{select_tl}.dat" if is_encrypt.is_file(): Path.unlink(f"{Path.home()}/.config/wire_py/{select_tl}.dat") Path.unlink(f"/tmp/tlecdcwg/{select_tl}.conf") with open(f"{Path.home()}/.config/wire_py/keys", "r", encoding="utf-8") as readfile: 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) file_one = Path(f"{Path.home()}/.config/wire_py/keys2") file_two = file_one.with_name("keys") file_one.replace(file_two) self.wg_autostart.configure(state="disabled") # for disabling checkbox when Listbox empty if self.l_box.size() == 0: self.wg_autostart.configure(state="disabled") self.lb_rename.configure(state="disabled") Tooltip(self.wg_autostart, _("You must have at least one\ntunnel in the list,to use the autostart") , tips) Tooltip(self.btn_exp, _("No Tunnels in List for Export"), tips) Tooltip(self.btn_stst, _("No tunnels to start in the list"), tips) Tooltip(self.lb_rename, _("To rename a tunnel, at least one must be in the list"), tips, ) self.lb_rename.insert(0, _("Max. 12 characters!")) if self.a != "" and self.a == select_tl: self.str_var.set(value="") self.start() self.l_box.update() self.reset_fields() except IndexError: if self.l_box.size() != 0: LxTools.msg_window(img_w, img_i2, sl, pstl) else: LxTools.msg_window(img_w, img_i2, sl, pfit) # Button Trash self.btn_tr = ttk.Button(self.lb_frame_btn_lbox, image=self.tr_pic, command=delete, padding=0, style="CButton.TButton") self.btn_tr.grid(column=0, row=2, padx=15, pady=8) if self.l_box.size() == 0: Tooltip(self.btn_tr, _("No tunnels to delete in the list"), tips) else: Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!"), tips) # 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) self.btn_exp.grid(column=0, row=3, padx=15, pady=8) if self.l_box.size() == 0: Tooltip(self.btn_exp, _("No Tunnels in List for Export"), tips) else: Tooltip(self.btn_exp, _("Click to export all\nWireguard Tunnel to Zipfile"), tips) # Label Entry self.lb_rename = ttk.Entry(self.lb_frame4, width=20) self.lb_rename.grid(column=2, row=0, padx=8, pady=10, sticky="ne") self.lb_rename.insert(0, _("Max. 12 characters!")) self.lb_rename.config(state="disable") if self.l_box.size() != 0: Tooltip(self.lb_rename, _("To rename a tunnel, you need to\nselect a tunnel from the list"), tips) else: Tooltip(self.lb_rename, _("To rename a tunnel, at least one must be in the list"), tips) def tl_rename(): 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")) elif len(self.lb_rename.get()) == 0: LxTools.msg_window(img_w, img_i2, rnp, _("At least one character must be entered")) 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) else: try: self.select_tunnel = self.l_box.curselection() 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()]) source = Path(f"/tmp/tlecdcwg/{select_tl}.conf") destination = source.with_name(f"{self.lb_rename.get()}.conf") source.replace(destination) Path.unlink(f"{Path.home()}/.config/wire_py/{select_tl}.dat") self.l_box.delete(self.select_tunnel[0]) self.l_box.insert("end", self.lb_rename.get()) self.l_box.update() new_a_connect = self.lb_rename.get() self.lb_rename.delete(0, tk.END) if self.a != "" and self.a == select_tl: self.a = Tunnel.active() self.str_var.set(value=self.a) with open(set_file, "r", encoding="utf-8") as set_f5: 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(set_file, "w", encoding="utf-8") as theme_set5: theme_set5.writelines(lines5) self.autoconnect_var.set(value=new_a_connect) Create.encrypt() except IndexError: LxTools.msg_window(img_w, img_i2, rnp, pstl) # Button Rename self.btn_rename = ttk.Button(self.lb_frame4, text=_("Rename"), state="disable", command=tl_rename, padding=4, style="RnButton.TButton") self.btn_rename.grid(column=3, row=0, padx=5, pady=10, sticky="ne") # Check Buttons self.selected_option = tk.IntVar() self.autoconnect_var = tk.StringVar() self.autoconnect_var.set(self.auto_con) # Frame for Labels, Entry and Button 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.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) 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) else: Tooltip(self.wg_autostart, _("To use the autostart, a tunnel must be selected from the list"), tips) self.on_off() def import_sl(self): """ Import Methode for Wireguard config Files. Before importing, it is checked whether PrivateKey and PublicKey are in the file. If True, then it is checked whether the PreSharedKey is already in the key file to avoid an import error so that no double wgconf are imported. Thus, tunnels can be renamed without the problems arising. If False, then the key is written into the file. Furthermore, it is checked whether the name is longer than 12 characters. If True, then the name is automatically shortened to 12 characters and then imported. If in each case false comes out, a corresponding window comes to inform the user that something is wrong. """ Create.dir_and_files() try: filepath = filedialog.askopenfilename(initialdir=f"{Path.home()}", title=_("Select Wireguard config File"), filetypes=[(_("WG config files"), "*.conf")]) with open(filepath, "r", encoding="utf-8") as file: read = file.read() path_split = filepath.split("/") path_split1 = path_split[-1] self.a = Tunnel.active() 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] if len(pre_key) != 0: with open(f"{Path.home()}/.config/wire_py/keys", "r", encoding="utf-8") as readfile: p_key = readfile.readlines() 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) else: with open(f"{Path.home()}/.config/wire_py/keys", "a", encoding="utf-8") as keyfile: keyfile.write(f"{pre_key}\r") if len(path_split1) > 17: p1 = shutil.copy(filepath, "/tmp/tlecdcwg/") path_split = path_split1[len(path_split1) - 17:] os.rename(p1, f"/tmp/tlecdcwg/{path_split}") new_conf = f"/tmp/tlecdcwg/{path_split}" if self.a != "": check_call(["nmcli", "connection", "down", Tunnel.active()]) self.reset_fields() subprocess.check_output(["nmcli", "connection", "import", "type", "wireguard", "file", new_conf], text=True) Create.encrypt() else: shutil.copy(filepath, "/tmp/tlecdcwg/") if self.a != "": check_call(["nmcli", "connection", "down", Tunnel.active()]) self.reset_fields() subprocess.check_output(["nmcli", "connection", "import", "type", "wireguard", "file", filepath], text=True) Create.encrypt() self.str_var.set("") self.a = Tunnel.active() self.l_box.insert(0, self.a) self.wg_autostart.configure(state="normal") self.l_box.selection_clear(0, tk.END) self.l_box.update() self.l_box.selection_set(0) Tooltip(self.wg_autostart, _("To use the autostart, enable this Checkbox"), tips) # Tooltip(self.l_box, _("List of available tunnels")) Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!") , tips,) Tooltip(self.btn_exp, _(" Click to export all\nWireguard Tunnel to Zipfile") , tips) Tooltip(self.btn_rename, _("To rename a tunnel, you need to\nselect a tunnel from" " the list"), tips) self.lb_rename.insert(0, "Max. 12 characters!") self.str_var = tk.StringVar() self.str_var.set(self.a) self.color_label() self.stop() data = self.handle_tunnel_data(self.a) check_call(["nmcli", "con", "mod", self.a, "connection.autoconnect", "no"]) if ("PrivateKey = " in read) and ("Endpoint = " in read): 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) except EOFError as e: print(e) except TypeError: print("File import: abort by user...") except FileNotFoundError: print("File import: abort by user...") except subprocess.CalledProcessError: print("Tunnel exist!") def handle_tunnel_data(self, tunnel_name: str) -> dict[str, str]: """_summary_ Args: tunnel_name (str): name of tunnel Returns: Dict[str, str]: dictionary with tunneldata """ wg_read = f"/tmp/tlecdcwg/{tunnel_name}.conf" with open(wg_read, "r", encoding="utf-8") as file: data = Tunnel.con_to_dict(file) self.init_and_report(data) self.show_data() return data def box_set(self): """ This Method will display the autostart label which Tunnel is automatically started regardless of the active tunnel. The selected tunnel is written into a file to read it after the start of the system. """ try: select_tunnel = self.l_box.curselection() select_tl = self.l_box.get(select_tunnel[0]) if self.selected_option.get() == 0: with open(set_file, "r", encoding="utf-8") as set_f3: lines3 = set_f3.readlines() lines3[7] = "off\n" with open(set_file, "w", encoding="utf-8") as set_f3: set_f3.writelines(lines3) tl = Tunnel.list() if len(tl) == 0: self.wg_autostart.configure(state="disabled") if self.selected_option.get() >= 1: with open(set_file, "r", encoding="utf-8") as set_f3: lines3 = set_f3.readlines() lines3[7] = select_tl with open(set_file, "w", encoding="utf-8") as set_f3: set_f3.writelines(lines3) except IndexError: self.selected_option.set(1) self.on_off() def on_off(self): """ Here it is checked whether the path to the file is there, if not, it is created. Set (on), the selected tunnel is displayed in the label. At (off) the label is first emptied then filled with No Autoconnect """ with open(set_file, "r", encoding="utf-8") as set_f4: lines4 = set_f4.readlines() if lines4[7] != "off\n": print(f"{lines4[7]} starts automatically when the system starts.") self.selected_option.set(1) self.autoconnect_var.set("") self.auto_con = lines4[7] else: self.selected_option.set(0) self.auto_con = _("no Autoconnect") print("Autostart disabled.") self.autoconnect_var.set("") 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.config(font=("Ubuntu", 11)) self.autoconnect.grid(column=1, row=0, sticky="e", pady=19) def init_and_report(self, data=None): """ Displays the value address, DNS and peer in the labels or empty it again """ # Address Label self.add = tk.StringVar() self.add.set(f"{_("Address: ")}{data[0]}") self.DNS = tk.StringVar() self.DNS.set(f" DNS: {data[1]}") self.enp = tk.StringVar() self.enp.set(f"{_("Endpoint: ")}{data[2]}") def reset_fields(self) -> None: """ reset data from labels """ fields = [self.add, self.DNS, self.enp] for field in fields: field.set("") def show_data(self): """ shows data in the label """ # Address Label 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)) # DNS Label self.dns = ttk.Label(self.lb_frame, textvariable=self.DNS, foreground="#0071ff") self.dns.grid(column=0, row=7, sticky="w", padx=10, pady=6) self.dns.config(font=("Ubuntu", 9)) # Endpoint Label 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)) def stop(self): """ Stop Button """ self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_stop, command=self.wg_switch, 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) def start(self): """ Start Button """ self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_start, command=self.wg_switch, padding=0) self.btn_stst.grid(column=0, row=0, padx=5, pady=8) tl = Tunnel.list() if len(tl) == 0: Tooltip(self.btn_stst, _("No tunnels to start in the list"), tips) else: Tooltip(self.btn_stst, _("Click to start selected Wireguard Tunnel"), tips) def color_label(self): """ View activ Tunnel in the color green or yellow """ with open(set_file, "r", encoding="utf-8") as read_file: lines = read_file.readlines() if "light\n" in lines: 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.config(font=("Ubuntu", 11, "bold")) self.lb_tunnel.grid(column=2, padx=10, row=1) def wg_switch(self): """ switch Tunnel method change from labels and buttons """ self.a = Tunnel.active() try: if self.a == "": self.start() self.select_tunnel = self.l_box.curselection() select_tl = self.l_box.get(self.select_tunnel[0]) check_call(["nmcli", "connection", "up", select_tl]) data = self.handle_tunnel_data(self.a) # Button Start/Stop self.stop() self.a = Tunnel.active() self.str_var = tk.StringVar() self.str_var.set(self.a) self.color_label() elif self.a != "": # Button Start/Stop self.stop() check_call(["nmcli", "connection", "down", self.a]) # Button Start/Stop self.start() self.a = Tunnel.active() self.str_var.set("") self.color_label() self.reset_fields() self.show_data() except IndexError: if self.l_box.size() != 0: LxTools.msg_window(img_w, img_i2, sl, pstl) else: LxTools.msg_window(img_w, img_i2, sl, pfit) if __name__ == "__main__": window = Wirepy() """ the hidden files are hidden in Filedialog """ try: window.tk.call("tk_getOpenFile", "-foobarbaz") except TclError: pass window.tk.call("set", "::tk::dialog::file::showHiddenBtn", "0") window.tk.call("set", "::tk::dialog::file::showHiddenVar", "0") window.mainloop() LxTools.clean_files(folder_path, user_file) sys.exit(0)