Wire-Py/wg_main.py

1047 lines
45 KiB
Python
Raw Normal View History

2024-08-14 22:05:00 +02:00
#!/usr/bin/python3
import os
import shutil
import subprocess
2024-08-14 22:05:00 +02:00
import tkinter as tk
from pathlib import Path
from subprocess import check_call
from tkinter import *
from tkinter import filedialog, ttk
2024-10-26 12:35:18 +02:00
from wg_func import (Tunnel, FileHandle, OnOff, msg_window, WirePyUpdate, res, _u, version, path_to_file2,
path_to_file3, tips)
tcl_path = Path('/usr/share/TK-Themes')
2024-08-14 22:05:00 +02:00
class MainWindow(tk.Tk):
2024-08-14 22:05:00 +02:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.my_tool_tip = None
2024-08-14 22:05:00 +02:00
self.switch_on = None
self.switch_off = None
self.x_width = 600
self.y_height = 400
2024-08-14 22:05:00 +02:00
self.monitor_center_x = self.winfo_screenwidth() / 2 - (self.x_width / 2)
self.monitor_center_y = self.winfo_screenheight() / 2 - (self.y_height / 2)
self.resizable(width=False, height=False)
2024-08-14 22:05:00 +02:00
self.title('Wire-Py')
self.geometry('%dx%d+%d+%d' % (self.x_width, self.y_height, self.monitor_center_x, self.monitor_center_y))
self.style = ttk.Style(self)
self.tk.call('source', str(tcl_path) + '/water.tcl')
#self.tk.call('source', 'TK-Themes/water.tcl')
with open(path_to_file3, 'r') as read_file:
if 'light' in read_file:
self.tk.call('set_theme', 'light')
else:
self.tk.call('set_theme', 'dark')
''' Load the image file from disk. '''
self.wg_icon = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn.png')
2024-08-14 22:05:00 +02:00
# Set it as the window icon.
self.iconphoto(True, self.wg_icon)
2024-08-14 22:05:00 +02:00
#Set on or off in file
def on_off():
if set_option.get() == 1:
with open(path_to_file2, 'w') as set_file2:
set_file2.write('Update off')
if set_option.get() == 0:
with open(path_to_file2, 'w') as set_file2:
set_file2.write('Update on')
2024-09-07 23:52:16 +02:00
# Set dark or light
def theme_change_light():
if self.tk.call("ttk::style", "theme", "use") == "water-dark":
# Set light theme
self.tk.call('set_theme', 'light')
with open(path_to_file3, 'w') as theme_set2:
theme_set2.write('light')
def theme_change_dark():
if not self.tk.call("ttk::style", "theme", "use") == "water-dark":
# Set dark theme
self.tk.call('set_theme', 'dark')
with open(path_to_file3, 'w') as theme_set2:
theme_set2.write('dark')
2024-10-26 12:35:18 +02:00
def info():
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/48/wg_vpn.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Instruction'
2024-10-26 12:35:18 +02:00
msg_t = ('Wire-Py: 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'
'https://git.ilunix.de/punix/Wire-P\n\n'
'Use without warranty!\n')
msg_window(iw, ii, wt, msg_t)
''' Frame for Menu '''
self.menu_frame = ttk.Frame(self)
self.menu_frame.configure(relief='flat')
self.menu_frame.grid(column=0, row=0, sticky='w')
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
# 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, padx=10)
2024-10-26 12:35:18 +02:00
def version_enter(event):
""" The mouse moves into the Version widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, f'Version: {version[2:]}')
2024-10-26 12:35:18 +02:00
def version_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
self.options_btn = ttk.Menubutton(self.menu_frame, text='Options')
self.options_btn.grid(column=1, row=0)
2024-10-26 12:35:18 +02:00
def sets_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Settings')
2024-10-26 12:35:18 +02:00
def sets_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.version_lb.bind('<Enter>', version_enter)
self.version_lb.bind('<Leave>', version_leave)
self.options_btn.bind('<Enter>', sets_enter)
self.options_btn.bind('<Leave>', sets_leave)
set_option = tk.IntVar()
self.settings = tk.Menu(self)
self.options_btn.configure(menu=self.settings, style='Toolbutton')
self.settings.add_checkbutton(label='Disable updates', command=on_off, variable=set_option)
self.settings.add_command(label='Light', command=theme_change_light)
self.settings.add_command(label='Dark', command=theme_change_dark)
2024-10-26 12:35:18 +02:00
''' About BTN Menu / Label '''
self.about_btn = ttk.Menubutton(self.menu_frame, text='About')
self.about_btn.grid(column=2, row=0)
2024-10-26 12:35:18 +02:00
def about_enter(event):
""" The mouse moves into the entry widget """
2024-10-26 12:35:18 +02:00
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Info')
2024-10-26 12:35:18 +02:00
def about_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.about_btn.bind('<Enter>', about_enter)
self.about_btn.bind('<Leave>', about_leave)
self.readme = tk.Menu(self)
2024-10-26 12:35:18 +02:00
self.about_btn.configure(menu=self.readme, style='Toolbutton')
self.readme.add_command(label='Info', command=info)
''' Update Label '''
self.updates_lb = ttk.Label(self.menu_frame)
self.updates_lb.grid(column=3, row=0, padx=10)
if res == 'False':
set_option.set(value=1)
self.updates_lb.configure(text='Update search off')
2024-10-26 12:35:18 +02:00
def disable_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Updates you have disabled')
2024-10-26 12:35:18 +02:00
def disable_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.updates_lb.bind('<Enter>', disable_enter)
self.updates_lb.bind('<Leave>', disable_leave)
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')
2024-10-26 12:35:18 +02:00
def congratulations_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Congratulations! Wire-Py is up to date')
2024-10-26 12:35:18 +02:00
def congratulations_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.updates_lb.bind('<Enter>', congratulations_enter)
self.updates_lb.bind('<Leave>', congratulations_leave)
else:
set_option.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, row=0, padx=0)
2024-10-26 12:35:18 +02:00
def download_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to download new version')
2024-10-26 12:35:18 +02:00
def download_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.update_btn.bind('<Enter>', download_enter)
self.update_btn.bind('<Leave>', download_leave)
self.download = tk.Menu(self)
self.update_btn.configure(menu=self.download, style='Toolbutton')
self.download.add_command(label='Download', command=WirePyUpdate.download)
FrameWidgets(self).grid()
2024-10-26 12:35:18 +02:00
class StSt:
"""
Show Start and Stop Button in Label
"""
def __init__(self):
self.lb_frame_btn_lbox = None
self.wg_switch = None
self.btn_stst = None
self.wg_vpn_start = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-start.png')
self.wg_vpn_stop = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-stop.png')
2024-10-26 12:35:18 +02:00
def stop(self):
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)
2024-10-26 12:35:18 +02:00
def stop_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to stop selected Wireguard Tunnel')
2024-10-26 12:35:18 +02:00
def stop_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.btn_stst.bind('<Enter>', stop_enter)
self.btn_stst.bind('<Leave>', stop_leave)
2024-10-26 12:35:18 +02:00
def start(self):
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)
2024-10-26 12:35:18 +02:00
def empty_list_start_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'No tunnels to start in the list')
2024-10-26 12:35:18 +02:00
def empty_list_start_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
def start_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to start selected Wireguard Tunnel')
2024-10-26 12:35:18 +02:00
def start_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
tl = Tunnel.list()
if len(tl) == 0:
2024-10-26 12:35:18 +02:00
self.btn_stst.bind('<Enter>', empty_list_start_enter)
self.btn_stst.bind('<Leave>', empty_list_start_leave)
else:
2024-10-26 12:35:18 +02:00
self.btn_stst.bind('<Enter>', start_enter)
self.btn_stst.bind('<Leave>', start_leave)
2024-10-26 12:35:18 +02:00
# noinspection PyTypeChecker
class TLImp:
"""
Import Class 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 arise. 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.
"""
def __init__(self):
2024-10-26 12:35:18 +02:00
self.lb_rename = None
self.btn_tr = None
self.btn_exp = None
self.wg_autostart = None
self.select_tunnel = None
self.wg_switch = None
self.btn_stst = None
self.lb_tunnel = None
self.StrVar = None
self.a = None
self.l_box = None
2024-10-26 12:35:18 +02:00
def import_sl(self):
try:
filepath = filedialog.askopenfilename(initialdir=str(_u), title='Select Wireguard config File',
filetypes=[('WG config files', '*.conf')], )
with open(filepath, 'r') as file:
read = file.read()
path_split = filepath.split('/')
path_split1 = path_split[-1]
2024-10-26 12:35:18 +02:00
self.a = Tunnel.active()
if 'PrivateKey = ' in read and 'PublicKey = 'in read and 'Endpoint =' in read:
with open(filepath, 'r') as file:
2024-10-26 12:35:18 +02:00
key = Tunnel.con_to_dict(file)
pre_key = key[3]
if len(pre_key) != 0:
with open('/etc/wire_py/.keys', 'r') as readfile:
p_key = readfile.readlines()
if pre_key in p_key or pre_key + '\n' in p_key:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/error.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Import Error'
msg_t = 'Tunnel already available!\nPlease use another file for import'
msg_window(iw, ii, wt, msg_t)
else:
with open('/etc/wire_py/.keys', 'a') as keyfile:
keyfile.write(pre_key + '\r')
if len(path_split1) > 17:
p1 = shutil.copy(filepath, Path('/etc/wire_py/'))
path_split = path_split1[len(path_split1) - 17:]
os.rename(p1, Path('/etc/wire_py') / str(path_split))
new_conf = '/etc/wire_py/' + path_split
if self.a != '':
2024-10-26 12:35:18 +02:00
check_call(['nmcli', 'connection', 'down', Tunnel.active()])
Tunnel.label_empty(self)
subprocess.check_output(['nmcli', 'connection', 'import', 'type',
'wireguard', 'file', new_conf], text=True)
else:
shutil.copy(filepath, Path('/etc/wire_py/'))
if self.a != '':
2024-10-26 12:35:18 +02:00
check_call(['nmcli', 'connection', 'down', Tunnel.active()])
Tunnel.label_empty(self)
subprocess.check_output(['nmcli', 'connection', 'import', 'type',
'wireguard', 'file', filepath], text=True)
self.StrVar.set('')
2024-10-26 12:35:18 +02:00
self.a = Tunnel.active()
self.l_box.insert(0, self.a)
2024-10-26 12:35:18 +02:00
self.wg_autostart.configure(state='normal')
self.l_box.selection_clear(0, tk.END)
self.l_box.update()
2024-10-26 12:35:18 +02:00
self.l_box.selection_set(0)
def chk_a_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To use the autostart, enable this '
'Checkbox')
def chk_a_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
def list_info_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'List of available tunnels')
def list_info_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
def del_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to delete a Wireguard '
'Tunnel\nSelect from the list!')
def del_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
def exp_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
' Click to export '
'all\nWireguard Tunnel to Zipfile')
def exp_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
def rename_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To rename a tunnel, you need to\n'
'select a tunnel from the list')
def rename_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
self.wg_autostart.bind('<Enter>', chk_a_enter)
self.wg_autostart.bind('<Leave>', chk_a_leave)
self.l_box.bind('<Enter>', list_info_enter)
self.l_box.bind('<Leave>', list_info_leave)
self.btn_tr.bind('<Enter>', del_enter)
self.btn_tr.bind('<Leave>', del_leave)
self.btn_exp.bind('<Enter>', exp_enter)
self.btn_exp.bind('<Leave>', exp_leave)
self.lb_rename.bind('<Enter>', rename_enter)
self.lb_rename.bind('<Leave>', rename_leave)
self.lb_rename.insert(0, 'Max. 12 characters!')
self.StrVar = tk.StringVar()
self.StrVar.set(self.a)
2024-10-26 12:35:18 +02:00
Tunnel.color(self)
StSt.stop(self)
wg_read = Path('/etc/wire_py') / str(self.a + '.conf')
with open(wg_read, 'r') as file_for_key:
2024-10-26 12:35:18 +02:00
data = Tunnel.con_to_dict(file_for_key)
''' Address Label '''
2024-10-26 12:35:18 +02:00
Tunnel.init_and_report(self, data)
Tunnel.show_data(self)
check_call(['nmcli', 'con', 'mod', self.a, 'connection.autoconnect', 'no'])
Path.chmod(wg_read, 0o600)
2024-10-26 12:35:18 +02:00
if 'PrivateKey = ' and 'Endpoint = ' not in read:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/error.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Import Error'
msg_t = 'Oh... no valid Wireguard File!\nPlease select a valid Wireguard File'
msg_window(iw, ii, wt, msg_t)
except EOFError:
pass
except TypeError:
pass
except FileNotFoundError:
pass
except subprocess.CalledProcessError:
print('Tunnel exist!')
2024-10-26 12:35:18 +02:00
# noinspection PyTypeChecker
class FrameWidgets(ttk.Frame):
def __init__(self, container, **kwargs):
super().__init__(container, **kwargs)
self.btn_stst = None
2024-09-06 18:20:29 +02:00
self.auto_con = None
self.enp = None
self.DNS = None
self.add = None
self.data = None
self.peer = None
self.lb_tunnel = None
self.wg_read = None
self.wg_vpn_start = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-start.png')
self.wg_vpn_stop = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-stop.png')
self.imp_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_import.png')
self.tr_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_trash.png')
self.exp_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_export.png')
self.warning_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/64/error.png')
''' Show active Tunnel '''
2024-10-26 12:35:18 +02:00
self.a = Tunnel.active()
''' Label Frame 1 '''
2024-09-06 18:20:29 +02:00
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)
2024-09-06 18:20:29 +02:00
self.columnconfigure(0, weight=1)
self.rowconfigure(1, weight=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)
self.columnconfigure(2, weight=1)
self.rowconfigure(2, weight=1)
''' 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)
self.columnconfigure(2, weight=1)
self.rowconfigure(3, weight=1)
2024-09-06 18:20:29 +02:00
''' Show active Label '''
self.select_tunnel = None
self.lb = ttk.Label(self, text='Active: ')
2024-08-31 17:50:42 +02:00
self.lb.config(font=('Ubuntu', 11, 'bold'))
self.lb.grid(column=2, row=1, padx=15, pady=4, sticky='w')
self.columnconfigure(2, weight=1)
self.rowconfigure(0, weight=1)
''' Label to Show active Tunnel '''
self.StrVar = tk.StringVar(value=self.a)
2024-10-26 12:35:18 +02:00
Tunnel.color(self)
''' Interface Label '''
self.interface = ttk.Label(self.lb_frame, text='Interface')
self.interface.grid(column=0, row=3, sticky='we', padx=120)
2024-08-31 17:50:42 +02:00
self.interface.config(font=('Ubuntu', 9))
''' Peer Label '''
self.peer = ttk.Label(self.lb_frame2, text='Peer')
2024-08-31 17:50:42 +02:00
self.peer.config(font=('Ubuntu', 9))
self.peer.grid(column=0, row=4, sticky='we', padx=130)
''' Listbox with Scrollbar '''
2024-10-26 12:35:18 +02:00
def enable_check_box(_):
2024-10-26 12:35:18 +02:00
if self.l_box.size() != 0:
self.wg_autostart.configure(state='normal')
2024-09-21 12:40:18 +02:00
self.lb_rename.config(state='normal')
self.lb_rename.delete(0, tk.END)
self.btn_rename.config(state='normal')
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('<<ClickEvent>>', '<Button-1>')
self.l_box.bind('<<ClickEvent>>', enable_check_box)
2024-09-06 18:20:29 +02:00
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)
self.rowconfigure(0, weight=1)
''' Tunnel List '''
2024-10-26 12:35:18 +02:00
self.tl = Tunnel.list()
2024-08-14 22:05:00 +02:00
for tunnels in self.tl:
self.l_box.insert("end", tunnels)
self.l_box.update()
2024-10-26 12:35:18 +02:00
def list_empty_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'You must first import\na Wireguard tunnel')
def list_empty_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
def list_not_empty_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Select a Tunnel')
def list_not_empty_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
if self.l_box.size() == 0:
self.l_box.bind('<Enter>', list_empty_enter)
self.l_box.bind('<Leave>', list_empty_leave)
else:
self.l_box.bind('<Enter>', list_not_empty_enter)
self.l_box.bind('<Leave>', list_not_empty_leave)
''' Button Vpn '''
if self.a != '':
2024-10-26 12:35:18 +02:00
StSt.stop(self)
wg_read = Path('/etc/wire_py') / str(self.a + '.conf')
with open(wg_read, 'r') as file:
2024-10-26 12:35:18 +02:00
data = Tunnel.con_to_dict(file)
''' Address Label '''
2024-10-26 12:35:18 +02:00
Tunnel.init_and_report(self, data)
Tunnel.show_data(self)
2024-08-14 22:05:00 +02:00
else:
2024-10-26 12:35:18 +02:00
StSt.start(self)
''' Address Label '''
self.add = tk.StringVar()
self.DNS = tk.StringVar()
self.enp = tk.StringVar()
2024-10-26 12:35:18 +02:00
Tunnel.label_empty(self)
Tunnel.show_data(self)
''' Button Import '''
self.btn_i = ttk.Button(self.lb_frame_btn_lbox,
2024-10-26 12:35:18 +02:00
image=self.imp_pic, command=lambda: TLImp.import_sl(self),
padding=0)
self.btn_i.grid(column=0, row=1, padx=15, pady=8)
2024-10-26 12:35:18 +02:00
def imp_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to import a Wireguard Tunnel')
2024-10-26 12:35:18 +02:00
def imp_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.btn_i.bind('<Enter>', imp_enter)
self.btn_i.bind('<Leave>', imp_leave)
def delete():
try:
self.select_tunnel = self.l_box.curselection()
select_tl = self.l_box.get(self.select_tunnel[0])
with open('/etc/wire_py/' + select_tl + '.conf', 'r+') as file2:
2024-10-26 12:35:18 +02:00
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])
if Path.is_file(Path('/etc/wire_py/wg_py')):
path_to_file = Path('/etc/wire_py') / 'wg_py'
a_con = Path.read_text(path_to_file)
if select_tl == a_con:
self.selected_option.set(0)
self.autoconnect_var.set('no Autoconnect')
2024-10-26 12:35:18 +02:00
Path.unlink(path_to_file)
Path.unlink(Path('/etc/wire_py') / str(select_tl + '.conf'))
with open('/etc/wire_py/.keys', 'r') as readfile:
with open('/etc/wire_py/.keys2', 'w') as writefile:
for line in readfile:
if pre_key not in line.strip("\n"):
writefile.write(line)
file_one = Path('/etc/wire_py/.keys2')
file_two = file_one.with_name('.keys')
file_one.replace(file_two)
2024-10-26 12:35:18 +02:00
self.wg_autostart.configure(state='disabled')
''' for disable checkbox when Listbox empty '''
2024-10-26 12:35:18 +02:00
def empty_list_start_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'No tunnels to start in the list')
2024-10-26 12:35:18 +02:00
def empty_list_start_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
if self.l_box.size() == 0:
self.wg_autostart.configure(state='disabled')
2024-10-26 12:35:18 +02:00
self.lb_rename.configure(state='disabled')
self.l_box.bind('<Enter>', list_empty_enter)
self.l_box.bind('<Leave>', list_empty_leave)
self.wg_autostart.bind('<Enter>', chk_enter)
self.wg_autostart.bind('<Leave>', chk_leave)
self.btn_tr.bind('<Enter>', empty_list_enter)
self.btn_tr.bind('<Leave>', empty_list_leave)
self.btn_exp.bind('<Enter>', empty_list_enter)
self.btn_exp.bind('<Leave>', empty_list_leave)
self.btn_stst.bind('<Enter>', empty_list_start_enter)
self.btn_stst.bind('<Leave>', empty_list_start_leave)
self.lb_rename.bind('<Enter>', rename_no_active_enter)
self.lb_rename.bind('<Leave>', rename_no_active_leave)
self.lb_rename.insert(0, 'Max. 12 characters!')
if self.a != '' and self.a == select_tl:
self.StrVar.set(value='')
2024-10-26 12:35:18 +02:00
StSt.start(self)
self.l_box.update()
''' Address Label '''
self.add.set('')
self.DNS.set('')
self.enp.set('')
return select_tl
2024-10-26 12:35:18 +02:00
except IndexError:
2024-10-26 12:35:18 +02:00
if self.l_box.size() != 0:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Select tunnel'
msg_t = 'Please select a tunnel from the list.'
msg_window(iw, ii, wt, msg_t)
else:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Select tunnel'
msg_t = 'Please first import tunnel.'
msg_window(iw, ii, wt, msg_t)
''' 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)
2024-10-26 12:35:18 +02:00
def empty_list_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'No tunnels to delete in the list')
2024-10-26 12:35:18 +02:00
def empty_list_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
def del_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to delete a Wireguard Tunnel\nSelect from the list!')
2024-10-26 12:35:18 +02:00
def del_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
if self.l_box.size() == 0:
self.btn_tr.bind('<Enter>', empty_list_enter)
self.btn_tr.bind('<Leave>', empty_list_leave)
else:
2024-10-26 12:35:18 +02:00
self.btn_tr.bind('<Enter>', del_enter)
self.btn_tr.bind('<Leave>', del_leave)
''' Button Export '''
2024-10-26 12:35:18 +02:00
self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic, command=Tunnel.export,
padding=0)
self.btn_exp.grid(column=0, row=3, padx=15, pady=8)
2024-10-26 12:35:18 +02:00
def empty_list_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'No Tunnels in List for Export')
2024-10-26 12:35:18 +02:00
def empty_list_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
def exp_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
' Click to export all\nWireguard Tunnel to Zipfile')
2024-10-26 12:35:18 +02:00
def exp_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
if self.l_box.size() == 0:
self.btn_exp.bind('<Enter>', empty_list_enter)
self.btn_exp.bind('<Leave>', empty_list_leave)
else:
2024-10-26 12:35:18 +02:00
self.btn_exp.bind('<Enter>', exp_enter)
self.btn_exp.bind('<Leave>', exp_leave)
''' Label Entry '''
self.lb_rename = ttk.Entry(self, width=20)
self.lb_rename.grid(column=2, row=4, padx=30, pady=15, sticky='nw')
self.lb_rename.insert(0, 'Max. 12 characters!')
2024-09-21 12:40:18 +02:00
self.lb_rename.config(state='disable')
2024-10-26 12:35:18 +02:00
def rename_no_active_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
def rename_no_active_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To rename a tunnel, at least one must be in the list')
2024-10-26 12:35:18 +02:00
def rename_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To rename a tunnel, you need to\nselect a tunnel from the list')
def rename_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
if self.l_box.size() != 0:
self.lb_rename.bind('<Enter>', rename_enter)
self.lb_rename.bind('<Leave>', rename_leave)
else:
2024-10-26 12:35:18 +02:00
self.lb_rename.bind('<Enter>', rename_no_active_enter)
self.lb_rename.bind('<Leave>', rename_no_active_leave)
2024-09-21 12:40:18 +02:00
def tl_rename():
special_characters = ['\\', '/', '{', '}', ' ']
if len(self.lb_rename.get()) > 12:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Renaming not possible'
msg_t = 'The new name may contain only 12 characters.'
msg_window(iw, ii, wt, msg_t)
elif len(self.lb_rename.get()) == 0:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Renaming not possible'
msg_t = 'At least one character must be entered.'
msg_window(iw, ii, wt, msg_t)
elif any(ch in special_characters for ch in self.lb_rename.get()):
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Renaming not possible'
2024-09-26 21:18:48 +02:00
msg_t = 'No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n'
msg_window(iw, ii, wt, 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('/etc/wire_py') / str(select_tl + '.conf')
destination = source.with_name(str(self.lb_rename.get() + '.conf'))
source.replace(destination)
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:
2024-10-26 12:35:18 +02:00
self.a = Tunnel.active()
self.StrVar.set(value=self.a)
if Path.is_file(Path('/etc/wire_py/wg_py')):
path_to_file = Path('/etc/wire_py') / 'wg_py'
a_con = Path.read_text(path_to_file)
if select_tl == a_con:
self.autoconnect_var.set(value=new_a_connect)
Path.write_text(path_to_file, new_a_connect)
2024-10-26 12:35:18 +02:00
return select_tl
except IndexError:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Renaming not possible'
msg_t = 'Please select a tunnel from the list.'
msg_window(iw, ii, wt, msg_t)
2024-09-21 12:40:18 +02:00
''' Button Rename '''
self.btn_rename = ttk.Button(self, text='Rename', state='disable', command=tl_rename, padding=4,
style='RnButton.TButton')
self.btn_rename.grid(column=2, row=4, padx=20, pady=15, sticky='ne')
''' Check Buttons '''
self.selected_option = tk.IntVar()
2024-09-06 18:20:29 +02:00
self.autoconnect_var = tk.StringVar()
self.autoconnect_var.set(self.auto_con)
''' Frame for Labels, Entry and Button'''
self.autoconnect = ttk.Label(self, textvariable=self.autoconnect_var)
2024-09-06 18:20:29 +02:00
self.autoconnect.config(font=('Ubuntu', 11))
self.autoconnect.grid(column=0, row=4, sticky='ne', padx=10, pady=15)
self.wg_autostart = ttk.Checkbutton(self,
text='Autoconnect on:',
variable=self.selected_option,
command=lambda: FileHandle.box_set(self))
self.wg_autostart.grid(column=0, row=4, pady=15, padx=15, sticky='nw')
2024-10-26 12:35:18 +02:00
def chk_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'You must have at least one\n'
'tunnel in the list,to use the autostart')
2024-10-26 12:35:18 +02:00
def chk_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
if self.l_box.size() >= 1 and len(self.l_box.curselection()) >= 1:
def chk_a_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To use the autostart, enable this Checkbox')
def chk_a_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
self.wg_autostart.bind('<Enter>', chk_a_enter)
self.wg_autostart.bind('<Leave>', chk_a_leave)
if self.l_box.size() == 0:
self.wg_autostart.bind('<Enter>', chk_enter)
self.wg_autostart.bind('<Leave>', chk_leave)
else:
2024-10-26 12:35:18 +02:00
def chk_a_enter(event):
""" The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To use the autostart, a tunnel must be selected from the list')
2024-10-26 12:35:18 +02:00
def chk_a_leave(_):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
2024-10-26 12:35:18 +02:00
self.wg_autostart.bind('<Enter>', chk_a_enter)
self.wg_autostart.bind('<Leave>', chk_a_leave)
OnOff.on_off(self)
2024-08-14 22:05:00 +02:00
def wg_switch(self):
2024-10-26 12:35:18 +02:00
self.a = Tunnel.active()
try:
if self.a == '':
2024-10-26 12:35:18 +02:00
StSt.start(self)
self.select_tunnel = self.l_box.curselection()
select_tl = self.l_box.get(self.select_tunnel[0])
check_call(['nmcli', 'connection', 'up', select_tl])
wg_read = Path('/etc/wire_py') / str(select_tl + '.conf')
with open(wg_read, 'r') as file:
2024-10-26 12:35:18 +02:00
data = Tunnel.con_to_dict(file)
''' Address Label '''
2024-10-26 12:35:18 +02:00
Tunnel.init_and_report(self, data)
Tunnel.show_data(self)
''' Button Start/Stop '''
2024-10-26 12:35:18 +02:00
StSt.stop(self)
self.a = Tunnel.active()
self.StrVar = tk.StringVar()
self.StrVar.set(self.a)
2024-10-26 12:35:18 +02:00
Tunnel.color(self)
elif self.a != '':
''' Button Start/Stop '''
2024-10-26 12:35:18 +02:00
StSt.stop(self)
check_call(['nmcli', 'connection', 'down', self.a])
''' Button Start/Stop '''
2024-10-26 12:35:18 +02:00
StSt.start(self)
self.a = Tunnel.active()
self.StrVar.set('')
2024-10-26 12:35:18 +02:00
Tunnel.color(self)
''' Address Label '''
self.add.set('')
self.DNS.set('')
self.enp.set('')
2024-10-26 12:35:18 +02:00
Tunnel.show_data(self)
except IndexError:
2024-10-26 12:35:18 +02:00
if self.l_box.size() != 0:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Select tunnel'
msg_t = 'Please select a tunnel from the list.'
msg_window(iw, ii, wt, msg_t)
else:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Select tunnel'
msg_t = 'Please first import tunnel.'
msg_window(iw, ii, wt, msg_t)
2024-08-14 22:05:00 +02:00
class MyToolTip(tk.Toplevel):
2024-10-26 12:35:18 +02:00
TIP_X_OFFSET = 20
TIP_Y_OFFSET = 20
if not tips:
AUTO_CLEAR_TIME = 0
else:
AUTO_CLEAR_TIME = 900 # Millisecond. (1/90 sec.)
def __init__(self, x_pos, y_pos, message=None, auto_clear=True):
self.x_pos = x_pos
self.y_pos = y_pos
self.message = message
self.auto_clear = auto_clear
tk.Toplevel.__init__(self)
self.overrideredirect(True)
2024-10-26 12:35:18 +02:00
self.message_label = ttk.Label(self, compound='left', text=self.message, padding=6)
self.message_label.pack()
self.geometry("+%d+%d" % (self.x_pos + self.TIP_X_OFFSET,
self.y_pos + self.TIP_X_OFFSET))
if self.auto_clear:
self.after(self.AUTO_CLEAR_TIME, self.clear_tip)
def clear_tip(self):
"""Remove Tool-Tip"""
self.destroy()
2024-08-14 22:05:00 +02:00
if __name__ == '__main__':
window = MainWindow()
"""
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()