29.06.2025 (show changelog)
This commit is contained in:
24
.gitignore
vendored
24
.gitignore
vendored
@ -4,3 +4,27 @@ debug.log
|
|||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
|
# Build-Artefakte
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
certs/
|
||||||
|
*.spec.bak
|
||||||
|
lxtools_installer
|
||||||
|
lxtools_installer.AppImage
|
||||||
|
lxtools_installer_compat
|
||||||
|
build_compatible.sh
|
||||||
|
build_local.sh
|
||||||
|
clean_build.sh
|
||||||
|
start_builder.sh
|
||||||
|
test_extract.py
|
||||||
|
test_paths.py
|
||||||
|
test_resources.py
|
||||||
|
manager_fixed.py
|
||||||
|
|
||||||
|
# Docker-Build
|
||||||
|
docker_build/
|
||||||
|
debug_docker.sh
|
||||||
|
Dockerfile.nuitka
|
||||||
|
DOCKER_BUILD_ANLEITUNG.md
|
||||||
|
nuitka_builder.py
|
||||||
|
14
Changelog
14
Changelog
@ -2,10 +2,20 @@ Changelog for LXTools installer
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
- language set auto detection
|
|
||||||
|
|
||||||
-
|
-
|
||||||
|
|
||||||
|
|
||||||
|
### Added
|
||||||
|
29.06.2025
|
||||||
|
|
||||||
|
- add methode sigi, clean_files and remove_lxtools_files
|
||||||
|
for remove files and dirs on close lxtools_installer
|
||||||
|
|
||||||
|
- fix message dialog on font and padding
|
||||||
|
|
||||||
|
- add methods check polkit and check Networkmanager is installed
|
||||||
|
and view in header is result false
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
23-06-2025
|
23-06-2025
|
||||||
|
|
||||||
|
Binary file not shown.
BIN
lx-icons/16/settings.png
Normal file
BIN
lx-icons/16/settings.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 575 B |
BIN
lx-icons/16/wg_vpn.png
Normal file
BIN
lx-icons/16/wg_vpn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 846 B |
@ -2,6 +2,7 @@
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
import getpass
|
import getpass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -37,12 +38,12 @@ class InstallationManager:
|
|||||||
"""Install or update project"""
|
"""Install or update project"""
|
||||||
project_info = self.app_manager.get_project_info(project_key)
|
project_info = self.app_manager.get_project_info(project_key)
|
||||||
if not project_info:
|
if not project_info:
|
||||||
raise Exception(f"{LocaleStrings.MSG["unknow_project"]}{project_key}")
|
raise Exception(f"{LocaleStrings.MSG['unknow_project']}{project_key}")
|
||||||
|
|
||||||
self.update_progress(
|
self.update_progress(
|
||||||
f"{LocaleStrings.MSGI["start_install"]}{project_info['name']}..."
|
f"{LocaleStrings.MSGI['start_install']}{project_info['name']}..."
|
||||||
)
|
)
|
||||||
self.log(f"=== {LocaleStrings.MSGI["install"]}{project_info['name']} ===")
|
self.log(f"=== {LocaleStrings.MSGI['install']}{project_info['name']} ===")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Create installation script
|
# Create installation script
|
||||||
@ -52,19 +53,19 @@ class InstallationManager:
|
|||||||
self._execute_install_script(script_content)
|
self._execute_install_script(script_content)
|
||||||
|
|
||||||
self.update_progress(
|
self.update_progress(
|
||||||
f"{project_info["name"]}{LocaleStrings.MSGI["install_success"]}"
|
f"{project_info['name']}{LocaleStrings.MSGI['install_success']}"
|
||||||
)
|
)
|
||||||
self.log(
|
self.log(
|
||||||
f"=== {project_info["name"]}{LocaleStrings.MSGI["install_success"]} ==="
|
f"=== {project_info['name']}{LocaleStrings.MSGI['install_success']} ==="
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set success icon
|
# Set success icon
|
||||||
self.update_icon("success")
|
self.update_icon("success")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log(f"ERROR: {LocaleStrings.MSGI["install_failed"]}{e}")
|
self.log(f"ERROR: {LocaleStrings.MSGI['install_failed']}{e}")
|
||||||
self.update_icon("error")
|
self.update_icon("error")
|
||||||
raise Exception(f"{LocaleStrings.MSGI["install_failed"]}{e}")
|
raise Exception(f"{LocaleStrings.MSGI['install_failed']}{e}")
|
||||||
|
|
||||||
def _create_install_script(self, project_key):
|
def _create_install_script(self, project_key):
|
||||||
"""Create installation script based on project"""
|
"""Create installation script based on project"""
|
||||||
@ -73,7 +74,7 @@ class InstallationManager:
|
|||||||
elif project_key == "logviewer":
|
elif project_key == "logviewer":
|
||||||
return self._create_logviewer_install_script()
|
return self._create_logviewer_install_script()
|
||||||
else:
|
else:
|
||||||
raise Exception(f"{LocaleStrings.MSGI["unknow_project"]}{project_key}")
|
raise Exception(f"{LocaleStrings.MSGI['unknow_project']}{project_key}")
|
||||||
|
|
||||||
def _create_wirepy_install_script(self):
|
def _create_wirepy_install_script(self):
|
||||||
detected_os = Detector.get_os()
|
detected_os = Detector.get_os()
|
||||||
@ -331,7 +332,7 @@ echo "LogViewer installation completed!"
|
|||||||
|
|
||||||
# Make script executable
|
# Make script executable
|
||||||
os.chmod(script_file.name, 0o755)
|
os.chmod(script_file.name, 0o755)
|
||||||
self.log(f"{LocaleStrings.MSGI["install_create"]}{script_file.name}")
|
self.log(f"{LocaleStrings.MSGI['install_create']}{script_file.name}")
|
||||||
|
|
||||||
# Execute with pkexec
|
# Execute with pkexec
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
@ -352,13 +353,13 @@ echo "LogViewer installation completed!"
|
|||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"{LocaleStrings.MSGI["install_script_failed"]}{result.stderr}"
|
f"{LocaleStrings.MSGI['install_script_failed']}{result.stderr}"
|
||||||
)
|
)
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
raise Exception(LocaleStrings.MSGI["install_timeout"])
|
raise Exception(LocaleStrings.MSGI["install_timeout"])
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise Exception(f"{LocaleStrings.MSGI["install_script_failed"]}{e}")
|
raise Exception(f"{LocaleStrings.MSGI['install_script_failed']}{e}")
|
||||||
|
|
||||||
def update_progress(self, message):
|
def update_progress(self, message):
|
||||||
if self.progress_callback:
|
if self.progress_callback:
|
||||||
@ -383,17 +384,17 @@ class UninstallationManager:
|
|||||||
"""Uninstall project"""
|
"""Uninstall project"""
|
||||||
project_info = self.app_manager.get_project_info(project_key)
|
project_info = self.app_manager.get_project_info(project_key)
|
||||||
if not project_info:
|
if not project_info:
|
||||||
raise Exception(f"{LocaleStrings.MSGO["unknow_project"]}{project_key}")
|
raise Exception(f"{LocaleStrings.MSGO['unknow_project']}{project_key}")
|
||||||
|
|
||||||
if not self.app_manager.is_installed(project_key):
|
if not self.app_manager.is_installed(project_key):
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"{project_info["name"]}{LocaleStrings.MSGO["not_installed"]}"
|
f"{project_info['name']}{LocaleStrings.MSGO['not_installed']}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.update_progress(
|
self.update_progress(
|
||||||
f"{LocaleStrings.MSGU["uninstall"]}{project_info['name']}..."
|
f"{LocaleStrings.MSGU['uninstall']}{project_info['name']}..."
|
||||||
)
|
)
|
||||||
self.log(f"=== {LocaleStrings.MSGU["uninstall"]}{project_info['name']} ===")
|
self.log(f"=== {LocaleStrings.MSGU['uninstall']}{project_info['name']} ===")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Create uninstallation script
|
# Create uninstallation script
|
||||||
@ -403,15 +404,15 @@ class UninstallationManager:
|
|||||||
self._execute_uninstall_script(script_content)
|
self._execute_uninstall_script(script_content)
|
||||||
|
|
||||||
self.update_progress(
|
self.update_progress(
|
||||||
f"{project_info['name']}{LocaleStrings.MSGU["uninstall_success"]}"
|
f"{project_info['name']}{LocaleStrings.MSGU['uninstall_success']}"
|
||||||
)
|
)
|
||||||
self.log(
|
self.log(
|
||||||
f"=== {project_info['name']}{LocaleStrings.MSGU["uninstall_success"]} ==="
|
f"=== {project_info['name']}{LocaleStrings.MSGU['uninstall_success']} ==="
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log(f"ERROR: {LocaleStrings.MSGU['uninstall_failed']}{e}")
|
self.log(f"ERROR: {LocaleStrings.MSGU['uninstall_failed']}{e}")
|
||||||
raise Exception(f"{LocaleStrings.MSGU["uninstall_failed"]}{e}")
|
raise Exception(f"{LocaleStrings.MSGU['uninstall_failed']}{e}")
|
||||||
|
|
||||||
def _create_uninstall_script(self, project_key):
|
def _create_uninstall_script(self, project_key):
|
||||||
"""Create uninstallation script based on project"""
|
"""Create uninstallation script based on project"""
|
||||||
@ -420,7 +421,7 @@ class UninstallationManager:
|
|||||||
elif project_key == "logviewer":
|
elif project_key == "logviewer":
|
||||||
return self._create_logviewer_uninstall_script()
|
return self._create_logviewer_uninstall_script()
|
||||||
else:
|
else:
|
||||||
raise Exception(f"{LocaleStrings.MSGO["unknow_project"]}{project_key}")
|
raise Exception(f"{LocaleStrings.MSGO['unknow_project']}{project_key}")
|
||||||
|
|
||||||
def _create_wirepy_uninstall_script(self):
|
def _create_wirepy_uninstall_script(self):
|
||||||
detected_os = Detector.get_os()
|
detected_os = Detector.get_os()
|
||||||
@ -555,7 +556,7 @@ echo "LogViewer uninstallation completed!"
|
|||||||
|
|
||||||
# Make script executable
|
# Make script executable
|
||||||
os.chmod(script_file.name, 0o755)
|
os.chmod(script_file.name, 0o755)
|
||||||
self.log(f"{LocaleStrings.MSGU["uninstall_create"]}{script_file.name}")
|
self.log(f"{LocaleStrings.MSGU['uninstall_create']}{script_file.name}")
|
||||||
|
|
||||||
# Execute with pkexec
|
# Execute with pkexec
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
@ -576,13 +577,13 @@ echo "LogViewer uninstallation completed!"
|
|||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"{LocaleStrings.MSGU["uninstall_script_failed"]}{result.stderr}"
|
f"{LocaleStrings.MSGU['uninstall_script_failed']}{result.stderr}"
|
||||||
)
|
)
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
raise Exception(LocaleStrings.MSGU["uninstall_timeout"])
|
raise Exception(LocaleStrings.MSGU["uninstall_timeout"])
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise Exception(f"{LocaleStrings.MSGU["uninstall_script_failed"]}{e}")
|
raise Exception(f"{LocaleStrings.MSGU['uninstall_script_failed']}{e}")
|
||||||
|
|
||||||
def update_progress(self, message):
|
def update_progress(self, message):
|
||||||
if self.progress_callback:
|
if self.progress_callback:
|
||||||
@ -599,7 +600,7 @@ class DownloadManager:
|
|||||||
"""Download and extract ZIP file"""
|
"""Download and extract ZIP file"""
|
||||||
try:
|
try:
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback(f"{LocaleStrings.MSGO["download_from"]}{url}...")
|
progress_callback(f"{LocaleStrings.MSGO['download_from']}{url}...")
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as tmp_file:
|
with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as tmp_file:
|
||||||
urllib.request.urlretrieve(url, tmp_file.name)
|
urllib.request.urlretrieve(url, tmp_file.name)
|
||||||
@ -615,7 +616,7 @@ class DownloadManager:
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback(f"{LocaleStrings.MSGO["download_failed"]}{e}")
|
progress_callback(f"{LocaleStrings.MSGO['download_failed']}{e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@ -738,7 +739,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
tk.Label(
|
tk.Label(
|
||||||
text_frame,
|
text_frame,
|
||||||
text=f"v {LXToolsAppConfig.VERSION} • {LocaleStrings.MSGO["head_string3"]}",
|
text=f"v {LXToolsAppConfig.VERSION} • {LocaleStrings.MSGO['head_string3']}",
|
||||||
font=("Helvetica", 9),
|
font=("Helvetica", 9),
|
||||||
fg="#bdc3c7",
|
fg="#bdc3c7",
|
||||||
bg="#2c3e50",
|
bg="#2c3e50",
|
||||||
@ -750,7 +751,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
tk.Label(
|
tk.Label(
|
||||||
right_side,
|
right_side,
|
||||||
text=f"{LocaleStrings.MSGO["head_string2"]}{self.detected_os}",
|
text=f"{LocaleStrings.MSGO['head_string2']}{self.detected_os}",
|
||||||
font=("Helvetica", 11),
|
font=("Helvetica", 11),
|
||||||
fg="#ecf0f1",
|
fg="#ecf0f1",
|
||||||
bg="#2c3e50",
|
bg="#2c3e50",
|
||||||
@ -774,10 +775,21 @@ class LXToolsGUI:
|
|||||||
def check_ready_status(self):
|
def check_ready_status(self):
|
||||||
"""Check if system is ready for installation"""
|
"""Check if system is ready for installation"""
|
||||||
# Checks:
|
# Checks:
|
||||||
|
polkit_ok = Detector.get_polkit()
|
||||||
|
networkmanager_ok = Detector.get_networkmanager()
|
||||||
internet_ok = NetworkChecker.check_internet_connection()
|
internet_ok = NetworkChecker.check_internet_connection()
|
||||||
repo_ok = NetworkChecker.check_repository_access()
|
repo_ok = NetworkChecker.check_repository_access()
|
||||||
result = Detector.get_host_python_version()
|
result = Detector.get_host_python_version()
|
||||||
|
|
||||||
|
if not polkit_ok:
|
||||||
|
self.update_header_status(
|
||||||
|
LocaleStrings.MSGO["polkit_check"], "#e74c3c"
|
||||||
|
) # Red
|
||||||
|
if not networkmanager_ok:
|
||||||
|
self.update_header_status(
|
||||||
|
LocaleStrings.MSGO["networkmanager_check"], "#e74c3c"
|
||||||
|
) # Red
|
||||||
|
|
||||||
if internet_ok and repo_ok and result is not None:
|
if internet_ok and repo_ok and result is not None:
|
||||||
self.update_header_status(LocaleStrings.MSGO["ready"], "#1abc9c") # Green
|
self.update_header_status(LocaleStrings.MSGO["ready"], "#1abc9c") # Green
|
||||||
elif not internet_ok:
|
elif not internet_ok:
|
||||||
@ -897,7 +909,7 @@ class LXToolsGUI:
|
|||||||
# Status label
|
# Status label
|
||||||
status_label = tk.Label(
|
status_label = tk.Label(
|
||||||
status_frame,
|
status_frame,
|
||||||
text=f"❓ {LocaleStrings.MSGC["checking"]}",
|
text=f"❓ {LocaleStrings.MSGC['checking']}",
|
||||||
font=("Helvetica", 10),
|
font=("Helvetica", 10),
|
||||||
bg=self.colors["card_bg"],
|
bg=self.colors["card_bg"],
|
||||||
fg="#95a5a6",
|
fg="#95a5a6",
|
||||||
@ -991,7 +1003,7 @@ class LXToolsGUI:
|
|||||||
self._update_frame_children_bg(new_content, self.colors["selected_bg"])
|
self._update_frame_children_bg(new_content, self.colors["selected_bg"])
|
||||||
|
|
||||||
project_info = self.app_manager.get_project_info(project_key)
|
project_info = self.app_manager.get_project_info(project_key)
|
||||||
self.log_message(f"{LocaleStrings.MSGL["selected_app"]}{project_info["name"]}")
|
self.log_message(f"{LocaleStrings.MSGL['selected_app']}{project_info['name']}")
|
||||||
|
|
||||||
def _create_log_tab(self):
|
def _create_log_tab(self):
|
||||||
"""Create log tab"""
|
"""Create log tab"""
|
||||||
@ -1037,12 +1049,12 @@ class LXToolsGUI:
|
|||||||
self.log_message(
|
self.log_message(
|
||||||
f"=== {LXToolsAppConfig.APP_NAME} v {LXToolsAppConfig.VERSION} ==="
|
f"=== {LXToolsAppConfig.APP_NAME} v {LXToolsAppConfig.VERSION} ==="
|
||||||
)
|
)
|
||||||
self.log_message(f"{LocaleStrings.MSGL["work_dir"]}{LXToolsAppConfig.WORK_DIR}")
|
self.log_message(f"{LocaleStrings.MSGL['work_dir']}{LXToolsAppConfig.WORK_DIR}")
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{LocaleStrings.MSGL["icons_dir"]}{LXToolsAppConfig.ICONS_DIR}"
|
f"{LocaleStrings.MSGL['icons_dir']}{LXToolsAppConfig.ICONS_DIR}"
|
||||||
)
|
)
|
||||||
self.log_message(f"{LocaleStrings.MSGL["detected_os"]}{self.detected_os}")
|
self.log_message(f"{LocaleStrings.MSGL['detected_os']}{self.detected_os}")
|
||||||
self.log_message(f"{LocaleStrings.MSGO["ready"]}...")
|
self.log_message(f"{LocaleStrings.MSGO['ready']}...")
|
||||||
|
|
||||||
def _create_progress_section(self):
|
def _create_progress_section(self):
|
||||||
"""Create progress section with download icon"""
|
"""Create progress section with download icon"""
|
||||||
@ -1062,7 +1074,7 @@ class LXToolsGUI:
|
|||||||
# Progress Text (right, expandable)
|
# Progress Text (right, expandable)
|
||||||
self.progress_label = tk.Label(
|
self.progress_label = tk.Label(
|
||||||
progress_container,
|
progress_container,
|
||||||
text=f"{LocaleStrings.MSGO["ready"]}...",
|
text=f"{LocaleStrings.MSGO['ready']}...",
|
||||||
font=("Helvetica", 10),
|
font=("Helvetica", 10),
|
||||||
fg="blue",
|
fg="blue",
|
||||||
anchor="w",
|
anchor="w",
|
||||||
@ -1175,22 +1187,22 @@ class LXToolsGUI:
|
|||||||
"""Refresh application status and version information"""
|
"""Refresh application status and version information"""
|
||||||
self.update_progress(LocaleStrings.MSGI["refresh_and_check"])
|
self.update_progress(LocaleStrings.MSGI["refresh_and_check"])
|
||||||
self._reset_download_icon()
|
self._reset_download_icon()
|
||||||
self.log_message(f"=== {LocaleStrings.MSGB["refresh"]} ===")
|
self.log_message(f"=== {LocaleStrings.MSGB['refresh']} ===")
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
for project_key, project_info in self.app_manager.get_all_projects().items():
|
for project_key, project_info in self.app_manager.get_all_projects().items():
|
||||||
status_label = self.status_labels[project_key]
|
status_label = self.status_labels[project_key]
|
||||||
version_label = self.version_labels[project_key]
|
version_label = self.version_labels[project_key]
|
||||||
|
|
||||||
self.log_message(f"{LocaleStrings.MSGC["checking"]} {project_info['name']}")
|
self.log_message(f"{LocaleStrings.MSGC['checking']} {project_info['name']}")
|
||||||
|
|
||||||
if self.app_manager.is_installed(project_key):
|
if self.app_manager.is_installed(project_key):
|
||||||
installed_version = self.app_manager.get_installed_version(project_key)
|
installed_version = self.app_manager.get_installed_version(project_key)
|
||||||
status_label.config(
|
status_label.config(
|
||||||
text=f"✅ {LocaleStrings.MSGI["installed"]}({installed_version})",
|
text=f"✅ {LocaleStrings.MSGI['installed']}({installed_version})",
|
||||||
fg="green",
|
fg="green",
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: {LocaleStrings.MSGI["installed"]}({installed_version})"
|
f"{project_info['name']}: {LocaleStrings.MSGI['installed']}({installed_version})"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get latest version from API
|
# Get latest version from API
|
||||||
@ -1199,41 +1211,41 @@ class LXToolsGUI:
|
|||||||
if latest_version != "Unknown":
|
if latest_version != "Unknown":
|
||||||
if installed_version != f"v. {latest_version}":
|
if installed_version != f"v. {latest_version}":
|
||||||
version_label.config(
|
version_label.config(
|
||||||
text=f"{LocaleStrings.MSGC["latest"]}(v. {latest_version}) {LocaleStrings.MSGC["update_available"]}",
|
text=f"{LocaleStrings.MSGC['latest']}(v. {latest_version}) {LocaleStrings.MSGC['update_available']}",
|
||||||
fg="orange",
|
fg="orange",
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: {LocaleStrings.MSGC["update_available"]}(v. {latest_version})"
|
f"{project_info['name']}: {LocaleStrings.MSGC['update_available']}(v. {latest_version})"
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
version_label.config(
|
version_label.config(
|
||||||
text=f"{LocaleStrings.MSGC["latest"]}: (v. {latest_version}) {LocaleStrings.MSGC["up_to_date"]}",
|
text=f"{LocaleStrings.MSGC['latest']}: (v. {latest_version}) {LocaleStrings.MSGC['up_to_date']}",
|
||||||
fg="green",
|
fg="green",
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: {LocaleStrings.MSGC["up_to_date"]}",
|
f"{project_info['name']}: {LocaleStrings.MSGC['up_to_date']}",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
version_label.config(
|
version_label.config(
|
||||||
text=LocaleStrings.MSGC["latest_unknown"], fg="gray"
|
text=LocaleStrings.MSGC["latest_unknown"], fg="gray"
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: {LocaleStrings.MSGC["could_not_check"]}"
|
f"{project_info['name']}: {LocaleStrings.MSGC['could_not_check']}"
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
version_label.config(
|
version_label.config(
|
||||||
text=LocaleStrings.MSGC["check_last_failed"], fg="gray"
|
text=LocaleStrings.MSGC["check_last_failed"], fg="gray"
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: {LocaleStrings.MSGC["version_check_failed"]}: {e}"
|
f"{project_info['name']}: {LocaleStrings.MSGC['version_check_failed']}: {e}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
status_label.config(
|
status_label.config(
|
||||||
text=f"❌ {LocaleStrings.MSGC["not_installed"]}", fg="red"
|
text=f"❌ {LocaleStrings.MSGC['not_installed']}", fg="red"
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: {LocaleStrings.MSGC["not_installed"]}"
|
f"{project_info['name']}: {LocaleStrings.MSGC['not_installed']}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Still show latest available version
|
# Still show latest available version
|
||||||
@ -1241,12 +1253,12 @@ class LXToolsGUI:
|
|||||||
latest_version = self.app_manager.get_latest_version(project_key)
|
latest_version = self.app_manager.get_latest_version(project_key)
|
||||||
if latest_version != "Unknown":
|
if latest_version != "Unknown":
|
||||||
version_label.config(
|
version_label.config(
|
||||||
text=f"{project_info['name']} {LocaleStrings.MSGC["available"]}: v {latest_version}",
|
text=f"{project_info['name']} {LocaleStrings.MSGC['available']}: v {latest_version}",
|
||||||
fg="blue",
|
fg="blue",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']} {LocaleStrings.MSGC["available"]}: v {latest_version}"
|
f"{project_info['name']} {LocaleStrings.MSGC['available']}: v {latest_version}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
version_label.config(
|
version_label.config(
|
||||||
@ -1257,11 +1269,11 @@ class LXToolsGUI:
|
|||||||
text=LocaleStrings.MSGC["available_check_unknown"], fg="gray"
|
text=LocaleStrings.MSGC["available_check_unknown"], fg="gray"
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f" {project_info['name']}: {LocaleStrings.MSGC["version_check_failed"]}: {e}"
|
f" {project_info['name']}: {LocaleStrings.MSGC['version_check_failed']}: {e}"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.update_progress(LocaleStrings.MSGO["refresh2"])
|
self.update_progress(LocaleStrings.MSGO["refresh2"])
|
||||||
self.log_message(f"=== {LocaleStrings.MSGO["refresh2"]} ===")
|
self.log_message(f"=== {LocaleStrings.MSGO['refresh2']} ===")
|
||||||
self.check_ready_status()
|
self.check_ready_status()
|
||||||
|
|
||||||
def install_selected(self):
|
def install_selected(self):
|
||||||
@ -1294,7 +1306,7 @@ class LXToolsGUI:
|
|||||||
self.update_download_icon("success")
|
self.update_download_icon("success")
|
||||||
MessageDialog(
|
MessageDialog(
|
||||||
"info",
|
"info",
|
||||||
f"{project_info["name"]} {LocaleStrings.MSGM["has_success_update"]}",
|
f"{project_info['name']} {LocaleStrings.MSGM['has_success_update']}",
|
||||||
wraplength=400,
|
wraplength=400,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1317,7 +1329,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
if not self.app_manager.is_installed(self.selected_project):
|
if not self.app_manager.is_installed(self.selected_project):
|
||||||
MessageDialog(
|
MessageDialog(
|
||||||
"error", f"{project_info["name"]} {LocaleStrings.MSGO["not_installed"]}"
|
"error", f"{project_info['name']} {LocaleStrings.MSGO['not_installed']}"
|
||||||
)
|
)
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
return
|
return
|
||||||
@ -1326,14 +1338,14 @@ class LXToolsGUI:
|
|||||||
self.uninstallation_manager.uninstall_project(self.selected_project)
|
self.uninstallation_manager.uninstall_project(self.selected_project)
|
||||||
MessageDialog(
|
MessageDialog(
|
||||||
"info",
|
"info",
|
||||||
f"{project_info["name"]} {LocaleStrings.MSGU["uninstall_success"]}",
|
f"{project_info['name']} {LocaleStrings.MSGU['uninstall_success']}",
|
||||||
wraplength=400,
|
wraplength=400,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.refresh_status()
|
self.refresh_status()
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
MessageDialog("error", f"{LocaleStrings.MSGU["uninstall_failed"]}: {e}")
|
MessageDialog("error", f"{LocaleStrings.MSGU['uninstall_failed']}: {e}")
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
|
|
||||||
def update_progress(self, message):
|
def update_progress(self, message):
|
||||||
@ -1341,7 +1353,7 @@ class LXToolsGUI:
|
|||||||
if self.progress_label:
|
if self.progress_label:
|
||||||
self.progress_label.config(text=message)
|
self.progress_label.config(text=message)
|
||||||
self.progress_label.update()
|
self.progress_label.update()
|
||||||
print(f"{LocaleStrings.MSGO["progress"]}: {message}")
|
print(f"{LocaleStrings.MSGO['progress']}: {message}")
|
||||||
|
|
||||||
def log_message(self, message):
|
def log_message(self, message):
|
||||||
"""Add message to log"""
|
"""Add message to log"""
|
||||||
@ -1368,16 +1380,17 @@ class LXToolsGUI:
|
|||||||
def main():
|
def main():
|
||||||
"""Main function to start the application"""
|
"""Main function to start the application"""
|
||||||
print(f"=== {LXToolsAppConfig.APP_NAME} v {LXToolsAppConfig.VERSION} ===")
|
print(f"=== {LXToolsAppConfig.APP_NAME} v {LXToolsAppConfig.VERSION} ===")
|
||||||
print(f"{LocaleStrings.MSGL["working_dir"]}{os.getcwd()}")
|
print(f"{LocaleStrings.MSGL['working_dir']}{os.getcwd()}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
LxTools.sigi(LXToolsAppConfig.TEMP_DIR)
|
||||||
# Create and run the GUI
|
# Create and run the GUI
|
||||||
app = LXToolsGUI()
|
app = LXToolsGUI()
|
||||||
app.run()
|
app.run()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print(LocaleStrings.MSGL["user_interrupt"])
|
print(LocaleStrings.MSGL["user_interrupt"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{LocaleStrings.MSGL["fatal_error"]}: {e}")
|
print(f"{LocaleStrings.MSGL['fatal_error']}: {e}")
|
||||||
try:
|
try:
|
||||||
MessageDialog("error", f"{LocaleStrings.MSGL['fatal_app_error']}: {e}")
|
MessageDialog("error", f"{LocaleStrings.MSGL['fatal_app_error']}: {e}")
|
||||||
|
|
||||||
@ -1387,3 +1400,6 @@ def main():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
LxTools.remove_lxtools_files()
|
||||||
|
LxTools.clean_files(LXToolsAppConfig.TEMP_DIR)
|
||||||
|
sys.exit(0)
|
||||||
|
38
lxtools_installer.spec
Normal file
38
lxtools_installer.spec
Normal 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,
|
||||||
|
)
|
221
manager.py
221
manager.py
@ -1,8 +1,11 @@
|
|||||||
import locale
|
import locale
|
||||||
import gettext
|
import gettext
|
||||||
|
import signal
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Optional, NoReturn, Any, Dict
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
@ -96,6 +99,114 @@ class Detector:
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_polkit() -> bool:
|
||||||
|
"""Check if network manager is installed"""
|
||||||
|
os_system = Detector.get_os()
|
||||||
|
deb = ["Debian", "Ubuntu", "Linux Mint", "Pop!_OS"]
|
||||||
|
arch = ["Arch Linux", "Manjaro", "EndeavourOS", "ArcoLinux", "Garuda Linux"]
|
||||||
|
if os_system in deb:
|
||||||
|
result = subprocess.run(
|
||||||
|
["apt", "list", "--installed", "|", "grep", "polkit"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif os_system in arch:
|
||||||
|
result = subprocess.run(
|
||||||
|
["pacman", "-Qs", "polkit"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif os_system == "Fedora":
|
||||||
|
result = subprocess.run(
|
||||||
|
["dnf", "list", "--installed", "|", "grep", "polkit"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif os_system == "SUSE Tumbleweed" or os_system == "SUSE Leap":
|
||||||
|
result = subprocess.run(
|
||||||
|
["zypper", "search", "--installed-only", "|", "grep", "polkit"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_networkmanager() -> bool:
|
||||||
|
"""Check if network manager is installed"""
|
||||||
|
os_system = Detector.get_os()
|
||||||
|
deb = ["Debian", "Ubuntu", "Linux Mint", "Pop!_OS"]
|
||||||
|
arch = ["Arch Linux", "Manjaro", "EndeavourOS", "ArcoLinux", "Garuda Linux"]
|
||||||
|
if os_system in deb:
|
||||||
|
result = subprocess.run(
|
||||||
|
["apt", "list", "--installed", "|", "grep", "network-manager"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif os_system in arch:
|
||||||
|
result = subprocess.run(
|
||||||
|
["pacman", "-Qs", "networkmanager"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif os_system == "Fedora":
|
||||||
|
result = subprocess.run(
|
||||||
|
["dnf", "list", "--installed", "|", "grep", "NetworkManager"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif os_system == "SUSE Tumbleweed" or os_system == "SUSE Leap":
|
||||||
|
result = subprocess.run(
|
||||||
|
["zypper", "search", "--installed-only", "|", "grep", "networkmanager"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class Theme:
|
class Theme:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -180,7 +291,7 @@ class Image:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.images = {}
|
self.images = {}
|
||||||
|
|
||||||
def load_image(self, image_key, fallback_paths=None) -> None | tk.PhotoImage:
|
def load_image(self, image_key, fallback_paths=None) -> Optional[tk.PhotoImage]:
|
||||||
"""Load PNG image using tk.PhotoImage with fallback options"""
|
"""Load PNG image using tk.PhotoImage with fallback options"""
|
||||||
if image_key in self.images:
|
if image_key in self.images:
|
||||||
return self.images[image_key]
|
return self.images[image_key]
|
||||||
@ -228,7 +339,7 @@ class Image:
|
|||||||
self.images[image_key] = photo
|
self.images[image_key] = photo
|
||||||
return photo
|
return photo
|
||||||
except tk.TclError as e:
|
except tk.TclError as e:
|
||||||
print(f"{LocaleStrings.MSGP["fail_load_image"]}{path}: {e}")
|
print(f"{LocaleStrings.MSGP['fail_load_image']}{path}: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Return None if no image found
|
# Return None if no image found
|
||||||
@ -239,7 +350,7 @@ class AppManager:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.projects = LXToolsAppConfig.PROJECTS
|
self.projects = LXToolsAppConfig.PROJECTS
|
||||||
|
|
||||||
def get_project_info(self, project_key) -> dict | None:
|
def get_project_info(self, project_key) -> Optional[dict]:
|
||||||
"""Get project information by key"""
|
"""Get project information by key"""
|
||||||
return self.projects.get(project_key)
|
return self.projects.get(project_key)
|
||||||
|
|
||||||
@ -281,10 +392,10 @@ class AppManager:
|
|||||||
|
|
||||||
# Debug logging
|
# Debug logging
|
||||||
print(LocaleStrings.MSGP["logviewer_check"])
|
print(LocaleStrings.MSGP["logviewer_check"])
|
||||||
print(f"{LocaleStrings.MSGP["symlink_exist"]}{symlink_exists}")
|
print(f"{LocaleStrings.MSGP['symlink_exist']}{symlink_exists}")
|
||||||
print(f"{LocaleStrings.MSGP["executable_exist"]}{executable_exists}")
|
print(f"{LocaleStrings.MSGP['executable_exist']}{executable_exists}")
|
||||||
print(f"{LocaleStrings.MSGP["is_executable"]}{executable_is_executable}")
|
print(f"{LocaleStrings.MSGP['is_executable']}{executable_is_executable}")
|
||||||
print(f"{LocaleStrings.MSGP["final_result"]}{is_installed}")
|
print(f"{LocaleStrings.MSGP['final_result']}{is_installed}")
|
||||||
|
|
||||||
return is_installed
|
return is_installed
|
||||||
|
|
||||||
@ -310,7 +421,7 @@ class AppManager:
|
|||||||
return version
|
return version
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{LocaleStrings.MSGP["get_version_error"]}{project_key}: {e}")
|
print(f"{LocaleStrings.MSGP['get_version_error']}{project_key}: {e}")
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
|
|
||||||
def get_latest_version(self, project_key) -> str:
|
def get_latest_version(self, project_key) -> str:
|
||||||
@ -417,12 +528,98 @@ class LxTools:
|
|||||||
y = (screen_height - height) // 2
|
y = (screen_height - height) // 2
|
||||||
window.geometry(f"{width}x{height}+{x}+{y}")
|
window.geometry(f"{width}x{height}+{x}+{y}")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clean_files(tmp_dir: Path = None, file: Path = None) -> None:
|
||||||
|
"""
|
||||||
|
Deletes temporary files and directories for cleanup when exiting the application.
|
||||||
|
|
||||||
|
This method safely removes an optional directory defined by `AppConfig.TEMP_DIR`
|
||||||
|
and a single file to free up resources at the end of the program's execution.
|
||||||
|
All operations are performed securely, and errors such as `FileNotFoundError`
|
||||||
|
are ignored if the target files or directories do not exist.
|
||||||
|
:param tmp_dir: (Path, optional): Path to the temporary directory that should be deleted.
|
||||||
|
If `None`, the value of `AppConfig.TEMP_DIR` is used.
|
||||||
|
:param file: (Path, optional): Path to the file that should be deleted.
|
||||||
|
If `None`, no additional file will be deleted.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None: The method does not return any value.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if tmp_dir is not None:
|
||||||
|
shutil.rmtree(tmp_dir, ignore_errors=True)
|
||||||
|
try:
|
||||||
|
if file is not None:
|
||||||
|
Path.unlink(file)
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def sigi(file_path: Optional[Path] = None, file: Optional[Path] = None) -> None:
|
||||||
|
"""
|
||||||
|
Function for cleanup after a program interruption
|
||||||
|
|
||||||
|
:param file: Optional - File to be deleted
|
||||||
|
:param file_path: Optional - Directory to be deleted
|
||||||
|
"""
|
||||||
|
|
||||||
|
def signal_handler(signum: int, frame: Any) -> NoReturn:
|
||||||
|
"""
|
||||||
|
Determines clear text names for signal numbers and handles signals
|
||||||
|
|
||||||
|
Args:
|
||||||
|
signum: The signal number
|
||||||
|
frame: The current stack frame
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
NoReturn since the function either exits the program or continues execution
|
||||||
|
"""
|
||||||
|
|
||||||
|
signals_to_names_dict: Dict[int, str] = dict(
|
||||||
|
(getattr(signal, n), n)
|
||||||
|
for n in dir(signal)
|
||||||
|
if n.startswith("SIG") and "_" not in n
|
||||||
|
)
|
||||||
|
|
||||||
|
signal_name: str = signals_to_names_dict.get(
|
||||||
|
signum, f"Unnamed signal: {signum}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# End program for certain signals, report to others only reception
|
||||||
|
if signum in (signal.SIGINT, signal.SIGTERM):
|
||||||
|
exit_code: int = 1
|
||||||
|
logging.error(
|
||||||
|
f"\nSignal {signal_name} {signum} received. => Aborting with exit code {exit_code}.",
|
||||||
|
exc_info=True,
|
||||||
|
)
|
||||||
|
LxTools.clean_files(file_path, file)
|
||||||
|
logging.info("Breakdown by user...")
|
||||||
|
sys.exit(exit_code)
|
||||||
|
else:
|
||||||
|
logging.info(f"Signal {signum} received and ignored.")
|
||||||
|
LxTools.clean_files(file_path, file)
|
||||||
|
logging.error("Process unexpectedly ended...")
|
||||||
|
|
||||||
|
# Register signal handlers for various signals
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
signal.signal(signal.SIGTERM, signal_handler)
|
||||||
|
signal.signal(signal.SIGHUP, signal_handler)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def remove_lxtools_files() -> None:
|
||||||
|
if getattr(sys, "_MEIPASS", None) is not None:
|
||||||
|
shutil.rmtree("./locale")
|
||||||
|
shutil.rmtree("./TK-Themes")
|
||||||
|
shutil.rmtree("./lx-icons")
|
||||||
|
|
||||||
|
|
||||||
class LXToolsAppConfig:
|
class LXToolsAppConfig:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def extract_data_files() -> None:
|
def extract_data_files() -> None:
|
||||||
if getattr(sys, "_MEIPASS", None) is not None:
|
if getattr(sys, "_MEIPASS", None) is not None:
|
||||||
|
os.makedirs("/tmp/lxtools", exist_ok=True)
|
||||||
# Liste der Quellordner (entspricht dem "datas"-Eintrag in lxtools_installer.spec)
|
# Liste der Quellordner (entspricht dem "datas"-Eintrag in lxtools_installer.spec)
|
||||||
source_dirs = [
|
source_dirs = [
|
||||||
os.path.join(sys._MEIPASS, "locale"), # für locale/...
|
os.path.join(sys._MEIPASS, "locale"), # für locale/...
|
||||||
@ -437,7 +634,7 @@ class LXToolsAppConfig:
|
|||||||
for source_dir in source_dirs:
|
for source_dir in source_dirs:
|
||||||
group_name = os.path.basename(
|
group_name = os.path.basename(
|
||||||
source_dir
|
source_dir
|
||||||
) # Erhält den Gruppen-Name (z. B. 'locale', 'TK-Themes')
|
) # Erhält den Gruppen-Name (z. B. 'locale', 'TK-Themes')
|
||||||
|
|
||||||
for root, dirs, files in os.walk(source_dir):
|
for root, dirs, files in os.walk(source_dir):
|
||||||
for file in files:
|
for file in files:
|
||||||
@ -476,15 +673,15 @@ class LXToolsAppConfig:
|
|||||||
pass
|
pass
|
||||||
return gettext.gettext
|
return gettext.gettext
|
||||||
|
|
||||||
VERSION = "1.1.6"
|
VERSION = "1.1.7"
|
||||||
APP_NAME = "lxtoolsinstaller"
|
APP_NAME = "lxtoolsinstaller"
|
||||||
WINDOW_WIDTH = 450
|
WINDOW_WIDTH = 450
|
||||||
WINDOW_HEIGHT = 580
|
WINDOW_HEIGHT = 580
|
||||||
|
|
||||||
# Working directory
|
# Working directory
|
||||||
WORK_DIR = os.getcwd()
|
WORK_DIR = os.getcwd()
|
||||||
ICONS_DIR = os.path.join(WORK_DIR, "lx-icons")
|
ICONS_DIR = os.path.join(WORK_DIR, "lx-icons")
|
||||||
THEMES_DIR = os.path.join(WORK_DIR, "TK-Themes")
|
THEMES_DIR = os.path.join(WORK_DIR, "TK-Themes")
|
||||||
|
TEMP_DIR = "/tmp/lxtools"
|
||||||
|
|
||||||
# Locale settings
|
# Locale settings
|
||||||
LOCALE_DIR = "./locale/"
|
LOCALE_DIR = "./locale/"
|
||||||
@ -618,6 +815,8 @@ class LocaleStrings:
|
|||||||
"progress": _("Progress"),
|
"progress": _("Progress"),
|
||||||
"refresh2": _("Status refresh completed"),
|
"refresh2": _("Status refresh completed"),
|
||||||
"python_check": _("Python not installed"),
|
"python_check": _("Python not installed"),
|
||||||
|
"polkit_check": _("Please install Polkit!"),
|
||||||
|
"networkmanager_check": _("Please install Networkmanager!"),
|
||||||
}
|
}
|
||||||
|
|
||||||
# MSGC = Strings on Cards
|
# MSGC = Strings on Cards
|
||||||
|
@ -129,7 +129,7 @@ class MessageDialog:
|
|||||||
self.window = tk.Toplevel(master)
|
self.window = tk.Toplevel(master)
|
||||||
self.window.grab_set()
|
self.window.grab_set()
|
||||||
self.window.resizable(False, False)
|
self.window.resizable(False, False)
|
||||||
ttk.Style().configure("TButton", font=("Helvetica", 11), padding=5)
|
ttk.Style().configure("TButton")
|
||||||
self.buttons_widgets = []
|
self.buttons_widgets = []
|
||||||
self.current_button_index = 0
|
self.current_button_index = 0
|
||||||
self._load_icons()
|
self._load_icons()
|
||||||
|
Reference in New Issue
Block a user