Compare commits
13 Commits
21-04-2025
...
2311661735
Author | SHA1 | Date | |
---|---|---|---|
2311661735 | |||
c10667ec21 | |||
08bef8fe6e | |||
2e94a324a6 | |||
18ed97bf20 | |||
5dcfc91621 | |||
5fb4e68867 | |||
19d413ea97 | |||
213f772f40 | |||
6f02724daa | |||
53f66ea76d | |||
3039dbecb0 | |||
eadc2a06bf |
44
.idea/workspace.xml
generated
44
.idea/workspace.xml
generated
@ -5,7 +5,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment=" - Update Translate Files">
|
<list default="true" id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment=" - Update Translate Files">
|
||||||
<change beforePath="$PROJECT_DIR$/cls_mth_fc.py" beforeDir="false" afterPath="$PROJECT_DIR$/cls_mth_fc.py" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/wirepy.py" beforeDir="false" afterPath="$PROJECT_DIR$/wirepy.py" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/wirepy.py" beforeDir="false" afterPath="$PROJECT_DIR$/wirepy.py" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
@ -43,28 +43,28 @@
|
|||||||
<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[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||||
"Python.INSTALL.executor": "Run",
|
"Python.INSTALL.executor": "Run",
|
||||||
"Python.cls_mth_fc.executor": "Run",
|
"Python.cls_mth_fc.executor": "Run",
|
||||||
"Python.install.executor": "Run",
|
"Python.install.executor": "Run",
|
||||||
"Python.main.executor": "Run",
|
"Python.main.executor": "Run",
|
||||||
"Python.messagebox.executor": "Run",
|
"Python.messagebox.executor": "Run",
|
||||||
"Python.start_wg.executor": "Run",
|
"Python.start_wg.executor": "Run",
|
||||||
"Python.testtheme.executor": "Run",
|
"Python.testtheme.executor": "Run",
|
||||||
"Python.wg_func.executor": "Run",
|
"Python.wg_func.executor": "Run",
|
||||||
"Python.wg_main.executor": "Run",
|
"Python.wg_main.executor": "Run",
|
||||||
"Python.wirepy.executor": "Run",
|
"Python.wirepy.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"Shell Script.install.executor": "Run",
|
"Shell Script.install.executor": "Run",
|
||||||
"Shell Script.run_as.executor": "Run",
|
"Shell Script.run_as.executor": "Run",
|
||||||
"git-widget-placeholder": "21-04-2025-new-tooltip",
|
"git-widget-placeholder": "28-04-2025-more-methods-and-optimize-methods",
|
||||||
"last_opened_file_path": "/home/punix/Pyapps/wire-py",
|
"last_opened_file_path": "/home/punix/Pyapps/wire-py",
|
||||||
"settings.editor.selected.configurable": "ml.llm.LLMConfigurable"
|
"settings.editor.selected.configurable": "ml.llm.LLMConfigurable"
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$/lx-icons" />
|
<recent name="$PROJECT_DIR$/lx-icons" />
|
||||||
|
@ -41,7 +41,7 @@ My standard System: Linux Mint 22 Cinnamon
|
|||||||
|
|
||||||
- Fix ipv6 in Config File on import
|
- Fix ipv6 in Config File on import
|
||||||
- Wirepy run now as user
|
- Wirepy run now as user
|
||||||
- settings, keys and Config Files now in ~/.config/wire_py
|
- settings, AppConfig.KEYS_FILE and Config Files now in ~/.config/wire_py
|
||||||
- For new users, the required files are created and autostart service is started.
|
- For new users, the required files are created and autostart service is started.
|
||||||
- Tunnels are now read from the directory to view them in the list.
|
- Tunnels are now read from the directory to view them in the list.
|
||||||
To display only own tunnels, and read errors are minimized.
|
To display only own tunnels, and read errors are minimized.
|
||||||
|
Binary file not shown.
BIN
__pycache__/wp_app_config.cpython-312.pyc
Normal file
BIN
__pycache__/wp_app_config.cpython-312.pyc
Normal file
Binary file not shown.
@ -14,16 +14,11 @@ from datetime import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import check_call, CompletedProcess
|
from subprocess import check_call, CompletedProcess
|
||||||
from tkinter import ttk, Toplevel
|
from tkinter import ttk, Toplevel
|
||||||
|
from wp_app_config import AppConfig, Msg
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
APP = "wirepy"
|
# Translate
|
||||||
LOCALE_DIR = "/usr/share/locale/"
|
_ = AppConfig.setup_translations()
|
||||||
locale.bindtextdomain(APP, LOCALE_DIR)
|
|
||||||
gettext.bindtextdomain(APP, LOCALE_DIR)
|
|
||||||
gettext.textdomain(APP)
|
|
||||||
_ = gettext.gettext
|
|
||||||
|
|
||||||
|
|
||||||
class Create:
|
class Create:
|
||||||
"""
|
"""
|
||||||
@ -41,7 +36,7 @@ class Create:
|
|||||||
pth: Path = Path.home() / ".config/wire_py"
|
pth: Path = Path.home() / ".config/wire_py"
|
||||||
pth.mkdir(parents=True, exist_ok=True)
|
pth.mkdir(parents=True, exist_ok=True)
|
||||||
sett: Path = Path.home() / ".config/wire_py/settings"
|
sett: Path = Path.home() / ".config/wire_py/settings"
|
||||||
ks: Path = Path.home() / ".config/wire_py/keys"
|
AppConfig.KEYS_FILE
|
||||||
|
|
||||||
if sett.exists():
|
if sett.exists():
|
||||||
pass
|
pass
|
||||||
@ -50,11 +45,11 @@ class Create:
|
|||||||
sett.touch()
|
sett.touch()
|
||||||
sett.write_text("[UPDATES]\non\n[THEME]\nlight\n[TOOLTIP]\nTrue\n[AUTOSTART ON]\noff\n")
|
sett.write_text("[UPDATES]\non\n[THEME]\nlight\n[TOOLTIP]\nTrue\n[AUTOSTART ON]\noff\n")
|
||||||
|
|
||||||
if ks.exists():
|
if AppConfig.KEYS_FILE.exists():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
ks.touch()
|
AppConfig.KEYS_FILE.touch()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def files_for_autostart() -> None:
|
def files_for_autostart() -> None:
|
||||||
@ -80,11 +75,10 @@ class Create:
|
|||||||
def make_dir() -> None:
|
def make_dir() -> None:
|
||||||
"""Folder Name "tlecdewg" = Tunnel Encrypt Decrypt Wireguard"""
|
"""Folder Name "tlecdewg" = Tunnel Encrypt Decrypt Wireguard"""
|
||||||
|
|
||||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
if AppConfig.TEMP_DIR.exists():
|
||||||
if folder_path.exists():
|
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
folder_path.mkdir()
|
AppConfig.TEMP_DIR.mkdir()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def decrypt() -> None:
|
def decrypt() -> None:
|
||||||
@ -125,6 +119,31 @@ class LxTools(tk.Tk):
|
|||||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_file_name(path: Path, i: int = 5) -> List[str]:
|
||||||
|
"""
|
||||||
|
Recursively searches the specified path for files and returns a list of filenames,
|
||||||
|
with the last 'i' characters of each filename removed.
|
||||||
|
|
||||||
|
This method is useful for obtaining filenames without specific file extensions,
|
||||||
|
e.g., to remove '.conf' from Wireguard configuration files.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (Path): The directory path to search
|
||||||
|
i (int, optional): Number of characters to remove from the end of each filename.
|
||||||
|
Default is 5, which typically corresponds to the length of '.conf'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: A list of filenames without the last 'i' characters
|
||||||
|
|
||||||
|
Example:
|
||||||
|
If path contains files like 'tunnel1.conf', 'tunnel2.conf' and i=5,
|
||||||
|
the method returns ['tunnel1', 'tunnel2'].
|
||||||
|
"""
|
||||||
|
lists_file = list(path.rglob("*"))
|
||||||
|
lists_file = [conf_file.name[:-i] for conf_file in lists_file]
|
||||||
|
return lists_file
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def uos() -> None:
|
def uos() -> None:
|
||||||
"""
|
"""
|
||||||
@ -135,19 +154,18 @@ class LxTools(tk.Tk):
|
|||||||
"""
|
"""
|
||||||
log_name: str = f"{Path.home()}"[6:]
|
log_name: str = f"{Path.home()}"[6:]
|
||||||
file: Path = Path.home() / "/tmp/.log_user"
|
file: Path = Path.home() / "/tmp/.log_user"
|
||||||
with open(file, "w", encoding="utf-8") as f:
|
Path(file).write_text(log_name, encoding="utf-8")
|
||||||
f.write(log_name)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def clean_files(folder_path: Path = None, file: Path = None) -> None:
|
def clean_files(TEMP_DIR: Path = None, file: Path = None) -> None:
|
||||||
"""
|
"""
|
||||||
method that can be added after need to delete a folder and a file when quitting.
|
method that can be added after need to delete a folder and a file when quitting.
|
||||||
Args:
|
Args:
|
||||||
:param file: default None
|
:param file: default None
|
||||||
:param folder_path: default None
|
:param AppConfig.TEMP_DIR: default None
|
||||||
"""
|
"""
|
||||||
if folder_path is not None:
|
if AppConfig.TEMP_DIR is not None:
|
||||||
shutil.rmtree(folder_path)
|
shutil.rmtree(AppConfig.TEMP_DIR)
|
||||||
if file is not None:
|
if file is not None:
|
||||||
Path.unlink(file)
|
Path.unlink(file)
|
||||||
|
|
||||||
@ -156,14 +174,22 @@ class LxTools(tk.Tk):
|
|||||||
"""
|
"""
|
||||||
method that writes in file whether tooltip is displayed or not
|
method that writes in file whether tooltip is displayed or not
|
||||||
"""
|
"""
|
||||||
with open(path, "r", encoding="utf-8") as set_f2:
|
lines = Path(path).read_text(encoding="utf-8")
|
||||||
lines2 = set_f2.readlines()
|
if "False\n" in lines:
|
||||||
if "False\n" in lines2:
|
|
||||||
tip = False
|
tip = False
|
||||||
else:
|
else:
|
||||||
tip = True
|
tip = True
|
||||||
return tip
|
return tip
|
||||||
|
|
||||||
|
|
||||||
|
def theme_change(self) -> None:
|
||||||
|
|
||||||
|
lines = AppConfig.SETTINGS_FILE.read_text()
|
||||||
|
if "light\n" in lines:
|
||||||
|
self.tk.call("set_theme", "light")
|
||||||
|
else:
|
||||||
|
self.tk.call("set_theme", "dark")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def msg_window(img_w: str, img_i: str, w_title: str, w_txt: str, txt2: Optional[str] = None,
|
def msg_window(img_w: str, img_i: str, w_title: str, w_txt: str, txt2: Optional[str] = None,
|
||||||
com: Optional[str] = None) -> None:
|
com: Optional[str] = None) -> None:
|
||||||
@ -394,8 +420,8 @@ class Tunnel:
|
|||||||
"""
|
"""
|
||||||
Returns a list of Wireguard tunnel names
|
Returns a list of Wireguard tunnel names
|
||||||
"""
|
"""
|
||||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
AppConfig.TEMP_DIR: Path = Path("/tmp/tlecdcwg/")
|
||||||
wg_s: List[str] = os.listdir(folder_path)
|
wg_s: List[str] = os.listdir(AppConfig.TEMP_DIR)
|
||||||
|
|
||||||
return wg_s
|
return wg_s
|
||||||
|
|
||||||
@ -425,17 +451,15 @@ class Tunnel:
|
|||||||
with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf:
|
with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf:
|
||||||
if len(zf.namelist()) != 0:
|
if len(zf.namelist()) != 0:
|
||||||
|
|
||||||
msg_t: str = _("Your zip file is in home directory")
|
LxTools.msg_window(img_w, img_i, Msg.STR["exp_succ"], Msg.STR["exp_in_home"])
|
||||||
LxTools.msg_window(img_w, img_i, _("Export Successful"), msg_t)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
msg_t: str = _("Export failed! Please try again")
|
LxTools.msg_window(img_w2, img_i2, Msg.STR["exp_err"], Msg.STR["exp_try"])
|
||||||
LxTools.msg_window(img_w2, img_i2, _("Export error"), msg_t)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, sl, pfit)
|
LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["tl_first"])
|
||||||
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
@ -485,6 +509,7 @@ class Tooltip:
|
|||||||
label: tk.Label = tk.Label(tw, text=self.text, background="lightgreen", foreground="black", relief="solid",
|
label: tk.Label = tk.Label(tw, text=self.text, background="lightgreen", foreground="black", relief="solid",
|
||||||
borderwidth=1, padx=5, pady=5)
|
borderwidth=1, padx=5, pady=5)
|
||||||
label.grid()
|
label.grid()
|
||||||
|
self.tooltip_window.after(2200, lambda: tw.destroy())
|
||||||
|
|
||||||
def hide_tooltip(self, event: Optional[Any] = None) -> None:
|
def hide_tooltip(self, event: Optional[Any] = None) -> None:
|
||||||
"""
|
"""
|
||||||
|
10
install
10
install
@ -17,7 +17,7 @@ install_file_with(){
|
|||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
sudo apt install python3-tk && \
|
sudo apt install python3-tk && \
|
||||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
sudo cp -fv wirepy.py start_wg.py wp_app_config.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||||
@ -43,7 +43,7 @@ install_arch_d(){
|
|||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
sudo pacman -S --noconfirm tk python3 python-requests && \
|
sudo pacman -S --noconfirm tk python3 python-requests && \
|
||||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
sudo cp -fv wirepy.py start_wg.py wp_app_config.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||||
@ -120,7 +120,7 @@ install(){
|
|||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
sudo dnf install python3-tkinter -y
|
sudo dnf install python3-tkinter -y
|
||||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
sudo cp -fv wirepy.py start_wg.py wp_app_config.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||||
@ -145,7 +145,7 @@ install(){
|
|||||||
rm -r ~/.config/wire_py && rm -r ~/.config/systemd
|
rm -r ~/.config/wire_py && rm -r ~/.config/systemd
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
sudo cp -fv wirepy.py start_wg.py wp_app_config.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||||
@ -181,7 +181,7 @@ install(){
|
|||||||
|
|
||||||
remove(){
|
remove(){
|
||||||
sudo rm -f /usr/local/bin/wirepy /usr/local/bin/wirepy.py /usr/local/bin/start_wg.py \
|
sudo rm -f /usr/local/bin/wirepy /usr/local/bin/wirepy.py /usr/local/bin/start_wg.py \
|
||||||
/usr/local/bin/cls_mth_fc.py /usr/local/bin/ssl_encrypt.py /usr/local/bin/ssl_decrypt.py
|
/usr/local/bin/wp_app_config.py cls_mth_fc.py /usr/local/bin/ssl_encrypt.py /usr/local/bin/ssl_decrypt.py
|
||||||
if [ $? -ne 0 ]
|
if [ $? -ne 0 ]
|
||||||
then
|
then
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -5,14 +5,12 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
|
from wp_app_config import AppConfig
|
||||||
|
|
||||||
uname: Path = Path("/tmp/.log_user")
|
uname: Path = Path("/tmp/.log_user")
|
||||||
|
|
||||||
with open(uname, "r", encoding="utf-8") as f:
|
log_name = Path(uname).read_text(encoding="utf-8")
|
||||||
log_name = f.readline()
|
|
||||||
|
|
||||||
# Folder Name "tlecdewg" = Tunnel Encrypt Decrypt Wireguard
|
|
||||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
|
||||||
keyfile: Path = Path(f"/home/{log_name}/.config/wire_py/pbwgk.pem")
|
keyfile: Path = Path(f"/home/{log_name}/.config/wire_py/pbwgk.pem")
|
||||||
PKEYFILE: Path = "/usr/local/etc/ssl/pwgk.pem"
|
PKEYFILE: Path = "/usr/local/etc/ssl/pwgk.pem"
|
||||||
|
|
||||||
@ -21,15 +19,16 @@ if not keyfile.is_file():
|
|||||||
check_call(["openssl", "rsa", "-in", PKEYFILE, "-out", keyfile, "-outform", "PEM", "-pubout"])
|
check_call(["openssl", "rsa", "-in", PKEYFILE, "-out", keyfile, "-outform", "PEM", "-pubout"])
|
||||||
shutil.chown(keyfile, 1000, 1000)
|
shutil.chown(keyfile, 1000, 1000)
|
||||||
|
|
||||||
folder_path2 = f"/home/{log_name}/.config/wire_py/"
|
AppConfig.TEMP_DIR2 = f"/home/{log_name}/.config/wire_py/"
|
||||||
detl: list[str] = os.listdir(folder_path2)
|
detl: list[str] = os.listdir(AppConfig.TEMP_DIR2)
|
||||||
os.chdir(folder_path2)
|
os.chdir(AppConfig.TEMP_DIR2)
|
||||||
detl.remove("keys")
|
detl.remove("keys")
|
||||||
detl.remove("settings")
|
detl.remove("settings")
|
||||||
if os.path.exists(f"{folder_path2}pbwgk.pem"):
|
if os.path.exists(f"{AppConfig.TEMP_DIR2}pbwgk.pem"):
|
||||||
detl.remove("pbwgk.pem")
|
detl.remove("pbwgk.pem")
|
||||||
for detunnels in detl:
|
for detunnels in detl:
|
||||||
tlname2 = f"{detunnels[:-4]}.conf"
|
tlname2 = f"{detunnels[:-4]}.conf"
|
||||||
extpath = f"{folder_path}/{tlname2}"
|
extpath = f"{AppConfig.TEMP_DIR}/{tlname2}"
|
||||||
check_call(["openssl", "pkeyutl", "-decrypt", "-inkey", PKEYFILE, "-in", detunnels, "-out", extpath])
|
check_call(["openssl", "pkeyutl", "-decrypt", "-inkey", PKEYFILE, "-in", detunnels,
|
||||||
|
"-out", extpath])
|
||||||
shutil.chown(extpath, 1000, 1000)
|
shutil.chown(extpath, 1000, 1000)
|
||||||
|
@ -6,13 +6,13 @@ import shutil
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
|
|
||||||
|
from wp_app_config import AppConfig
|
||||||
|
|
||||||
uname: Path = Path("/tmp/.log_user")
|
uname: Path = Path("/tmp/.log_user")
|
||||||
|
|
||||||
with open(uname, "r", encoding="utf-8") as f:
|
log_name = Path(uname).read_text(encoding="utf-8")
|
||||||
log_name: str = f.readline()
|
|
||||||
|
|
||||||
keyfile: Path = Path(f"/home/{log_name}/.config/wire_py/pbwgk.pem")
|
keyfile: Path = Path(f"/home/{log_name}/.config/wire_py/pbwgk.pem")
|
||||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
|
||||||
PKEYFILE = "/usr/local/etc/ssl/pwgk.pem"
|
PKEYFILE = "/usr/local/etc/ssl/pwgk.pem"
|
||||||
|
|
||||||
if not keyfile.is_file():
|
if not keyfile.is_file():
|
||||||
@ -20,28 +20,28 @@ if not keyfile.is_file():
|
|||||||
check_call(["openssl", "rsa", "-in", PKEYFILE, "-out", keyfile, "-outform", "PEM", "-pubout"])
|
check_call(["openssl", "rsa", "-in", PKEYFILE, "-out", keyfile, "-outform", "PEM", "-pubout"])
|
||||||
shutil.chown(keyfile, 1000, 1000)
|
shutil.chown(keyfile, 1000, 1000)
|
||||||
|
|
||||||
if folder_path.exists():
|
if AppConfig.TEMP_DIR.exists():
|
||||||
tl = os.listdir(f"{folder_path}")
|
tl = os.listdir(f"{AppConfig.TEMP_DIR}")
|
||||||
CPTH: str = f"{keyfile}"
|
CPTH: str = f"{keyfile}"
|
||||||
CRYPTFILES: str = CPTH[:-9]
|
CRYPTFILES: str = CPTH[:-9]
|
||||||
|
|
||||||
if keyfile.exists() and len(tl) != 0:
|
if keyfile.exists() and len(tl) != 0:
|
||||||
for tunnels in tl:
|
for tunnels in tl:
|
||||||
sourcetl: str = f"{folder_path}/{tunnels}"
|
sourcetl: str = f"{AppConfig.TEMP_DIR}/{tunnels}"
|
||||||
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
|
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
|
||||||
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
|
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
|
||||||
tlname,])
|
tlname,])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if folder_path.exists():
|
if AppConfig.TEMP_DIR.exists():
|
||||||
tl: list[str] = os.listdir(f"{folder_path}")
|
tl: list[str] = os.listdir(f"{AppConfig.TEMP_DIR}")
|
||||||
CPTH: str = f"{keyfile}"
|
CPTH: str = f"{keyfile}"
|
||||||
CRYPTFILES: str = CPTH[:-9]
|
CRYPTFILES: str = CPTH[:-9]
|
||||||
|
|
||||||
if keyfile.exists() and len(tl) != 0:
|
if keyfile.exists() and len(tl) != 0:
|
||||||
for tunnels in tl:
|
for tunnels in tl:
|
||||||
sourcetl: str = f"{folder_path}/{tunnels}"
|
sourcetl: str = f"{AppConfig.TEMP_DIR}/{tunnels}"
|
||||||
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
|
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
|
||||||
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
|
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
|
||||||
tlname])
|
tlname])
|
||||||
|
@ -7,11 +7,8 @@ from subprocess import check_call
|
|||||||
|
|
||||||
path_to_file = Path(Path.home() / ".config/wire_py/settings")
|
path_to_file = Path(Path.home() / ".config/wire_py/settings")
|
||||||
|
|
||||||
with open(path_to_file, "r", encoding="utf-8") as a_con:
|
a_con = Path(path_to_file).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
|
a_con = a_con[7].strip()
|
||||||
# This function is for the independent autostarted of the previously selected tunnel
|
|
||||||
lines = a_con.readlines()
|
|
||||||
a_con = lines[7].strip()
|
|
||||||
if a_con != "off":
|
if a_con != "off":
|
||||||
check_call(["nmcli", "connection", "up", a_con])
|
check_call(["nmcli", "connection", "up", a_con])
|
||||||
else:
|
else:
|
||||||
|
670
wirepy.py
670
wirepy.py
@ -15,73 +15,53 @@ from subprocess import check_call
|
|||||||
from tkinter import TclError, filedialog, ttk
|
from tkinter import TclError, filedialog, ttk
|
||||||
|
|
||||||
from cls_mth_fc import (Create, GiteaUpdate, Tooltip, Tunnel, LxTools)
|
from cls_mth_fc import (Create, GiteaUpdate, Tooltip, Tunnel, LxTools)
|
||||||
|
from wp_app_config import AppConfig, Msg
|
||||||
|
|
||||||
LxTools.uos()
|
LxTools.uos()
|
||||||
Create.dir_and_files()
|
Create.dir_and_files()
|
||||||
Create.make_dir()
|
Create.make_dir()
|
||||||
Create.decrypt()
|
Create.decrypt()
|
||||||
|
|
||||||
tcl_path: Path = Path("/usr/share/TK-Themes")
|
tips = LxTools.if_tip(AppConfig.SETTINGS_FILE)
|
||||||
set_file: Path = Path(Path.home() / ".config/wire_py/settings")
|
|
||||||
tips = LxTools.if_tip(set_file)
|
|
||||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
|
||||||
user_file = Path("/tmp/.log_user")
|
|
||||||
|
|
||||||
# 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year
|
# 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year
|
||||||
VERSION: str = "v. 2.04.1725"
|
VERSION: str = "v. 2.04.1725"
|
||||||
|
|
||||||
res = GiteaUpdate.api_down("https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases", VERSION, set_file)
|
res = GiteaUpdate.api_down("https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases", VERSION, AppConfig.SETTINGS_FILE)
|
||||||
|
|
||||||
# Translate
|
# Translate
|
||||||
APP = "wirepy"
|
_ = AppConfig.setup_translations()
|
||||||
LOCALE_DIR = "/usr/share/locale/"
|
|
||||||
locale.bindtextdomain(APP, LOCALE_DIR)
|
|
||||||
gettext.bindtextdomain(APP, LOCALE_DIR)
|
|
||||||
gettext.textdomain(APP)
|
|
||||||
_ = gettext.gettext
|
|
||||||
|
|
||||||
img_w: str = r"/usr/share/icons/lx-icons/64/info.png"
|
img_w: str = r"/usr/share/icons/lx-icons/64/info.png"
|
||||||
img_i: str = r"/usr/share/icons/lx-icons/48/wg_vpn.png"
|
img_i: str = r"/usr/share/icons/lx-icons/48/wg_vpn.png"
|
||||||
img_w2: str = r"/usr/share/icons/lx-icons/64/error.png"
|
img_w2: str = r"/usr/share/icons/lx-icons/64/error.png"
|
||||||
img_i2: str = r"/usr/share/icons/lx-icons/48/wg_msg.png"
|
img_i2: str = r"/usr/share/icons/lx-icons/48/wg_msg.png"
|
||||||
sl: str = _("Select tunnel")
|
|
||||||
rnp: str = _("Renaming not possible")
|
|
||||||
ie:str = _("Import Error")
|
|
||||||
pfit: str = _("Please first import tunnel")
|
|
||||||
pstl: str = _("Please select a tunnel from the list")
|
|
||||||
|
|
||||||
LxTools.sigi(folder_path, user_file)
|
LxTools.sigi(AppConfig.TEMP_DIR, AppConfig.USER_FILE)
|
||||||
|
|
||||||
class Wirepy(tk.Tk):
|
class Wirepy(tk.Tk):
|
||||||
"""
|
"""
|
||||||
Class Wirepy this is the Main Window of wirepy
|
Class Wirepy this is the Main Window of wirepy
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.my_tool_tip = None
|
self.my_tool_tip = None
|
||||||
self.x_width = 600
|
self.x_width = AppConfig.UI_CONFIG["window_size"][0]
|
||||||
self.y_height = 383
|
self.y_height = AppConfig.UI_CONFIG["window_size"][1]
|
||||||
self.monitor_center_x = int(self.winfo_screenwidth() / 2 - (self.x_width / 2))
|
self.monitor_center_x = int(self.winfo_screenwidth() / 2 - (self.x_width / 2))
|
||||||
self.monitor_center_y = int(self.winfo_screenheight() / 2 - (self.y_height / 2))
|
self.monitor_center_y = int(self.winfo_screenheight() / 2 - (self.y_height / 2))
|
||||||
self.resizable(width=False, height=False)
|
self.resizable(AppConfig.UI_CONFIG["resizable_window"][0], AppConfig.UI_CONFIG["resizable_window"][1])
|
||||||
self.title("Wire-Py")
|
self.title(AppConfig.UI_CONFIG["window_title"])
|
||||||
self.geometry(f"{self.x_width}x{self.y_height}+{self.monitor_center_x}+{self.monitor_center_y}")
|
self.geometry(f"{self.x_width}x{self.y_height}+{self.monitor_center_x}+{self.monitor_center_y}")
|
||||||
self.columnconfigure(0, weight=1)
|
self.columnconfigure(0, weight=1)
|
||||||
self.rowconfigure(0, weight=1)
|
self.rowconfigure(0, weight=1)
|
||||||
|
|
||||||
self.style = ttk.Style(self)
|
self.style = ttk.Style(self)
|
||||||
self.tk.call("source", f"{tcl_path}/water.tcl")
|
self.tk.call("source", f"{AppConfig.SYSTEM_PATHS["tcl_path"]}/water.tcl")
|
||||||
with open(set_file, "r", encoding="utf-8") as read_file:
|
LxTools.theme_change(self)
|
||||||
lines = read_file.readlines()
|
|
||||||
if "light\n" in lines:
|
|
||||||
self.tk.call("set_theme", "light")
|
|
||||||
else:
|
|
||||||
self.tk.call("set_theme", "dark")
|
|
||||||
|
|
||||||
# Load the image file from the disk
|
# Load the image file from the disk
|
||||||
self.wg_icon = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn.png")
|
self.wg_icon = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_vpn"])
|
||||||
|
|
||||||
# Set it as the window icon
|
# Set it as the window icon
|
||||||
self.iconphoto(True, self.wg_icon)
|
self.iconphoto(True, self.wg_icon)
|
||||||
@ -93,7 +73,6 @@ class FrameWidgets(ttk.Frame):
|
|||||||
"""
|
"""
|
||||||
ttk frame class for better structure
|
ttk frame class for better structure
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, container, **kwargs):
|
def __init__(self, container, **kwargs):
|
||||||
super().__init__(container, **kwargs)
|
super().__init__(container, **kwargs)
|
||||||
|
|
||||||
@ -103,85 +82,12 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.dns = None
|
self.dns = None
|
||||||
self.address = None
|
self.address = None
|
||||||
self.auto_con = None
|
self.auto_con = None
|
||||||
self.wg_vpn_start = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn-start.png")
|
self.wg_vpn_start = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_start"])
|
||||||
self.wg_vpn_stop = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn-stop.png")
|
self.wg_vpn_stop = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_stop"])
|
||||||
self.imp_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_import.png")
|
self.imp_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_import"])
|
||||||
self.tr_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_trash.png")
|
self.tr_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_trash"])
|
||||||
self.exp_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_export.png")
|
self.exp_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_export"])
|
||||||
self.warning_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/64/error.png")
|
self.warning_pic = tk.PhotoImage(file=AppConfig.IMAGE_PATHS["icon_error"])
|
||||||
|
|
||||||
def update():
|
|
||||||
"""
|
|
||||||
Set on or off in file
|
|
||||||
"""
|
|
||||||
if set_update.get() == 1:
|
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
|
||||||
lines2 = set_f2.readlines()
|
|
||||||
lines2[1] = "off\n"
|
|
||||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
|
||||||
set_f2.writelines(lines2)
|
|
||||||
|
|
||||||
if set_update.get() == 0:
|
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
|
||||||
lines2 = set_f2.readlines()
|
|
||||||
lines2[1] = "on\n"
|
|
||||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
|
||||||
set_f2.writelines(lines2)
|
|
||||||
|
|
||||||
def theme_change_light():
|
|
||||||
"""
|
|
||||||
Set a light theme
|
|
||||||
"""
|
|
||||||
if self.tk.call("ttk::style", "theme", "use") == "water-dark":
|
|
||||||
self.tk.call("set_theme", "light")
|
|
||||||
with open(set_file, "r", encoding="utf-8") as theme_set2:
|
|
||||||
lines3 = theme_set2.readlines()
|
|
||||||
lines3[3] = "light\n"
|
|
||||||
with open(set_file, "w", encoding="utf-8") as theme_set2:
|
|
||||||
theme_set2.writelines(lines3)
|
|
||||||
self.color_label()
|
|
||||||
|
|
||||||
def theme_change_dark():
|
|
||||||
"""
|
|
||||||
Set a dark theme
|
|
||||||
"""
|
|
||||||
if not self.tk.call("ttk::style", "theme", "use") == "water-dark":
|
|
||||||
self.tk.call("set_theme", "dark")
|
|
||||||
with open(set_file, "r", encoding="utf-8") as theme_set2:
|
|
||||||
lines4 = theme_set2.readlines()
|
|
||||||
lines4[3] = "dark\n"
|
|
||||||
with open(set_file, "w", encoding="utf-8") as theme_set2:
|
|
||||||
theme_set2.writelines(lines4)
|
|
||||||
self.color_label()
|
|
||||||
|
|
||||||
def tooltip():
|
|
||||||
"""
|
|
||||||
Set True or False in a file
|
|
||||||
"""
|
|
||||||
if set_tip.get():
|
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
|
||||||
lines2 = set_f2.readlines()
|
|
||||||
lines2[5] = "False\n"
|
|
||||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
|
||||||
set_f2.writelines(lines2)
|
|
||||||
|
|
||||||
else:
|
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
|
||||||
lines2 = set_f2.readlines()
|
|
||||||
lines2[5] = "True\n"
|
|
||||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
|
||||||
set_f2.writelines(lines2)
|
|
||||||
|
|
||||||
def info():
|
|
||||||
def link_btn():
|
|
||||||
webbrowser.open("https://git.ilunix.de/punix/Wire-Py")
|
|
||||||
|
|
||||||
msg_t = _("Wire-Py a simple Wireguard Gui for Linux systems.\n\n"
|
|
||||||
"Wire-Py is open source software written in Python.\n\n"
|
|
||||||
"Email: polunga40@unity-mail.de also likes for donation.\n\n"
|
|
||||||
"Use without warranty!\n")
|
|
||||||
|
|
||||||
LxTools.msg_window(img_i, img_i, _("Info"), msg_t, _("Go to Wire-Py git"), link_btn)
|
|
||||||
|
|
||||||
# Frame for Menu
|
# Frame for Menu
|
||||||
self.menu_frame = ttk.Frame(self)
|
self.menu_frame = ttk.Frame(self)
|
||||||
@ -204,15 +110,16 @@ class FrameWidgets(ttk.Frame):
|
|||||||
set_tip = tk.BooleanVar()
|
set_tip = tk.BooleanVar()
|
||||||
self.settings = tk.Menu(self, relief="flat")
|
self.settings = tk.Menu(self, relief="flat")
|
||||||
self.options_btn.configure(menu=self.settings, style="Toolbutton")
|
self.options_btn.configure(menu=self.settings, style="Toolbutton")
|
||||||
self.settings.add_checkbutton(label=_("Disable Updates"), command=update, variable=set_update)
|
self.settings.add_checkbutton(label=_("Disable Updates"),
|
||||||
self.settings.add_checkbutton(label=_("Disable Tooltips"), command=tooltip, variable=set_tip)
|
command=lambda: self.update_setting(set_update.get()), variable=set_update)
|
||||||
self.settings.add_command(label=_("Light"), command=theme_change_light)
|
self.settings.add_checkbutton(label=_("Disable Tooltips"),
|
||||||
self.settings.add_command(label=_("Dark"), command=theme_change_dark)
|
command=lambda: self.tooltip(set_tip.get()), variable=set_tip)
|
||||||
|
self.settings.add_command(label=_("Light"), command=self.theme_change_light)
|
||||||
|
self.settings.add_command(label=_("Dark"), command=self.theme_change_dark)
|
||||||
|
|
||||||
# About BTN Menu / Label
|
# About BTN Menu / Label
|
||||||
self.about_btn = ttk.Button(
|
self.about_btn = ttk.Button(
|
||||||
self.menu_frame, text=_("About"), style="Toolbutton", command=info
|
self.menu_frame, text=_("About"), style="Toolbutton", command=self.about)
|
||||||
)
|
|
||||||
self.about_btn.grid(column=2, columnspan=2, row=0)
|
self.about_btn.grid(column=2, columnspan=2, row=0)
|
||||||
self.readme = tk.Menu(self)
|
self.readme = tk.Menu(self)
|
||||||
|
|
||||||
@ -306,23 +213,12 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.peer.config(font=("Ubuntu", 9))
|
self.peer.config(font=("Ubuntu", 9))
|
||||||
self.peer.grid(column=0, row=4, sticky="we", padx=130)
|
self.peer.grid(column=0, row=4, sticky="we", padx=130)
|
||||||
|
|
||||||
def enable_check_box(_):
|
|
||||||
"""
|
|
||||||
checkbox for enable autostart Tunnel
|
|
||||||
"""
|
|
||||||
Create.files_for_autostart()
|
|
||||||
if self.l_box.size() != 0:
|
|
||||||
self.wg_autostart.configure(state="normal")
|
|
||||||
self.lb_rename.config(state="normal")
|
|
||||||
self.lb_rename.delete(0, tk.END)
|
|
||||||
self.btn_rename.config(state="normal")
|
|
||||||
|
|
||||||
# Listbox with Scrollbar
|
# Listbox with Scrollbar
|
||||||
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")
|
||||||
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>>", self.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)
|
||||||
self.scrollbar.grid(column=1, rowspan=4, row=0, sticky="nse")
|
self.scrollbar.grid(column=1, rowspan=4, row=0, sticky="nse")
|
||||||
self.l_box.configure(yscrollcommand=self.scrollbar.set)
|
self.l_box.configure(yscrollcommand=self.scrollbar.set)
|
||||||
@ -336,13 +232,7 @@ class FrameWidgets(ttk.Frame):
|
|||||||
# Button Vpn
|
# Button Vpn
|
||||||
if self.a != "":
|
if self.a != "":
|
||||||
self.stop()
|
self.stop()
|
||||||
wg_read = f"/tmp/tlecdcwg/{self.a}.conf"
|
data = self.handle_tunnel_data(self.a)
|
||||||
with open(wg_read, "r", encoding="utf-8") as file:
|
|
||||||
data = Tunnel.con_to_dict(file)
|
|
||||||
|
|
||||||
# Address Label
|
|
||||||
self.init_and_report(data)
|
|
||||||
self.show_data()
|
|
||||||
else:
|
else:
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
@ -350,7 +240,7 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.add = tk.StringVar()
|
self.add = tk.StringVar()
|
||||||
self.DNS = tk.StringVar()
|
self.DNS = tk.StringVar()
|
||||||
self.enp = tk.StringVar()
|
self.enp = tk.StringVar()
|
||||||
self.label_empty()
|
self.reset_fields()
|
||||||
self.show_data()
|
self.show_data()
|
||||||
|
|
||||||
# Button Import
|
# Button Import
|
||||||
@ -359,7 +249,151 @@ class FrameWidgets(ttk.Frame):
|
|||||||
|
|
||||||
Tooltip(self.btn_i, _("Click to import a Wireguard Tunnel"), tips)
|
Tooltip(self.btn_i, _("Click to import a Wireguard Tunnel"), tips)
|
||||||
|
|
||||||
def delete():
|
# Button Trash
|
||||||
|
self.btn_tr = ttk.Button(self.lb_frame_btn_lbox, image=self.tr_pic, command=self.delete, padding=0,
|
||||||
|
style="CButton.TButton")
|
||||||
|
self.btn_tr.grid(column=0, row=2, padx=15, pady=8)
|
||||||
|
|
||||||
|
if self.l_box.size() == 0:
|
||||||
|
Tooltip(self.btn_tr, _("No tunnels to delete in the list"), tips)
|
||||||
|
else:
|
||||||
|
Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!"), tips)
|
||||||
|
|
||||||
|
# Button Export
|
||||||
|
self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic,
|
||||||
|
command=lambda: Tunnel.export(img_w, img_i, img_w2, img_i2,
|
||||||
|
Msg.STR["sel_tl"], Msg.STR["tl_first"]), padding=0)
|
||||||
|
self.btn_exp.grid(column=0, row=3, padx=15, pady=8)
|
||||||
|
|
||||||
|
if self.l_box.size() == 0:
|
||||||
|
Tooltip(self.btn_exp, _("No Tunnels in List for Export"), tips)
|
||||||
|
else:
|
||||||
|
Tooltip(self.btn_exp, _("Click to export all\nWireguard Tunnel to Zipfile"), tips)
|
||||||
|
|
||||||
|
# Label Entry
|
||||||
|
self.lb_rename = ttk.Entry(self.lb_frame4, width=20)
|
||||||
|
self.lb_rename.grid(column=2, row=0, padx=8, pady=10, sticky="ne")
|
||||||
|
self.lb_rename.insert(0, _("Max. 12 characters!"))
|
||||||
|
self.lb_rename.config(state="disable")
|
||||||
|
|
||||||
|
if self.l_box.size() != 0:
|
||||||
|
Tooltip(self.lb_rename, _("To rename a tunnel, you need to\nselect a tunnel from the list"), tips)
|
||||||
|
else:
|
||||||
|
Tooltip(self.lb_rename, _("To rename a tunnel, at least one must be in the list"), tips)
|
||||||
|
|
||||||
|
# Button Rename
|
||||||
|
self.btn_rename = ttk.Button(self.lb_frame4, text=_("Rename"), state="disable", command=self.tl_rename,
|
||||||
|
padding=4, style="RnButton.TButton")
|
||||||
|
self.btn_rename.grid(column=3, row=0, padx=5, pady=10, sticky="ne")
|
||||||
|
|
||||||
|
# Check Buttons
|
||||||
|
self.selected_option = tk.IntVar()
|
||||||
|
self.autoconnect_var = tk.StringVar()
|
||||||
|
self.autoconnect_var.set(f"{self.auto_con}")
|
||||||
|
|
||||||
|
# Frame for Labels, Entry and Button
|
||||||
|
self.autoconnect = ttk.Label(self.lb_frame3, textvariable=self.autoconnect_var, width=15)
|
||||||
|
self.autoconnect.config(font=("Ubuntu", 11))
|
||||||
|
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
|
||||||
|
self.wg_autostart = ttk.Checkbutton(self.lb_frame3, text=_("Autoconnect on:"), variable=self.selected_option,
|
||||||
|
command=self.box_set)
|
||||||
|
self.wg_autostart.grid(column=0, row=0, pady=15, padx=15, sticky="nw")
|
||||||
|
|
||||||
|
if self.l_box.size() >= 1 and len(self.l_box.curselection()) >= 1:
|
||||||
|
Tooltip(self.wg_autostart, Msg.TTIP["autostart"], tips)
|
||||||
|
|
||||||
|
if self.l_box.size() == 0:
|
||||||
|
Tooltip(self.wg_autostart, Msg.TTIP["autostart_info"], tips)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
Tooltip(self.wg_autostart, Msg.TTIP["autostart"], tips)
|
||||||
|
|
||||||
|
self.on_off()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def about() -> None:
|
||||||
|
"""
|
||||||
|
a tk.Toplevel window
|
||||||
|
"""
|
||||||
|
def link_btn() -> str | None:
|
||||||
|
webbrowser.open("https://git.ilunix.de/punix/Wire-Py")
|
||||||
|
|
||||||
|
msg_t = _("Wire-Py a simple Wireguard Gui for Linux systems.\n\n"
|
||||||
|
"Wire-Py is open source software written in Python.\n\n"
|
||||||
|
"Email: polunga40@unity-mail.de also likes for donation.\n\n"
|
||||||
|
"Use without warranty!\n")
|
||||||
|
|
||||||
|
LxTools.msg_window(img_i, img_i, _("Info"), msg_t, _("Go to Wire-Py git"), link_btn)
|
||||||
|
|
||||||
|
def theme_change_light(self) -> None:
|
||||||
|
"""
|
||||||
|
Set a light theme
|
||||||
|
"""
|
||||||
|
if self.tk.call("ttk::style", "theme", "use") == "water-dark":
|
||||||
|
self.tk.call("set_theme", "light")
|
||||||
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True) # (keepends=True) = not changed
|
||||||
|
lines[3] = 'light\n'
|
||||||
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
|
self.color_label()
|
||||||
|
|
||||||
|
def theme_change_dark(self) -> None:
|
||||||
|
"""
|
||||||
|
Set a dark theme
|
||||||
|
"""
|
||||||
|
if not self.tk.call("ttk::style", "theme", "use") == "water-dark":
|
||||||
|
self.tk.call("set_theme", "dark")
|
||||||
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
|
lines[3] = 'dark\n'
|
||||||
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
|
self.color_label()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_setting(update_res) -> None:
|
||||||
|
"""
|
||||||
|
write off or on in file
|
||||||
|
Args:
|
||||||
|
update_res (int): argument that is passed contains 0 or 1
|
||||||
|
"""
|
||||||
|
if update_res == 1:
|
||||||
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
|
lines[1] = 'off\n'
|
||||||
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
|
|
||||||
|
else:
|
||||||
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
|
lines[1] = 'on\n'
|
||||||
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def tooltip(tip) -> None:
|
||||||
|
"""
|
||||||
|
write True or False in a file
|
||||||
|
Args:
|
||||||
|
tip (bool): argument that is passed contains True or False
|
||||||
|
"""
|
||||||
|
if tip:
|
||||||
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
|
lines[5] = 'False\n'
|
||||||
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
|
|
||||||
|
else:
|
||||||
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
|
lines[5] = 'True\n'
|
||||||
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
|
|
||||||
|
def enable_check_box(self, _) -> None:
|
||||||
|
"""
|
||||||
|
checkbox for enable autostart Tunnel
|
||||||
|
"""
|
||||||
|
Create.files_for_autostart()
|
||||||
|
if self.l_box.size() != 0:
|
||||||
|
self.wg_autostart.configure(state="normal")
|
||||||
|
self.lb_rename.config(state="normal")
|
||||||
|
self.lb_rename.delete(0, tk.END)
|
||||||
|
self.btn_rename.config(state="normal")
|
||||||
|
|
||||||
|
def delete(self) -> None:
|
||||||
"""
|
"""
|
||||||
delete Wireguard Tunnel
|
delete Wireguard Tunnel
|
||||||
"""
|
"""
|
||||||
@ -371,14 +405,12 @@ class FrameWidgets(ttk.Frame):
|
|||||||
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])
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f6:
|
with open(AppConfig.SETTINGS_FILE, "r", encoding="utf-8") as set_f6:
|
||||||
lines6 = set_f6.readlines()
|
lines6 = set_f6.readlines()
|
||||||
if (
|
if (select_tl == lines6[7].strip()
|
||||||
select_tl == lines6[7].strip()
|
and "off\n" not in lines6[7].strip()):
|
||||||
and "off\n" not in lines6[7].strip()
|
|
||||||
):
|
|
||||||
lines6[7] = "off\n"
|
lines6[7] = "off\n"
|
||||||
with open(set_file, "w", encoding="utf-8") as set_f7:
|
with open(AppConfig.SETTINGS_FILE, "w", encoding="utf-8") as set_f7:
|
||||||
set_f7.writelines(lines6)
|
set_f7.writelines(lines6)
|
||||||
self.selected_option.set(0)
|
self.selected_option.set(0)
|
||||||
self.autoconnect_var.set(_("no Autoconnect"))
|
self.autoconnect_var.set(_("no Autoconnect"))
|
||||||
@ -386,7 +418,7 @@ class FrameWidgets(ttk.Frame):
|
|||||||
if is_encrypt.is_file():
|
if is_encrypt.is_file():
|
||||||
Path.unlink(f"{Path.home()}/.config/wire_py/{select_tl}.dat")
|
Path.unlink(f"{Path.home()}/.config/wire_py/{select_tl}.dat")
|
||||||
Path.unlink(f"/tmp/tlecdcwg/{select_tl}.conf")
|
Path.unlink(f"/tmp/tlecdcwg/{select_tl}.conf")
|
||||||
with open(f"{Path.home()}/.config/wire_py/keys", "r", encoding="utf-8") as readfile:
|
with open(AppConfig.KEYS_FILE, "r", encoding="utf-8") as readfile:
|
||||||
with open(f"{Path.home()}/.config/wire_py/keys2", "w", encoding="utf-8") as writefile:
|
with open(f"{Path.home()}/.config/wire_py/keys2", "w", encoding="utf-8") as writefile:
|
||||||
for line in readfile:
|
for line in readfile:
|
||||||
if pre_key not in line.strip("\n"):
|
if pre_key not in line.strip("\n"):
|
||||||
@ -412,69 +444,40 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.str_var.set(value="")
|
self.str_var.set(value="")
|
||||||
self.start()
|
self.start()
|
||||||
self.l_box.update()
|
self.l_box.update()
|
||||||
|
self.reset_fields()
|
||||||
# Address Label
|
|
||||||
self.add.set("")
|
|
||||||
self.DNS.set("")
|
|
||||||
self.enp.set("")
|
|
||||||
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
|
||||||
if self.l_box.size() != 0:
|
if self.l_box.size() != 0:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, sl, pstl)
|
LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["sel_list"])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, sl, pfit)
|
LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["tl_first"])
|
||||||
|
|
||||||
# Button Trash
|
|
||||||
self.btn_tr = ttk.Button(self.lb_frame_btn_lbox, image=self.tr_pic, command=delete, padding=0,
|
|
||||||
style="CButton.TButton")
|
|
||||||
self.btn_tr.grid(column=0, row=2, padx=15, pady=8)
|
|
||||||
|
|
||||||
if self.l_box.size() == 0:
|
|
||||||
Tooltip(self.btn_tr, _("No tunnels to delete in the list"), tips)
|
|
||||||
else:
|
|
||||||
Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!"), tips)
|
|
||||||
|
|
||||||
# Button Export
|
|
||||||
self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic,
|
|
||||||
command=lambda: Tunnel.export(img_w, img_i, img_w2, img_i2, sl, pfit), padding=0)
|
|
||||||
self.btn_exp.grid(column=0, row=3, padx=15, pady=8)
|
|
||||||
|
|
||||||
if self.l_box.size() == 0:
|
|
||||||
Tooltip(self.btn_exp, _("No Tunnels in List for Export"), tips)
|
|
||||||
else:
|
|
||||||
Tooltip(self.btn_exp, _("Click to export all\nWireguard Tunnel to Zipfile"), tips)
|
|
||||||
|
|
||||||
# Label Entry
|
|
||||||
self.lb_rename = ttk.Entry(self.lb_frame4, width=20)
|
|
||||||
self.lb_rename.grid(column=2, row=0, padx=8, pady=10, sticky="ne")
|
|
||||||
self.lb_rename.insert(0, _("Max. 12 characters!"))
|
|
||||||
self.lb_rename.config(state="disable")
|
|
||||||
|
|
||||||
if self.l_box.size() != 0:
|
|
||||||
Tooltip(self.lb_rename, _("To rename a tunnel, you need to\nselect a tunnel from the list"), tips)
|
|
||||||
else:
|
|
||||||
Tooltip(self.lb_rename, _("To rename a tunnel, at least one must be in the list"), tips)
|
|
||||||
|
|
||||||
def tl_rename():
|
|
||||||
|
|
||||||
|
def tl_rename(self) -> None:
|
||||||
|
"""
|
||||||
|
method to rename a tunnel
|
||||||
|
"""
|
||||||
|
name_of_file = LxTools.get_file_name(AppConfig.TEMP_DIR)
|
||||||
special_characters = ["\\", "/", "{", "}", " "]
|
special_characters = ["\\", "/", "{", "}", " "]
|
||||||
|
|
||||||
if len(self.lb_rename.get()) > 12:
|
if len(self.lb_rename.get()) > 12:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, rnp, _("The new name may contain only 12 characters"))
|
LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["sign_len"])
|
||||||
|
|
||||||
elif len(self.lb_rename.get()) == 0:
|
elif len(self.lb_rename.get()) == 0:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, rnp, _("At least one character must be entered"))
|
LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["zero_signs"])
|
||||||
|
|
||||||
elif any(ch in special_characters for ch in self.lb_rename.get()):
|
elif any(ch in special_characters for ch in self.lb_rename.get()):
|
||||||
|
|
||||||
msg_t = _("No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n")
|
LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["false_signs"])
|
||||||
LxTools.msg_window(img_w, img_i2, rnp, msg_t)
|
|
||||||
|
elif self.lb_rename.get() in name_of_file:
|
||||||
|
|
||||||
|
LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["is_in_use"])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
@ -483,7 +486,7 @@ class FrameWidgets(ttk.Frame):
|
|||||||
select_tl = self.l_box.get(self.select_tunnel[0])
|
select_tl = self.l_box.get(self.select_tunnel[0])
|
||||||
|
|
||||||
# nmcli connection modify old connection.id iphone
|
# nmcli connection modify old connection.id iphone
|
||||||
check_call(["nmcli", "connection", "modify", select_tl, "connection.id", self.lb_rename.get()])
|
subprocess.check_output(["nmcli", "connection", "modify", select_tl, "connection.id", self.lb_rename.get()], text=True)
|
||||||
source = Path(f"/tmp/tlecdcwg/{select_tl}.conf")
|
source = Path(f"/tmp/tlecdcwg/{select_tl}.conf")
|
||||||
destination = source.with_name(f"{self.lb_rename.get()}.conf")
|
destination = source.with_name(f"{self.lb_rename.get()}.conf")
|
||||||
source.replace(destination)
|
source.replace(destination)
|
||||||
@ -494,68 +497,31 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.l_box.update()
|
self.l_box.update()
|
||||||
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:
|
|
||||||
self.a = Tunnel.active()
|
with open(AppConfig.SETTINGS_FILE, "r", encoding="utf-8") as set_f5:
|
||||||
self.str_var.set(value=self.a)
|
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f5:
|
|
||||||
lines5 = set_f5.readlines()
|
lines5 = set_f5.readlines()
|
||||||
if select_tl == lines5[7].strip() and "off\n" not in lines5[7].strip():
|
if select_tl == lines5[7].strip() and "off\n" not in lines5[7].strip():
|
||||||
lines5[7] = new_a_connect
|
lines5[7] = new_a_connect
|
||||||
with open(set_file, "w", encoding="utf-8") as theme_set5:
|
with open(AppConfig.SETTINGS_FILE, "w", encoding="utf-8") as theme_set5:
|
||||||
theme_set5.writelines(lines5)
|
theme_set5.writelines(lines5)
|
||||||
self.autoconnect_var.set(value=new_a_connect)
|
self.autoconnect_var.set(value=new_a_connect)
|
||||||
|
self.update_connection_display()
|
||||||
Create.encrypt()
|
Create.encrypt()
|
||||||
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, rnp, pstl)
|
LxTools.msg_window(img_w, img_i2, Msg.STR["ren_err"], Msg.STR["sel_list"])
|
||||||
|
|
||||||
# Button Rename
|
except subprocess.CalledProcessError:
|
||||||
self.btn_rename = ttk.Button(self.lb_frame4, text=_("Rename"), state="disable", command=tl_rename, padding=4,
|
pass
|
||||||
style="RnButton.TButton")
|
|
||||||
self.btn_rename.grid(column=3, row=0, padx=5, pady=10, sticky="ne")
|
|
||||||
|
|
||||||
# Check Buttons
|
except EOFError as e:
|
||||||
self.selected_option = tk.IntVar()
|
print(e)
|
||||||
self.autoconnect_var = tk.StringVar()
|
|
||||||
self.autoconnect_var.set(self.auto_con)
|
|
||||||
|
|
||||||
# Frame for Labels, Entry and Button
|
def import_sl(self) -> None:
|
||||||
self.autoconnect = ttk.Label(self.lb_frame3, textvariable=self.autoconnect_var, width=15)
|
|
||||||
self.autoconnect.config(font=("Ubuntu", 11))
|
|
||||||
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
|
|
||||||
self.wg_autostart = ttk.Checkbutton(self.lb_frame3, text=_("Autoconnect on:"), variable=self.selected_option,
|
|
||||||
command=self.box_set)
|
|
||||||
self.wg_autostart.grid(column=0, row=0, pady=15, padx=15, sticky="nw")
|
|
||||||
|
|
||||||
if self.l_box.size() >= 1 and len(self.l_box.curselection()) >= 1:
|
|
||||||
Tooltip(self.wg_autostart, _("To use the autostart, enable this Checkbox"), tips)
|
|
||||||
|
|
||||||
if self.l_box.size() == 0:
|
|
||||||
Tooltip(self.wg_autostart, _("You must have at least one\ntunnel in the list,to use the autostart"), tips)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
Tooltip(self.wg_autostart, _("To use the autostart, a tunnel must be selected from the list"), tips)
|
|
||||||
|
|
||||||
self.on_off()
|
|
||||||
|
|
||||||
def import_sl(self):
|
|
||||||
"""
|
"""
|
||||||
Import Methode for Wireguard config Files.
|
validity check of wireguard config files
|
||||||
Before importing, it is checked whether PrivateKey and PublicKey are in the file.
|
|
||||||
If True, then it is checked whether the PreSharedKey is already in the key file
|
|
||||||
to avoid an import error so that no double wgconf are imported.
|
|
||||||
Thus, tunnels can be renamed without the problems arising.
|
|
||||||
If False, then the key is written into the file.
|
|
||||||
Furthermore, it is checked whether the name is longer than 12 characters.
|
|
||||||
If True, then the name is automatically shortened to 12 characters
|
|
||||||
and then imported.
|
|
||||||
If in each case false comes out, a corresponding window comes to
|
|
||||||
inform the user that something is wrong.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Create.dir_and_files()
|
Create.dir_and_files()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -566,32 +532,29 @@ class FrameWidgets(ttk.Frame):
|
|||||||
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 = 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", encoding="utf-8") as file:
|
with open(filepath, "r", encoding="utf-8") as file:
|
||||||
key = Tunnel.con_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(f"{Path.home()}/.config/wire_py/keys", "r", encoding="utf-8") as readfile:
|
p_key = AppConfig.KEYS_FILE.read_text(encoding="utf-8")
|
||||||
p_key = readfile.readlines()
|
|
||||||
if pre_key in p_key or f"{pre_key}\n" in p_key:
|
if pre_key in p_key or f"{pre_key}\n" in p_key:
|
||||||
|
|
||||||
msg_t = _("Tunnel already available!\nPlease use another file for import")
|
LxTools.msg_window(img_w2, img_i2, Msg.STR["imp_err"], Msg.STR["tl_exist"])
|
||||||
LxTools.msg_window(img_w2, img_i2, ie, msg_t)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
with open(f"{Path.home()}/.config/wire_py/keys", "a", encoding="utf-8") as keyfile:
|
with open(AppConfig.KEYS_FILE, "a", encoding="utf-8") as keyfile:
|
||||||
keyfile.write(f"{pre_key}\r")
|
keyfile.write(f"{pre_key}\r")
|
||||||
if len(path_split1) > 17:
|
if len(path_split1) > 17:
|
||||||
p1 = shutil.copy(filepath, "/tmp/tlecdcwg/")
|
p1 = shutil.copy(filepath, AppConfig.TEMP_DIR)
|
||||||
path_split = path_split1[len(path_split1) - 17:]
|
path_split = path_split1[len(path_split1) - 17:]
|
||||||
os.rename(p1, f"/tmp/tlecdcwg/{path_split}")
|
os.rename(p1, f"{AppConfig.TEMP_DIR}/{path_split}")
|
||||||
new_conf = f"/tmp/tlecdcwg/{path_split}"
|
new_conf = f"{AppConfig.TEMP_DIR}/{path_split}"
|
||||||
if self.a != "":
|
if self.a != "":
|
||||||
check_call(["nmcli", "connection", "down", Tunnel.active()])
|
check_call(["nmcli", "connection", "down", self.a])
|
||||||
self.label_empty()
|
self.reset_fields()
|
||||||
|
|
||||||
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)
|
||||||
@ -599,10 +562,10 @@ class FrameWidgets(ttk.Frame):
|
|||||||
Create.encrypt()
|
Create.encrypt()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
shutil.copy(filepath, "/tmp/tlecdcwg/")
|
shutil.copy(filepath, f"{AppConfig.TEMP_DIR}/")
|
||||||
if self.a != "":
|
if self.a != "":
|
||||||
check_call(["nmcli", "connection", "down", Tunnel.active()])
|
check_call(["nmcli", "connection", "down", self.a])
|
||||||
self.label_empty()
|
self.reset_fields()
|
||||||
|
|
||||||
subprocess.check_output(["nmcli", "connection", "import", "type",
|
subprocess.check_output(["nmcli", "connection", "import", "type",
|
||||||
"wireguard", "file", filepath], text=True)
|
"wireguard", "file", filepath], text=True)
|
||||||
@ -617,40 +580,27 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.l_box.update()
|
self.l_box.update()
|
||||||
self.l_box.selection_set(0)
|
self.l_box.selection_set(0)
|
||||||
|
|
||||||
Tooltip(self.wg_autostart, _("To use the autostart, enable this Checkbox"), tips)
|
Tooltip(self.wg_autostart, Msg.TTIP["autostart"], tips)
|
||||||
|
|
||||||
# Tooltip(self.l_box, _("List of available tunnels"))
|
Tooltip(self.btn_tr, Msg.TTIP["trash_tl"], tips)
|
||||||
|
|
||||||
Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!")
|
Tooltip(self.btn_exp, Msg.TTIP["export_tl"], tips)
|
||||||
, tips,)
|
|
||||||
|
|
||||||
Tooltip(self.btn_exp, _(" Click to export all\nWireguard Tunnel to Zipfile")
|
Tooltip(self.btn_rename, Msg.TTIP["rename_tl"], tips)
|
||||||
, tips)
|
|
||||||
|
|
||||||
Tooltip(self.btn_rename, _("To rename a tunnel, you need to\nselect a tunnel from"
|
|
||||||
" the list"), tips)
|
|
||||||
|
|
||||||
self.lb_rename.insert(0, "Max. 12 characters!")
|
self.lb_rename.insert(0, "Max. 12 characters!")
|
||||||
self.str_var = tk.StringVar()
|
self.str_var = tk.StringVar()
|
||||||
self.str_var.set(self.a)
|
self.str_var.set(self.a)
|
||||||
self.color_label()
|
self.color_label()
|
||||||
self.stop()
|
self.stop()
|
||||||
wg_read = f"/tmp/tlecdcwg/{self.a}.conf"
|
data = self.handle_tunnel_data(self.a)
|
||||||
with open(wg_read, "r", encoding="utf-8") as file_for_key:
|
|
||||||
data = Tunnel.con_to_dict(file_for_key)
|
|
||||||
|
|
||||||
# Address Label
|
|
||||||
self.init_and_report(data)
|
|
||||||
self.show_data()
|
|
||||||
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)
|
|
||||||
|
|
||||||
if ("PrivateKey = " in read) and ("Endpoint = " in read):
|
if ("PrivateKey = " in read) and ("Endpoint = " in read):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
||||||
msg_t = _("Oh... no valid Wireguard File!\nPlease select a valid Wireguard File")
|
LxTools.msg_window(img_w2, img_i2, Msg.STR["imp_err"], Msg.STR["no_valid_file"])
|
||||||
LxTools.msg_window(img_w2, img_i2, ie, msg_t)
|
|
||||||
|
|
||||||
except EOFError as e:
|
except EOFError as e:
|
||||||
print(e)
|
print(e)
|
||||||
@ -661,9 +611,25 @@ class FrameWidgets(ttk.Frame):
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
print("Tunnel exist!")
|
print("Tunnel exist!")
|
||||||
|
|
||||||
def box_set(self):
|
def handle_tunnel_data(self, tunnel_name: str) -> tuple[str, str, str, str | None]:
|
||||||
|
"""_summary_
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tunnel_name (str): name of a tunnel
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple[str, str]: tuple with tunnel data
|
||||||
"""
|
"""
|
||||||
This Method will display the autostart label which
|
wg_read = f"/tmp/tlecdcwg/{tunnel_name}.conf"
|
||||||
|
with open(wg_read, "r", encoding="utf-8") as file:
|
||||||
|
data = Tunnel.con_to_dict(file)
|
||||||
|
self.init_and_report(data)
|
||||||
|
self.show_data()
|
||||||
|
return data
|
||||||
|
|
||||||
|
def box_set(self) -> None:
|
||||||
|
"""
|
||||||
|
This Method will display the autostarted label which
|
||||||
Tunnel is automatically started regardless of the active tunnel.
|
Tunnel is automatically started regardless of the active tunnel.
|
||||||
The selected tunnel is written into a file to read it after the start of the system.
|
The selected tunnel is written into a file to read it after the start of the system.
|
||||||
"""
|
"""
|
||||||
@ -672,11 +638,9 @@ class FrameWidgets(ttk.Frame):
|
|||||||
select_tl = self.l_box.get(select_tunnel[0])
|
select_tl = self.l_box.get(select_tunnel[0])
|
||||||
|
|
||||||
if self.selected_option.get() == 0:
|
if self.selected_option.get() == 0:
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f3:
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
lines3 = set_f3.readlines()
|
lines[7] = 'off\n'
|
||||||
lines3[7] = "off\n"
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
with open(set_file, "w", encoding="utf-8") as set_f3:
|
|
||||||
set_f3.writelines(lines3)
|
|
||||||
|
|
||||||
tl = Tunnel.list()
|
tl = Tunnel.list()
|
||||||
|
|
||||||
@ -684,31 +648,28 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.wg_autostart.configure(state="disabled")
|
self.wg_autostart.configure(state="disabled")
|
||||||
|
|
||||||
if self.selected_option.get() >= 1:
|
if self.selected_option.get() >= 1:
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f3:
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
lines3 = set_f3.readlines()
|
lines[7] = select_tl
|
||||||
lines3[7] = select_tl
|
Path(AppConfig.SETTINGS_FILE).write_text(''.join(lines), encoding="utf-8")
|
||||||
with open(set_file, "w", encoding="utf-8") as set_f3:
|
|
||||||
set_f3.writelines(lines3)
|
|
||||||
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
self.selected_option.set(1)
|
self.selected_option.set(1)
|
||||||
|
|
||||||
self.on_off()
|
self.on_off()
|
||||||
|
|
||||||
def on_off(self):
|
def on_off(self) -> None:
|
||||||
"""
|
"""
|
||||||
Here it is checked whether the path to the file is there, if not, it is created.
|
Here it is checked whether the path to the file is there, if not, it is created.
|
||||||
Set (on), the selected tunnel is displayed in the label.
|
Set (on), the selected tunnel is displayed in the label.
|
||||||
At (off) the label is first emptied then filled with No Autoconnect
|
At (off) the label is first emptied then filled with No Autoconnect
|
||||||
"""
|
"""
|
||||||
with open(set_file, "r", encoding="utf-8") as set_f4:
|
lines = Path(AppConfig.SETTINGS_FILE).read_text(encoding="utf-8").splitlines(keepends=True)
|
||||||
lines4 = set_f4.readlines()
|
|
||||||
|
|
||||||
if lines4[7] != "off\n":
|
if lines[7] != "off\n":
|
||||||
print(f"{lines4[7]} starts automatically when the system starts.")
|
print(f"{lines[7]} starts automatically when the system starts.")
|
||||||
self.selected_option.set(1)
|
self.selected_option.set(1)
|
||||||
self.autoconnect_var.set("")
|
self.autoconnect_var.set("")
|
||||||
self.auto_con = lines4[7]
|
self.auto_con = lines[7]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.selected_option.set(0)
|
self.selected_option.set(0)
|
||||||
@ -722,12 +683,11 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.autoconnect.config(font=("Ubuntu", 11))
|
self.autoconnect.config(font=("Ubuntu", 11))
|
||||||
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
|
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
|
||||||
|
|
||||||
def init_and_report(self, data=None):
|
def init_and_report(self, data=None) -> None:
|
||||||
"""
|
"""
|
||||||
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
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Address Label
|
# Address Label
|
||||||
self.add = tk.StringVar()
|
self.add = tk.StringVar()
|
||||||
self.add.set(f"{_("Address: ")}{data[0]}")
|
self.add.set(f"{_("Address: ")}{data[0]}")
|
||||||
@ -736,19 +696,18 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.enp = tk.StringVar()
|
self.enp = tk.StringVar()
|
||||||
self.enp.set(f"{_("Endpoint: ")}{data[2]}")
|
self.enp.set(f"{_("Endpoint: ")}{data[2]}")
|
||||||
|
|
||||||
def label_empty(self):
|
def reset_fields(self) -> None:
|
||||||
"""
|
"""
|
||||||
empty labels
|
reset data from labels
|
||||||
"""
|
"""
|
||||||
self.add.set("")
|
fields = [self.add, self.DNS, self.enp]
|
||||||
self.DNS.set("")
|
for field in fields:
|
||||||
self.enp.set("")
|
field.set("")
|
||||||
|
|
||||||
def show_data(self):
|
def show_data(self) -> None:
|
||||||
"""
|
"""
|
||||||
shows data in the label
|
shows data in the label
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Address Label
|
# Address Label
|
||||||
self.address = ttk.Label(self.lb_frame, textvariable=self.add, foreground="#0071ff")
|
self.address = ttk.Label(self.lb_frame, textvariable=self.add, foreground="#0071ff")
|
||||||
self.address.grid(column=0, row=5, sticky="w", padx=10, pady=6)
|
self.address.grid(column=0, row=5, sticky="w", padx=10, pady=6)
|
||||||
@ -764,35 +723,35 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.endpoint.grid(column=0, row=8, sticky="w", padx=10, pady=20)
|
self.endpoint.grid(column=0, row=8, sticky="w", padx=10, pady=20)
|
||||||
self.endpoint.config(font=("Ubuntu", 9))
|
self.endpoint.config(font=("Ubuntu", 9))
|
||||||
|
|
||||||
def stop(self):
|
def stop(self) -> None:
|
||||||
"""
|
"""
|
||||||
Stop Button
|
Stop Button
|
||||||
"""
|
"""
|
||||||
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_stop, command=self.wg_switch, padding=0)
|
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_stop,
|
||||||
|
command=lambda: self.wg_switch("stop"), 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)
|
||||||
|
|
||||||
Tooltip(self.btn_stst, _("Click to stop selected Wireguard Tunnel"), tips)
|
Tooltip(self.btn_stst, Msg.TTIP["stop_tl"], tips)
|
||||||
|
|
||||||
def start(self):
|
def start(self) -> None:
|
||||||
"""
|
"""
|
||||||
Start Button
|
Start Button
|
||||||
"""
|
"""
|
||||||
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_start, command=self.wg_switch, padding=0)
|
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_start,
|
||||||
|
command=lambda: self.wg_switch("start"), 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)
|
||||||
|
|
||||||
tl = Tunnel.list()
|
tl = Tunnel.list()
|
||||||
if len(tl) == 0:
|
if len(tl) == 0:
|
||||||
Tooltip(self.btn_stst, _("No tunnels to start in the list"), tips)
|
Tooltip(self.btn_stst, Msg.TTIP["empty_list"], tips)
|
||||||
else:
|
else:
|
||||||
Tooltip(self.btn_stst, _("Click to start selected Wireguard Tunnel"), tips)
|
Tooltip(self.btn_stst, Msg.TTIP["start_tl"], tips)
|
||||||
|
|
||||||
def color_label(self):
|
def color_label(self) -> None:
|
||||||
"""
|
"""
|
||||||
View activ Tunnel in the color green or yellow
|
View activ Tunnel in the color green or yellow
|
||||||
"""
|
"""
|
||||||
|
lines = AppConfig.SETTINGS_FILE.read_text()
|
||||||
with open(set_file, "r", encoding="utf-8") as read_file:
|
|
||||||
lines = read_file.readlines()
|
|
||||||
if "light\n" in lines:
|
if "light\n" in lines:
|
||||||
self.lb_tunnel = ttk.Label(self, textvariable=self.str_var, foreground="green")
|
self.lb_tunnel = ttk.Label(self, textvariable=self.str_var, foreground="green")
|
||||||
|
|
||||||
@ -802,60 +761,75 @@ class FrameWidgets(ttk.Frame):
|
|||||||
self.lb_tunnel.config(font=("Ubuntu", 11, "bold"))
|
self.lb_tunnel.config(font=("Ubuntu", 11, "bold"))
|
||||||
self.lb_tunnel.grid(column=2, padx=10, row=1)
|
self.lb_tunnel.grid(column=2, padx=10, row=1)
|
||||||
|
|
||||||
def wg_switch(self):
|
def wg_switch(self, event=None) -> None:
|
||||||
"""
|
"""
|
||||||
switch Tunnel method change from labels and buttons
|
Deals with switching the VPN connection
|
||||||
"""
|
"""
|
||||||
self.a = Tunnel.active()
|
|
||||||
try:
|
try:
|
||||||
if self.a == "":
|
if self.a == "":
|
||||||
|
|
||||||
self.start()
|
|
||||||
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])
|
self.handle_connection_state("start", select_tl)
|
||||||
wg_read = f"/tmp/tlecdcwg/{select_tl}.conf"
|
|
||||||
with open(wg_read, "r", encoding="utf-8") as file:
|
|
||||||
data = Tunnel.con_to_dict(file)
|
|
||||||
|
|
||||||
# Address Label
|
else:
|
||||||
self.init_and_report(data)
|
|
||||||
self.show_data()
|
|
||||||
|
|
||||||
# Button Start/Stop
|
data = self.handle_tunnel_data(self.a)
|
||||||
self.stop()
|
if data:
|
||||||
self.a = Tunnel.active()
|
|
||||||
self.str_var = tk.StringVar()
|
|
||||||
self.str_var.set(self.a)
|
|
||||||
self.color_label()
|
|
||||||
|
|
||||||
elif self.a != "":
|
self.handle_connection_state("stop")
|
||||||
|
|
||||||
# Button Start/Stop
|
|
||||||
self.stop()
|
|
||||||
check_call(["nmcli", "connection", "down", self.a])
|
|
||||||
|
|
||||||
# Button Start/Stop
|
|
||||||
self.start()
|
|
||||||
self.a = Tunnel.active()
|
|
||||||
self.str_var.set("")
|
|
||||||
self.color_label()
|
|
||||||
|
|
||||||
# Address Label
|
|
||||||
self.add.set("")
|
|
||||||
self.DNS.set("")
|
|
||||||
self.enp.set("")
|
|
||||||
self.show_data()
|
|
||||||
|
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
|
||||||
if self.l_box.size() != 0:
|
if self.l_box.size() != 0:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, sl, pstl)
|
LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["sel_list"])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
LxTools.msg_window(img_w, img_i2, sl, pfit)
|
LxTools.msg_window(img_w, img_i2, Msg.STR["sel_tl"], Msg.STR["tl_first"])
|
||||||
|
|
||||||
|
def handle_connection_state(self, action: str, tunnel_name: str = None) -> None:
|
||||||
|
"""
|
||||||
|
central management for connection states
|
||||||
|
|
||||||
|
Args:
|
||||||
|
action (str): "start", "stop" or "toggle"
|
||||||
|
tunnel_name (str, optional): name of a tunnel for a start-option. defaults to None.
|
||||||
|
"""
|
||||||
|
if action == "stop":
|
||||||
|
if self.a:
|
||||||
|
check_call(["nmcli", "connection", "down", self.a])
|
||||||
|
self.update_connection_display()
|
||||||
|
self.reset_fields()
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
elif action == "start":
|
||||||
|
if tunnel_name or self.a:
|
||||||
|
target_tunnel = tunnel_name or self.a
|
||||||
|
check_call(["nmcli", "connection", "up", target_tunnel])
|
||||||
|
self.update_connection_display()
|
||||||
|
data = self.handle_tunnel_data(self.a)
|
||||||
|
self.init_and_report(data)
|
||||||
|
self.show_data()
|
||||||
|
self.color_label()
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
elif action == "toggle":
|
||||||
|
if self.a:
|
||||||
|
self.handle_connection_state("stop")
|
||||||
|
else:
|
||||||
|
self.handle_connection_state("start")
|
||||||
|
|
||||||
|
def update_connection_display(self) -> None:
|
||||||
|
"""
|
||||||
|
Updated the display after connection changes
|
||||||
|
"""
|
||||||
|
self.a = Tunnel.active()
|
||||||
|
if not hasattr(self, "str_var"):
|
||||||
|
self.str_var = tk.StringVar()
|
||||||
|
self.str_var.set(self.a)
|
||||||
|
self.color_label()
|
||||||
|
self.show_data()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@ -871,5 +845,5 @@ if __name__ == "__main__":
|
|||||||
window.tk.call("set", "::tk::dialog::file::showHiddenVar", "0")
|
window.tk.call("set", "::tk::dialog::file::showHiddenVar", "0")
|
||||||
window.mainloop()
|
window.mainloop()
|
||||||
|
|
||||||
LxTools.clean_files(folder_path, user_file)
|
LxTools.clean_files(AppConfig.TEMP_DIR, AppConfig.USER_FILE)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
177
wp_app_config.py
Normal file
177
wp_app_config.py
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""App configuration for Wire-Py"""
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
import locale
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict, Any
|
||||||
|
|
||||||
|
class AppConfig:
|
||||||
|
"""Central configuration class for Wire-Py application"""
|
||||||
|
|
||||||
|
# Localization
|
||||||
|
APP_NAME: str = "wirepy"
|
||||||
|
LOCALE_DIR: Path = Path("/usr/share/locale/")
|
||||||
|
|
||||||
|
# Base paths
|
||||||
|
BASE_DIR: Path = Path.home()
|
||||||
|
CONFIG_DIR: Path = BASE_DIR / ".config/wire_py"
|
||||||
|
TEMP_DIR: Path = Path("/tmp/tlecdcwg")
|
||||||
|
USER_FILE: Path = Path("/tmp/.log_user")
|
||||||
|
|
||||||
|
# Configuration files
|
||||||
|
SETTINGS_FILE: Path = CONFIG_DIR / "settings"
|
||||||
|
KEYS_FILE: Path = CONFIG_DIR / "keys"
|
||||||
|
AUTOSTART_SERVICE: Path = Path.home() / ".config/systemd/user/wg_start.service"
|
||||||
|
|
||||||
|
# Default settings
|
||||||
|
DEFAULT_SETTINGS: Dict[str, Any] = {
|
||||||
|
"updates": "on",
|
||||||
|
"theme": "light",
|
||||||
|
"tooltip": True,
|
||||||
|
"autostart": "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
# UI configuration
|
||||||
|
UI_CONFIG: Dict[str, Any] = {
|
||||||
|
"window_title": "Wire-Py",
|
||||||
|
"window_size": (600, 383),
|
||||||
|
"font_family": "Ubuntu",
|
||||||
|
"font_size": 11,
|
||||||
|
"resizable_window": (False, False)
|
||||||
|
}
|
||||||
|
|
||||||
|
# System-dependent paths
|
||||||
|
SYSTEM_PATHS: Dict[str, str]= {
|
||||||
|
"ssl_decrypt": "/usr/local/bin/ssl_decrypt.py",
|
||||||
|
"ssl_encrypt": "/usr/local/bin/ssl_encrypt.py",
|
||||||
|
"tcl_path": "/usr/share/TK-Themes",
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Images and icons paths
|
||||||
|
IMAGE_PATHS: Dict[str, str] = {
|
||||||
|
"icon_vpn": "/usr/share/icons/lx-icons/48/wg_vpn.png",
|
||||||
|
"icon_msg": "/usr/share/icons/lx-icons/48/wg_msg.png",
|
||||||
|
"icon_import": "/usr/share/icons/lx-icons/48/wg_import.png",
|
||||||
|
"icon_export": "/usr/share/icons/lx-icons/48/wg_export.png",
|
||||||
|
"icon_trash": "/usr/share/icons/lx-icons/48/wg_trash.png",
|
||||||
|
"icon_start": "/usr/share/icons/lx-icons/48/wg_vpn-start.png",
|
||||||
|
"icon_stop": "/usr/share/icons/lx-icons/48/wg_vpn-stop.png",
|
||||||
|
"icon_info": "/usr/share/icons/lx-icons/64/info.png",
|
||||||
|
"icon_error": "/usr/share/icons/lx-icons/64/error.png"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setup_translations() -> gettext.gettext:
|
||||||
|
"""
|
||||||
|
Initialize translations and set the translation function
|
||||||
|
Special method for translating strings in this file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The gettext translation function
|
||||||
|
"""
|
||||||
|
locale.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR)
|
||||||
|
gettext.bindtextdomain(AppConfig.APP_NAME, AppConfig.LOCALE_DIR)
|
||||||
|
gettext.textdomain(AppConfig.APP_NAME)
|
||||||
|
return gettext.gettext
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def ensure_directories(cls) -> None:
|
||||||
|
"""Ensures that all required directories exist"""
|
||||||
|
cls.CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
cls.TEMP_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_default_settings(cls) -> None:
|
||||||
|
"""Creates default settings if they don't exist"""
|
||||||
|
if not cls.SETTINGS_FILE.exists():
|
||||||
|
content = "\n".join(f"[{k.upper()}]\n{v}" for k, v in cls.DEFAULT_SETTINGS.items())
|
||||||
|
cls.SETTINGS_FILE.write_text(content)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_image_paths(cls) -> Dict[str, Path]:
|
||||||
|
"""Returns paths to UI images"""
|
||||||
|
return {
|
||||||
|
"main_icon": cls.SYSTEM_PATHS["image_path"] / "48/wg_vpn.png",
|
||||||
|
"warning": cls.CONFIG_DIR / "images/warning.png",
|
||||||
|
"success": cls.CONFIG_DIR / "images/success.png",
|
||||||
|
"error": cls.CONFIG_DIR / "images/error.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_autostart_content(cls) -> str:
|
||||||
|
"""Returns the content for the autostart service file"""
|
||||||
|
return """[Unit]
|
||||||
|
Description=Automatic Tunnel Start
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStartPre=/bin/sleep 5
|
||||||
|
ExecStart=/usr/local/bin/start_wg.py
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target"""
|
||||||
|
|
||||||
|
# here is inizialize the class for translate strrings
|
||||||
|
_ = AppConfig.setup_translations()
|
||||||
|
|
||||||
|
class Msg:
|
||||||
|
"""
|
||||||
|
A utility class that provides centralized access to translated message strings.
|
||||||
|
|
||||||
|
This class contains a dictionary of message strings used throughout the Wire-Py application.
|
||||||
|
All strings are prepared for translation using gettext. The short key names make the code
|
||||||
|
more concise while maintaining readability.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
STR (dict): A dictionary mapping short keys to translated message strings.
|
||||||
|
Keys are abbreviated for brevity but remain descriptive.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
Import this class and access messages using the dictionary:
|
||||||
|
`Msg.STR["sel_tl"]` returns the translated "Select tunnel" message.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Ensure that gettext translation is properly initialized before
|
||||||
|
accessing these strings to ensure correct localization.
|
||||||
|
"""
|
||||||
|
STR: Dict[str, str] = {
|
||||||
|
# Strings for messages
|
||||||
|
"sel_tl": _("Select tunnel"),
|
||||||
|
"ren_err": _("Renaming not possible"),
|
||||||
|
"exp_succ": _("Export successful"),
|
||||||
|
"exp_in_home": _("Your zip file is in home directory"),
|
||||||
|
"imp_err": _("Import Error"),
|
||||||
|
"exp_err": _("Export Error"),
|
||||||
|
"exp_try": _("Export failed! Please try again"),
|
||||||
|
"tl_first": _("Please first import tunnel"),
|
||||||
|
"sel_list": _("Please select a tunnel from the list"),
|
||||||
|
"sign_len": _("The new name may contain only 12 characters"),
|
||||||
|
"zero_signs": _("At least one character must be entered"),
|
||||||
|
"false signs": _("No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n"),
|
||||||
|
"is_in_use": _("The tunnel is already in use"),
|
||||||
|
"no_valid_file": _("Oh... no valid Wireguard File!\nPlease select a valid Wireguard File"),
|
||||||
|
"tl_exist": _("Tunnel already available!\nPlease use another file for import")
|
||||||
|
|
||||||
|
}
|
||||||
|
TTIP: Dict[str, str] = {
|
||||||
|
#Strings for Tooltips
|
||||||
|
"start_tl": _("Click to start selected Wireguard Tunnel"),
|
||||||
|
"empty_list": _("No tunnels to start in the list"),
|
||||||
|
"stop_tl": _("Click to stop selected Wireguard Tunnel"),
|
||||||
|
"del_tl": _("Click to delete selected Wireguard Tunnel"),
|
||||||
|
"rename_tl": _("To rename a tunnel, you need to\nselect a tunnel from the list"),
|
||||||
|
"export_tl": _(" Click to export all\nWireguard Tunnel to Zipfile"),
|
||||||
|
"trash_tl": _("Click to delete a Wireguard Tunnel\nSelect from the list!"),
|
||||||
|
"autostart": _("To use the autostart, enable this Checkbox"),
|
||||||
|
"autostart_info": _("You must have at least one\ntunnel in the list,to use the autostart"),
|
||||||
|
"export_tl_info": _("No Tunnels in List for Export"),
|
||||||
|
"start_tl_info": _("Click to start selected Wireguard Tunnel"),
|
||||||
|
"rename_tl_info": _("To rename a tunnel, at least one must be in the list"),
|
||||||
|
"trash_tl_info": _("No tunnels to delete in the list"),
|
||||||
|
"list_auto_info": _("To use the autostart, a tunnel must be selected from the list")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user