- Optimize Class and Tooltip

This commit is contained in:
Désiré Werner Menrath 2024-10-26 12:35:18 +02:00
parent 0769cabc1e
commit 18e042400c
5 changed files with 431 additions and 336 deletions

View File

@ -4,10 +4,9 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment=" - Fix a ConToDict Class when Endpoint not in Wireguard config file"> <list default="true" id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Changelog" beforeDir="false" afterPath="$PROJECT_DIR$/Changelog" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Changelog" beforeDir="false" afterPath="$PROJECT_DIR$/Changelog" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/testtheme.py" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/testtheme.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/wg_func.py" beforeDir="false" afterPath="$PROJECT_DIR$/wg_func.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/wg_func.py" beforeDir="false" afterPath="$PROJECT_DIR$/wg_func.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/wg_main.py" beforeDir="false" afterPath="$PROJECT_DIR$/wg_main.py" afterDir="false" /> <change beforePath="$PROJECT_DIR$/wg_main.py" beforeDir="false" afterPath="$PROJECT_DIR$/wg_main.py" afterDir="false" />
@ -48,24 +47,24 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;ASKED_ADD_EXTERNAL_FILES&quot;: &quot;true&quot;, "ASKED_ADD_EXTERNAL_FILES": "true",
&quot;Python.INSTALL.executor&quot;: &quot;Run&quot;, "Python.INSTALL.executor": "Run",
&quot;Python.install.executor&quot;: &quot;Run&quot;, "Python.install.executor": "Run",
&quot;Python.main.executor&quot;: &quot;Run&quot;, "Python.main.executor": "Run",
&quot;Python.messagebox.executor&quot;: &quot;Run&quot;, "Python.messagebox.executor": "Run",
&quot;Python.start_wg.executor&quot;: &quot;Run&quot;, "Python.start_wg.executor": "Run",
&quot;Python.testtheme.executor&quot;: &quot;Run&quot;, "Python.testtheme.executor": "Run",
&quot;Python.wg_func.executor&quot;: &quot;Run&quot;, "Python.wg_func.executor": "Run",
&quot;Python.wg_main.executor&quot;: &quot;Run&quot;, "Python.wg_main.executor": "Run",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;Shell Script.install.executor&quot;: &quot;Run&quot;, "Shell Script.install.executor": "Run",
&quot;git-widget-placeholder&quot;: &quot;main&quot;, "git-widget-placeholder": "main",
&quot;last_opened_file_path&quot;: &quot;/home/punix/Pyapps/wire-py&quot;, "last_opened_file_path": "/home/punix/Pyapps/wire-py",
&quot;settings.editor.selected.configurable&quot;: &quot;configurable.group.editor&quot; "settings.editor.selected.configurable": "reference.settingsdialog.IDE.editor.colors"
} }
}</component> }]]></component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" /> <recent name="$PROJECT_DIR$" />
@ -144,30 +143,6 @@
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1723279982210</updated> <updated>1723279982210</updated>
</task> </task>
<task id="LOCAL-00013" summary="In FrameWidged Class else Block StrVar, this resorts reference and variable assignment together">
<option name="closed" value="true" />
<created>1724401340512</created>
<option name="number" value="00013" />
<option name="presentableId" value="LOCAL-00013" />
<option name="project" value="LOCAL" />
<updated>1724401340512</updated>
</task>
<task id="LOCAL-00014" summary="add method init_and_report and label_empty to Class ShowAddress">
<option name="closed" value="true" />
<created>1724410630021</created>
<option name="number" value="00014" />
<option name="presentableId" value="LOCAL-00014" />
<option name="project" value="LOCAL" />
<updated>1724410630021</updated>
</task>
<task id="LOCAL-00015" summary="little fixes in Class Import">
<option name="closed" value="true" />
<created>1724416642213</created>
<option name="number" value="00015" />
<option name="presentableId" value="LOCAL-00015" />
<option name="project" value="LOCAL" />
<updated>1724416642213</updated>
</task>
<task id="LOCAL-00016" summary="fix label when laat Tunnel delete and fix Tuple error in delete and Start/Stop when listbox empty"> <task id="LOCAL-00016" summary="fix label when laat Tunnel delete and fix Tuple error in delete and Start/Stop when listbox empty">
<option name="closed" value="true" /> <option name="closed" value="true" />
<created>1724495688099</created> <created>1724495688099</created>
@ -536,7 +511,31 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1729353898830</updated> <updated>1729353898830</updated>
</task> </task>
<option name="localTasksCounter" value="62" /> <task id="LOCAL-00062" summary="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip">
<option name="closed" value="true" />
<created>1729541504291</created>
<option name="number" value="00062" />
<option name="presentableId" value="LOCAL-00062" />
<option name="project" value="LOCAL" />
<updated>1729541504292</updated>
</task>
<task id="LOCAL-00063" summary="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip">
<option name="closed" value="true" />
<created>1729541561434</created>
<option name="number" value="00063" />
<option name="presentableId" value="LOCAL-00063" />
<option name="project" value="LOCAL" />
<updated>1729541561434</updated>
</task>
<task id="LOCAL-00064" summary="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip">
<option name="closed" value="true" />
<created>1729593628907</created>
<option name="number" value="00064" />
<option name="presentableId" value="LOCAL-00064" />
<option name="project" value="LOCAL" />
<updated>1729593628908</updated>
</task>
<option name="localTasksCounter" value="65" />
<servers /> <servers />
</component> </component>
<component name="UnknownFeatures"> <component name="UnknownFeatures">
@ -577,7 +576,6 @@
</component> </component>
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" /> <option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="set rights in install and a .conf a import Tunnel Filedialog Part 1 /home when open" />
<MESSAGE value="fix set rights in install and a .conf a import Tunnel Filedialog Part 1 /home when open" /> <MESSAGE value="fix set rights in install and a .conf a import Tunnel Filedialog Part 1 /home when open" />
<MESSAGE value="fix a filedialog for hidden Files work&#10;install rollback to bash for start wirepy and wirepy rollback to bash" /> <MESSAGE value="fix a filedialog for hidden Files work&#10;install rollback to bash for start wirepy and wirepy rollback to bash" />
<MESSAGE value="install rollback bash to py wirepy and wirepy rollback to py" /> <MESSAGE value="install rollback bash to py wirepy and wirepy rollback to py" />
@ -602,22 +600,7 @@
<MESSAGE value=" - Menu add &#10; - New Modern Dark and Light(default) Theme" /> <MESSAGE value=" - Menu add &#10; - New Modern Dark and Light(default) Theme" />
<MESSAGE value=" - Theme modify to water-theme&#10; - add ttk.Menubutton vor modern Menu and automatic theme and textvariable for color on font in menu" /> <MESSAGE value=" - Theme modify to water-theme&#10; - add ttk.Menubutton vor modern Menu and automatic theme and textvariable for color on font in menu" />
<MESSAGE value=" - Add Options, Help, Update Label and Update Menubutton &#10; - Theme now separate Light and Dark" /> <MESSAGE value=" - Add Options, Help, Update Label and Update Menubutton &#10; - Theme now separate Light and Dark" />
<option name="LAST_COMMIT_MESSAGE" value=" - Add Options, Help, Update Label and Update Menubutton &#10; - Theme now separate Light and Dark" /> <MESSAGE value="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip" />
</component> <option name="LAST_COMMIT_MESSAGE" value="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip" />
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/wg_func.py</url>
<line>341</line>
<option name="timeStamp" value="8" />
</line-breakpoint>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/wg_main.py</url>
<line>273</line>
<option name="timeStamp" value="11" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component> </component>
</project> </project>

