add requests for arch linux
This commit is contained in:
@ -1,68 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
# ✅ Path to be added in the .pth file
|
||||
SHARED_LIBS_PATH = "/usr/local/share/shared_libs"
|
||||
PTH_FILE_NAME = "shared_libs.pth"
|
||||
|
||||
|
||||
def ensure_shared_libs_pth_exists():
|
||||
"""
|
||||
Checks if all site-packages directories have a `.pth` file with the correct path.
|
||||
Creates or updates it if missing or incorrect.
|
||||
"""
|
||||
# Search for all site-packages directories (e.g., /usr/lib/python3.x/site-packages/)
|
||||
for root, dirs, files in os.walk("/usr"):
|
||||
if "site-packages" in dirs:
|
||||
site_packages_dir = os.path.join(root, "site-packages")
|
||||
|
||||
pth_file_path = os.path.join(site_packages_dir, PTH_FILE_NAME)
|
||||
|
||||
# Check if the file exists and is correct
|
||||
if not os.path.exists(pth_file_path):
|
||||
print(f"⚠️ .pth file not found: {pth_file_path}. Creating...")
|
||||
with open(pth_file_path, "w") as f:
|
||||
f.write(SHARED_LIBS_PATH + "\n")
|
||||
|
||||
else:
|
||||
# Check if the correct path is in the file
|
||||
with open(pth_file_path, "r") as f:
|
||||
content = f.read().strip()
|
||||
|
||||
if not content == SHARED_LIBS_PATH:
|
||||
print(f"⚠️ .pth file exists but has incorrect content. Fixing...")
|
||||
with open(pth_file_path, "w") as f:
|
||||
f.write(SHARED_LIBS_PATH + "\n")
|
||||
|
||||
print("✅ All .pth files checked and corrected.")
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
# Try to import the module
|
||||
from shared_libs.wp_app_config import AppConfig
|
||||
|
||||
print("✅ 'shared_libs' is correctly loaded. Starting the application...")
|
||||
|
||||
# Your main program logic here...
|
||||
except ModuleNotFoundError as e:
|
||||
# Only handle errors related to missing .pth file
|
||||
if "No module named 'shared_libs'" in str(e):
|
||||
print("⚠️ Error: 'shared_libs' module not found. Checking .pth file...")
|
||||
ensure_shared_libs_pth_exists()
|
||||
|
||||
# Try again after fixing the .pth file
|
||||
try:
|
||||
from shared_libs.wp_app_config import AppConfig
|
||||
|
||||
print("✅ After correcting the .pth file: Module loaded.")
|
||||
# Your main program logic here...
|
||||
except Exception as e2:
|
||||
print(f"❌ Error after correcting the .pth file: {e2}")
|
||||
else:
|
||||
# For other errors, re-raise them
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -3,12 +3,13 @@ import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import os
|
||||
import subprocess
|
||||
import getpass
|
||||
from datetime import datetime
|
||||
import tempfile
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from manager import (
|
||||
OSDetector,
|
||||
Detector,
|
||||
Theme,
|
||||
LocaleStrings,
|
||||
LXToolsAppConfig,
|
||||
@ -75,14 +76,27 @@ class InstallationManager:
|
||||
raise Exception(f"{LocaleStrings.MSGI["unknow_project"]}{project_key}")
|
||||
|
||||
def _create_wirepy_install_script(self):
|
||||
detected_os = Detector.get_os()
|
||||
if detected_os == "Arch Linux":
|
||||
result_unzip = Detector.get_unzip()
|
||||
result_wget = Detector.get_wget()
|
||||
"""Create Wire-Py installation script"""
|
||||
script = f"""#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Wire-Py Installation ==="
|
||||
if [ "{detected_os}" = "Arch Linux" ]; then
|
||||
if [ "{result_unzip}" = "False" ]; then
|
||||
pacman -S --noconfirm unzip
|
||||
fi
|
||||
|
||||
if [ "{result_wget}" = "False" ]; then
|
||||
pacman -S --noconfirm wget
|
||||
fi
|
||||
fi
|
||||
{LXToolsAppConfig.TKINTER_INSTALL_COMMANDS[detected_os]} 2>&1 | grep -v "apt does not have a stable CLI interface"
|
||||
# Create necessary directories
|
||||
mkdir -p /usr/local/share/shared_libs
|
||||
mkdir -p {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}
|
||||
mkdir -p /usr/share/icons/lx-icons
|
||||
mkdir -p /usr/share/locale/de/LC_MESSAGES
|
||||
mkdir -p /usr/share/applications
|
||||
@ -118,7 +132,7 @@ done
|
||||
|
||||
# Install config
|
||||
if [ -f "$WIREPY_DIR/wp_app_config.py" ]; then
|
||||
cp -f "$WIREPY_DIR/wp_app_config.py" /usr/local/share/shared_libs/
|
||||
cp -f "$WIREPY_DIR/wp_app_config.py" {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/
|
||||
echo "Installed wp_app_config.py"
|
||||
fi
|
||||
|
||||
@ -126,15 +140,15 @@ fi
|
||||
echo "Installing shared libraries..."
|
||||
for file in common_tools.py message.py file_and_dir_ensure.py gitea.py __init__.py logview_app_config.py; do
|
||||
if [ -f "$SHARED_DIR/$file" ]; then
|
||||
cp -f "$SHARED_DIR/$file" /usr/local/share/shared_libs/
|
||||
cp -f "$SHARED_DIR/$file" {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/
|
||||
echo "Installed shared lib: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# Install LogViewer executable
|
||||
if [ -f "$SHARED_DIR/logviewer.py" ]; then
|
||||
cp -f "$SHARED_DIR/logviewer.py" /usr/local/share/shared_libs/
|
||||
chmod 755 /usr/local/share/shared_libs/logviewer.py
|
||||
cp -f "$SHARED_DIR/logviewer.py" {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/
|
||||
chmod 755 {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py
|
||||
echo "Installed logviewer.py (executable)"
|
||||
fi
|
||||
|
||||
@ -171,7 +185,7 @@ fi
|
||||
# Create symlink for Wirepy
|
||||
ln -sf /usr/local/bin/wirepy.py /usr/local/bin/wirepy
|
||||
# Create symlink for LogViewer
|
||||
ln -sf /usr/local/share/shared_libs/logviewer.py /usr/local/bin/logviewer
|
||||
ln -sf {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py /usr/local/bin/logviewer
|
||||
echo "Created Wirepy and LogViewer symlink"
|
||||
|
||||
# Install language files if available
|
||||
@ -197,14 +211,32 @@ echo "Wire-Py installation completed!"
|
||||
return script
|
||||
|
||||
def _create_logviewer_install_script(self):
|
||||
detected_os = Detector.get_os()
|
||||
if detected_os == "Arch Linux":
|
||||
result_unzip = Detector.get_unzip()
|
||||
result_wget = Detector.get_wget()
|
||||
result_requests = Detector.get_requests()
|
||||
|
||||
"""Create LogViewer installation script"""
|
||||
script = f"""#!/bin/bash
|
||||
set -e
|
||||
|
||||
{LXToolsAppConfig.TKINTER_INSTALL_COMMANDS[detected_os]} 2>&1 | grep -v "apt does not have a stable CLI interface"
|
||||
echo "=== LogViewer Installation ==="
|
||||
if [ "{detected_os}" = "Arch Linux" ]; then
|
||||
if [ "{result_unzip}" = "False" ]; then
|
||||
pacman -S --noconfirm unzip
|
||||
fi
|
||||
|
||||
if [ "{result_wget}" = "False" ]; then
|
||||
pacman -S --noconfirm wget
|
||||
fi
|
||||
|
||||
if [ "{result_requests}" = "False" ]; then
|
||||
pacman -S --noconfirm python-requests
|
||||
fi
|
||||
fi
|
||||
# Create necessary directories
|
||||
mkdir -p /usr/local/share/shared_libs
|
||||
mkdir -p {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}
|
||||
mkdir -p /usr/share/icons/lx-icons
|
||||
mkdir -p /usr/share/locale/de/LC_MESSAGES
|
||||
mkdir -p /usr/share/applications
|
||||
@ -244,36 +276,21 @@ fi
|
||||
echo "Installing shared libraries..."
|
||||
for file in common_tools.py message.py file_and_dir_ensure.py gitea.py __init__.py logview_app_config.py; do
|
||||
if [ -f "$SHARED_DIR/$file" ]; then
|
||||
cp -f "$SHARED_DIR/$file" /usr/local/share/shared_libs/
|
||||
cp -f "$SHARED_DIR/$file" {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/
|
||||
echo "Installed shared lib: $file"
|
||||
fi
|
||||
done
|
||||
|
||||
# Install LogViewer executable
|
||||
if [ -f "$SHARED_DIR/logviewer.py" ]; then
|
||||
cp -f "$SHARED_DIR/logviewer.py" /usr/local/share/shared_libs/
|
||||
chmod 755 /usr/local/share/shared_libs/logviewer.py
|
||||
cp -f "$SHARED_DIR/logviewer.py" {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/
|
||||
chmod 755 {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py
|
||||
echo "Installed logviewer.py (executable)"
|
||||
fi
|
||||
|
||||
# Create LogViewer desktop file
|
||||
cat > /usr/share/applications/LogViewer.desktop << 'EOF'
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=LogViewer
|
||||
Comment=System Log Viewer
|
||||
Exec=/usr/local/bin/logviewer
|
||||
Icon=/usr/share/icons/lx-icons/48/log.png
|
||||
Terminal=false
|
||||
Categories=System;Utility;
|
||||
StartupNotify=true
|
||||
EOF
|
||||
|
||||
echo "Created LogViewer desktop file"
|
||||
|
||||
# Create symlink for LogViewer
|
||||
ln -sf /usr/local/share/shared_libs/logviewer.py /usr/local/bin/logviewer
|
||||
ln -sf {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py /usr/local/bin/logviewer
|
||||
echo "Created LogViewer symlink"
|
||||
|
||||
# Install language files if available
|
||||
@ -393,8 +410,9 @@ class UninstallationManager:
|
||||
raise Exception(f"{LocaleStrings.MSGO["unknow_project"]}{project_key}")
|
||||
|
||||
def _create_wirepy_uninstall_script(self):
|
||||
detected_os = Detector.get_os()
|
||||
"""Create Wire-Py uninstallation script"""
|
||||
script = """#!/bin/bash
|
||||
script = f"""#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Wire-Py Uninstallation ==="
|
||||
@ -411,7 +429,7 @@ rm -f /usr/local/bin/wirepy
|
||||
echo "Removed wirepy symlink"
|
||||
|
||||
# Remove config
|
||||
rm -f /usr/local/share/shared_libs/wp_app_config.py
|
||||
rm -f {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/wp_app_config.py
|
||||
echo "Removed wp_app_config.py"
|
||||
|
||||
# Remove desktop file
|
||||
@ -427,13 +445,16 @@ rm -f /usr/share/locale/de/LC_MESSAGES/wirepy.mo
|
||||
echo "Removed language files"
|
||||
|
||||
# Remove user config directory
|
||||
if [ -d "$HOME/.config/wire_py" ]; then
|
||||
rm -rf "$HOME/.config/wire_py"
|
||||
if [ -d /home/{getpass.getuser()}/.config/wire_py ]; then
|
||||
rm -rf /home/{getpass.getuser()}/.config/wire_py
|
||||
echo "Removed user config directory"
|
||||
fi
|
||||
# Remove ssl private key
|
||||
rm -rf /usr/local/etc/ssl
|
||||
echo "Removed ssl private key"
|
||||
|
||||
# Remove log file
|
||||
rm -f "$HOME/.local/share/lxlogs/wirepy.log"
|
||||
rm -f /home/{getpass.getuser()}/.local/share/lxlogs/wirepy.log
|
||||
echo "Removed log file"
|
||||
|
||||
# Check if LogViewer is still installed before removing shared resources
|
||||
@ -441,15 +462,14 @@ if [ ! -f /usr/local/bin/logviewer ] || [ ! -L /usr/local/bin/logviewer ]; then
|
||||
echo "No other LX apps found, removing shared resources..."
|
||||
rm -rf /usr/share/icons/lx-icons
|
||||
rm -rf /usr/share/TK-Themes
|
||||
rm -rf /usr/local/etc/ssl
|
||||
|
||||
# Remove shared libs
|
||||
for file in common_tools.py file_and_dir_ensure.py gitea.py __init__.py logview_app_config.py logviewer.py; do
|
||||
rm -f /usr/local/share/shared_libs/$file
|
||||
rm -f {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/$file
|
||||
done
|
||||
|
||||
# Try to remove shared_libs directory if empty
|
||||
rmdir /usr/local/share/shared_libs 2>/dev/null || true
|
||||
rmdir {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]} 2>/dev/null || true
|
||||
else
|
||||
echo "LogViewer still installed, keeping shared resources"
|
||||
fi
|
||||
@ -459,8 +479,9 @@ echo "Wire-Py uninstallation completed!"
|
||||
return script
|
||||
|
||||
def _create_logviewer_uninstall_script(self):
|
||||
detected_os = Detector.get_os()
|
||||
"""Create LogViewer uninstallation script"""
|
||||
script = """#!/bin/bash
|
||||
script = f"""#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== LogViewer Uninstallation ==="
|
||||
@ -469,22 +490,18 @@ echo "=== LogViewer Uninstallation ==="
|
||||
rm -f /usr/local/bin/logviewer
|
||||
echo "Removed logviewer symlink"
|
||||
|
||||
# Remove desktop file
|
||||
rm -f /usr/share/applications/LogViewer.desktop
|
||||
echo "Removed desktop file"
|
||||
|
||||
# Remove language files
|
||||
rm -f /usr/share/locale/de/LC_MESSAGES/logviewer.mo
|
||||
echo "Removed language files"
|
||||
|
||||
# Remove user config directory
|
||||
if [ -d "$HOME/.config/logviewer" ]; then
|
||||
rm -rf "$HOME/.config/logviewer"
|
||||
if [ -d /home/{getpass.getuser()}/.config/logviewer ]; then
|
||||
rm -rf /home/{getpass.getuser()}/.config/logviewer
|
||||
echo "Removed user config directory"
|
||||
fi
|
||||
|
||||
# Remove log file
|
||||
rm -f "$HOME/.local/share/lxlogs/logviewer.log"
|
||||
rm -f /home/{getpass.getuser()}/.local/share/lxlogs/logviewer.log
|
||||
echo "Removed log file"
|
||||
|
||||
# Check if Wire-Py is still installed before removing shared resources
|
||||
@ -495,19 +512,19 @@ if [ ! -f /usr/local/bin/wirepy ] || [ ! -L /usr/local/bin/wirepy ]; then
|
||||
|
||||
# Remove shared libs (but keep logviewer.py if we're only uninstalling logviewer)
|
||||
for file in common_tools.py file_and_dir_ensure.py gitea.py __init__.py logview_app_config.py; do
|
||||
rm -f /usr/local/share/shared_libs/$file
|
||||
rm -f {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/$file
|
||||
done
|
||||
|
||||
# Remove logviewer.py last
|
||||
rm -f /usr/local/share/shared_libs/logviewer.py
|
||||
rm -f {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py
|
||||
|
||||
# Try to remove shared_libs directory if empty
|
||||
rmdir /usr/local/share/shared_libs 2>/dev/null || true
|
||||
rmdir LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os] 2>/dev/null || true
|
||||
else
|
||||
echo "Wire-Py still installed, keeping shared resources"
|
||||
# Only remove logviewer-specific files
|
||||
rm -f /usr/local/share/shared_libs/logview_app_config.py
|
||||
rm -f /usr/local/share/shared_libs/logviewer.py
|
||||
rm -f {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logview_app_config.py
|
||||
rm -f {LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py
|
||||
fi
|
||||
|
||||
echo "LogViewer uninstallation completed!"
|
||||
@ -614,7 +631,7 @@ class LXToolsGUI:
|
||||
self.image_manager = Image()
|
||||
|
||||
# Detect OS
|
||||
self.detected_os = OSDetector.detect_os()
|
||||
self.detected_os = Detector.get_os()
|
||||
|
||||
# Color scheme
|
||||
self.colors = {
|
||||
@ -746,8 +763,9 @@ class LXToolsGUI:
|
||||
# Checks:
|
||||
internet_ok = NetworkChecker.check_internet_connection()
|
||||
repo_ok = NetworkChecker.check_repository_access()
|
||||
result = Detector.get_host_python_version()
|
||||
|
||||
if internet_ok and repo_ok:
|
||||
if internet_ok and repo_ok and result is not None:
|
||||
self.update_header_status(LocaleStrings.MSGO["ready"], "#1abc9c") # Green
|
||||
elif not internet_ok:
|
||||
self.update_header_status(
|
||||
@ -757,6 +775,10 @@ class LXToolsGUI:
|
||||
self.update_header_status(
|
||||
LocaleStrings.MSGO["repo_unavailable"], "#f39c12"
|
||||
) # Orange
|
||||
elif result is None:
|
||||
self.update_header_status(
|
||||
LocaleStrings.MSGO["python_check"], "#e74c3c"
|
||||
) # Red
|
||||
else:
|
||||
self.update_header_status(
|
||||
LocaleStrings.MSGO["system_check"], "#3498db"
|
||||
|
665
manager.py
665
manager.py
@ -2,6 +2,7 @@ import locale
|
||||
import gettext
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from pathlib import Path
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
@ -10,261 +11,9 @@ import stat
|
||||
from network import GiteaUpdate
|
||||
|
||||
|
||||
class LXToolsAppConfig:
|
||||
VERSION = "1.1.5"
|
||||
APP_NAME = "lxtoolsinstaller"
|
||||
WINDOW_WIDTH = 450
|
||||
WINDOW_HEIGHT = 580
|
||||
|
||||
# Working directory
|
||||
WORK_DIR = os.getcwd()
|
||||
ICONS_DIR = os.path.join(WORK_DIR, "lx-icons")
|
||||
THEMES_DIR = os.path.join(WORK_DIR, "TK-Themes")
|
||||
|
||||
# Locale settings
|
||||
LOCALE_DIR = "./locale/"
|
||||
|
||||
# Download URLs
|
||||
WIREPY_URL = "https://git.ilunix.de/punix/Wire-Py/archive/main.zip"
|
||||
SHARED_LIBS_URL = "https://git.ilunix.de/punix/shared_libs/archive/main.zip"
|
||||
|
||||
# API URLs for version checking
|
||||
WIREPY_API_URL = "https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases"
|
||||
SHARED_LIBS_API_URL = (
|
||||
"https://git.ilunix.de/api/v1/repos/punix/shared_libs/releases"
|
||||
)
|
||||
|
||||
# Project configurations
|
||||
PROJECTS = {
|
||||
"wirepy": {
|
||||
"name": "Wire-Py",
|
||||
"description": "WireGuard VPN Manager with GUI",
|
||||
"download_url": WIREPY_URL,
|
||||
"api_url": WIREPY_API_URL,
|
||||
"icon_key": "icon_vpn",
|
||||
"main_executable": "wirepy.py",
|
||||
"symlink_name": "wirepy",
|
||||
"config_file": "wp_app_config.py",
|
||||
"desktop_file": "Wire-Py.desktop",
|
||||
"policy_file": "org.sslcrypt.policy",
|
||||
"requires_ssl": True,
|
||||
},
|
||||
"logviewer": {
|
||||
"name": "LogViewer",
|
||||
"description": "System Log Viewer with GUI",
|
||||
"download_url": SHARED_LIBS_URL,
|
||||
"api_url": SHARED_LIBS_API_URL,
|
||||
"icon_key": "icon_log",
|
||||
"main_executable": "logviewer.py",
|
||||
"symlink_name": "logviewer",
|
||||
"config_file": "logview_app_config.py",
|
||||
"desktop_file": "LogViewer.desktop",
|
||||
"policy_file": None,
|
||||
"requires_ssl": False,
|
||||
},
|
||||
}
|
||||
|
||||
# OS Detection List (order matters - specific first, generic last)
|
||||
OS_DETECTION = [
|
||||
("mint", "Linux Mint"),
|
||||
("pop", "Pop!_OS"),
|
||||
("manjaro", "Manjaro"),
|
||||
("garuda", "Garuda Linux"),
|
||||
("endeavouros", "EndeavourOS"),
|
||||
("fedora", "Fedora"),
|
||||
("tumbleweed", "SUSE Tumbleweed"),
|
||||
("leap", "SUSE Leap"),
|
||||
("arch", "Arch Linux"),
|
||||
("ubuntu", "Ubuntu"),
|
||||
("debian", "Debian"),
|
||||
]
|
||||
|
||||
# Package manager commands for TKinter installation
|
||||
TKINTER_INSTALL_COMMANDS = {
|
||||
"Ubuntu": ["apt", "update", "&&", "apt", "install", "-y", "python3-tk"],
|
||||
"Debian": ["apt", "update", "&&", "apt", "install", "-y", "python3-tk"],
|
||||
"Linux Mint": ["apt", "update", "&&", "apt", "install", "-y", "python3-tk"],
|
||||
"Pop!_OS": ["apt", "update", "&&", "apt", "install", "-y", "python3-tk"],
|
||||
"Fedora": ["dnf", "install", "-y", "tkinter"],
|
||||
"Arch Linux": ["pacman", "-S", "--noconfirm", "tk"],
|
||||
"Manjaro": ["pacman", "-S", "--noconfirm", "tk"],
|
||||
"Garuda Linux": ["pacman", "-S", "--noconfirm", "tk"],
|
||||
"EndeavourOS": ["pacman", "-S", "--noconfirm", "tk"],
|
||||
"SUSE Tumbleweed": ["zypper", "install", "-y", "python314-tk"],
|
||||
"SUSE Leap": ["zypper", "install", "-y", "python312-tk"],
|
||||
}
|
||||
|
||||
class Detector:
|
||||
@staticmethod
|
||||
def extract_data_files():
|
||||
if getattr(sys, "_MEIPASS", None) is not None:
|
||||
# Liste der Quellordner (entspricht dem "datas"-Eintrag in lxtools_installer.spec)
|
||||
source_dirs = [
|
||||
os.path.join(sys._MEIPASS, "locale"), # für locale/...
|
||||
os.path.join(sys._MEIPASS, "TK-Themes"), # für TK-Themes/...
|
||||
os.path.join(sys._MEIPASS, "lx-icons"), # für lx-icons/...
|
||||
]
|
||||
|
||||
target_dir = os.path.abspath(
|
||||
os.getcwd()
|
||||
) # Zielverzeichnis: aktueller Ordner
|
||||
|
||||
for source_dir in source_dirs:
|
||||
group_name = os.path.basename(
|
||||
source_dir
|
||||
) # Erhält den Gruppen-Name (z. B. 'locale', 'TK-Themes')
|
||||
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for file in files:
|
||||
src_path = os.path.join(root, file)
|
||||
|
||||
# Relativer Pfad innerhalb des Quellordners
|
||||
rel_path_from_source_root = os.path.relpath(
|
||||
src_path, source_dir
|
||||
)
|
||||
|
||||
# Ziel-Pfad unter dem Gruppen-Ordner im aktuellen Verzeichnis
|
||||
dst_path = os.path.join(
|
||||
target_dir, group_name, rel_path_from_source_root
|
||||
)
|
||||
|
||||
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
|
||||
shutil.copy2(src_path, dst_path)
|
||||
|
||||
@staticmethod
|
||||
def setup_translations() -> gettext.gettext:
|
||||
"""Initialize translations and set the translation function"""
|
||||
try:
|
||||
locale.bindtextdomain(
|
||||
LXToolsAppConfig.APP_NAME, LXToolsAppConfig.LOCALE_DIR
|
||||
)
|
||||
gettext.bindtextdomain(
|
||||
LXToolsAppConfig.APP_NAME, LXToolsAppConfig.LOCALE_DIR
|
||||
)
|
||||
gettext.textdomain(LXToolsAppConfig.APP_NAME)
|
||||
except:
|
||||
pass
|
||||
return gettext.gettext
|
||||
|
||||
|
||||
LXToolsAppConfig.extract_data_files()
|
||||
# Initialize translations
|
||||
_ = LXToolsAppConfig.setup_translations()
|
||||
|
||||
|
||||
class LocaleStrings:
|
||||
|
||||
MSGI = {
|
||||
"refresh_and_check": _("Refreshing status and checking versions..."),
|
||||
"start_install": _("Starting installation of "),
|
||||
"install": _("Installing "),
|
||||
"install_success": _(" installation successfully!"),
|
||||
"install_failed": _("Installation failed: "),
|
||||
"install_create": _("Created install script: "),
|
||||
"install_script_failed": _("Installation script failed: "),
|
||||
"install_timeout": _("Installation timed out"),
|
||||
"installed": _("Installed "),
|
||||
}
|
||||
|
||||
MSGU = {
|
||||
"uninstall": _("Uninstalling "),
|
||||
"uninstall_success": _(" uninstalled successfully!"),
|
||||
"uninstall_failed": _("Uninstallation failed: "),
|
||||
"uninstall_create": _("Created uninstall script: "),
|
||||
"uninstall_script_failed": _("Uninstallation script failed: "),
|
||||
"uninstall_timeout": _("Uninstallation timed out"),
|
||||
}
|
||||
# MSGO = Other messages
|
||||
MSGO = {
|
||||
"unknown_project": _("Unknown project: "),
|
||||
"not_install": _(" is not installed."),
|
||||
"download_from": _("Downloading from "),
|
||||
"extract_files": _("Extracting files..."),
|
||||
"download_failed": _("Download failed: "),
|
||||
"head_string2": _("System: "),
|
||||
"head_string3": _("Linux App Installer"),
|
||||
"ready": _("Ready for installation"),
|
||||
"no_internet": _("No internet connection"),
|
||||
"repo_unavailable": _("Repository unavailable"),
|
||||
"system_check": _("System checking..."),
|
||||
"applications": _("Applications"),
|
||||
"progress": _("Progress"),
|
||||
"refresh2": _("Status refresh completed"),
|
||||
}
|
||||
|
||||
# MSGC = Strings on Cards
|
||||
MSGC = {
|
||||
"checking": _("Checking..."),
|
||||
"version_check": _("Version: Checking..."),
|
||||
"latest": _("Latest: "),
|
||||
"update_available": _("Update available "),
|
||||
"up_to_date": _("Up to date"),
|
||||
"latest_unknown": _("Latest unknown"),
|
||||
"could_not_check": _("Could not check latest version"),
|
||||
"check_last_failed": _("Latest: Check failed"),
|
||||
"version_check_failed": _("Version check failed"),
|
||||
"not_installed": _("Not installed"),
|
||||
"available": _("Available "),
|
||||
"available_unknown": _("Available unknown"),
|
||||
"available_ckeck_failed": _("Available: Check failed"),
|
||||
}
|
||||
|
||||
# MSGL = Strings on Logmessages
|
||||
MSGL = {
|
||||
"selected_app": _("Selected project: "),
|
||||
"log_name": _("Installation Log"),
|
||||
"work_dir": _("Working directory: "),
|
||||
"icons_dir": _("Icons directory: "),
|
||||
"detected_os": _("Detected OS: "),
|
||||
"log_cleared": _("Log cleared"),
|
||||
"working_dir": _("Working directory: "),
|
||||
"user_interuppt": _("\nApplication interrupted by user."),
|
||||
"fatal_error": _("Fatal error: "),
|
||||
"fatal_app_error": _("Fatal Error Application failed to start: "),
|
||||
}
|
||||
|
||||
# MSGB = Strings on Buttons
|
||||
MSGB = {
|
||||
"clear_log": _("Clear Log"),
|
||||
"install": _("Install/Update"),
|
||||
"uninstall": _("Uninstall"),
|
||||
"refresh": _("Refresh Status"),
|
||||
}
|
||||
|
||||
# MSGM = String on MessagDialogs
|
||||
MSGM = {
|
||||
"please_select": _("Please select a project to install."),
|
||||
"network_error": _(
|
||||
"No internet connection available.\nPlease check your network connection.",
|
||||
),
|
||||
"repo_error": _(
|
||||
"Cannot access repository.\nPlease try again later.",
|
||||
),
|
||||
"has_success_update": _("has been successfully installed/updated."),
|
||||
"please_select_uninstall": _("Please select a project to uninstall."),
|
||||
}
|
||||
|
||||
# MSGP = Others print strings
|
||||
MSGP = {
|
||||
"tk_install": _("Installing tkinter for )"),
|
||||
"command_string": _("Command: "),
|
||||
"tk_success": _("TKinter installation completed successfully!"),
|
||||
"tk_failed": _("TKinter installation failed: "),
|
||||
"tk_timeout": _("TKinter installation timed out"),
|
||||
"tk_install_error": _("Error installing tkinter: "),
|
||||
"tk_command_error": _("No tkinter installation command defined for "),
|
||||
"fail_load_image": _("Failed to load image from "),
|
||||
"logviewer_check": _("LogViewer installation check:"),
|
||||
"symlink_exist": _(" Symlink exists: "),
|
||||
"executable_exist": _(" Executable exists: "),
|
||||
"is_executable": _(" Is executable: "),
|
||||
"final_result": _(" Final result: "),
|
||||
"get_version_error": _("Error getting version for "),
|
||||
}
|
||||
|
||||
|
||||
class OSDetector:
|
||||
@staticmethod
|
||||
def detect_os():
|
||||
def get_os() -> str:
|
||||
"""Detect operating system using ordered list"""
|
||||
try:
|
||||
with open("/etc/os-release", "r") as f:
|
||||
@ -280,54 +29,77 @@ class OSDetector:
|
||||
return "File not found"
|
||||
|
||||
@staticmethod
|
||||
def check_tkinter_available():
|
||||
"""Check if tkinter is available"""
|
||||
def get_host_python_version() -> str:
|
||||
try:
|
||||
import tkinter
|
||||
result = subprocess.run(
|
||||
["python3", "--version"], capture_output=True, text=True, check=True
|
||||
)
|
||||
version_str = result.stdout.strip().replace("Python ", "")
|
||||
return version_str[:4] # example "3.13"
|
||||
except Exception:
|
||||
print("Python not found")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_user_gt_1() -> bool:
|
||||
"""This method may be required for the future if the number of users"""
|
||||
path = Path("/home")
|
||||
|
||||
user_directories = [
|
||||
entry
|
||||
for entry in path.iterdir()
|
||||
if entry.is_dir() and entry.name != "root" and entry.name != "lost+found"
|
||||
]
|
||||
|
||||
# Count the number of user directories
|
||||
numbers = len(user_directories)
|
||||
if not numbers > 1:
|
||||
return True
|
||||
except ImportError:
|
||||
else:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def install_tkinter():
|
||||
"""Install tkinter based on detected OS"""
|
||||
detected_os = OSDetector.detect_os()
|
||||
def get_wget() -> bool:
|
||||
"""Check if wget is installed"""
|
||||
|
||||
if detected_os in LXToolsAppConfig.TKINTER_INSTALL_COMMANDS:
|
||||
commands = LXToolsAppConfig.TKINTER_INSTALL_COMMANDS[detected_os]
|
||||
|
||||
print(f"{LocaleStrings.MSGP["tk_install"]}{detected_os}...")
|
||||
print(f"{LocaleStrings.MSGP["command_string"]}{' '.join(commands)}")
|
||||
|
||||
try:
|
||||
# Use pkexec for privilege escalation
|
||||
full_command = ["pkexec", "bash", "-c", " ".join(commands)]
|
||||
result = subprocess.run(
|
||||
full_command, capture_output=True, text=True, timeout=300
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"{LocaleStrings.MSGP["tk_succcess"]}")
|
||||
return True
|
||||
else:
|
||||
print(f"{LocaleStrings.MSGP["tk_failed"]}{result.stderr}")
|
||||
return False
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
print(LocaleStrings.MSGP["tk_timeout"])
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"{LocaleStrings.MSGP['tk_install_error']}{str(e)}")
|
||||
return False
|
||||
result = subprocess.run(
|
||||
["which", "wget"], capture_output=True, text=True, check=False
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def get_unzip() -> bool:
|
||||
"""Check if wget is installed"""
|
||||
|
||||
result = subprocess.run(
|
||||
["which", "unzip"], capture_output=True, text=True, check=False
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def get_requests() -> bool:
|
||||
"""Check if requests is installed"""
|
||||
result = subprocess.run(
|
||||
["pacman", "-Qs", "python-requests"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
return True
|
||||
else:
|
||||
print(f"{LocaleStrings.MSGP["tk_command_error"]}{detected_os}")
|
||||
return False
|
||||
|
||||
|
||||
class Theme:
|
||||
@staticmethod
|
||||
def apply_light_theme(root):
|
||||
def apply_light_theme(root) -> bool:
|
||||
"""Apply light theme"""
|
||||
try:
|
||||
theme_dir = LXToolsAppConfig.THEMES_DIR
|
||||
@ -358,41 +130,41 @@ class Theme:
|
||||
|
||||
class System:
|
||||
@staticmethod
|
||||
def create_directories(directories):
|
||||
def create_directories(directories) -> None:
|
||||
"""Create system directories using pkexec"""
|
||||
for directory in directories:
|
||||
subprocess.run(["pkexec", "mkdir", "-p", directory], check=True)
|
||||
|
||||
@staticmethod
|
||||
def copy_file(src, dest, make_executable=False):
|
||||
def copy_file(src, dest, make_executable=False) -> None:
|
||||
"""Copy file using pkexec"""
|
||||
subprocess.run(["pkexec", "cp", src, dest], check=True)
|
||||
if make_executable:
|
||||
subprocess.run(["pkexec", "chmod", "755", dest], check=True)
|
||||
|
||||
@staticmethod
|
||||
def copy_directory(src, dest):
|
||||
def copy_directory(src, dest) -> None:
|
||||
"""Copy directory using pkexec"""
|
||||
subprocess.run(["pkexec", "cp", "-r", src, dest], check=True)
|
||||
|
||||
@staticmethod
|
||||
def remove_file(path):
|
||||
def remove_file(path) -> None:
|
||||
"""Remove file using pkexec"""
|
||||
subprocess.run(["pkexec", "rm", "-f", path], check=False)
|
||||
|
||||
@staticmethod
|
||||
def remove_directory(path):
|
||||
def remove_directory(path) -> None:
|
||||
"""Remove directory using pkexec"""
|
||||
subprocess.run(["pkexec", "rm", "-rf", path], check=False)
|
||||
|
||||
@staticmethod
|
||||
def create_symlink(target, link_name):
|
||||
def create_symlink(target, link_name) -> None:
|
||||
"""Create symbolic link using pkexec"""
|
||||
subprocess.run(["pkexec", "rm", "-f", link_name], check=False)
|
||||
subprocess.run(["pkexec", "ln", "-sf", target, link_name], check=True)
|
||||
|
||||
@staticmethod
|
||||
def create_ssl_key(pem_file):
|
||||
def create_ssl_key(pem_file) -> bool:
|
||||
"""Create SSL key using pkexec"""
|
||||
try:
|
||||
subprocess.run(
|
||||
@ -408,7 +180,7 @@ class Image:
|
||||
def __init__(self):
|
||||
self.images = {}
|
||||
|
||||
def load_image(self, image_key, fallback_paths=None):
|
||||
def load_image(self, image_key, fallback_paths=None) -> None | tk.PhotoImage:
|
||||
"""Load PNG image using tk.PhotoImage with fallback options"""
|
||||
if image_key in self.images:
|
||||
return self.images[image_key]
|
||||
@ -467,15 +239,16 @@ class AppManager:
|
||||
def __init__(self):
|
||||
self.projects = LXToolsAppConfig.PROJECTS
|
||||
|
||||
def get_project_info(self, project_key):
|
||||
def get_project_info(self, project_key) -> dict | None:
|
||||
"""Get project information by key"""
|
||||
return self.projects.get(project_key)
|
||||
|
||||
def get_all_projects(self):
|
||||
def get_all_projects(self) -> dict:
|
||||
"""Get all project configurations"""
|
||||
return self.projects
|
||||
|
||||
def is_installed(self, project_key):
|
||||
def is_installed(self, project_key) -> bool:
|
||||
detected_os = Detector.get_os()
|
||||
"""Check if project is installed with better detection"""
|
||||
if project_key == "wirepy":
|
||||
# Check for wirepy symlink
|
||||
@ -487,14 +260,16 @@ class AppManager:
|
||||
# Check for logviewer symlink AND executable file
|
||||
symlink_exists = os.path.exists("/usr/local/bin/logviewer")
|
||||
executable_exists = os.path.exists(
|
||||
"/usr/local/share/shared_libs/logviewer.py"
|
||||
f"{LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py"
|
||||
)
|
||||
executable_is_executable = False
|
||||
|
||||
if executable_exists:
|
||||
try:
|
||||
# Check if file is executable
|
||||
file_stat = os.stat("/usr/local/share/shared_libs/logviewer.py")
|
||||
file_stat = os.stat(
|
||||
f"{LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logviewer.py"
|
||||
)
|
||||
executable_is_executable = bool(file_stat.st_mode & stat.S_IEXEC)
|
||||
except:
|
||||
executable_is_executable = False
|
||||
@ -515,13 +290,14 @@ class AppManager:
|
||||
|
||||
return False
|
||||
|
||||
def get_installed_version(self, project_key):
|
||||
def get_installed_version(self, project_key) -> str:
|
||||
detected_os = Detector.get_os()
|
||||
"""Get installed version from config file"""
|
||||
try:
|
||||
if project_key == "wirepy":
|
||||
config_file = "/usr/local/share/shared_libs/wp_app_config.py"
|
||||
config_file = f"{LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/wp_app_config.py"
|
||||
elif project_key == "logviewer":
|
||||
config_file = "/usr/local/share/shared_libs/logview_app_config.py"
|
||||
config_file = f"{LXToolsAppConfig.SHARED_LIBS_DESTINATION[detected_os]}/logview_app_config.py"
|
||||
else:
|
||||
return "Unknown"
|
||||
|
||||
@ -537,7 +313,7 @@ class AppManager:
|
||||
print(f"{LocaleStrings.MSGP["get_version_error"]}{project_key}: {e}")
|
||||
return "Unknown"
|
||||
|
||||
def get_latest_version(self, project_key):
|
||||
def get_latest_version(self, project_key) -> str:
|
||||
"""Get latest version from API"""
|
||||
project_info = self.get_project_info(project_key)
|
||||
if not project_info:
|
||||
@ -545,7 +321,7 @@ class AppManager:
|
||||
|
||||
return GiteaUpdate.api_down(project_info["api_url"])
|
||||
|
||||
def check_other_apps_installed(self, exclude_key):
|
||||
def check_other_apps_installed(self, exclude_key) -> bool:
|
||||
"""Check if other apps are still installed"""
|
||||
return any(
|
||||
self.is_installed(key) for key in self.projects.keys() if key != exclude_key
|
||||
@ -554,7 +330,7 @@ class AppManager:
|
||||
|
||||
class LxTools:
|
||||
@staticmethod
|
||||
def center_window_cross_platform(window, width, height):
|
||||
def center_window_cross_platform(window, width, height) -> None:
|
||||
"""
|
||||
Centers a window on the primary monitor in a way that works on both X11 and Wayland
|
||||
|
||||
@ -640,3 +416,276 @@ class LxTools:
|
||||
x = (screen_width - width) // 2
|
||||
y = (screen_height - height) // 2
|
||||
window.geometry(f"{width}x{height}+{x}+{y}")
|
||||
|
||||
|
||||
class LXToolsAppConfig:
|
||||
|
||||
@staticmethod
|
||||
def extract_data_files() -> None:
|
||||
if getattr(sys, "_MEIPASS", None) is not None:
|
||||
# Liste der Quellordner (entspricht dem "datas"-Eintrag in lxtools_installer.spec)
|
||||
source_dirs = [
|
||||
os.path.join(sys._MEIPASS, "locale"), # für locale/...
|
||||
os.path.join(sys._MEIPASS, "TK-Themes"), # für TK-Themes/...
|
||||
os.path.join(sys._MEIPASS, "lx-icons"), # für lx-icons/...
|
||||
]
|
||||
|
||||
target_dir = os.path.abspath(
|
||||
os.getcwd()
|
||||
) # Zielverzeichnis: aktueller Ordner
|
||||
|
||||
for source_dir in source_dirs:
|
||||
group_name = os.path.basename(
|
||||
source_dir
|
||||
) # Erhält den Gruppen-Name (z. B. 'locale', 'TK-Themes')
|
||||
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for file in files:
|
||||
src_path = os.path.join(root, file)
|
||||
|
||||
# Relativer Pfad innerhalb des Quellordners
|
||||
rel_path_from_source_root = os.path.relpath(
|
||||
src_path, source_dir
|
||||
)
|
||||
|
||||
# Ziel-Pfad unter dem Gruppen-Ordner im aktuellen Verzeichnis
|
||||
dst_path = os.path.join(
|
||||
target_dir, group_name, rel_path_from_source_root
|
||||
)
|
||||
|
||||
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
|
||||
shutil.copy2(src_path, dst_path)
|
||||
|
||||
# Set the SSL certificate file path by start as appimage
|
||||
os.environ["SSL_CERT_FILE"] = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), "certs", "cacert.pem"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def setup_translations() -> gettext.gettext:
|
||||
"""Initialize translations and set the translation function"""
|
||||
try:
|
||||
locale.bindtextdomain(
|
||||
LXToolsAppConfig.APP_NAME, LXToolsAppConfig.LOCALE_DIR
|
||||
)
|
||||
gettext.bindtextdomain(
|
||||
LXToolsAppConfig.APP_NAME, LXToolsAppConfig.LOCALE_DIR
|
||||
)
|
||||
gettext.textdomain(LXToolsAppConfig.APP_NAME)
|
||||
except:
|
||||
pass
|
||||
return gettext.gettext
|
||||
|
||||
VERSION = "1.1.5"
|
||||
APP_NAME = "lxtoolsinstaller"
|
||||
WINDOW_WIDTH = 450
|
||||
WINDOW_HEIGHT = 580
|
||||
|
||||
# Working directory
|
||||
WORK_DIR = os.getcwd()
|
||||
ICONS_DIR = os.path.join(WORK_DIR, "lx-icons")
|
||||
THEMES_DIR = os.path.join(WORK_DIR, "TK-Themes")
|
||||
|
||||
# Locale settings
|
||||
LOCALE_DIR = "./locale/"
|
||||
|
||||
# Download URLs
|
||||
WIREPY_URL = "https://git.ilunix.de/punix/Wire-Py/archive/main.zip"
|
||||
SHARED_LIBS_URL = "https://git.ilunix.de/punix/shared_libs/archive/main.zip"
|
||||
|
||||
# API URLs for version checking
|
||||
WIREPY_API_URL = "https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases"
|
||||
SHARED_LIBS_API_URL = (
|
||||
"https://git.ilunix.de/api/v1/repos/punix/shared_libs/releases"
|
||||
)
|
||||
|
||||
# Project configurations
|
||||
PROJECTS = {
|
||||
"wirepy": {
|
||||
"name": "Wire-Py",
|
||||
"description": "WireGuard VPN Manager with GUI",
|
||||
"download_url": WIREPY_URL,
|
||||
"api_url": WIREPY_API_URL,
|
||||
"icon_key": "icon_vpn",
|
||||
"main_executable": "wirepy.py",
|
||||
"symlink_name": "wirepy",
|
||||
"config_file": "wp_app_config.py",
|
||||
"desktop_file": "Wire-Py.desktop",
|
||||
"policy_file": "org.sslcrypt.policy",
|
||||
"requires_ssl": True,
|
||||
},
|
||||
"logviewer": {
|
||||
"name": "LogViewer",
|
||||
"description": "System Log Viewer with GUI",
|
||||
"download_url": SHARED_LIBS_URL,
|
||||
"api_url": SHARED_LIBS_API_URL,
|
||||
"icon_key": "icon_log",
|
||||
"main_executable": "logviewer.py",
|
||||
"symlink_name": "logviewer",
|
||||
"config_file": "logview_app_config.py",
|
||||
"desktop_file": "LogViewer.desktop",
|
||||
"policy_file": None,
|
||||
"requires_ssl": False,
|
||||
},
|
||||
}
|
||||
|
||||
# OS Detection List (order matters - specific first, generic last)
|
||||
OS_DETECTION = [
|
||||
("mint", "Linux Mint"),
|
||||
("pop", "Pop!_OS"),
|
||||
("manjaro", "Manjaro"),
|
||||
("garuda", "Garuda Linux"),
|
||||
("endeavouros", "EndeavourOS"),
|
||||
("fedora", "Fedora"),
|
||||
("tumbleweed", "SUSE Tumbleweed"),
|
||||
("leap", "SUSE Leap"),
|
||||
("arch", "Arch Linux"),
|
||||
("ubuntu", "Ubuntu"),
|
||||
("debian", "Debian"),
|
||||
]
|
||||
|
||||
# Package manager commands for TKinter installation
|
||||
TKINTER_INSTALL_COMMANDS = {
|
||||
"Ubuntu": "apt install -y python3-tk",
|
||||
"Debian": "apt install -y python3-tk",
|
||||
"Linux Mint": "apt install -y python3-tk",
|
||||
"Pop!_OS": "apt install -y python3-tk",
|
||||
"Fedora": "dnf install -y python3-tkinter",
|
||||
"Arch Linux": "pacman -S --noconfirm tk",
|
||||
"Manjaro": "pacman -S --noconfirm tk",
|
||||
"Garuda Linux": "pacman -S --noconfirm tk",
|
||||
"EndeavourOS": "pacman -S --noconfirm tk",
|
||||
"SUSE Tumbleweed": "zypper install -y python3-tk",
|
||||
"SUSE Leap": "zypper install -y python3-tk",
|
||||
}
|
||||
|
||||
SHARED_LIBS_DESTINATION = {
|
||||
"Ubuntu": "/usr/lib/python3/dist-packages/shared_libs",
|
||||
"Debian": "/usr/lib/python3/dist-packages/shared_libs",
|
||||
"Linux Mint": "/usr/lib/python3/dist-packages/shared_libs",
|
||||
"Pop!_OS": "/usr/lib/python3/dist-packages/shared_libs",
|
||||
"Fedora": f"/usr/lib64/python{Detector.get_host_python_version()}/site-packages/shared_libs",
|
||||
"Arch Linux": f"/usr/lib64/python{Detector.get_host_python_version()}/site-packages/shared_libs",
|
||||
"Manjaro": f"/usr/lib64/python{Detector.get_host_python_version()}/site-packages/shared_libs",
|
||||
"Garuda Linux": f"/usr/lib64/python{Detector.get_host_python_version()}/site-packages/shared_libs",
|
||||
"EndeavourOS": f"/usr/lib64/python{Detector.get_host_python_version()}/site-packages/shared_libs",
|
||||
"SUSE Tumbleweed": f"/usr/lib64/python{Detector.get_host_python_version()}/site-packages/shared_libs",
|
||||
"SUSE Leap": f"/usr/lib64/python{Detector.get_host_python_version()}/site-packages/shared_libs",
|
||||
}
|
||||
|
||||
|
||||
LXToolsAppConfig.extract_data_files()
|
||||
# Initialize translations
|
||||
_ = LXToolsAppConfig.setup_translations()
|
||||
|
||||
|
||||
class LocaleStrings:
|
||||
|
||||
MSGI = {
|
||||
"refresh_and_check": _("Refreshing status and checking versions..."),
|
||||
"start_install": _("Starting installation of "),
|
||||
"install": _("Installing "),
|
||||
"install_success": _(" installation successfully!"),
|
||||
"install_failed": _("Installation failed: "),
|
||||
"install_create": _("Created install script: "),
|
||||
"install_script_failed": _("Installation script failed: "),
|
||||
"install_timeout": _("Installation timed out"),
|
||||
"installed": _("Installed "),
|
||||
}
|
||||
|
||||
MSGU = {
|
||||
"uninstall": _("Uninstalling "),
|
||||
"uninstall_success": _(" uninstalled successfully!"),
|
||||
"uninstall_failed": _("Uninstallation failed: "),
|
||||
"uninstall_create": _("Created uninstall script: "),
|
||||
"uninstall_script_failed": _("Uninstallation script failed: "),
|
||||
"uninstall_timeout": _("Uninstallation timed out"),
|
||||
}
|
||||
# MSGO = Other messages
|
||||
MSGO = {
|
||||
"unknown_project": _("Unknown project: "),
|
||||
"not_install": _(" is not installed."),
|
||||
"download_from": _("Downloading from "),
|
||||
"extract_files": _("Extracting files..."),
|
||||
"download_failed": _("Download failed: "),
|
||||
"head_string2": _("System: "),
|
||||
"head_string3": _("Linux App Installer"),
|
||||
"ready": _("Ready for installation"),
|
||||
"no_internet": _("No internet connection"),
|
||||
"repo_unavailable": _("Repository unavailable"),
|
||||
"system_check": _("System checking..."),
|
||||
"applications": _("Applications"),
|
||||
"progress": _("Progress"),
|
||||
"refresh2": _("Status refresh completed"),
|
||||
"python_check": _("Python not installed"),
|
||||
}
|
||||
|
||||
# MSGC = Strings on Cards
|
||||
MSGC = {
|
||||
"checking": _("Checking..."),
|
||||
"version_check": _("Version: Checking..."),
|
||||
"latest": _("Latest: "),
|
||||
"update_available": _("Update available "),
|
||||
"up_to_date": _("Up to date"),
|
||||
"latest_unknown": _("Latest unknown"),
|
||||
"could_not_check": _("Could not check latest version"),
|
||||
"check_last_failed": _("Latest: Check failed"),
|
||||
"version_check_failed": _("Version check failed"),
|
||||
"not_installed": _("Not installed"),
|
||||
"available": _("Available "),
|
||||
"available_unknown": _("Available unknown"),
|
||||
"available_ckeck_failed": _("Available: Check failed"),
|
||||
}
|
||||
|
||||
# MSGL = Strings on Logmessages
|
||||
MSGL = {
|
||||
"selected_app": _("Selected project: "),
|
||||
"log_name": _("Installation Log"),
|
||||
"work_dir": _("Working directory: "),
|
||||
"icons_dir": _("Icons directory: "),
|
||||
"detected_os": _("Detected OS: "),
|
||||
"log_cleared": _("Log cleared"),
|
||||
"working_dir": _("Working directory: "),
|
||||
"user_interuppt": _("\nApplication interrupted by user."),
|
||||
"fatal_error": _("Fatal error: "),
|
||||
"fatal_app_error": _("Fatal Error Application failed to start: "),
|
||||
}
|
||||
|
||||
# MSGB = Strings on Buttons
|
||||
MSGB = {
|
||||
"clear_log": _("Clear Log"),
|
||||
"install": _("Install/Update"),
|
||||
"uninstall": _("Uninstall"),
|
||||
"refresh": _("Refresh Status"),
|
||||
}
|
||||
|
||||
# MSGM = String on MessagDialogs
|
||||
MSGM = {
|
||||
"please_select": _("Please select a project to install."),
|
||||
"network_error": _(
|
||||
"No internet connection available.\nPlease check your network connection.",
|
||||
),
|
||||
"repo_error": _(
|
||||
"Cannot access repository.\nPlease try again later.",
|
||||
),
|
||||
"has_success_update": _("has been successfully installed/updated."),
|
||||
"please_select_uninstall": _("Please select a project to uninstall."),
|
||||
}
|
||||
|
||||
# MSGP = Others print strings
|
||||
MSGP = {
|
||||
"tk_install": _("Installing tkinter for )"),
|
||||
"command_string": _("Command: "),
|
||||
"tk_success": _("TKinter installation completed successfully!"),
|
||||
"tk_failed": _("TKinter installation failed: "),
|
||||
"tk_timeout": _("TKinter installation timed out"),
|
||||
"tk_install_error": _("Error installing tkinter: "),
|
||||
"tk_command_error": _("No tkinter installation command defined for "),
|
||||
"fail_load_image": _("Failed to load image from "),
|
||||
"logviewer_check": _("LogViewer installation check:"),
|
||||
"symlink_exist": _(" Symlink exists: "),
|
||||
"executable_exist": _(" Executable exists: "),
|
||||
"is_executable": _(" Is executable: "),
|
||||
"final_result": _(" Final result: "),
|
||||
"get_version_error": _("Error getting version for "),
|
||||
}
|
||||
|
Reference in New Issue
Block a user