Merge pull request '1.10.2124' (#21) from 1.10.2124 into main
Reviewed-on: https://git.ilunix.de/punix/Wire-Py/pulls/21
This commit is contained in:
commit
3102c685fd
@ -4,9 +4,13 @@
|
|||||||
<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=" - Add Options, Help, Update Label and Update Menubutton - Theme now separate Light and Dark - Add Own Tooltip (Class and def's) Part One">
|
<list default="true" id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment=" - Fix a ConToDict Class when Endpoint not in Wireguard config file">
|
||||||
<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$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="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" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@ -29,6 +33,10 @@
|
|||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
<option name="UPDATE_TYPE" value="REBASE" />
|
<option name="UPDATE_TYPE" value="REBASE" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="HighlightingSettingsPerFile">
|
||||||
|
<setting file="file://$PROJECT_DIR$/wg_func.py" root0="SKIP_INSPECTION" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/wg_main.py" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
</component>
|
||||||
<component name="ProjectColorInfo">{
|
<component name="ProjectColorInfo">{
|
||||||
"associatedIndex": 3
|
"associatedIndex": 3
|
||||||
}</component>
|
}</component>
|
||||||
@ -596,4 +604,20 @@
|
|||||||
<MESSAGE value=" - Add Options, Help, Update Label and Update Menubutton - Theme now separate Light and Dark" />
|
<MESSAGE value=" - Add Options, Help, Update Label and Update Menubutton - Theme now separate Light and Dark" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value=" - Add Options, Help, Update Label and Update Menubutton - Theme now separate Light and Dark" />
|
<option name="LAST_COMMIT_MESSAGE" value=" - Add Options, Help, Update Label and Update Menubutton - Theme now separate Light and Dark" />
|
||||||
</component>
|
</component>
|
||||||
|
<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>
|
||||||
</project>
|
</project>
|
@ -11,6 +11,13 @@ My standard System: Linux Mint 22 Cinnamon
|
|||||||
- for loops with lists replaced by List Comprehensions
|
- for loops with lists replaced by List Comprehensions
|
||||||
- Keeping Classes Together
|
- Keeping Classes Together
|
||||||
|
|
||||||
|
|
||||||
|
### Added
|
||||||
|
21-10-2024
|
||||||
|
|
||||||
|
- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip
|
||||||
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
19-10-2024
|
19-10-2024
|
||||||
|
|
||||||
|
23
README.md
23
README.md
@ -1,2 +1,25 @@
|
|||||||
# Wire-Py
|
# Wire-Py
|
||||||
|
|
||||||
|
Wire-Py is an easy-to-use Gui for nmcli.
|
||||||
|
|
||||||
|
Before the first use of Wire-Py, all previous tunnels with "nmcli connection delete example" should be removed.
|
||||||
|
|
||||||
|
Wire-Py can easily be imported, exported, started, popped as well as renamed and deleted.
|
||||||
|
|
||||||
|
Wire-Py runs on many distros.
|
||||||
|
Tested on Arch Linux, OpenSuse Tumbleweed,
|
||||||
|
Fedora, Debian12, Linux Mint 22 Cinnamon
|
||||||
|
|
||||||
|
With the desktops:
|
||||||
|
Xfce4, Cinnamon, Kde, and Mate, LXDE, LXQT
|
||||||
|
|
||||||
|
|
||||||
|
# Screenshots
|
||||||
|
[![wire-py.png](https://fb.ilunix.de/api/public/dl/0cx7pPYK?inline=true)](https://fb.ilunix.de/share/0cx7pPYK)
|
||||||
|
|
||||||
|
# Instruction
|
||||||
|
|
||||||
|
[![Import.png](https://fb.ilunix.de/api/public/dl/VpYEn3Gz?inline=true)](https://fb.ilunix.de/share/VpYEn3Gz)
|
||||||
|
[![Stop.png](https://fb.ilunix.de/api/public/dl/zBnbIiyD?inline=true)](https://fb.ilunix.de/share/zBnbIiyD)
|
||||||
|
[![export.png](https://fb.ilunix.de/api/public/dl/gMc4-NAj?inline=true)](https://fb.ilunix.de/share/gMc4-NAj)
|
||||||
|
[![rename.png](https://fb.ilunix.de/api/public/dl/v0y_WiqV?inline=true)](https://fb.ilunix.de/share/v0y_WiqV)
|
159
wg_func.py
159
wg_func.py
@ -8,12 +8,12 @@ import zipfile
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
from tkinter import filedialog, ttk
|
from tkinter import ttk
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
''' 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year '''
|
''' 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year '''
|
||||||
version = 'v. 1.10.2024'
|
version = 'v. 1.10.2124'
|
||||||
|
|
||||||
path_to_file = Path('/etc/wire_py/wg_py')
|
path_to_file = Path('/etc/wire_py/wg_py')
|
||||||
path_to_file2 = Path('/etc/wire_py/settings')
|
path_to_file2 = Path('/etc/wire_py/settings')
|
||||||
@ -135,25 +135,6 @@ class GreenLabel:
|
|||||||
def rowconfigure(self, param, weight):
|
def rowconfigure(self, param, weight):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class StartStopBTN:
|
|
||||||
"""
|
|
||||||
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')
|
|
||||||
|
|
||||||
def button_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)
|
|
||||||
|
|
||||||
def button_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)
|
|
||||||
|
|
||||||
class ConToDict:
|
class ConToDict:
|
||||||
"""
|
"""
|
||||||
@ -281,117 +262,6 @@ class ListTunnels:
|
|||||||
return tl
|
return tl
|
||||||
|
|
||||||
|
|
||||||
class ImportTunnel:
|
|
||||||
"""
|
|
||||||
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):
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def wg_import_select(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]
|
|
||||||
self.a = TunnelActiv.active()
|
|
||||||
|
|
||||||
if 'PrivateKey = ' in read and 'PublicKey = 'in read and 'Endpoint =' in read:
|
|
||||||
with open(filepath, 'r') as file:
|
|
||||||
key = ConToDict.covert_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 != '':
|
|
||||||
check_call(['nmcli', 'connection', 'down', TunnelActiv.active()])
|
|
||||||
ShowAddress.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 != '':
|
|
||||||
check_call(['nmcli', 'connection', 'down', TunnelActiv.active()])
|
|
||||||
ShowAddress.label_empty(self)
|
|
||||||
|
|
||||||
subprocess.check_output(['nmcli', 'connection', 'import', 'type',
|
|
||||||
'wireguard', 'file', filepath], text=True)
|
|
||||||
|
|
||||||
self.StrVar.set('')
|
|
||||||
self.a = TunnelActiv.active()
|
|
||||||
self.l_box.insert(0, self.a)
|
|
||||||
self.l_box.update()
|
|
||||||
self.StrVar = tk.StringVar()
|
|
||||||
self.StrVar.set(self.a)
|
|
||||||
GreenLabel.green_show_label(self)
|
|
||||||
StartStopBTN.button_stop(self)
|
|
||||||
wg_read = Path('/etc/wire_py') / str(self.a + '.conf')
|
|
||||||
with open(wg_read, 'r') as file_for_key:
|
|
||||||
data = ConToDict.covert_to_dict(file_for_key)
|
|
||||||
|
|
||||||
''' Address Label '''
|
|
||||||
ShowAddress.init_and_report(self, data)
|
|
||||||
ShowAddress.show_data(self)
|
|
||||||
check_call(['nmcli', 'con', 'mod', self.a, 'connection.autoconnect', 'no'])
|
|
||||||
Path.chmod(wg_read, 0o600)
|
|
||||||
|
|
||||||
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!')
|
|
||||||
|
|
||||||
|
|
||||||
class FileHandle:
|
class FileHandle:
|
||||||
"""
|
"""
|
||||||
This class will display the autostart label which
|
This class will display the autostart label which
|
||||||
@ -527,29 +397,4 @@ class ExportTunnels:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MyToolTip(tk.Toplevel):
|
|
||||||
TIP_X_OFFSET = 8
|
|
||||||
TIP_Y_OFFSET = 8
|
|
||||||
AUTO_CLEAR_TIME = 10 # Millisecond. (1/100 sec.)
|
|
||||||
|
|
||||||
def __init__(self, x_pos, y_pos, message=None, auto_clear=False):
|
|
||||||
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)
|
|
||||||
|
|
||||||
self.message_label = ttk.Label(self, compound='left', text=self.message, padding=4)
|
|
||||||
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()
|
|
||||||
|
155
wg_main.py
155
wg_main.py
@ -1,14 +1,16 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from select import select
|
from pathlib import Path
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
from tkinter import *
|
from tkinter import *
|
||||||
from pathlib import Path
|
from tkinter import filedialog, ttk
|
||||||
from tkinter import ttk
|
|
||||||
from wg_func import (TunnelActiv, ListTunnels, ImportTunnel, ConToDict, GreenLabel, ShowAddress, FileHandle,
|
from wg_func import (TunnelActiv, ListTunnels, ConToDict, GreenLabel, ShowAddress, FileHandle,
|
||||||
ExportTunnels, OnOff, msg_window, WirePyUpdate, res, version, path_to_file2,
|
ExportTunnels, OnOff, msg_window, WirePyUpdate, res, _u, version, path_to_file2,
|
||||||
path_to_file3, MyToolTip)
|
path_to_file3)
|
||||||
|
|
||||||
tcl_path = Path('/usr/share/TK-Themes')
|
tcl_path = Path('/usr/share/TK-Themes')
|
||||||
|
|
||||||
@ -269,6 +271,117 @@ class StartStopBTN:
|
|||||||
self.btn_stst.bind('<Leave>', start_mouse_leave)
|
self.btn_stst.bind('<Leave>', start_mouse_leave)
|
||||||
|
|
||||||
|
|
||||||
|
class ImportTunnel:
|
||||||
|
"""
|
||||||
|
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):
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def wg_import_select(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]
|
||||||
|
self.a = TunnelActiv.active()
|
||||||
|
|
||||||
|
if 'PrivateKey = ' in read and 'PublicKey = 'in read and 'Endpoint =' in read:
|
||||||
|
with open(filepath, 'r') as file:
|
||||||
|
key = ConToDict.covert_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 != '':
|
||||||
|
check_call(['nmcli', 'connection', 'down', TunnelActiv.active()])
|
||||||
|
ShowAddress.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 != '':
|
||||||
|
check_call(['nmcli', 'connection', 'down', TunnelActiv.active()])
|
||||||
|
ShowAddress.label_empty(self)
|
||||||
|
|
||||||
|
subprocess.check_output(['nmcli', 'connection', 'import', 'type',
|
||||||
|
'wireguard', 'file', filepath], text=True)
|
||||||
|
|
||||||
|
self.StrVar.set('')
|
||||||
|
self.a = TunnelActiv.active()
|
||||||
|
self.l_box.insert(0, self.a)
|
||||||
|
self.l_box.update()
|
||||||
|
self.StrVar = tk.StringVar()
|
||||||
|
self.StrVar.set(self.a)
|
||||||
|
GreenLabel.green_show_label(self)
|
||||||
|
StartStopBTN.button_stop(self)
|
||||||
|
wg_read = Path('/etc/wire_py') / str(self.a + '.conf')
|
||||||
|
with open(wg_read, 'r') as file_for_key:
|
||||||
|
data = ConToDict.covert_to_dict(file_for_key)
|
||||||
|
|
||||||
|
''' Address Label '''
|
||||||
|
ShowAddress.init_and_report(self, data)
|
||||||
|
ShowAddress.show_data(self)
|
||||||
|
check_call(['nmcli', 'con', 'mod', self.a, 'connection.autoconnect', 'no'])
|
||||||
|
Path.chmod(wg_read, 0o600)
|
||||||
|
|
||||||
|
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!')
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
@ -751,6 +864,34 @@ class FrameWidgets(ttk.Frame):
|
|||||||
msg_window(iw, ii, wt, msg_t)
|
msg_window(iw, ii, wt, msg_t)
|
||||||
|
|
||||||
|
|
||||||
|
class MyToolTip(tk.Toplevel):
|
||||||
|
TIP_X_OFFSET = 8
|
||||||
|
TIP_Y_OFFSET = 8
|
||||||
|
AUTO_CLEAR_TIME = 10 # Millisecond. (1/100 sec.)
|
||||||
|
|
||||||
|
def __init__(self, x_pos, y_pos, message=None, auto_clear=False):
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.message_label = ttk.Label(self, compound='left', text=self.message, padding=4)
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
window = MainWindow()
|
window = MainWindow()
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user