View File

@ -12,6 +12,12 @@ My standard System: Linux Mint 22 Cinnamon
- Keeping Classes Together - Keeping Classes Together
### Added
25-10-2024
- Optimize Class and Tooltip
### Added ### Added
21-10-2024 21-10-2024

View File

@ -1,27 +0,0 @@
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
# Pack a big frame so, it behaves like the window background
big_frame = ttk.Frame(root)
big_frame.pack(fill="both", expand=True)
# Set the initial theme
root.tk.call("source", "TK-Themes/azure.tcl")
root.tk.call("set_theme", "light")
def change_theme():
# NOTE: The theme's real name is azure-<mode>
if root.tk.call("ttk::style", "theme", "use") == "azure-dark":
# Set light theme
root.tk.call("set_theme", "light")
else:
# Set dark theme
root.tk.call("set_theme", "dark")
# Remember, you have to use ttk widgets
button = ttk.Button(big_frame, text="Change theme!", command=change_theme)
button.pack()
root.mainloop()

View File

@ -3,6 +3,7 @@
import os import os
import shutil import shutil
import subprocess import subprocess
import time
import tkinter as tk import tkinter as tk
import zipfile import zipfile
from datetime import datetime from datetime import datetime
@ -22,6 +23,7 @@ _u = Path.read_text(Path('/tmp/_u'))
UPDATE_API_URL = 'https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases' UPDATE_API_URL = 'https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases'
tips = True
class WirePyUpdate: class WirePyUpdate:
@staticmethod @staticmethod
@ -107,16 +109,25 @@ def msg_window(img_w, img_i, w_title, w_txt):
msg.winfo_toplevel() msg.winfo_toplevel()
class GreenLabel: class Tunnel:
""" """
Show the active tunnel in green in the label Show the active tunnel in green or yellow in the label
""" """
def __init__(self): def __init__(self):
self.StrVar = None self.StrVar = None
self.lb_tunnel = None self.lb_tunnel = None
self.lb_frame2 = None
self.lb_frame = None
self.endpoint = None
self.dns = None
self.address = None
self.enp = None
self.DNS = None
self.add = None
def green_show_label(self): def color(self):
with open(path_to_file3, 'r') as read_file: with open(path_to_file3, 'r') as read_file:
if 'light' in read_file: if 'light' in read_file:
self.lb_tunnel = ttk.Label(self, textvariable=self.StrVar, foreground='green') self.lb_tunnel = ttk.Label(self, textvariable=self.StrVar, foreground='green')
@ -136,14 +147,13 @@ class GreenLabel:
pass pass
class ConToDict:
""" """
The config file is packed into a dictionary, The config file is packed into a dictionary,
to display the values Address , DNS and Peer in the labels to display the values Address , DNS and Peer in the labels
""" """
@classmethod @classmethod
def covert_to_dict(cls, file): def con_to_dict(cls, file):
dictlist = [] dictlist = []
for lines in file.readlines(): for lines in file.readlines():
@ -184,7 +194,6 @@ class ConToDict:
return address, dns, endpoint, pre_key return address, dns, endpoint, pre_key
class TunnelActiv:
""" """
Shows the Active Tunnel Shows the Active Tunnel
""" """
@ -201,21 +210,11 @@ class TunnelActiv:
return active return active
class ShowAddress:
""" """
Displays the value address, DNS and peer in the labels Displays the value address, DNS and peer in the labels
or empty it again or empty it again
""" """
def __init__(self):
self.lb_frame2 = None
self.lb_frame = None
self.endpoint = None
self.dns = None
self.address = None
self.enp = None
self.DNS = None
self.add = None
def init_and_report(self, data=None): def init_and_report(self, data=None):
""" Address Label """ """ Address Label """
@ -248,13 +247,12 @@ class ShowAddress:
self.endpoint.config(font=('Ubuntu', 9)) self.endpoint.config(font=('Ubuntu', 9))
class ListTunnels:
""" """
Shows all existing Wireguard tunnels Shows all existing Wireguard tunnels
""" """
@staticmethod @staticmethod
def tl_list(): def list():
wg_s = os.popen('nmcli con show | grep -iPo "(.*)(wireguard)"').read().split() wg_s = os.popen('nmcli con show | grep -iPo "(.*)(wireguard)"').read().split()
''' tl = Tunnel list # Show of 4.Element in list ''' ''' tl = Tunnel list # Show of 4.Element in list '''
@ -262,6 +260,63 @@ class ListTunnels:
return tl return tl
"""
This will export the tunnels.
A zipfile with current date and time is created
in the user's home directory with correct right
"""
@staticmethod
def export():
_u1 = str(_u[6:])
now_time = datetime.now()
now_datetime = now_time.strftime('wg-exp-' + '%m-%d-%Y' + '-' + '%H:%M')
tl = Tunnel.list()
try:
if len(tl) != 0:
wg_tar = str(_u) + '/' + now_datetime
shutil.copytree('/etc/wire_py', '/tmp/wire_py', dirs_exist_ok=True)
source = Path('/tmp/wire_py')
Path.unlink(Path(source) / 'wg_py', missing_ok=True)
Path.unlink(Path(source) / '.keys', missing_ok=True)
Path.unlink(Path(source) / 'settings', missing_ok=True)
Path.unlink(Path(source) / 'theme', missing_ok=True)
shutil.make_archive(wg_tar, 'zip', source)
shutil.chown(wg_tar + '.zip', 1000, 1000)
shutil.rmtree(source)
with zipfile.ZipFile((wg_tar + '.zip'), 'r') as zf:
if len(zf.namelist()) != 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_vpn.png'
wt = 'Export Successful'
msg_t = 'Your zip file is in home directory'
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/error.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Export error'
msg_t = 'Export failed! Please try again'
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)
except TypeError:
pass
class FileHandle: class FileHandle:
""" """
This class will display the autostart label which This class will display the autostart label which
@ -287,7 +342,7 @@ class FileHandle:
if self.selected_option.get() == 0: if self.selected_option.get() == 0:
Path.unlink(path_to_file) Path.unlink(path_to_file)
tl = ListTunnels.tl_list() tl = Tunnel.list()
if len(tl) == 0: if len(tl) == 0:
self.wg_autostart.configure(state='disabled') self.wg_autostart.configure(state='disabled')
@ -337,64 +392,3 @@ class OnOff:
self.autoconnect = ttk.Label(self, textvariable=self.autoconnect_var, foreground='#0071ff') self.autoconnect = ttk.Label(self, textvariable=self.autoconnect_var, foreground='#0071ff')
self.autoconnect.config(font=('Ubuntu', 11)) self.autoconnect.config(font=('Ubuntu', 11))
self.autoconnect.grid(column=0, row=4, sticky='ne', pady=19) self.autoconnect.grid(column=0, row=4, sticky='ne', pady=19)
class ExportTunnels:
"""
This will export the tunnels.
A zipfile with current date and time is created
in the user's home directory with correct right
"""
@staticmethod
def wg_export():
_u1 = str(_u[6:])
now_time = datetime.now()
now_datetime = now_time.strftime('wg-exp-' + '%m-%d-%Y' + '-' + '%H:%M')
tl = ListTunnels.tl_list()
try:
if len(tl) != 0:
wg_tar = str(_u) + '/' + now_datetime
shutil.copytree('/etc/wire_py', '/tmp/wire_py', dirs_exist_ok=True)
source = Path('/tmp/wire_py')
Path.unlink(Path(source) / 'wg_py', missing_ok=True)
Path.unlink(Path(source) / '.keys', missing_ok=True)
Path.unlink(Path(source) / 'settings', missing_ok=True)
Path.unlink(Path(source) / 'theme', missing_ok=True)
shutil.make_archive(wg_tar, 'zip', source)
shutil.chown(wg_tar + '.zip', 1000, 1000)
shutil.rmtree(source)
with zipfile.ZipFile((wg_tar + '.zip'), 'r') as zf:
if len(zf.namelist()) != 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_vpn.png'
wt = 'Export Successful'
msg_t = 'Your zip file is in home directory'
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/error.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Export error'
msg_t = 'Export failed! Please try again'
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)
except TypeError:
pass

