94 Commits

Author SHA1 Message Date
6051ad1546 Version number update 2025-06-04 18:54:45 +02:00
f682858051 large update 2025-06-04 18:49:17 +02:00
68580d0ded return and back to back 2025-05-24 18:12:05 +02:00
b764547d16 fix in export method (remove !=0 by nemelist) 2025-05-24 16:26:44 +02:00
7f4fabe856 Enhanced export functionality with error handling and updated Active method implementation for improved error management 2025-05-24 14:53:56 +02:00
79f6fc0265 finish logging 2025-05-23 12:36:28 +02:00
5ac37ad9ad remove USER_FILE usage in ssl_decrypt.py and ssl_encrypt.py; switch to argparse for command-line arguments 2025-05-21 21:29:21 +02:00
4cdcfadbac class descriptions added redundancy reduced 2025-05-20 12:31:30 +02:00
55f2119bc3 conversion to app and configmanager part 2 export still missing 2025-05-19 21:35:14 +02:00
d6c20b81f9 part 1 load data from dictionary works 2025-05-18 12:47:52 +02:00
0c4d000d96 add ckeck_key_is_exist() for import 2025-05-12 16:48:48 +02:00
3da54642a0 ssl_de/encrypt new works 2025-05-12 15:11:40 +02:00
fb0158d1cd replace all check_call with subprocess.run 2025-05-11 22:00:28 +02:00
6604650adf ssl_decrypt.py now with output and check_call replace with subprocess.run 2025-05-11 18:24:57 +02:00
a903666a26 fix ssl_encrypt.py read user_log datei added again 2025-05-10 14:23:22 +02:00
d0adaa76e4 AppConfig and common_utils further developed for Zenrale configuration 2025-05-10 01:55:30 +02:00
481362b2e6 add new methode of get_username() as fallback and add own file_parser for replace con_to_dict 2025-05-09 16:04:43 +02:00
ca26576eab test with methode for username 2025-05-07 22:42:08 +02:00
f4a51f0050 fix message window a path errors 2025-05-07 20:25:09 +02:00
c56b42df3e add .gitignore to .gitignore 2025-05-07 19:29:00 +02:00
a62394e40e add remove .gitignore file 2025-05-07 19:28:35 +02:00
d6e9613157 new file .gitignore 2025-05-07 19:26:48 +02:00
786b909adc remove files and folders that are not for repo 2025-05-07 19:24:34 +02:00
a8aba71638 tooltips add x_offset: int = 65, y_offset: int = 40 as atribute for edit 2025-05-07 12:46:52 +02:00
742c6d0cc5 tooltip message complete with AppConfig Manager 2025-05-07 11:41:33 +02:00
42870e2942 trace_add() for menu labels works 2025-05-07 10:47:49 +02:00
9a4d8b3506 optimize performance 06-05-2025-23:00 2025-05-07 08:14:46 +02:00
dba6138aa7 optimize performance 06-05-2025 2025-05-06 19:47:14 +02:00
d0aed9e253 optimize performance 03-05-2025 2025-05-05 20:42:19 +02:00
0cdad100b6 part two more optimization with app_config file 2025-05-03 17:58:19 +02:00
2cdc40f414 part two more optimization with app_config file 2025-05-03 17:57:57 +02:00
2311661735 part one more optimization with app_config file 2025-04-30 23:24:00 +02:00
c10667ec21 bug fix in rename 2025-04-30 10:43:51 +02:00
08bef8fe6e add_wp_app_config.py for central configuration 2025-04-30 09:49:57 +02:00
2e94a324a6 add wp_app_config.py for central configuration 2025-04-30 09:48:40 +02:00
18ed97bf20 delete empty row 2025-04-29 16:20:07 +02:00
5dcfc91621 replace more "with open" 2025-04-29 15:09:56 +02:00
5fb4e68867 methods optimized-13:24 2025-04-29 13:25:03 +02:00
19d413ea97 optimized remove with open 2025-04-29 12:32:23 +02:00
213f772f40 methods optimized in wirepy and cls_mth_fc 2025-04-29 11:39:05 +02:00
6f02724daa with opening reduced 2025-04-29 09:02:06 +02:00
53f66ea76d method info and update to staticmethod 2025-04-28 21:16:21 +02:00
3039dbecb0 now only methodologies within the class 2025-04-28 19:55:44 +02:00
eadc2a06bf methods optimized 2025-04-28 12:35:19 +02:00
4eb9d6acd4 Message window optimized2 2025-04-26 22:33:59 +02:00
97ea07d34b Message window optimized 2025-04-26 21:32:35 +02:00
cd625d173d empty row add 2025-04-26 00:49:34 +02:00
950e04a246 korreckturen throughout code2 2025-04-26 00:41:17 +02:00
1a853d4ff1 korreckturen throughout code 2025-04-26 00:28:34 +02:00
f6204c9071 line formatted for better reading 2025-04-25 17:37:04 +02:00
f9ecd54e0a methods back in wirepy as functions "theme dark and light" 2025-04-25 16:19:36 +02:00
67ff24f0b6 fix set_file and remove wg_set variable 2025-04-25 14:42:37 +02:00
af702f297b rename wg_set to file_set fix LxTools.clean_files 2025-04-25 13:40:19 +02:00
d2a57b329b Class LxTools expands wg_set to set_file renamed 2025-04-24 23:04:34 +02:00
87943b2489 add new class LxTools and funktion to methode in new class 2025-04-24 12:43:39 +02:00
c43c12f961 rows reformat 2025-04-23 14:29:47 +02:00
3bab0710a4 replace "str(" with f"format{example}" 2025-04-23 14:18:06 +02:00
aa66f4dc68 remove return select_tl 2025-04-22 17:42:47 +02:00
c220951781 fix when list emty by start of wirepy 2025-04-22 17:11:46 +02:00
6c0662c62c import sorted 2025-04-22 14:26:04 +02:00
5753a35d6c fix new tooltip signal now in modul cls_mth_fc.py 2025-04-22 14:22:39 +02:00
47bdfbfb17 new class foe tooltip 2025-04-21 22:25:10 +02:00
2a3bf2bbcb add new class for tooltip 2025-04-21 13:29:36 +02:00
8896f59efd fix in converter and fix in import for no valid files 2025-04-21 09:39:35 +02:00
c58a630e25 format fixes 2025-04-20 00:43:01 +02:00
dc6f8cb094 format fixes 2025-04-20 00:09:04 +02:00
dcda647e90 format fixes 2025-04-19 23:29:06 +02:00
2a995eabd5 in cont_to_dict if replaced by get 2025-04-19 19:29:46 +02:00
ea750b0cfc fix tooltip "True" and "False" back to True and False 2025-04-19 14:40:37 +02:00
980ce3c7a7 Gitea response improved 2025-04-19 14:28:34 +02:00
28cc423138 class to functions and check=True to subprocess.run 2025-04-18 22:12:18 +02:00
39550b392d format with blank and pylint 2025-04-18 20:50:32 +02:00
582ef21042 reformat files 2025-04-18 15:04:22 +02:00
ca58ac86a4 fix ssldecrypt 2025-04-17 16:25:24 +02:00
177fa1cc34 fix installer 2025-04-13 20:44:28 +02:00
ca1a7a6b94 - Installer update for Open Suse Tumbleweed and Leap
- add symbolic link wirepy.py
2025-04-13 20:38:02 +02:00
a49c5b00e1 - Installer update python311 to python313 for Open Suse
- add symbolic link wirepy.py
2025-04-13 13:04:51 +02:00
75a247797d add install >/dev/null 2>&1 2025-04-09 08:51:18 +02:00
4b019b0c1f fix2 install 2025-04-09 08:27:21 +02:00
ab78eb4f59 fix installer 2025-04-09 08:16:25 +02:00
9f3f0246b4 Installer now with query and remove
icons merged
2025-04-09 08:08:48 +02:00
5302aae807 Installers will support other systems again
Installer is now finished clean with wrong password
Rename wg_main to wirepy
2025-04-07 12:46:45 +02:00
13832d916f ssl encrypt and decrypt works now 2025-03-19 21:24:33 +01:00
1667682c9d ssl part one 2025-03-08 22:13:22 +01:00
8771be760d Fixes a new user files create 2025-03-03 18:27:49 +01:00
97bf9df041 replace-old-files-with-new-files-and-remove-no longer needed 2025-03-02 15:33:42 +01:00
1bba45a6c1 add-new-install 2025-03-02 15:29:38 +01:00
a5eb6293c6 add-new-cls-mth-fc-file 2025-03-02 15:27:37 +01:00
6e54529c0f Merge pull request 'Fix for allow ipv6' (#31) from 24-02-2025 into main
Reviewed-on: #31
2025-02-24 18:59:04 +01:00
e28235af4b Fix for allow ipv6 2025-02-24 18:51:14 +01:00
862cc91fa1 Merge pull request '1.11.2124' (#30) from 1.11.2124 into main
Reviewed-on: #30
2024-11-17 13:04:26 +01:00
5fe6fd3f29 - Update Translate Files 2024-11-17 12:51:46 +01:00
48a48ffd4c - Update Translate Files 2024-11-17 12:49:41 +01:00
1278b02a95 - Update Translate Files 2024-11-17 12:28:05 +01:00
90 changed files with 1990 additions and 2367 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
debug.log
.venv
.venv.bak
.idea
.vscode
__pycache__

View File

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated
View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (wire-py)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (wire-py)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated
View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/wire-py.iml" filepath="$PROJECT_DIR$/.idea/wire-py.iml" />
</modules>
</component>
</project>

File diff suppressed because one or more lines are too long

View File

@ -1,4 +0,0 @@
<changelist name="Uncommitted_changes_before_Checkout_at_19_08_24,_06_49_[Changes]" date="1724042999949" recycled="false" toDelete="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Checkout_at_19_08_24,_06_49_[Changes]/shelved.patch" />
<option name="DESCRIPTION" value="Uncommitted changes before Checkout at 19.08.24, 06:49 [Changes]" />
</changelist>

6
.idea/vcs.xml generated
View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

10
.idea/wire-py.iml generated
View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

618
.idea/workspace.xml generated
View File

@ -1,618 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment="- methods from class MainWindow move to class FrameWidgets for active color_label when theme change&#10;- optimize columnconfigure, rowconfigure in class MainWindow and FrameWidgets&#10;- add new Frame for Widgets on Bottom&#10;- optimize from tkinter * to from tkinter import filedialog, ttk, TclError">
<change afterPath="$PROJECT_DIR$/lx-icons/128/error.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/128/info.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/256/error.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/256/info.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/32/error.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/32/info.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/48/error.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/48/info.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/64/error.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/lx-icons/64/info.png" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/install" beforeDir="false" afterPath="$PROJECT_DIR$/install" afterDir="false" />
<change beforePath="$PROJECT_DIR$/wg_func.py" beforeDir="false" afterPath="$PROJECT_DIR$/cls_mth_fc.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/wg_main.py" beforeDir="false" afterPath="$PROJECT_DIR$/wg_main.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="1.11.0824" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
<option name="UPDATE_TYPE" value="REBASE" />
</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">{
&quot;associatedIndex&quot;: 3
}</component>
<component name="ProjectId" id="2kSbZdjOvr0wsVJSNcaMwSfVaxR" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_ADD_EXTERNAL_FILES": "true",
"Python.INSTALL.executor": "Run",
"Python.install.executor": "Run",
"Python.main.executor": "Run",
"Python.messagebox.executor": "Run",
"Python.start_wg.executor": "Run",
"Python.testtheme.executor": "Run",
"Python.wg_func.executor": "Run",
"Python.wg_main.executor": "Run",
"RunOnceActivity.ShowReadmeOnStart": "true",
"Shell Script.install.executor": "Run",
"Shell Script.run_as.executor": "Run",
"git-widget-placeholder": "1.11.0824",
"last_opened_file_path": "/home/punix/Pyapps/wire-py/lx-icons",
"settings.editor.selected.configurable": "reference.settingsdialog.IDE.editor.colors"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/lx-icons" />
<recent name="$PROJECT_DIR$" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/TK-Themes/theme" />
<recent name="$PROJECT_DIR$/TK-Themes" />
<recent name="$PROJECT_DIR$" />
<recent name="$PROJECT_DIR$/wire-py" />
</key>
</component>
<component name="RunManager" selected="Python.wg_main">
<configuration name="start_wg" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="wire-py" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/start_wg.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="wg_main" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
<module name="wire-py" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/wg_main.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python.start_wg" />
</list>
</recent_temporary>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-python-sdk-8336bb23522e-31b6be0877a2-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-241.19072.16" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment="" />
<created>1723279982210</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1723279982210</updated>
</task>
<task id="LOCAL-00020" summary="columnconfigure on all widgets set">
<option name="closed" value="true" />
<created>1724778892233</created>
<option name="number" value="00020" />
<option name="presentableId" value="LOCAL-00020" />
<option name="project" value="LOCAL" />
<updated>1724778892233</updated>
</task>
<task id="LOCAL-00021" summary="little fixes a &quot; &quot; to ' '">
<option name="closed" value="true" />
<created>1725119445803</created>
<option name="number" value="00021" />
<option name="presentableId" value="LOCAL-00021" />
<option name="project" value="LOCAL" />
<updated>1725119445803</updated>
</task>
<task id="LOCAL-00022" summary="add class FileHandle,&#10;add Label to show autoconnect Tunnel&#10;disable checkbox when Listbox is empty or no select Tunnel">
<option name="closed" value="true" />
<created>1725391658456</created>
<option name="number" value="00022" />
<option name="presentableId" value="LOCAL-00022" />
<option name="project" value="LOCAL" />
<updated>1725391658456</updated>
</task>
<task id="LOCAL-00023" summary="add if question and add autoconnect, autoconnect_var to class Filehandle in box_set no finish!">
<option name="closed" value="true" />
<created>1725434328731</created>
<option name="number" value="00023" />
<option name="presentableId" value="LOCAL-00023" />
<option name="project" value="LOCAL" />
<updated>1725434328731</updated>
</task>
<task id="LOCAL-00024" summary="fixes on empty Listbox now is disable and now works autoconnect label with read and write, delete works now with read and write">
<option name="closed" value="true" />
<created>1725475967338</created>
<option name="number" value="00024" />
<option name="presentableId" value="LOCAL-00024" />
<option name="project" value="LOCAL" />
<updated>1725475967338</updated>
</task>
<task id="LOCAL-00025" summary="add Frame widget 3&#10;for Buttons and Listbox with Scrollbar.&#10;all Widgets new format&#10;delete works now of disable checkbox when Listbox empty (part two)">
<option name="closed" value="true" />
<created>1725567453540</created>
<option name="number" value="00025" />
<option name="presentableId" value="LOCAL-00025" />
<option name="project" value="LOCAL" />
<updated>1725567453540</updated>
</task>
<task id="LOCAL-00026" summary="little fixes">
<option name="closed" value="true" />
<created>1725639633873</created>
<option name="number" value="00026" />
<option name="presentableId" value="LOCAL-00026" />
<option name="project" value="LOCAL" />
<updated>1725639633873</updated>
</task>
<task id="LOCAL-00027" summary="little fixes">
<option name="closed" value="true" />
<created>1725746027132</created>
<option name="number" value="00027" />
<option name="presentableId" value="LOCAL-00027" />
<option name="project" value="LOCAL" />
<updated>1725746027132</updated>
</task>
<task id="LOCAL-00028" summary="little fixes replace os.system with check_call&#10;first steps in install Script add wg_start.service file">
<option name="closed" value="true" />
<created>1725820337669</created>
<option name="number" value="00028" />
<option name="presentableId" value="LOCAL-00028" />
<option name="project" value="LOCAL" />
<updated>1725820337669</updated>
</task>
<task id="LOCAL-00029" summary="little fixes a labels when stop and start, installer first functions works">
<option name="closed" value="true" />
<created>1725991610908</created>
<option name="number" value="00029" />
<option name="presentableId" value="LOCAL-00029" />
<option name="project" value="LOCAL" />
<updated>1725991610908</updated>
</task>
<task id="LOCAL-00030" summary="little fixes, add msg_window() &#10;function for Messagebox to show a tk.Toplevel()&#10;replace var = open() with: &#10;with open() as var:&#10;and remove by classes (tk.tk) and super()">
<option name="closed" value="true" />
<created>1726349168248</created>
<option name="number" value="00030" />
<option name="presentableId" value="LOCAL-00030" />
<option name="project" value="LOCAL" />
<updated>1726349168248</updated>
</task>
<task id="LOCAL-00031" summary="in delete replace open with Path&#10;install fixes">
<option name="closed" value="true" />
<created>1726359012150</created>
<option name="number" value="00031" />
<option name="presentableId" value="LOCAL-00031" />
<option name="project" value="LOCAL" />
<updated>1726359012150</updated>
</task>
<task id="LOCAL-00032" summary="new format little fixes icons sort add policy add .desktop File install Part 2">
<option name="closed" value="true" />
<created>1726599446537</created>
<option name="number" value="00032" />
<option name="presentableId" value="LOCAL-00032" />
<option name="project" value="LOCAL" />
<updated>1726599446538</updated>
</task>
<task id="LOCAL-00033" summary="install fix for set dir right">
<option name="closed" value="true" />
<created>1726599588155</created>
<option name="number" value="00033" />
<option name="presentableId" value="LOCAL-00033" />
<option name="project" value="LOCAL" />
<updated>1726599588155</updated>
</task>
<task id="LOCAL-00034" summary="fix checkbox disable and policy rename main.py to wg_main.py">
<option name="closed" value="true" />
<created>1726650691719</created>
<option name="number" value="00034" />
<option name="presentableId" value="LOCAL-00034" />
<option name="project" value="LOCAL" />
<updated>1726650691719</updated>
</task>
<task id="LOCAL-00035" summary="fix rename in Messagebox warning to error">
<option name="closed" value="true" />
<created>1726652747322</created>
<option name="number" value="00035" />
<option name="presentableId" value="LOCAL-00035" />
<option name="project" value="LOCAL" />
<updated>1726652747322</updated>
</task>
<task id="LOCAL-00036" summary="set rights in install and a .conf a import Tunnel Filedialog Part 1 /home when open">
<option name="closed" value="true" />
<created>1726691611936</created>
<option name="number" value="00036" />
<option name="presentableId" value="LOCAL-00036" />
<option name="project" value="LOCAL" />
<updated>1726691611936</updated>
</task>
<task id="LOCAL-00037" summary="fix set rights in install and a .conf a import Tunnel Filedialog Part 1 /home when open">
<option name="closed" value="true" />
<created>1726734843529</created>
<option name="number" value="00037" />
<option name="presentableId" value="LOCAL-00037" />
<option name="project" value="LOCAL" />
<updated>1726734843529</updated>
</task>
<task id="LOCAL-00038" summary="fix a filedialog for hidden Files work&#10;install rollback to bash for start wirepy and wirepy rollback to bash">
<option name="closed" value="true" />
<created>1726764877546</created>
<option name="number" value="00038" />
<option name="presentableId" value="LOCAL-00038" />
<option name="project" value="LOCAL" />
<updated>1726764877546</updated>
</task>
<task id="LOCAL-00039" summary="install rollback bash to py wirepy and wirepy rollback to py">
<option name="closed" value="true" />
<created>1726770649542</created>
<option name="number" value="00039" />
<option name="presentableId" value="LOCAL-00039" />
<option name="project" value="LOCAL" />
<updated>1726770649542</updated>
</task>
<task id="LOCAL-00040" summary="fix install and .desktop File Tar works now for user home and filebrowser.askfilebrowser start now in user home">
<option name="closed" value="true" />
<created>1726777434040</created>
<option name="number" value="00040" />
<option name="presentableId" value="LOCAL-00040" />
<option name="project" value="LOCAL" />
<updated>1726777434040</updated>
</task>
<task id="LOCAL-00041" summary="replace tar with zip and Check if Zip file is empty">
<option name="closed" value="true" />
<created>1726836930251</created>
<option name="number" value="00041" />
<option name="presentableId" value="LOCAL-00041" />
<option name="project" value="LOCAL" />
<updated>1726836930251</updated>
</task>
<task id="LOCAL-00042" summary="Create your own message boxes for export">
<option name="closed" value="true" />
<created>1726841190285</created>
<option name="number" value="00042" />
<option name="presentableId" value="LOCAL-00042" />
<option name="project" value="LOCAL" />
<updated>1726841190285</updated>
</task>
<task id="LOCAL-00043" summary="chown Export File to 1000:1000">
<option name="closed" value="true" />
<created>1726860371820</created>
<option name="number" value="00043" />
<option name="presentableId" value="LOCAL-00043" />
<option name="project" value="LOCAL" />
<updated>1726860371820</updated>
</task>
<task id="LOCAL-00044" summary="add rename Label rename works">
<option name="closed" value="true" />
<created>1726915238475</created>
<option name="number" value="00044" />
<option name="presentableId" value="LOCAL-00044" />
<option name="project" value="LOCAL" />
<updated>1726915238475</updated>
</task>
<task id="LOCAL-00045" summary="add con_to_dict in import for write PreSharedKey in .key File to warning if tunnel has already been imported and delete that the key is deleted again">
<option name="closed" value="true" />
<created>1726959423800</created>
<option name="number" value="00045" />
<option name="presentableId" value="LOCAL-00045" />
<option name="project" value="LOCAL" />
<updated>1726959423800</updated>
</task>
<task id="LOCAL-00046" summary="add con_to_dict in import for write PreSharedKey in .key File to warning if tunnel has already been imported and delete that the key is deleted again&#10;now works">
<option name="closed" value="true" />
<created>1727015078922</created>
<option name="number" value="00046" />
<option name="presentableId" value="LOCAL-00046" />
<option name="project" value="LOCAL" />
<updated>1727015078922</updated>
</task>
<task id="LOCAL-00047" summary="Descriptions added in wg_func-py">
<option name="closed" value="true" />
<created>1727018233930</created>
<option name="number" value="00047" />
<option name="presentableId" value="LOCAL-00047" />
<option name="project" value="LOCAL" />
<updated>1727018233930</updated>
</task>
<task id="LOCAL-00048" summary="If tunnel is renamed and this is in the car start,&#10;is now renamed the label">
<option name="closed" value="true" />
<created>1727028762875</created>
<option name="number" value="00048" />
<option name="presentableId" value="LOCAL-00048" />
<option name="project" value="LOCAL" />
<updated>1727028762875</updated>
</task>
<task id="LOCAL-00049" summary="fix scrollbar view with set self.y_height = 330 to self.y_height = 340">
<option name="closed" value="true" />
<created>1727028915701</created>
<option name="number" value="00049" />
<option name="presentableId" value="LOCAL-00049" />
<option name="project" value="LOCAL" />
<updated>1727028915701</updated>
</task>
<task id="LOCAL-00050" summary="in msg_window two further parameters to be added to the pass, so height and wide can also be specified.&#10;In rename, messages come now if new names do not fit&#10;Fix Index Error on msg_window()">
<option name="closed" value="true" />
<created>1727118598759</created>
<option name="number" value="00050" />
<option name="presentableId" value="LOCAL-00050" />
<option name="project" value="LOCAL" />
<updated>1727118598760</updated>
</task>
<task id="LOCAL-00051" summary="ad max 12-character message, no character message and special_characters message for entry label">
<option name="closed" value="true" />
<created>1727288788988</created>
<option name="number" value="00051" />
<option name="presentableId" value="LOCAL-00051" />
<option name="project" value="LOCAL" />
<updated>1727288788988</updated>
</task>
<task id="LOCAL-00052" summary="info icon shadow fix end msg Export fix to">
<option name="closed" value="true" />
<created>1727347126769</created>
<option name="number" value="00052" />
<option name="presentableId" value="LOCAL-00052" />
<option name="project" value="LOCAL" />
<updated>1727347126769</updated>
</task>
<task id="LOCAL-00053" summary="little fixes">
<option name="closed" value="true" />
<created>1727378355274</created>
<option name="number" value="00053" />
<option name="presentableId" value="LOCAL-00053" />
<option name="project" value="LOCAL" />
<updated>1727378355275</updated>
</task>
<task id="LOCAL-00054" summary="fix msg_boxes when tunnel list = 0 a Start, Delete and Export">
<option name="closed" value="true" />
<created>1727379755537</created>
<option name="number" value="00054" />
<option name="presentableId" value="LOCAL-00054" />
<option name="project" value="LOCAL" />
<updated>1727379755537</updated>
</task>
<task id="LOCAL-00055" summary="fix installer add .keys file">
<option name="closed" value="true" />
<created>1727380793216</created>
<option name="number" value="00055" />
<option name="presentableId" value="LOCAL-00055" />
<option name="project" value="LOCAL" />
<updated>1727380793216</updated>
</task>
<task id="LOCAL-00056" summary="Changelog create When exporting, the folder is now copied to /tmp and the non .conf files are deleted before the zip file is created. In main.py os import removed. Since os have been replaced by pathlib and shutil.&#10;Start with version number 1.4.7&#10;Message window size corrected so text is displayed better">
<option name="closed" value="true" />
<created>1727525609727</created>
<option name="number" value="00056" />
<option name="presentableId" value="LOCAL-00056" />
<option name="project" value="LOCAL" />
<updated>1727525609728</updated>
</task>
<task id="LOCAL-00057" summary="Fix msg_window and remove x , y argument&#10;Install further adapted and with colored&#10;text if user is not in group sudo or wheel.&#10;Added to install Opensuse for installation">
<option name="closed" value="true" />
<created>1728059870005</created>
<option name="number" value="00057" />
<option name="presentableId" value="LOCAL-00057" />
<option name="project" value="LOCAL" />
<updated>1728059870005</updated>
</task>
<task id="LOCAL-00058" summary=" - Menu add &#10; - New Modern Dark and Light(default) Theme">
<option name="closed" value="true" />
<created>1729103964804</created>
<option name="number" value="00058" />
<option name="presentableId" value="LOCAL-00058" />
<option name="project" value="LOCAL" />
<updated>1729103964804</updated>
</task>
<task id="LOCAL-00059" summary=" - Theme modify to water-theme&#10; - add ttk.Menubutton vor modern Menu and automatic theme and textvariable for color on font in menu">
<option name="closed" value="true" />
<created>1729283656386</created>
<option name="number" value="00059" />
<option name="presentableId" value="LOCAL-00059" />
<option name="project" value="LOCAL" />
<updated>1729283656387</updated>
</task>
<task id="LOCAL-00060" summary=" - Theme modify to water-theme&#10; - add ttk.Menubutton vor modern Menu and automatic theme and textvariable for color on font in menu">
<option name="closed" value="true" />
<created>1729283719951</created>
<option name="number" value="00060" />
<option name="presentableId" value="LOCAL-00060" />
<option name="project" value="LOCAL" />
<updated>1729283719951</updated>
</task>
<task id="LOCAL-00061" summary=" - Add Options, Help, Update Label and Update Menubutton &#10; - Theme now separate Light and Dark">
<option name="closed" value="true" />
<created>1729353898829</created>
<option name="number" value="00061" />
<option name="presentableId" value="LOCAL-00061" />
<option name="project" value="LOCAL" />
<updated>1729353898830</updated>
</task>
<task id="LOCAL-00062" summary="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip">
<option name="closed" value="true" />
<created>1729541504291</created>
<option name="number" value="00062" />
<option name="presentableId" value="LOCAL-00062" />
<option name="project" value="LOCAL" />
<updated>1729541504292</updated>
</task>
<task id="LOCAL-00063" summary="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip">
<option name="closed" value="true" />
<created>1729541561434</created>
<option name="number" value="00063" />
<option name="presentableId" value="LOCAL-00063" />
<option name="project" value="LOCAL" />
<updated>1729541561434</updated>
</task>
<task id="LOCAL-00064" summary="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip">
<option name="closed" value="true" />
<created>1729593628907</created>
<option name="number" value="00064" />
<option name="presentableId" value="LOCAL-00064" />
<option name="project" value="LOCAL" />
<updated>1729593628908</updated>
</task>
<task id="LOCAL-00065" summary="- Optimize Class and Tooltip">
<option name="closed" value="true" />
<created>1729938941026</created>
<option name="number" value="00065" />
<option name="presentableId" value="LOCAL-00065" />
<option name="project" value="LOCAL" />
<updated>1729938941027</updated>
</task>
<task id="LOCAL-00066" summary="- methods from class MainWindow move to class FrameWidgets for active color_label when theme change&#10;- optimize columnconfigure, rowconfigure in class MainWindow and FrameWidgets&#10;- add new Frame for Widgets on Bottom&#10;- optimize from tkinter * to from tkinter import filedialog, ttk, TclError">
<option name="closed" value="true" />
<created>1731097309468</created>
<option name="number" value="00066" />
<option name="presentableId" value="LOCAL-00066" />
<option name="project" value="LOCAL" />
<updated>1731097309468</updated>
</task>
<task id="LOCAL-00067" summary="- methods from class MainWindow move to class FrameWidgets for active color_label when theme change&#10;- optimize columnconfigure, rowconfigure in class MainWindow and FrameWidgets&#10;- add new Frame for Widgets on Bottom&#10;- optimize from tkinter * to from tkinter import filedialog, ttk, TclError">
<option name="closed" value="true" />
<created>1731097969343</created>
<option name="number" value="00067" />
<option name="presentableId" value="LOCAL-00067" />
<option name="project" value="LOCAL" />
<updated>1731097969344</updated>
</task>
<task id="LOCAL-00068" summary="- methods from class MainWindow move to class FrameWidgets for active color_label when theme change&#10;- optimize columnconfigure, rowconfigure in class MainWindow and FrameWidgets&#10;- add new Frame for Widgets on Bottom&#10;- optimize from tkinter * to from tkinter import filedialog, ttk, TclError">
<option name="closed" value="true" />
<created>1731098372497</created>
<option name="number" value="00068" />
<option name="presentableId" value="LOCAL-00068" />
<option name="project" value="LOCAL" />
<updated>1731098372497</updated>
</task>
<option name="localTasksCounter" value="69" />
<servers />
</component>
<component name="UnknownFeatures">
<option featureType="com.intellij.fileTypeFactory" implementationName="*.policy" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State>
<option name="FILTERS">
<map>
<entry key="branch">
<value>
<list>
<option value="1.11.0824" />
</list>
</value>
</entry>
</map>
</option>
</State>
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="install rollback bash to py wirepy and wirepy rollback to py" />
<MESSAGE value="fix install and .desktop File Tar works now for user home and filebrowser.askfilebrowser start now in user home" />
<MESSAGE value="replace tar with zip and Check if Zip file is empty" />
<MESSAGE value="Create your own message boxes for export" />
<MESSAGE value="chown Export File to 1000:1000" />
<MESSAGE value="add rename Label rename works" />
<MESSAGE value="add con_to_dict in import for write PreSharedKey in .key File to warning if tunnel has already been imported and delete that the key is deleted again" />
<MESSAGE value="add con_to_dict in import for write PreSharedKey in .key File to warning if tunnel has already been imported and delete that the key is deleted again&#10;now works" />
<MESSAGE value="Descriptions added in wg_func-py" />
<MESSAGE value="If tunnel is renamed and this is in the car start,&#10;is now renamed the label" />
<MESSAGE value="fix scrollbar view with set self.y_height = 330 to self.y_height = 340" />
<MESSAGE value="in msg_window two further parameters to be added to the pass, so height and wide can also be specified.&#10;In rename, messages come now if new names do not fit&#10;Fix Index Error on msg_window()" />
<MESSAGE value="ad max 12-character message, no character message and special_characters message for entry label" />
<MESSAGE value="info icon shadow fix end msg Export fix to" />
<MESSAGE value="little fixes" />
<MESSAGE value="fix msg_boxes when tunnel list = 0 a Start, Delete and Export" />
<MESSAGE value="fix installer add .keys file" />
<MESSAGE value="Changelog create When exporting, the folder is now copied to /tmp and the non .conf files are deleted before the zip file is created. In main.py os import removed. Since os have been replaced by pathlib and shutil.&#10;Start with version number 1.4.7&#10;Message window size corrected so text is displayed better" />
<MESSAGE value="Fix msg_window and remove x , y argument&#10;Install further adapted and with colored&#10;text if user is not in group sudo or wheel.&#10;Added to install Opensuse for installation" />
<MESSAGE value=" - Menu add &#10; - New Modern Dark and Light(default) Theme" />
<MESSAGE value=" - Theme modify to water-theme&#10; - add ttk.Menubutton vor modern Menu and automatic theme and textvariable for color on font in menu" />
<MESSAGE value=" - Add Options, Help, Update Label and Update Menubutton &#10; - Theme now separate Light and Dark" />
<MESSAGE value="- Optimize Class. Move to wg_main Import Start/StopBTN and Tooltip" />
<MESSAGE value="- Optimize Class and Tooltip" />
<MESSAGE value="- methods from class MainWindow move to class FrameWidgets for active color_label when theme change&#10;- optimize columnconfigure, rowconfigure in class MainWindow and FrameWidgets&#10;- add new Frame for Widgets on Bottom&#10;- optimize from tkinter * to from tkinter import filedialog, ttk, TclError" />
<option name="LAST_COMMIT_MESSAGE" value="- methods from class MainWindow move to class FrameWidgets for active color_label when theme change&#10;- optimize columnconfigure, rowconfigure in class MainWindow and FrameWidgets&#10;- add new Frame for Widgets on Bottom&#10;- optimize from tkinter * to from tkinter import filedialog, ttk, TclError" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/start_wg.py</url>
<line>1</line>
<option name="timeStamp" value="2" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

View File

@ -3,16 +3,53 @@ My standard System: Linux Mint 22 Cinnamon
## [Unreleased]
- os import in cls_mth_fc.py replaced by other methods
- os import in common_tools.py replaced by other methods
- If Wire-Py already runs, prevent further start
- for loops with lists replaced by List Comprehensions
- Update search after start of Wire-Py
### Added
04-06-2025
- large update in the module were outsourced and can now be used as
dependencies to wirepy us other apps from git.ilunix.de
### Added
13-04-20255
- Installer update for Open Suse Tumbleweed and Leap
- add symbolic link wirepy.py
### Added
09-04-2025
- Installer now with query and remove
- Icons merged
### Added
07-04-2025
- Installers will support other systems again
- Installer is now finished clean with wrong password
- Rename wg_main to wirepy
### Added
03-03-2025
- Fixes a new user files create
### Added
07-11-2024
- remove classes and add methods to class FrameWidgets (removed self errors)
02-03-2025
- Fix ipv6 in Config File on import
- Wirepy run now as user
- 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.
- Tunnels are now read from the directory to view them in the list.
To display only own tunnels, and read errors are minimized.
### Added
10-11-2024
@ -62,7 +99,7 @@ My standard System: Linux Mint 22 Cinnamon
### Added
27-10-2024
- Add Autoconnect settings to settings.conf
- Add Autoconnect settings to settings
### Added
@ -70,7 +107,7 @@ My standard System: Linux Mint 22 Cinnamon
- Add run_as Bash script and open_gitea.py python script
- Add Tooltip disable/enable
- Rename settings to settings.conf for theme, updates and tooltip enable in one file
- Rename settings to settings for theme, updates and tooltip enable in one file
### Added

4
Wire-Py.desktop Executable file → Normal file
View File

@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=Wire-Py
Exec=/usr/bin/wirepy.py
Exec=/usr/local/bin/wirepy.py
Terminal=false
Categories=Network;
Icon=/usr/share/icons/wp-icons/128/wg_vpn.png
Icon=/usr/share/icons/lx-icons/128/wg_vpn.png

View File

@ -1,272 +0,0 @@
""" Classes Method and functions for lx apps """
import gettext
import locale
import os
import shutil
import subprocess
import tkinter as tk
import zipfile
from datetime import datetime
from pathlib import Path
from tkinter import ttk
import requests
APP = 'cls_mth_fc'
LOCALE_DIR = "/usr/share/locale/"
locale.bindtextdomain(APP, LOCALE_DIR)
gettext.bindtextdomain(APP, LOCALE_DIR)
gettext.textdomain(APP)
_ = gettext.gettext
wg_set = Path('/etc/wire_py/settings.conf')
_u = Path.read_text(Path('/tmp/_u'))
class GiteaUpdate:
"""
Calling api_down requests the URL and the version of the running script.
Example: version = 'v. 1.1.1.1' GiteaUpdate.api_down(http://example.de, version)
Calling download requests the download URL of the running script,
the taskbar image for the “Download OK” window, the taskbar image for the
“Download error” window and the variable res
"""
@staticmethod
def api_down(update_api_url, version):
try:
response = requests.get(update_api_url)
response_dict = response.json()
response_dict = response_dict[0]
with open(wg_set, 'r') as set_file:
set_file = set_file.read()
if 'on\n' in set_file:
if version[3:] != response_dict['tag_name']:
return response_dict['tag_name']
else:
return 'No Updates'
else:
return 'False'
except requests.exceptions.ConnectionError:
return 'No Internet Connection!'
@staticmethod
def download(urld, down_ok_image, down_not_ok_image, res):
try:
to_down = 'wget -qP ' + str(_u) + ' ' + urld
result = subprocess.call(to_down, shell=True)
if result == 0:
shutil.chown(str(_u) + f'/{res}.zip', 1000, 1000)
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/lx-icons/64/info.png'
ii = down_ok_image
wt = _('Download Successful')
msg_t = _('Your zip file is in home directory')
msg_window(iw, ii, wt, msg_t)
else:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/lx-icons/64/error.png'
ii = down_not_ok_image
wt = _('Download error')
msg_t = _('Download failed! Please try again')
msg_window(iw, ii, wt, msg_t)
except subprocess.CalledProcessError:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/lx-icons/64/error.png'
ii = down_not_ok_image
wt = _('Download error')
msg_t = _('Download failed! No internet connection!')
msg_window(iw, ii, wt, msg_t)
def msg_window(img_w, img_i, w_title, w_txt, txt2=None, com=None):
"""
Function for different message windows for the user. with 4 arguments to be passed.
To create messages with your own images, icons, and titles. As an alternative to Python Messagebox.
Paths to images must be specified: r'/usr/share/icons/lx-icons/64/info.png'
img_w = Image for Tk Window
img_i = Image for Icon
w_title = Windows Title
w_txt = Text for Tk Window
txt2 = Text for Button two
com = function for Button command
"""
msg = tk.Toplevel()
msg.resizable(width=False, height=False)
msg.title(w_title)
msg.configure(pady=15, padx=15)
msg.img = tk.PhotoImage(file=img_w)
msg.i_window = tk.Label(msg, image=msg.img)
label = tk.Label(msg, text=w_txt)
label.grid(column=1, row=0)
if txt2 is not None and com is not None:
label.config(font=('Ubuntu', 11), padx=15, justify='left')
msg.i_window.grid(column=0, row=0, sticky='nw')
button2 = ttk.Button(msg, text=f'{txt2}', command=com, padding=4)
button2.grid(column=0, row=1, sticky='e', columnspan=2)
button = ttk.Button(msg, text='OK', command=msg.destroy, padding=4)
button.grid(column=0, row=1, sticky='w', columnspan=2)
else:
label.config(font=('Ubuntu', 11), padx=15)
msg.i_window.grid(column=0, row=0)
button = ttk.Button(msg, text='OK', command=msg.destroy, padding=4)
button.grid(column=0, columnspan=2, row=1)
img_i = tk.PhotoImage(file=img_i)
msg.iconphoto(True, img_i)
msg.columnconfigure(0, weight=1)
msg.rowconfigure(0, weight=1)
msg.winfo_toplevel()
class Tunnel:
"""
Class of Methods for Wire-Py
"""
"""
The config file is packed into a dictionary,
to display the values Address , DNS and Peer in the labels
"""
@classmethod
def con_to_dict(cls, file):
dictlist = []
for lines in file.readlines():
line_plit = lines.split()
dictlist = dictlist + line_plit
dictlist.remove('[Interface]')
dictlist.remove('[Peer]')
for items in dictlist:
if items == '=':
dictlist.remove(items)
''' Here is the beginning (Loop) of convert List to Dictionary '''
for _ in dictlist:
a = [dictlist[0], dictlist[1]]
b = [dictlist[2], dictlist[3]]
c = [dictlist[4], dictlist[5]]
d = [dictlist[6], dictlist[7]]
e = [dictlist[8], dictlist[9]]
f = [dictlist[10], dictlist[11]]
g = [dictlist[12], dictlist[13]]
h = [dictlist[14], dictlist[15]]
new_list = [a, b, c, d, e, f, g, h]
final_dict = {}
for elements in new_list:
final_dict[elements[0]] = elements[1]
''' end... result a Dictionary '''
address = final_dict['Address']
dns = final_dict['DNS']
if ',' in dns:
dns = dns[:-1]
endpoint = final_dict['Endpoint']
if 'PresharedKey' in final_dict:
pre_key = final_dict['PresharedKey']
else:
pre_key = final_dict['PreSharedKey']
return address, dns, endpoint, pre_key
"""
Shows the Active Tunnel
"""
@staticmethod
def active():
active = os.popen('nmcli con show --active | grep -iPo "(.*)(wireguard)"').read().split()
if not active:
active = ''
else:
active = active[0]
return active
"""
Shows all existing Wireguard tunnels
"""
@staticmethod
def list():
wg_s = os.popen('nmcli con show | grep -iPo "(.*)(wireguard)"').read().split()
''' tl = Tunnel list # Show of 4.Element in list '''
tl = wg_s[::3]
return tl
"""
This will export the tunnels.
A zipfile with current date and time is created
in the user's home directory with correct right
"""
@staticmethod
def export():
_u1 = str(_u[6:])
now_time = datetime.now()
now_datetime = now_time.strftime('wg-exp-' + '%m-%d-%Y' + '-' + '%H:%M')
tl = Tunnel.list()
try:
if len(tl) != 0:
wg_tar = str(_u) + '/' + now_datetime
shutil.copytree('/etc/wire_py', '/tmp/wire_py', dirs_exist_ok=True)
source = Path('/tmp/wire_py')
Path.unlink(Path(source) / 'wg_py', missing_ok=True)
Path.unlink(Path(source) / '.keys', missing_ok=True)
Path.unlink(Path(source) / 'settings.conf', missing_ok=True)
shutil.make_archive(wg_tar, 'zip', source)
shutil.chown(wg_tar + '.zip', 1000, 1000)
shutil.rmtree(source)
with zipfile.ZipFile((wg_tar + '.zip'), 'r') as zf:
if len(zf.namelist()) != 0:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/lx-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_vpn.png'
wt = _('Export Successful')
msg_t = _('Your zip file is in home directory')
msg_window(iw, ii, wt, msg_t)
else:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/lx-icons/64/error.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = _('Export error')
msg_t = _('Export failed! Please try again')
msg_window(iw, ii, wt, msg_t)
else:
"""img_w, img_i, w_title, w_txt hand over"""
iw = r'/usr/share/icons/lx-icons/64/info.png'
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
wt = _('Select tunnel')
msg_t = _('Please first import tunnel')
msg_window(iw, ii, wt, msg_t)
except TypeError:
pass
class Tipi:
"""
Class for Tooltip setting write in File
Calling request path to file
"""
@staticmethod
def if_tip(path):
with open(path, 'r') as set_file2:
lines2 = set_file2.readlines()
if 'False\n' in lines2:
return False
else:
return True
wg_tips = Tipi.if_tip(wg_set)

135
install
View File

@ -1,135 +0,0 @@
#!/bin/bash
NORMAL='\033[0m'
GREEN='\033[1;32m'
RED='\033[31;1;42m'
BLUE='\033[30;1;34m'
install_file_with(){
clear
sudo apt install python3-tk && \
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && sudo cp -u settings.conf /etc/wire_py/ && \
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
sudo cp -u wg_start.service /lib/systemd/system/ && \
sudo systemctl enable wg_start.service
}
install_arch_d(){
clear
sudo pacman -S --noconfirm tk python3 python-requests && \
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && sudo cp -u settings.conf /etc/wire_py/ && \
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
sudo cp -u wg_start.service /lib/systemd/system/ && \
sudo systemctl enable wg_start.service
}
if grep -i 'debian' /etc/os-release > /dev/null 2>&1
then
groups > /tmp/isgroup
if grep 'sudo' /tmp/isgroup
then
install_file_with
else
echo -e "$BLUE"The installer found that they are not in the group sudo.""
echo -e "with "$RED"su -"$BLUE" "they can enter the root shell in which they then""
echo -e "enter "$GREEN""usermod -aG sudo $USER.""$BLUE""
echo -e ""after logging in from the system, they can then run Wire-Py install again." $NORMAL"
read -n 1 -s -r -p $"To close the Window press a button"
clear
exit 0
fi
elif grep -i 'mint\|ubuntu\|pop|' /etc/os-release > /dev/null 2>&1
then
install_file_with
elif grep -i 'arch' /etc/os-release > /dev/null 2>&1
then
groups > /tmp/isgroup
clear
if grep 'wheel' /tmp/isgroup
then
install_arch_d
else
echo "The installer found that they are not in the group sudo."
echo "The sudoers file must be edited with"
echo -e "$RED""su -""$NORMAL"
echo -e "$GREEN"""EDITOR=nano visudo"""$NORMAL"
echo "Find the line:"
echo "## Uncomment to allow members of group wheel to execute any command"
echo "remove '#' on # %wheel ALL=(ALL) ALL and save the file"
echo -e "then enter "$GREEN"gpasswd -a $USER wheel.""$NORMAL"
echo "after logging in from the system, they can then run Wire-Py install again."
read -n 1 -s -r -p $"To close the Window press a button"
clear
exit 0
fi
elif grep -i '|manjaro\|garuda\|endeavour|' /etc/os-release > /dev/null 2>&1
then
install_arch_d
elif grep -i 'fedora' /etc/os-release > /dev/null 2>&1
then
if ! which python3-tkinter &> /dev/null
then sudo dnf install python3-tkinter -y
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && \
sudo cp -u settings.conf /etc/wire_py/ && \
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
sudo cp -u wg_start.service /lib/systemd/system/ && \
sudo systemctl enable wg_start.service
fi
elif grep -i 'suse' /etc/os-release > /dev/null 2>&1
then
if ! which python311-tk &> /dev/null
then sudo zypper install python311-tk
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && \
sudo cp -u settings.conf /etc/wire_py/ && \
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
sudo cp -u wg_start.service /lib/systemd/system/ && \
sudo systemctl enable wg_start.service
fi
else
clear
echo $"Your System could not be determined."
echo
read -n 1 -s -r -p $"To close the window press a button"
clear
exit 0
fi
clear
read -n 1 -s -r -p $"To close the Window press a button"
clear

Binary file not shown.

Binary file not shown.

BIN
lx-icons/128/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
lx-icons/128/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

BIN
lx-icons/256/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
lx-icons/256/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

BIN
lx-icons/32/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

BIN
lx-icons/32/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
lx-icons/48/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

BIN
lx-icons/48/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
lx-icons/64/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
lx-icons/64/log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

61
match_found.py Executable file
View File

@ -0,0 +1,61 @@
#!/usr/bin/python3
import argparse
from pathlib import Path
directorys: list[str] = [
"/etc/netplan/",
"/etc/NetworkManager/system-connections/",
"/var/lib/NetworkManager/user-connections/",
]
def search_string_in_directory(
directories: list[str] = directorys, # Use the predefined list as default
search_string: str = "", # Default is empty string
) -> bool:
if len(search_string) == 0:
return False
result = False
for directory in directories:
in_paths = Path(directory)
if not in_paths.exists() or not in_paths.is_dir():
continue
files = [file for file in in_paths.iterdir() if file.is_file()]
if not files:
continue
# Search for the string in each file
for file in files:
try:
with open(file, "r", errors="ignore") as f:
for line in f:
if search_string in line:
result = True # String found
break
if result:
break # No need to check further
except Exception:
continue # Skip files that cause errors
return result
def main() -> None:
parser = argparse.ArgumentParser(
description="Script only for use to compare the private key in the"
"Network configurations to avoid errors with the network manager."
)
parser.add_argument("search_string", help="Search string")
args = parser.parse_args()
result = search_string_in_directory(search_string=args.search_string)
print(result)
if __name__ == "__main__":
main()

View File

@ -1,5 +0,0 @@
#!/usr/bin/python3
import webbrowser
webbrowser.open('https://git.ilunix.de/punix/Wire-Py')

51
org.sslcrypt.policy Normal file
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<!--
Policy definitions for ssl_encrypt and ssl_decrypt
Copyright (C) 2025 Désiré Werner Menrath <polunga40@unity-mail.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see
<http://www.gnu.org/licenses/>.
-->
<policyconfig>
<action id="org.ssl_encrypt">
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/local/bin/ssl_encrypt.py</annotate>
</action>
<action id="org.ssl_decrypt">
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/local/bin/ssl_decrypt.py</annotate>
</action>
<action id="org.match_found">
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/local/bin/match_found.py</annotate>
</action>
</policyconfig>

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<vendor>Project Wire-Py</vendor>
<vendor_url>https://git.ilunix.de/punix/Wire-Py</vendor_url>
<icon_name>wg-vpn</icon_name>
<action id="org.wirepy">
<defaults>
<allow_any>auth_admin_keep</allow_any>
<allow_inactive>auth_admin_keep</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/wg_main.py</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>

2
run_as
View File

@ -1,2 +0,0 @@
#!/bin/bash
/usr/bin/./open_gitea.py

View File

@ -1,8 +0,0 @@
[UPDATES]
on
[THEME]
light
[TOOLTIP]
True
[AUTOSTART ON]
off

84
ssl_decrypt.py Executable file
View File

@ -0,0 +1,84 @@
#!/usr/bin/python3
""" This Script decrypt Wireguard files for Wirepy users """
import argparse
from pathlib import Path
import pwd
import shutil
from subprocess import CompletedProcess, run
from shared_libs.wp_app_config import AppConfig, logging
parser = argparse.ArgumentParser()
parser.add_argument("--user", required=True, help="Username of the target file system")
args = parser.parse_args()
try:
# Retrieve UID and GID
user_info = pwd.getpwnam(args.user)
uid = user_info.pw_uid # User ID (e.g., 1000)
gid = user_info.pw_gid # Group ID (e.g., 1000)
except KeyError:
logging.error(f"User '{args.user}' not found.", exc_info=True)
exit(1)
keyfile: Path = Path(f"/home/{args.user}/.config/wire_py/pbwgk.pem")
path_of_crypted_tunnel: Path = Path(f"/home/{args.user}/.config/wire_py")
if not keyfile.is_file():
process: CompletedProcess[str] = run(
[
"openssl",
"rsa",
"-in",
AppConfig.SYSTEM_PATHS["pkey_path"],
"-out",
keyfile,
"-outform",
"PEM",
"-pubout",
],
capture_output=True,
text=True,
check=False,
)
if process.returncode == 0:
logging.info("Public key generated successfully.", exc_info=True)
else:
logging.error(
f"Error with the following code... {process.returncode}", exc_info=True
)
shutil.chown(keyfile, uid, gid)
if AppConfig.PUBLICKEY.exists():
crypted__tunnel = [str(file) for file in path_of_crypted_tunnel.glob("*.dat")]
for tunnel_path in crypted__tunnel:
base_name = Path(tunnel_path).stem
process: CompletedProcess[str] = run(
[
"openssl",
"pkeyutl",
"-decrypt",
"-inkey",
AppConfig.SYSTEM_PATHS["pkey_path"],
"-in",
tunnel_path, # full path to the file
"-out",
f"{AppConfig.TEMP_DIR}/{base_name}.conf",
],
capture_output=True,
text=True,
check=False,
)
shutil.chown(f"{AppConfig.TEMP_DIR}/{base_name}.conf", uid, gid)
logging.info(f"Processing of the file: {tunnel_path}", exc_info=True)
# Output from Openssl Error
if process.stderr:
logging.error(
f"{process.stderr} Error by [{tunnel_path}] Code: {process.returncode}",
exc_info=True,
)

82
ssl_encrypt.py Executable file
View File

@ -0,0 +1,82 @@
#!/usr/bin/python3
""" This Script encrypt Wireguardfiles for Wirepy users for more Security """
import argparse
from pathlib import Path
import pwd
import shutil
from subprocess import CompletedProcess, run
from shared_libs.wp_app_config import AppConfig, logging
parser = argparse.ArgumentParser()
parser.add_argument("--user", required=True, help="Username of the target file system")
args = parser.parse_args()
try:
# Retrieve UID and GID
user_info = pwd.getpwnam(args.user)
uid = user_info.pw_uid # User ID (e.g., 1000)
gid = user_info.pw_gid # Group ID (e.g., 1000)
except KeyError:
logging.error(f"User '{args.user}' not found.", exc_info=True)
exit(1)
keyfile: Path = Path(f"/home/{args.user}/.config/wire_py/pbwgk.pem")
target: Path = Path(f"/home/{args.user}/.config/wire_py/")
if not keyfile.is_file():
process: CompletedProcess[str] = run(
[
"openssl",
"rsa",
"-in",
AppConfig.SYSTEM_PATHS["pkey_path"],
"-out",
keyfile,
"-outform",
"PEM",
"-pubout",
],
capture_output=True,
text=True,
check=False,
)
# Output from Openssl Error
if process.stderr:
logging.error(f"{process.stderr} Code: {process.returncode}", exc_info=True)
if process.returncode == 0:
logging.info("Public key generated successfully.", exc_info=True)
shutil.chown(keyfile, uid, gid)
# any() get True when directory is not empty
if AppConfig.TEMP_DIR.exists() and any(AppConfig.TEMP_DIR.iterdir()):
clear_files = [str(file) for file in AppConfig.TEMP_DIR.glob("*.conf")]
for config_file in clear_files:
base_name = Path(config_file).stem
process: CompletedProcess[str] = run(
[
"openssl",
"pkeyutl",
"-encrypt",
"-inkey",
keyfile,
"-pubin",
"-in",
config_file,
"-out",
f"{target}/{base_name}.dat",
],
capture_output=True,
text=True,
check=False,
)
# Output from Openssl Error
if process.stderr:
logging.error(process.stderr, exc_info=True)

View File

@ -1,14 +1,24 @@
#!/usr/bin/python3
from subprocess import check_call
from pathlib import Path
"""
This script belongs to wirepy and is for the auto start of the tunnel
"""
import logging
from subprocess import CompletedProcess, run
from shared_libs.wp_app_config import AppConfig
from shared_libs.common_tools import ConfigManager, LogConfig
path_to_file = Path('/etc/wire_py/settings.conf')
with open(path_to_file, 'r') as a_con:
lines = a_con.readlines()
a_con = lines[7].strip()
if a_con != 'off':
check_call(['nmcli', 'connection', 'up', a_con])
else:
pass
ConfigManager.init(AppConfig.SETTINGS_FILE)
LogConfig.logger(ConfigManager.get("logfile"))
if ConfigManager.get("autostart") != "off":
process: CompletedProcess[str] = run(
["nmcli", "connection", "up", ConfigManager.get("autostart")],
capture_output=True,
text=True,
check=False,
)
# Output from start_wg error
if process.stderr:
logging.error(process.stderr, exc_info=True)
else:
pass

230
tunnel.py Normal file
View File

@ -0,0 +1,230 @@
#!/usr/bin/python3
import logging
import getpass
import zipfile
from datetime import datetime
from pathlib import Path
import shutil
from subprocess import run, CompletedProcess
import secrets
from shared_libs.wp_app_config import AppConfig, Msg
from shared_libs.common_tools import LxTools, CryptoUtil
# Translate
_ = AppConfig.setup_translations()
class Tunnel:
"""
Class of Methods for Wire-Py
"""
@staticmethod
def parse_files_to_dictionary(
directory: Path = None, filepath: str = None, content: str = None
) -> tuple[dict, str] | dict | None:
data = {}
if filepath is not None:
filepath = Path(filepath)
try:
content = filepath.read_text()
# parse the content
address_line = next(
line for line in content.splitlines() if line.startswith("Address")
)
dns_line = next(
line for line in content.splitlines() if line.startswith("DNS")
)
endpoint_line = next(
line for line in content.splitlines() if line.startswith("Endpoint")
)
private_key_line = next(
line
for line in content.splitlines()
if line.startswith("PrivateKey")
)
content = secrets.token_bytes(len(content))
# extract the values
address = address_line.split("=")[1].strip()
dns = dns_line.split("=")[1].strip()
endpoint = endpoint_line.split("=")[1].strip()
private_key = private_key_line.split("=")[1].strip()
# Shorten the tunnel name to the maximum allowed length if it exceeds 12 characters.
original_stem = filepath.stem
truncated_stem = (
original_stem[-12:] if len(original_stem) > 12 else original_stem
)
# save in the dictionary
data[truncated_stem] = {
"Address": address,
"DNS": dns,
"Endpoint": endpoint,
"PrivateKey": private_key,
}
content = secrets.token_bytes(len(content))
except StopIteration:
pass
elif directory is not None:
if not directory.exists() or not directory.is_dir():
logging.error(
"Temp directory does not exist or is not a directory.",
exc_info=True,
)
return None
# Get a list of all files in the directory
files = [file for file in AppConfig.TEMP_DIR.iterdir() if file.is_file()]
# Search for the string in the files
for file in files:
try:
content = file.read_text()
# parse the content
address_line = next(
line
for line in content.splitlines()
if line.startswith("Address")
)
dns_line = next(
line for line in content.splitlines() if line.startswith("DNS")
)
endpoint_line = next(
line
for line in content.splitlines()
if line.startswith("Endpoint")
)
# extract values
address = address_line.split("=")[1].strip()
dns = dns_line.split("=")[1].strip()
endpoint = endpoint_line.split("=")[1].strip()
# save values to dictionary
data[file.stem] = {
"Address": address,
"DNS": dns,
"Endpoint": endpoint,
}
except Exception:
# Ignore errors and continue to the next file
continue
if content is not None:
content = secrets.token_bytes(len(content))
if filepath is not None:
return data, truncated_stem
else:
return data
@staticmethod
def get_active() -> str:
"""
Shows the Active Tunnel
"""
active = None
try:
process: CompletedProcess[str] = run(
["nmcli", "-t", "-f", "NAME,TYPE", "connection", "show", "--active"],
capture_output=True,
text=True,
check=False,
)
active = next(
line.split(":")[0].strip()
for line in process.stdout.splitlines()
if line.endswith("wireguard")
)
if process.stderr and "error" in process.stderr.lower():
logging.error(f"Error output on nmcli: {process.stderr}")
except StopIteration:
active = None
except Exception as e:
logging.error(f"Error on nmcli: {e}")
active = None
return active if active is not None else ""
@staticmethod
def export() -> bool | None:
"""
This will export the tunnels.
A zipfile with the current date and time is created
in the user's home directory with the correct right
"""
now_time: datetime = datetime.now()
now_datetime: str = now_time.strftime("wg-exp-%m-%d-%Y-%H:%M")
try:
AppConfig.ensure_directories()
CryptoUtil.decrypt(getpass.getuser())
if len([file.name for file in AppConfig.TEMP_DIR.glob("*.conf")]) == 0:
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["sel_tl"],
Msg.STR["tl_first"],
)
return False
else:
wg_tar: str = f"{AppConfig.BASE_DIR}/{now_datetime}"
try:
shutil.make_archive(wg_tar, "zip", AppConfig.TEMP_DIR)
with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf:
if zf.namelist():
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_info"],
AppConfig.IMAGE_PATHS["icon_vpn"],
Msg.STR["exp_succ"],
Msg.STR["exp_in_home"],
)
else:
logging.error(
"There was a mistake at creating the Zip file. File is empty."
)
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["exp_err"],
Msg.STR["exp_zip"],
)
return False
return True
except PermissionError:
logging.error(
f"Permission denied when creating archive in {wg_tar}"
)
return False
except zipfile.BadZipFile as e:
logging.error(f"Invalid ZIP file: {e}")
return False
except TypeError:
pass
except Exception as e:
logging.error(f"Export failed: {str(e)}")
LxTools.msg_window(
AppConfig.IMAGE_PATHS["icon_error"],
AppConfig.IMAGE_PATHS["icon_msg"],
Msg.STR["exp_err"],
Msg.STR["exp_try"],
)
return False
finally:
LxTools.clean_files(AppConfig.TEMP_DIR)
AppConfig.ensure_directories()

1161
wg_main.py

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +0,0 @@
[Unit]
Description=Automatic Tunnel Start
After=network-online.target
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 5
ExecStart=/usr/bin/start_wg.py
[Install]
WantedBy=multi-user.target

1165
wirepy.py

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

247
wp_app_config.py Executable file
View File

@ -0,0 +1,247 @@
#!/usr/bin/python3
"""App configuration for Wire-Py"""
import logging
import gettext
import locale
from pathlib import Path
from subprocess import CompletedProcess, run
from typing import Dict, Any
class AppConfig:
"""Central configuration and system setup manager for the Wire-Py application.
This class serves as a singleton-like container for all global configuration data,
including paths, UI settings, localization, versioning, and system-specific resources.
It ensures that required directories, files, and services are created and configured
before the application starts. Additionally, it provides tools for managing translations,
default settings, and autostart functionality to maintain a consistent user experience.
Key Responsibilities:
- Centralizes all configuration values (paths, UI preferences, localization).
- Ensures required directories and files exist on startup.
- Handles translation setup via `gettext` for multilingual support.
- Manages default settings file generation.
- Configures autostart services using systemd for user-specific launch behavior.
This class is used globally across the application to access configuration data
consistently and perform system-level setup tasks.
"""
# Logging
LOG_DIR = Path.home() / ".local/share/lxlogs"
Path(LOG_DIR).mkdir(parents=True, exist_ok=True)
LOG_FILE_PATH = LOG_DIR / "wirepy.log"
# 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")
PUBLICKEY: Path = CONFIG_DIR / "pbwgk.pem"
# Configuration files
SETTINGS_FILE: Path = CONFIG_DIR / "settings"
SYSTEMD_USER_FOLDER: Path = Path.home() / ".config/systemd/user"
AUTOSTART_SERVICE: Path = Path.home() / ".config/systemd/user/wg_start.service"
DEFAULT_SETTINGS: Dict[str, str] = {
"# Configuration": "on",
"# Theme": "dark",
"# Tooltips": True,
"# Autostart": "off",
"# Logfile": LOG_FILE_PATH,
}
# Updates
# 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year
VERSION: str = "v. 2.06.0425"
UPDATE_URL: str = "https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases"
DOWNLOAD_URL: str = "https://git.ilunix.de/punix/Wire-Py/archive"
# UI configuration
UI_CONFIG: Dict[str, Any] = {
"window_title": "Wire-Py",
"window_title2": "LogViewer",
"window_size": (600, 383),
"font_family": "Ubuntu",
"font_size": 11,
"resizable_window": (False, False),
}
# System-dependent paths
SYSTEM_PATHS: Dict[str, Path] = {
"ssl_decrypt": "/usr/local/bin/ssl_decrypt.py",
"ssl_encrypt": "/usr/local/bin/ssl_encrypt.py",
"tcl_path": "/usr/share/TK-Themes",
"pkey_path": "/usr/local/etc/ssl/pwgk.pem",
}
# Images and icons paths
IMAGE_PATHS: Dict[str, Path] = {
"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",
"icon_log": "/usr/share/icons/lx-icons/48/log.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"""
if not cls.CONFIG_DIR.exists():
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_autostart_content(cls) -> None:
"""Returns the content for an autostart service file"""
systemd_file: list[str] = [
"[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",
]
if not cls.SYSTEMD_USER_FOLDER.exists():
cls.SYSTEMD_USER_FOLDER.mkdir(parents=True, exist_ok=True)
if not cls.AUTOSTART_SERVICE.is_file():
content = "\n".join([line for line in systemd_file])
cls.AUTOSTART_SERVICE.write_text(content)
process: CompletedProcess[str] = run(
["systemctl", "--user", "enable", "wg_start.service"],
capture_output=True,
text=True,
check=False,
)
if process.stderr:
logging.error(f"{process.stderr} Code: {process.returncode}", exc_info=True)
@classmethod
def ensure_log(cls) -> None:
"""Ensures that the log file exists"""
if not cls.LOG_FILE_PATH.exists():
cls.LOG_FILE_PATH.touch()
# here is initializing the class for translation strings
_ = 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"),
"exp_zip": _(
"The error occurs because the zipfile module encountered an issue.\n"
"Please verify that you have the latest version of WirePy installed.\n"
"You can also contact the WirePy developer team to resolve this issue quickly.\n"
),
"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"),
"invalid_base64": _(
"Invalid base64 format!\nPlease use a Config file with valid key."
),
}
TTIP: Dict[str, str] = {
# Strings for Tooltips
"settings": _("Click for Settings"),
"import_tl": _("Click to import a Wireguard Tunnel"),
"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"
),
"download": _("Click to download new version"),
}