Compare commits

2 Commits

8 changed files with 671 additions and 19 deletions

4
.gitignore vendored
View File

@@ -23,10 +23,6 @@ test_resources.py
manager_fixed.py
test_simple.sh
test_container.sh
gpg_setup.sh
gpg_simple_setup.sh
lxtools_installer.spec
lxtoolsinstaller.pot
# Docker-Build
docker_build/

View File

@@ -2,26 +2,36 @@
LX Tools Installer is a GUI for simple install, update, and remove Apps from ilunix.de
# Fingerprint
743745087C6414E00F1EF84D4CCF06B6CE2A4C7F
add to your gpg keyring:
## Build
Create a compatible AppImage:
```bash
wget https://git.ilunix.de/punix/lxtools_installer/raw/branch/main/public_key.asc -O - | gpg --import
./build_compatible.sh
```
or
This creates:
- `lxtools_installer{VERSION}-x86_64.AppImage` - The executable
- `lxtools_installer{VERSION}-x86_64.AppImage.sha256` - SHA256 checksum
- `lxtools_installer{VERSION}-x86_64.AppImage.asc` - GPG signature (if configured)
## GPG Setup
To enable GPG signing:
```bash
wget https://keys.openpgp.org/vks/v1/by-fingerprint/743745087C6414E00F1EF84D4CCF06B6CE2A4C7F -O - | gpg --import
./gpg_setup.sh
```
The Appimage automatically checks whether the public_key has already been imported,
and if not it is downloaded from both sources and only imported when all the keys match.
This is to ensure that no manipulated software is used.
## Verification
# Not currently supported
- Open Suse Tumbleweed and Leap (Let's get back)
Verify the downloaded AppImage:
```bash
# Check SHA256
sha256sum -c lxtools_installer{VERSION}-x86_64.AppImage.sha256
# Verify GPG signature (requires public key)
gpg --import public_key.asc
gpg --verify lxtools_installer{VERSION}-x86_64.AppImage.asc lxtools_installer{VERSION}-x86_64.AppImage
```
# Screenshots
[![wire-py.png](https://fb.ilunix.de/api/public/dl/ZnfG9gxv?inline=true)](https://fb.ilunix.de/share/ZnfG9gxv)

51
gpg_setup.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/bash
echo "🔐 GPG Setup für lxtools_installer"
echo "=================================="
# Check if GPG is installed
if ! command -v gpg &> /dev/null; then
echo "❌ GPG ist nicht installiert"
echo "Installation: sudo apt install gnupg"
exit 1
fi
# Check if GPG key exists
if ! gpg --list-secret-keys | grep -q "sec"; then
echo "📋 Kein GPG-Schlüssel gefunden. Erstelle einen neuen..."
echo "Verwende diese Einstellungen:"
echo "- Typ: RSA"
echo "- Größe: 4096"
echo "- Gültigkeitsdauer: 2y (2 Jahre)"
echo "- Email: deine@email.com"
echo ""
gpg --full-generate-key
else
echo "✅ GPG-Schlüssel bereits vorhanden"
fi
# List available keys
echo ""
echo "📋 Verfügbare Schlüssel:"
gpg --list-secret-keys --keyid-format SHORT
# Ask for key selection
echo ""
read -p "Welchen Key-ID möchtest du verwenden? (oder Enter für Standard): " KEY_ID
if [ -z "$KEY_ID" ]; then
# Use first available key
KEY_ID=$(gpg --list-secret-keys --keyid-format SHORT | grep "sec" | head -1 | sed 's/.*\///' | cut -d' ' -f1)
fi
echo "🔑 Verwende Key-ID: $KEY_ID"
# Export public key
gpg --export --armor "$KEY_ID" > public_key.asc
echo "✅ Öffentlicher Schlüssel exportiert: public_key.asc"
echo ""
echo "📋 Nächste Schritte:"
echo "1. Committen Sie public_key.asc ins Repository"
echo "2. Testen Sie den Build mit: ./build_compatible.sh"
echo "3. Verifizieren Sie die Signatur mit: gpg --verify file.asc file"

70
gpg_simple_setup.sh Executable file
View File

@@ -0,0 +1,70 @@
#!/bin/bash
echo "🔐 Einfaches GPG Setup für lxtools_installer"
echo "==========================================="
# Check if GPG is installed
if ! command -v gpg &> /dev/null; then
echo "❌ GPG ist nicht installiert"
echo "Installation: sudo apt install gnupg"
exit 1
fi
# Check if GPG key exists
if ! gpg --list-secret-keys | grep -q "sec"; then
echo "📋 Erstelle GPG-Schlüssel automatisch..."
echo ""
echo "Verwende diese Einstellungen:"
echo "- Name: Désiré Werner Menrath"
echo "- Email: polunga40@unity-mail.de"
echo "- Typ: RSA 4096"
echo "- Gültigkeitsdauer: 2 Jahre"
echo ""
# Create GPG key non-interactively
cat > /tmp/gpg_batch <<EOF
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: Désiré Werner Menrath
Name-Email: polunga40@unity-mail.de
Expire-Date: 2y
%no-protection
%commit
EOF
echo "🔑 Erstelle Schlüssel..."
gpg --batch --generate-key /tmp/gpg_batch
rm /tmp/gpg_batch
echo "✅ GPG-Schlüssel erstellt!"
else
echo "✅ GPG-Schlüssel bereits vorhanden"
fi
# Get the key ID
KEY_ID=$(gpg --list-secret-keys --keyid-format SHORT | grep "sec" | head -1 | sed 's/.*\///' | cut -d' ' -f1)
echo ""
echo "🔑 Verwende Key-ID: $KEY_ID"
# Export public key
gpg --export --armor "$KEY_ID" > public_key.asc
echo "✅ Öffentlicher Schlüssel exportiert: public_key.asc"
# Test the signing
echo ""
echo "🧪 Teste Signierung..."
echo "test" > /tmp/test.txt
if gpg --armor --detach-sign --yes /tmp/test.txt 2>/dev/null; then
echo "✅ Signierung funktioniert!"
rm /tmp/test.txt /tmp/test.txt.asc
else
echo "❌ Signierung fehlgeschlagen"
fi
echo ""
echo "📋 Setup abgeschlossen!"
echo "Jetzt kannst du ./build_compatible.sh ausführen"

38
lxtools_installer.spec Normal file
View File

@@ -0,0 +1,38 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['lxtools_installer.py'],
pathex=[],
binaries=[],
datas=[('locale/de/LC_MESSAGES/lxtoolsinstaller.mo', 'locale/de/LC_MESSAGES/'), ('manager.py', '.'), ('network.py', '.'), ('message.py', '.'), ('TK-Themes/theme/dark/*.png', 'TK-Themes/theme/dark'), ('TK-Themes/theme/light/*.png', 'TK-Themes/theme/light'), ('TK-Themes/water.tcl', 'TK-Themes'), ('TK-Themes/LICENSE', 'TK-Themes'), ('TK-Themes/theme/dark.tcl', 'TK-Themes/theme'), ('TK-Themes/theme/light.tcl', 'TK-Themes/theme'), ('lx-icons/32/*.png', 'lx-icons/32'), ('lx-icons/48/*.png', 'lx-icons/48'), ('lx-icons/64/*.png', 'lx-icons/64'), ('lx-icons/128/*.png', 'lx-icons/128'), ('lx-icons/256/*.png', 'lx-icons/256'), ('certs/cacert.pem', 'certs')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='lxtools_installer',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

487
lxtoolsinstaller.pot Normal file
View File

@@ -0,0 +1,487 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-07-09 08:01+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: manager.py:735
msgid "WireGuard VPN Manager with GUI"
msgstr "WireGuard-VPN-Manager mit GUI"
#: manager.py:748
msgid "System Log Viewer with GUI"
msgstr "Systemprotokoll-Ansicht mit GUI"
#: manager.py:812
msgid "Refreshing status and checking versions..."
msgstr "Status aktualisieren und Versionen prüfen..."
#: manager.py:813
msgid "Starting installation of "
msgstr "Installation von "
#: manager.py:814
msgid "Installing "
msgstr "Installiere "
#: manager.py:815
msgid " installation successfully!"
msgstr " Installation erfolgreich!"
#: manager.py:816
msgid "Installation failed: "
msgstr "Installation fehlgeschlagen: "
#: manager.py:817
msgid "Created install script: "
msgstr "Installations-Skript erstellt: "
#: manager.py:818
msgid "Installation script failed: "
msgstr "Installations-Skript fehlgeschlagen: "
#: manager.py:819
msgid "Installation timed out"
msgstr "Installation abgelaufen"
#: manager.py:820
msgid "Installed "
msgstr "Installiert: "
#: manager.py:824
msgid "Uninstalling "
msgstr "Deinstalieren von "
#: manager.py:825
msgid " uninstalled successfully!"
msgstr " erfolgreich deinstalliert!"
#: manager.py:826
msgid "Uninstallation failed: "
msgstr "Deinstallation fehlgeschlagen: "
#: manager.py:827
msgid "Created uninstall script: "
msgstr "Deinstallations-Skript erstellt: "
#: manager.py:828
msgid "Uninstallation script failed: "
msgstr "Deinstallations-Skript fehlgeschlagen: "
#: manager.py:829
msgid "Uninstallation timed out"
msgstr "Deinstallation abgelaufen"
#: manager.py:833
msgid "Unknown project: "
msgstr "Unbekanntes Projekt: "
#: manager.py:834
msgid " is not installed."
msgstr " ist nicht installiert."
#: manager.py:835
msgid "Downloading from "
msgstr "Herunterladen von "
#: manager.py:836
msgid "Extracting files..."
msgstr "Dateien entpacken..."
#: manager.py:837
msgid "Download failed: "
msgstr "Herunterladen fehlgeschlagen: "
#: manager.py:838
msgid "System: "
msgstr "System: "
#: manager.py:839
msgid "Linux App Installer"
msgstr "Linux-App-Installer"
#: manager.py:840
msgid "Ready for installation"
msgstr "Bereit für Installation"
#: manager.py:841
msgid "No internet connection"
msgstr "Keine Internetverbindung"
#: manager.py:842
msgid "Repository unavailable"
msgstr "Repository nicht verfügbar"
#: manager.py:843
msgid "System checking..."
msgstr "Systemprüfung..."
#: manager.py:844
msgid "Applications"
msgstr "Anwendungen"
#: manager.py:845
msgid "Progress"
msgstr "Fortschritt"
#: manager.py:846
msgid "Status refresh completed"
msgstr "Statusaktualisierung abgeschlossen"
#: manager.py:847
msgid "Python not installed"
msgstr "Python nicht installiert"
#: manager.py:848
msgid "Please install Polkit!"
msgstr "Bitte installieren Sie Polkit!"
#: manager.py:849
msgid "Please install Networkmanager!"
msgstr "Bitte installieren Sie Networkmanager!"
#: manager.py:850
msgid "Polkit check: "
msgstr "Polkit-Prüfung: "
#: manager.py:851
msgid "Networkmanager check: "
msgstr "Networkmanager-Prüfung: "
#: manager.py:856
msgid "Checking..."
msgstr "Prüfen..."
#: manager.py:857
msgid "Version: Checking..."
msgstr "Version: Prüfen..."
#: manager.py:858
msgid "Update on "
msgstr "Aktualisierung am "
#: manager.py:859
msgid "available"
msgstr "verfügbar"
#: manager.py:860
msgid "Up to date"
msgstr "Auf dem neuesten Stand"
#: manager.py:861
msgid "Latest unknown"
msgstr "Neueste Version unbekannt"
#: manager.py:862
msgid "Could not check latest version"
msgstr "Kann aktuelle Version nicht prüfen"
#: manager.py:863
msgid "Latest: Check failed"
msgstr "Neueste: Prüfung fehlgeschlagen"
#: manager.py:864
msgid "Version check failed"
msgstr "Versionsprüfung fehlgeschlagen"
#: manager.py:865
msgid "Not installed"
msgstr "Nicht installiert"
#: manager.py:866
msgid "Available "
msgstr "Verfügbar "
#: manager.py:867
msgid "Available unknown"
msgstr "Verfügbarkeit unbekannt"
#: manager.py:868
msgid "Available: Check failed"
msgstr "Verfügbar: Prüfung fehlgeschlagen"
#: manager.py:873
msgid "Selected project: "
msgstr "Ausgewähltes Projekt: "
#: manager.py:874
msgid "Installation Log"
msgstr "Installationsprotokoll"
#: manager.py:875 manager.py:879
msgid "Working directory: "
msgstr "Arbeitsverzeichnis: "
#: manager.py:876
msgid "Icons directory: "
msgstr "Icons-Verzeichnis: "
#: manager.py:877
msgid "Detected OS: "
msgstr "Erkanntes Betriebssystem: "
#: manager.py:878
msgid "Log cleared"
msgstr "Protokoll geleert"
#: manager.py:880
msgid ""
"\n"
"Application interrupted by user."
msgstr ""
"\n"
"Anwendung durch Benutzer unterbrochen."
#: manager.py:881
msgid "Fatal error: "
msgstr "Kritischer Fehler: "
#: manager.py:882
msgid "Fatal Error Application failed to start: "
msgstr "Kritischer Fehler: Anwendung konnte nicht gestartet werden: "
#: manager.py:887
msgid "Clear Log"
msgstr "Protokoll leeren"
#: manager.py:888
msgid "Install/Update"
msgstr "Installieren/Aktualisieren"
#: manager.py:889
msgid "Uninstall"
msgstr "Deinstallieren"
#: manager.py:890
msgid "Refresh Status"
msgstr "Status aktualisieren"
#: manager.py:895
msgid "Please select a project to install."
msgstr "Bitte ein Projekt zum Installieren auswählen."
#: manager.py:897
msgid ""
"No internet connection available.\n"
"Please check your network connection."
msgstr ""
"Keine Internetverbindung vorhanden.\n"
"Überprüfen Sie Ihre Netzwerkverbindung."
#: manager.py:900
msgid ""
"Cannot access repository.\n"
"Please try again later."
msgstr ""
"Repository nicht erreichbar.\n"
Bitte später erneut versuchen.
#: manager.py:902
msgid "has been successfully installed/updated."
msgstr "wurde erfolgreich installiert/aktualisiert."
#: manager.py:903
msgid "Please select a project to uninstall."
msgstr "Bitte ein Projekt zur Deinstallation auswählen."
#: manager.py:908
msgid "Installing tkinter for "
msgstr "Installation von tkinter für "
#: manager.py:909
msgid "Command: "
msgstr "Befehl: "
#: manager.py:910
msgid "TKinter installation completed successfully!"
msgstr "TKinter-Installation erfolgreich abgeschlossen!"
#: manager.py:911
msgid "TKinter installation failed: "
msgstr "TKinter-Installation fehlgeschlagen: "
#: manager.py:912
msgid "TKinter installation timed out"
msgstr "TKinter-Installation abgelaufen"
#: manager.py:913
msgid "Error installing tkinter: "
msgstr "Fehler bei der Installation von tkinter: "
#: manager.py:914
msgid "No tkinter installation command defined for "
msgstr "Kein Installationsbefehl für tkinter definiert für "
#: manager.py:915
msgid "Failed to load image from "
msgstr "Bild konnte nicht geladen werden aus "
#: manager.py:916
msgid "LogViewer installation check:"
msgstr "Prüfung der Installation von LogViewer:"
#: manager.py:917
msgid " Symlink exists: "
msgstr " Symbolischer Link existiert: "
#: manager.py:918
msgid " Executable exists: "
msgstr " Ausführbarer Datei existiert: "
#: manager.py:919
msgid " Is executable: "
msgstr " Ist ausführbar: "
#: manager.py:920
msgid " Final result: "
msgstr " Endergebnis: "
#: manager.py:921
msgid "Error getting version for "
msgstr "Fehler beim Abrufen der Version für "
#: manager.py:926
msgid "Error verifying signature: "
msgstr "Fehler bei der Prüfung der Signatur: "
#: manager.py:927
msgid "Could not find GPG signature: "
msgstr "GPG-Signatur nicht gefunden: "
#: manager.py:928
msgid "SHA256-File not found: "
msgstr "SHA256-Datei nicht gefunden: "
#: manager.py:929
msgid "Would you like to continue?"
msgstr "Möchten Sie fortfahren?"
#: manager.py:930
msgid "SHA256 hash mismatch. File might be corrupted!"
msgstr "SHA256-Hash passt nicht überein. Datei könnte beschädigt sein!"
#: manager.py:931
msgid "Failed to retrieve version from Gitea API"
msgstr "Konnte Version über die Gitea-API nicht abrufen"
#: manager.py:932
msgid "Error retrieving latest version: "
msgstr "Fehler beim Abrufen der neuesten Version: "
#: manager.py:933
msgid "GPG verification successful. Signature is valid."
msgstr "GPG-Prüfung erfolgreich. Die Signatur ist gültig."
#: manager.py:934
msgid "Error GPG check: "
msgstr "Fehler bei der GPG-Prüfung: "
#: manager.py:935
msgid "Error downloading or verifying AppImage: "
msgstr "Fehler beim Herunterladen oder Verifizieren der AppImage: "
#: manager.py:936
msgid "Error accessing Gitea repository: "
msgstr "Fehler beim Zugreifen auf das Gitea-Repository: "
#: manager.py:937
msgid "Error: "
msgstr "Fehler: "
#: manager.py:938
msgid "The AppImage renamed..."
msgstr "Die AppImage umbenannt..."
#: manager.py:939
msgid "Error renaming the AppImage: "
msgstr "Fehler beim Umbenennen der AppImage: "
#: manager.py:940
msgid "Error making the AppImage executable: "
msgstr "Fehler beim Markieren der AppImage als ausführbar: "
#: manager.py:941
msgid "The AppImage has been made executable"
msgstr "Die AppImage wurde als ausführbar markiert"
#: manager.py:942
msgid "Error: The AppImage file does not exist."
msgstr "Fehler: Die AppImage-Datei existiert nicht."
#: manager.py:947
msgid ""
"Warning: 'gpg' is not installed. Please install it to verify the AppImage "
"signature."
msgstr ""
"Warnung: 'gpg' ist nicht installiert. Bitte installieren Sie es, um die "
"AppImage-Signatur zu überprüfen."
#: manager.py:949
msgid "URL not reachable: "
msgstr "URL nicht erreichbar: "
#: manager.py:951
msgid "No fingerprint found in the key. File might be corrupted or empty."
msgstr "Kein Fingerabdruck in dem Schlüssel gefunden. Datei könnte beschädigt oder leer sein."
#: manager.py:953
msgid "Fingerprint mismatch: Expected "
msgstr "Fingerabdruck nicht übereinstimmend: Erwartet "
#: manager.py:954
msgid "but got: "
msgstr "aber erhalten: "
#: manager.py:955
msgid "Failed to import public key: "
msgstr "Fehler beim Importieren des öffentlichen Schlüssels: "
#: manager.py:956
msgid "GPG fingerprint extraction failed: "
msgstr "Extrahierung von GPG-Fingerabdruck fehlgeschlagen: "
#: manager.py:957
msgid "Error importing GPG key from "
msgstr "Fehler beim Importieren des GPG-Schlüssels aus "
#: manager.py:958
msgid "Error updating trust level: "
msgstr "Fehler beim Aktualisieren des Vertrauensniveaus: "
#: manager.py:959
msgid "Error executing script to update trust level: "
msgstr "Fehler beim Ausführen des Skripts zur Aktualisierung des Vertrauensniveaus: "
#: manager.py:961
msgid "OpenPGP keyserver is reachable. Proceeding with download."
msgstr "Der OpenPGP-Schlüsselserver ist erreichbar. Herunterladen wird fortgesetzt."
#: manager.py:964
msgid "OpenPGP keyserver unreachable. Skipping this source."
msgstr "Der OpenPGP-Schlüsselserver ist nicht erreichbar. Dieser Quelle wird übersprungen."
#: manager.py:967
msgid "All keys have valid fingerprints matching the expected value."
msgstr "Alle Schlüssel haben gültige Fingerabdrücke, die mit dem erwarteten Wert übereinstimmen."
#: manager.py:969
msgid "Trust level 5 successfully applied to key "
msgstr "Vertrauensniveau 5 erfolgreich auf Schlüssel angewendet "
#: manager.py:970
msgid "Not all keys are valid."
msgstr "Nicht alle Schlüssel sind gültig."

View File

@@ -128,7 +128,7 @@ class Detector:
arch = ["Arch Linux", "Manjaro", "EndeavourOS", "ArcoLinux", "Garuda Linux"]
if os_system in deb:
result = subprocess.run(
["which pkexec"],
["apt list --installed | grep polkit"],
capture_output=True,
shell=True,
text=True,
@@ -233,7 +233,7 @@ class Detector:
elif os_system == "SUSE Tumbleweed" or os_system == "SUSE Leap":
result = subprocess.run(
["systemctl status NetworkManager"],
["zypper search --installed-only | grep NetworkManager"],
capture_output=True,
shell=True,
text=True,