View File

@ -8,13 +8,11 @@ from subprocess import check_call
from tkinter import * from tkinter import *
from tkinter import filedialog, ttk from tkinter import filedialog, ttk
from wg_func import (TunnelActiv, ListTunnels, ConToDict, GreenLabel, ShowAddress, FileHandle, from wg_func import (Tunnel, FileHandle, OnOff, msg_window, WirePyUpdate, res, _u, version, path_to_file2,
ExportTunnels, OnOff, msg_window, WirePyUpdate, res, _u, version, path_to_file2, path_to_file3, tips)
path_to_file3)
tcl_path = Path('/usr/share/TK-Themes') tcl_path = Path('/usr/share/TK-Themes')
class MainWindow(tk.Tk): class MainWindow(tk.Tk):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -70,12 +68,17 @@ class MainWindow(tk.Tk):
with open(path_to_file3, 'w') as theme_set2: with open(path_to_file3, 'w') as theme_set2:
theme_set2.write('dark') theme_set2.write('dark')
def instruction(): def info():
"""img_w, img_i, w_title, w_txt hand over""" """img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/48/wg_vpn.png' iw = r'/usr/share/icons/wp-icons/48/wg_vpn.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png' ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = 'Instruction' wt = 'Instruction'
msg_t = 'Here comes the instructions for Wire-Py' 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) msg_window(iw, ii, wt, msg_t)
''' Frame for Menu ''' ''' Frame for Menu '''
@ -90,11 +93,11 @@ class MainWindow(tk.Tk):
self.version_lb.config(font=('Ubuntu', 11), foreground='#00c4ff') self.version_lb.config(font=('Ubuntu', 11), foreground='#00c4ff')
self.version_lb.grid(column=0, row=0, padx=10) self.version_lb.grid(column=0, row=0, padx=10)
def version_mouse_enter(event): def version_enter(event):
""" The mouse moves into the Version widget """ """ The mouse moves into the Version widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, f'Version: {version[2:]}') window.my_tool_tip = MyToolTip(event.x_root, event.y_root, f'Version: {version[2:]}')
def version_mouse_leave(event): def version_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
@ -102,19 +105,19 @@ class MainWindow(tk.Tk):
self.options_btn = ttk.Menubutton(self.menu_frame, text='Options') self.options_btn = ttk.Menubutton(self.menu_frame, text='Options')
self.options_btn.grid(column=1, row=0) self.options_btn.grid(column=1, row=0)
def sets_mouse_enter(event): def sets_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Settings') window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Settings')
def sets_mouse_leave(event): def sets_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.version_lb.bind('<Enter>', version_mouse_enter) self.version_lb.bind('<Enter>', version_enter)
self.version_lb.bind('<Leave>', version_mouse_leave) self.version_lb.bind('<Leave>', version_leave)
self.options_btn.bind('<Enter>', sets_mouse_enter) self.options_btn.bind('<Enter>', sets_enter)
self.options_btn.bind('<Leave>', sets_mouse_leave) self.options_btn.bind('<Leave>', sets_leave)
set_option = tk.IntVar() set_option = tk.IntVar()
@ -124,24 +127,24 @@ class MainWindow(tk.Tk):
self.settings.add_command(label='Light', command=theme_change_light) self.settings.add_command(label='Light', command=theme_change_light)
self.settings.add_command(label='Dark', command=theme_change_dark) self.settings.add_command(label='Dark', command=theme_change_dark)
''' Help BTN Menu / Label ''' ''' About BTN Menu / Label '''
self.help_btn = ttk.Menubutton(self.menu_frame, text='Help') self.about_btn = ttk.Menubutton(self.menu_frame, text='About')
self.help_btn.grid(column=2, row=0) self.about_btn.grid(column=2, row=0)
def help_mouse_enter(event): def about_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Help') window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Click for Info')
def help_mouse_leave(event): def about_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.help_btn.bind('<Enter>', help_mouse_enter) self.about_btn.bind('<Enter>', about_enter)
self.help_btn.bind('<Leave>', help_mouse_leave) self.about_btn.bind('<Leave>', about_leave)
self.readme = tk.Menu(self) self.readme = tk.Menu(self)
self.help_btn.configure(menu=self.readme, style='Toolbutton') self.about_btn.configure(menu=self.readme, style='Toolbutton')
self.readme.add_command(label='Instruction', command=instruction) self.readme.add_command(label='Info', command=info)
''' Update Label ''' ''' Update Label '''
self.updates_lb = ttk.Label(self.menu_frame) self.updates_lb = ttk.Label(self.menu_frame)
@ -151,34 +154,34 @@ class MainWindow(tk.Tk):
set_option.set(value=1) set_option.set(value=1)
self.updates_lb.configure(text='Update search off') self.updates_lb.configure(text='Update search off')
def disable_mouse_enter(event): def disable_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Updates you have disabled') window.my_tool_tip = MyToolTip(event.x_root, event.y_root, 'Updates you have disabled')
def disable_mouse_leave(event): def disable_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.updates_lb.bind('<Enter>', disable_mouse_enter) self.updates_lb.bind('<Enter>', disable_enter)
self.updates_lb.bind('<Leave>', disable_mouse_leave) self.updates_lb.bind('<Leave>', disable_leave)
elif res == 'No Internet Connection!': elif res == 'No Internet Connection!':
self.updates_lb.configure(text='No Server Connection!', foreground='red') self.updates_lb.configure(text='No Server Connection!', foreground='red')
elif res == 'No Updates': elif res == 'No Updates':
self.updates_lb.configure(text='No Updates') self.updates_lb.configure(text='No Updates')
def congratulations_mouse_enter(event): def congratulations_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Congratulations! Wire-Py is up to date') 'Congratulations! Wire-Py is up to date')
def congratulations_mouse_leave(event): def congratulations_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.updates_lb.bind('<Enter>', congratulations_mouse_enter) self.updates_lb.bind('<Enter>', congratulations_enter)
self.updates_lb.bind('<Leave>', congratulations_mouse_leave) self.updates_lb.bind('<Leave>', congratulations_leave)
else: else:
set_option.set(value=0) set_option.set(value=0)
text = f'Update {res} available!' text = f'Update {res} available!'
@ -188,18 +191,18 @@ class MainWindow(tk.Tk):
self.update_btn = ttk.Menubutton(self.menu_frame, text=text) self.update_btn = ttk.Menubutton(self.menu_frame, text=text)
self.update_btn.grid(column=4, row=0, padx=0) self.update_btn.grid(column=4, row=0, padx=0)
def download_mouse_enter(event): def download_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to download new version') 'Click to download new version')
def download_mouse_leave(event): def download_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.update_btn.bind('<Enter>', download_mouse_enter) self.update_btn.bind('<Enter>', download_enter)
self.update_btn.bind('<Leave>', download_mouse_leave) self.update_btn.bind('<Leave>', download_leave)
self.download = tk.Menu(self) self.download = tk.Menu(self)
@ -209,7 +212,7 @@ class MainWindow(tk.Tk):
FrameWidgets(self).grid() FrameWidgets(self).grid()
class StartStopBTN: class StSt:
""" """
Show Start and Stop Button in Label Show Start and Stop Button in Label
""" """
@ -221,57 +224,58 @@ class StartStopBTN:
self.wg_vpn_start = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-start.png') 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.wg_vpn_stop = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-stop.png')
def button_stop(self): 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 = 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) self.btn_stst.grid(column=0, row=0, padx=5, pady=8)
def stop_mouse_enter(event): def stop_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to stop selected Wireguard Tunnel') 'Click to stop selected Wireguard Tunnel')
def stop_mouse_leave(event): def stop_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.btn_stst.bind('<Enter>', stop_mouse_enter) self.btn_stst.bind('<Enter>', stop_enter)
self.btn_stst.bind('<Leave>', stop_mouse_leave) self.btn_stst.bind('<Leave>', stop_leave)
def button_start(self): 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 = 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) self.btn_stst.grid(column=0, row=0, padx=5, pady=8)
def empty_list_start_mouse_enter(event): def empty_list_start_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'No tunnels to start in the list') 'No tunnels to start in the list')
def empty_list_start_mouse_leave(event): def empty_list_start_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
def start_mouse_enter(event): def start_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to start selected Wireguard Tunnel') 'Click to start selected Wireguard Tunnel')
def start_mouse_leave(event): def start_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
tl = ListTunnels.tl_list() tl = Tunnel.list()
if len(tl) == 0: if len(tl) == 0:
self.btn_stst.bind('<Enter>', empty_list_start_mouse_enter) self.btn_stst.bind('<Enter>', empty_list_start_enter)
self.btn_stst.bind('<Leave>', empty_list_start_mouse_leave) self.btn_stst.bind('<Leave>', empty_list_start_leave)
else: else:
self.btn_stst.bind('<Enter>', start_mouse_enter) self.btn_stst.bind('<Enter>', start_enter)
self.btn_stst.bind('<Leave>', start_mouse_leave) self.btn_stst.bind('<Leave>', start_leave)
class ImportTunnel: # noinspection PyTypeChecker
class TLImp:
""" """
Import Class for Wireguard config Files. Import Class for Wireguard config Files.
Before importing, it is checked whether PrivateKey and PublicKey are in the file. Before importing, it is checked whether PrivateKey and PublicKey are in the file.
@ -285,6 +289,10 @@ class ImportTunnel:
def __init__(self): def __init__(self):
self.lb_rename = None
self.btn_tr = None
self.btn_exp = None
self.wg_autostart = None
self.select_tunnel = None self.select_tunnel = None
self.wg_switch = None self.wg_switch = None
self.btn_stst = None self.btn_stst = None
@ -293,7 +301,7 @@ class ImportTunnel:
self.a = None self.a = None
self.l_box = None self.l_box = None
def wg_import_select(self): def import_sl(self):
try: try:
filepath = filedialog.askopenfilename(initialdir=str(_u), title='Select Wireguard config File', filepath = filedialog.askopenfilename(initialdir=str(_u), title='Select Wireguard config File',
@ -303,11 +311,11 @@ class ImportTunnel:
read = file.read() read = file.read()
path_split = filepath.split('/') path_split = filepath.split('/')
path_split1 = path_split[-1] path_split1 = path_split[-1]
self.a = TunnelActiv.active() self.a = Tunnel.active()
if 'PrivateKey = ' in read and 'PublicKey = 'in read and 'Endpoint =' in read: if 'PrivateKey = ' in read and 'PublicKey = 'in read and 'Endpoint =' in read:
with open(filepath, 'r') as file: with open(filepath, 'r') as file:
key = ConToDict.covert_to_dict(file) key = Tunnel.con_to_dict(file)
pre_key = key[3] pre_key = key[3]
if len(pre_key) != 0: if len(pre_key) != 0:
with open('/etc/wire_py/.keys', 'r') as readfile: with open('/etc/wire_py/.keys', 'r') as readfile:
@ -330,8 +338,8 @@ class ImportTunnel:
os.rename(p1, Path('/etc/wire_py') / str(path_split)) os.rename(p1, Path('/etc/wire_py') / str(path_split))
new_conf = '/etc/wire_py/' + path_split new_conf = '/etc/wire_py/' + path_split
if self.a != '': if self.a != '':
check_call(['nmcli', 'connection', 'down', TunnelActiv.active()]) check_call(['nmcli', 'connection', 'down', Tunnel.active()])
ShowAddress.label_empty(self) Tunnel.label_empty(self)
subprocess.check_output(['nmcli', 'connection', 'import', 'type', subprocess.check_output(['nmcli', 'connection', 'import', 'type',
'wireguard', 'file', new_conf], text=True) 'wireguard', 'file', new_conf], text=True)
@ -339,30 +347,101 @@ class ImportTunnel:
else: else:
shutil.copy(filepath, Path('/etc/wire_py/')) shutil.copy(filepath, Path('/etc/wire_py/'))
if self.a != '': if self.a != '':
check_call(['nmcli', 'connection', 'down', TunnelActiv.active()]) check_call(['nmcli', 'connection', 'down', Tunnel.active()])
ShowAddress.label_empty(self) Tunnel.label_empty(self)
subprocess.check_output(['nmcli', 'connection', 'import', 'type', subprocess.check_output(['nmcli', 'connection', 'import', 'type',
'wireguard', 'file', filepath], text=True) 'wireguard', 'file', filepath], text=True)
self.StrVar.set('') self.StrVar.set('')
self.a = TunnelActiv.active() self.a = Tunnel.active()
self.l_box.insert(0, self.a) 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.update()
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 = tk.StringVar()
self.StrVar.set(self.a) self.StrVar.set(self.a)
GreenLabel.green_show_label(self) Tunnel.color(self)
StartStopBTN.button_stop(self) StSt.stop(self)
wg_read = Path('/etc/wire_py') / str(self.a + '.conf') wg_read = Path('/etc/wire_py') / str(self.a + '.conf')
with open(wg_read, 'r') as file_for_key: with open(wg_read, 'r') as file_for_key:
data = ConToDict.covert_to_dict(file_for_key) data = Tunnel.con_to_dict(file_for_key)
''' Address Label ''' ''' Address Label '''
ShowAddress.init_and_report(self, data) Tunnel.init_and_report(self, data)
ShowAddress.show_data(self) Tunnel.show_data(self)
check_call(['nmcli', 'con', 'mod', self.a, 'connection.autoconnect', 'no']) check_call(['nmcli', 'con', 'mod', self.a, 'connection.autoconnect', 'no'])
Path.chmod(wg_read, 0o600) Path.chmod(wg_read, 0o600)
if 'PrivateKey = ' and 'Endpoint = ' not in read: if 'PrivateKey = ' and 'Endpoint = ' not in read:
"""img_w, img_i, w_title, w_txt hand over""" """img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/error.png' iw = r'/usr/share/icons/wp-icons/64/error.png'
@ -382,6 +461,7 @@ class ImportTunnel:
print('Tunnel exist!') print('Tunnel exist!')
# noinspection PyTypeChecker
class FrameWidgets(ttk.Frame): class FrameWidgets(ttk.Frame):
def __init__(self, container, **kwargs): def __init__(self, container, **kwargs):
super().__init__(container, **kwargs) super().__init__(container, **kwargs)
@ -403,7 +483,7 @@ class FrameWidgets(ttk.Frame):
self.warning_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/64/error.png') self.warning_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/64/error.png')
''' Show active Tunnel ''' ''' Show active Tunnel '''
self.a = TunnelActiv.active() self.a = Tunnel.active()
''' Label Frame 1 ''' ''' Label Frame 1 '''
self.lb_frame_btn_lbox = ttk.Frame(self) self.lb_frame_btn_lbox = ttk.Frame(self)
@ -436,7 +516,7 @@ class FrameWidgets(ttk.Frame):
''' Label to Show active Tunnel ''' ''' Label to Show active Tunnel '''
self.StrVar = tk.StringVar(value=self.a) self.StrVar = tk.StringVar(value=self.a)
GreenLabel.green_show_label(self) Tunnel.color(self)
''' Interface Label ''' ''' Interface Label '''
self.interface = ttk.Label(self.lb_frame, text='Interface') self.interface = ttk.Label(self.lb_frame, text='Interface')
@ -450,21 +530,9 @@ class FrameWidgets(ttk.Frame):
''' Listbox with Scrollbar ''' ''' Listbox with Scrollbar '''
def enable_check_box(_):
def box_info_mouse_enter(event): if self.l_box.size() != 0:
""" 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 box_info_mouse_leave(event):
""" The mouse moves from the entry widget """
''' Remove Tool-Tip '''
window.my_tool_tip.destroy()
def enable_check_box(event):
if len(tl) != 0:
self.wg_autostart.configure(state='normal') self.wg_autostart.configure(state='normal')
self.lb_rename.config(state='normal') self.lb_rename.config(state='normal')
self.lb_rename.delete(0, tk.END) self.lb_rename.delete(0, tk.END)
@ -474,10 +542,6 @@ class FrameWidgets(ttk.Frame):
self.l_box = tk.Listbox(self.lb_frame_btn_lbox, selectmode='single') 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.config(relief='ridge', font=('Ubuntu', 12, 'bold'))
self.l_box.grid(column=1, rowspan=4, row=0, sticky='ns') self.l_box.grid(column=1, rowspan=4, row=0, sticky='ns')
tl = ListTunnels.tl_list()
if len(tl) == 0:
self.l_box.bind('<Enter>', box_info_mouse_enter)
self.l_box.bind('<Leave>', box_info_mouse_leave)
self.l_box.event_add('<<ClickEvent>>', '<Button-1>') self.l_box.event_add('<<ClickEvent>>', '<Button-1>')
self.l_box.bind('<<ClickEvent>>', enable_check_box) self.l_box.bind('<<ClickEvent>>', enable_check_box)
self.scrollbar = ttk.Scrollbar(self.lb_frame_btn_lbox, orient='vertical', command=self.l_box.yview) self.scrollbar = ttk.Scrollbar(self.lb_frame_btn_lbox, orient='vertical', command=self.l_box.yview)
@ -486,49 +550,76 @@ class FrameWidgets(ttk.Frame):
self.rowconfigure(0, weight=1) self.rowconfigure(0, weight=1)
''' Tunnel List ''' ''' Tunnel List '''
self.tl = ListTunnels.tl_list() self.tl = Tunnel.list()
for tunnels in self.tl: for tunnels in self.tl:
self.l_box.insert("end", tunnels) self.l_box.insert("end", tunnels)
self.l_box.update() self.l_box.update()
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 ''' ''' Button Vpn '''
if self.a != '': if self.a != '':
StartStopBTN.button_stop(self) StSt.stop(self)
wg_read = Path('/etc/wire_py') / str(self.a + '.conf') wg_read = Path('/etc/wire_py') / str(self.a + '.conf')
with open(wg_read, 'r') as file: with open(wg_read, 'r') as file:
data = ConToDict.covert_to_dict(file) data = Tunnel.con_to_dict(file)
''' Address Label ''' ''' Address Label '''
ShowAddress.init_and_report(self, data) Tunnel.init_and_report(self, data)
ShowAddress.show_data(self) Tunnel.show_data(self)
else: else:
StartStopBTN.button_start(self) StSt.start(self)
''' Address Label ''' ''' Address Label '''
self.add = tk.StringVar() self.add = tk.StringVar()
self.DNS = tk.StringVar() self.DNS = tk.StringVar()
self.enp = tk.StringVar() self.enp = tk.StringVar()
ShowAddress.label_empty(self) Tunnel.label_empty(self)
ShowAddress.show_data(self) Tunnel.show_data(self)
''' Button Import ''' ''' Button Import '''
self.btn_i = ttk.Button(self.lb_frame_btn_lbox, self.btn_i = ttk.Button(self.lb_frame_btn_lbox,
image=self.imp_pic, command=lambda: ImportTunnel.wg_import_select(self), image=self.imp_pic, command=lambda: TLImp.import_sl(self),
padding=0) padding=0)
self.btn_i.grid(column=0, row=1, padx=15, pady=8) self.btn_i.grid(column=0, row=1, padx=15, pady=8)
def import_mouse_enter(event): def imp_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to import a Wireguard Tunnel') 'Click to import a Wireguard Tunnel')
def import_mouse_leave(event): def imp_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.btn_i.bind('<Enter>', import_mouse_enter) self.btn_i.bind('<Enter>', imp_enter)
self.btn_i.bind('<Leave>', import_mouse_leave) self.btn_i.bind('<Leave>', imp_leave)
def delete(): def delete():
@ -536,7 +627,7 @@ class FrameWidgets(ttk.Frame):
self.select_tunnel = self.l_box.curselection() self.select_tunnel = self.l_box.curselection()
select_tl = self.l_box.get(self.select_tunnel[0]) select_tl = self.l_box.get(self.select_tunnel[0])
with open('/etc/wire_py/' + select_tl + '.conf', 'r+') as file2: with open('/etc/wire_py/' + select_tl + '.conf', 'r+') as file2:
key = ConToDict.covert_to_dict(file2) key = Tunnel.con_to_dict(file2)
pre_key = key[3] pre_key = key[3]
check_call(['nmcli', 'connection', 'delete', select_tl]) check_call(['nmcli', 'connection', 'delete', select_tl])
self.l_box.delete(self.select_tunnel[0]) self.l_box.delete(self.select_tunnel[0])
@ -546,7 +637,7 @@ class FrameWidgets(ttk.Frame):
if select_tl == a_con: if select_tl == a_con:
self.selected_option.set(0) self.selected_option.set(0)
self.autoconnect_var.set('no Autoconnect') self.autoconnect_var.set('no Autoconnect')
self.wg_autostart.configure(state='disabled')
Path.unlink(path_to_file) Path.unlink(path_to_file)
Path.unlink(Path('/etc/wire_py') / str(select_tl + '.conf')) Path.unlink(Path('/etc/wire_py') / str(select_tl + '.conf'))
with open('/etc/wire_py/.keys', 'r') as readfile: with open('/etc/wire_py/.keys', 'r') as readfile:
@ -557,14 +648,39 @@ class FrameWidgets(ttk.Frame):
file_one = Path('/etc/wire_py/.keys2') file_one = Path('/etc/wire_py/.keys2')
file_two = file_one.with_name('.keys') file_two = file_one.with_name('.keys')
file_one.replace(file_two) file_one.replace(file_two)
self.wg_autostart.configure(state='disabled')
''' for disable checkbox when Listbox empty ''' ''' for disable checkbox when Listbox empty '''
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')
if len(tl) == 0: 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') self.wg_autostart.configure(state='disabled')
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: if self.a != '' and self.a == select_tl:
self.StrVar.set(value='') self.StrVar.set(value='')
StartStopBTN.button_start(self) StSt.start(self)
self.l_box.update() self.l_box.update()
''' Address Label ''' ''' Address Label '''
@ -572,9 +688,10 @@ class FrameWidgets(ttk.Frame):
self.DNS.set('') self.DNS.set('')
self.enp.set('') self.enp.set('')
return select_tl return select_tl
except IndexError: except IndexError:
if len(tl) != 0: if self.l_box.size() != 0:
"""img_w, img_i, w_title, w_txt hand over""" """img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png' iw = r'/usr/share/icons/wp-icons/64/info.png'
@ -597,94 +714,96 @@ class FrameWidgets(ttk.Frame):
style='CButton.TButton') style='CButton.TButton')
self.btn_tr.grid(column=0, row=2, padx=15, pady=8) self.btn_tr.grid(column=0, row=2, padx=15, pady=8)
def empty_list_del_mouse_enter(event): def empty_list_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'No tunnels to delete in the list') 'No tunnels to delete in the list')
def empty_list_del_mouse_leave(event): def empty_list_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
def delete_mouse_enter(event): def del_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'Click to delete a Wireguard Tunnel\nSelect from the list!') 'Click to delete a Wireguard Tunnel\nSelect from the list!')
def delete_mouse_leave(event): def del_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
if len(tl) == 0: if self.l_box.size() == 0:
self.btn_tr.bind('<Enter>', empty_list_del_mouse_enter) self.btn_tr.bind('<Enter>', empty_list_enter)
self.btn_tr.bind('<Leave>', empty_list_del_mouse_leave) self.btn_tr.bind('<Leave>', empty_list_leave)
else: else:
self.btn_tr.bind('<Enter>', delete_mouse_enter) self.btn_tr.bind('<Enter>', del_enter)
self.btn_tr.bind('<Leave>', delete_mouse_leave) self.btn_tr.bind('<Leave>', del_leave)
''' Button Export ''' ''' Button Export '''
self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic, command=ExportTunnels.wg_export, self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic, command=Tunnel.export,
padding=0) padding=0)
self.btn_exp.grid(column=0, row=3, padx=15, pady=8) self.btn_exp.grid(column=0, row=3, padx=15, pady=8)
def empty_list_mouse_enter(event): def empty_list_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'No Tunnels in List for Export') 'No Tunnels in List for Export')
def empty_list_mouse_leave(event): def empty_list_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
def export_mouse_enter(event): def exp_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
' Click to export all\nWireguard Tunnel to Zipfile') ' Click to export all\nWireguard Tunnel to Zipfile')
def export_mouse_leave(event): def exp_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
if len(tl) == 0: if self.l_box.size() == 0:
self.btn_exp.bind('<Enter>', empty_list_mouse_enter) self.btn_exp.bind('<Enter>', empty_list_enter)
self.btn_exp.bind('<Leave>', empty_list_mouse_leave) self.btn_exp.bind('<Leave>', empty_list_leave)
else: else:
self.btn_exp.bind('<Enter>', export_mouse_enter) self.btn_exp.bind('<Enter>', exp_enter)
self.btn_exp.bind('<Leave>', export_mouse_leave) self.btn_exp.bind('<Leave>', exp_leave)
''' Label Entry ''' ''' Label Entry '''
self.lb_rename = ttk.Entry(self, width=20) 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.grid(column=2, row=4, padx=30, pady=15, sticky='nw')
self.lb_rename.insert(0, 'Max. 12 characters!') self.lb_rename.insert(0, 'Max. 12 characters!')
self.lb_rename.config(state='disable') self.lb_rename.config(state='disable')
def rename_mouse_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_no_active_mouse_leave(event): def rename_no_active_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
def rename_no_active_mouse_enter(event): def rename_no_active_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To rename a tunnel, at least one must be in the list') 'To rename a tunnel, at least one must be in the list')
def rename_mouse_leave(event): 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 """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
if len(tl) != 0:
self.lb_rename.bind('<Enter>', rename_mouse_enter) if self.l_box.size() != 0:
self.lb_rename.bind('<Leave>', rename_mouse_leave) self.lb_rename.bind('<Enter>', rename_enter)
self.lb_rename.bind('<Leave>', rename_leave)
else: else:
self.lb_rename.bind('<Enter>', rename_no_active_mouse_enter) self.lb_rename.bind('<Enter>', rename_no_active_enter)
self.lb_rename.bind('<Leave>', rename_no_active_mouse_leave) self.lb_rename.bind('<Leave>', rename_no_active_leave)
def tl_rename(): def tl_rename():
special_characters = ['\\', '/', '{', '}', ' '] special_characters = ['\\', '/', '{', '}', ' ']
@ -732,7 +851,7 @@ class FrameWidgets(ttk.Frame):
new_a_connect = self.lb_rename.get() new_a_connect = self.lb_rename.get()
self.lb_rename.delete(0, tk.END) self.lb_rename.delete(0, tk.END)
if self.a != '' and self.a == select_tl: if self.a != '' and self.a == select_tl:
self.a = TunnelActiv.active() self.a = Tunnel.active()
self.StrVar.set(value=self.a) self.StrVar.set(value=self.a)
if Path.is_file(Path('/etc/wire_py/wg_py')): if Path.is_file(Path('/etc/wire_py/wg_py')):
path_to_file = Path('/etc/wire_py') / 'wg_py' path_to_file = Path('/etc/wire_py') / 'wg_py'
@ -740,6 +859,7 @@ class FrameWidgets(ttk.Frame):
if select_tl == a_con: if select_tl == a_con:
self.autoconnect_var.set(value=new_a_connect) self.autoconnect_var.set(value=new_a_connect)
Path.write_text(path_to_file, new_a_connect) Path.write_text(path_to_file, new_a_connect)
return select_tl return select_tl
except IndexError: except IndexError:
@ -770,82 +890,98 @@ class FrameWidgets(ttk.Frame):
variable=self.selected_option, variable=self.selected_option,
command=lambda: FileHandle.box_set(self)) command=lambda: FileHandle.box_set(self))
self.wg_autostart.grid(column=0, row=4, pady=15, padx=15, sticky='nw') self.wg_autostart.grid(column=0, row=4, pady=15, padx=15, sticky='nw')
def chk_mouse_enter(event): def chk_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'You must have at least one\n' 'You must have at least one\n'
'tunnel in the list,to use the autostart') 'tunnel in the list,to use the autostart')
def chk_mouse_leave(event): def chk_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
if len(tl) == 0: if self.l_box.size() >= 1 and len(self.l_box.curselection()) >= 1:
self.wg_autostart.bind('<Enter>', chk_mouse_enter)
self.wg_autostart.bind('<Leave>', chk_mouse_leave) 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: else:
def chk_a_mouse_enter(event): def chk_a_enter(event):
""" The mouse moves into the entry widget """ """ The mouse moves into the entry widget """
window.my_tool_tip = MyToolTip(event.x_root, event.y_root, window.my_tool_tip = MyToolTip(event.x_root, event.y_root,
'To use the autostart, a tunnel must be selected from the list') 'To use the autostart, a tunnel must be selected from the list')
def chk_a_mouse_leave(event): def chk_a_leave(_):
""" The mouse moves from the entry widget """ """ The mouse moves from the entry widget """
''' Remove Tool-Tip ''' ''' Remove Tool-Tip '''
window.my_tool_tip.destroy() window.my_tool_tip.destroy()
self.wg_autostart.bind('<Enter>', chk_a_mouse_enter) self.wg_autostart.bind('<Enter>', chk_a_enter)
self.wg_autostart.bind('<Leave>', chk_a_mouse_leave) self.wg_autostart.bind('<Leave>', chk_a_leave)
OnOff.on_off(self) OnOff.on_off(self)
def wg_switch(self): def wg_switch(self):
self.a = TunnelActiv.active() self.a = Tunnel.active()
try: try:
if self.a == '': if self.a == '':
StartStopBTN.button_start(self) StSt.start(self)
self.select_tunnel = self.l_box.curselection() self.select_tunnel = self.l_box.curselection()
select_tl = self.l_box.get(self.select_tunnel[0]) select_tl = self.l_box.get(self.select_tunnel[0])
check_call(['nmcli', 'connection', 'up', select_tl]) check_call(['nmcli', 'connection', 'up', select_tl])
wg_read = Path('/etc/wire_py') / str(select_tl + '.conf') wg_read = Path('/etc/wire_py') / str(select_tl + '.conf')
with open(wg_read, 'r') as file: with open(wg_read, 'r') as file:
data = ConToDict.covert_to_dict(file) data = Tunnel.con_to_dict(file)
''' Address Label ''' ''' Address Label '''
ShowAddress.init_and_report(self, data) Tunnel.init_and_report(self, data)
ShowAddress.show_data(self) Tunnel.show_data(self)
''' Button Start/Stop ''' ''' Button Start/Stop '''
StartStopBTN.button_stop(self) StSt.stop(self)
self.a = TunnelActiv.active() self.a = Tunnel.active()
self.StrVar = tk.StringVar() self.StrVar = tk.StringVar()
self.StrVar.set(self.a) self.StrVar.set(self.a)
GreenLabel.green_show_label(self) Tunnel.color(self)
elif self.a != '': elif self.a != '':
''' Button Start/Stop ''' ''' Button Start/Stop '''
StartStopBTN.button_stop(self) StSt.stop(self)
check_call(['nmcli', 'connection', 'down', self.a]) check_call(['nmcli', 'connection', 'down', self.a])
''' Button Start/Stop ''' ''' Button Start/Stop '''
StartStopBTN.button_start(self) StSt.start(self)
self.a = TunnelActiv.active() self.a = Tunnel.active()
self.StrVar.set('') self.StrVar.set('')
GreenLabel.green_show_label(self) Tunnel.color(self)
''' Address Label ''' ''' Address Label '''
self.add.set('') self.add.set('')
self.DNS.set('') self.DNS.set('')
self.enp.set('') self.enp.set('')
ShowAddress.show_data(self) Tunnel.show_data(self)
except IndexError: except IndexError:
tl = ListTunnels.tl_list() if self.l_box.size() != 0:
if len(tl) != 0:
"""img_w, img_i, w_title, w_txt hand over""" """img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/wp-icons/64/info.png' iw = r'/usr/share/icons/wp-icons/64/info.png'
@ -865,11 +1001,14 @@ class FrameWidgets(ttk.Frame):
class MyToolTip(tk.Toplevel): class MyToolTip(tk.Toplevel):
TIP_X_OFFSET = 8 TIP_X_OFFSET = 20
TIP_Y_OFFSET = 8 TIP_Y_OFFSET = 20
AUTO_CLEAR_TIME = 10 # Millisecond. (1/100 sec.) 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=False): def __init__(self, x_pos, y_pos, message=None, auto_clear=True):
self.x_pos = x_pos self.x_pos = x_pos
self.y_pos = y_pos self.y_pos = y_pos
self.message = message self.message = message
@ -878,7 +1017,7 @@ class MyToolTip(tk.Toplevel):
tk.Toplevel.__init__(self) tk.Toplevel.__init__(self)
self.overrideredirect(True) self.overrideredirect(True)
self.message_label = ttk.Label(self, compound='left', text=self.message, padding=4) self.message_label = ttk.Label(self, compound='left', text=self.message, padding=6)
self.message_label.pack() self.message_label.pack()
self.geometry("+%d+%d" % (self.x_pos + self.TIP_X_OFFSET, self.geometry("+%d+%d" % (self.x_pos + self.TIP_X_OFFSET,