Added language support for German
@ -2,7 +2,13 @@ Changelog for LXTools installer
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
-
|
- replace pack with grid
|
||||||
|
|
||||||
|
### Added
|
||||||
|
18-06-2025
|
||||||
|
|
||||||
|
- Added language support for German
|
||||||
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
14-06-2025
|
14-06-2025
|
||||||
|
BIN
locale/de/LC_MESSAGES/lxtoolsinstaller.mo
Normal file
BIN
lx-icons/128/Lunix_Tools.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
BIN
lx-icons/256/Lunix_Tools.png
Normal file
After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
lx-icons/32/Lunix_Tools.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
lx-icons/48/Lunix_Tools.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
lx-icons/64/Lunix_Tools.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.5 KiB |
@ -10,6 +10,7 @@ import zipfile
|
|||||||
from manager import (
|
from manager import (
|
||||||
OSDetector,
|
OSDetector,
|
||||||
Theme,
|
Theme,
|
||||||
|
LocaleStrings,
|
||||||
LXToolsAppConfig,
|
LXToolsAppConfig,
|
||||||
System,
|
System,
|
||||||
Image,
|
Image,
|
||||||
@ -19,9 +20,6 @@ from manager import (
|
|||||||
from network import NetworkChecker
|
from network import NetworkChecker
|
||||||
from message import MessageDialog
|
from message import MessageDialog
|
||||||
|
|
||||||
# Initialize translations
|
|
||||||
_ = LXToolsAppConfig.setup_translations()
|
|
||||||
|
|
||||||
|
|
||||||
class InstallationManager:
|
class InstallationManager:
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -38,10 +36,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"Unknown project: {project_key}"))
|
raise Exception(f"{LocaleStrings.MSG["unknow_project"]}{project_key}")
|
||||||
|
|
||||||
self.update_progress(_(f"Starting installation of {project_info['name']}..."))
|
self.update_progress(
|
||||||
self.log(_(f"=== Installing {project_info['name']} ==="))
|
f"{LocaleStrings.MSGI["start_install"]}{project_info['name']}..."
|
||||||
|
)
|
||||||
|
self.log(f"=== {LocaleStrings.MSGI["install"]}{project_info['name']} ===")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Create installation script
|
# Create installation script
|
||||||
@ -51,17 +51,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']} installation completed successfully!")
|
f"{project_info["name"]}{LocaleStrings.MSGI["install_success"]}"
|
||||||
|
)
|
||||||
|
self.log(
|
||||||
|
f"=== {project_info["name"]}{LocaleStrings.MSGI["install_success"]} ==="
|
||||||
)
|
)
|
||||||
self.log(_(f"=== {project_info['name']} installed successfully ==="))
|
|
||||||
|
|
||||||
# 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: Installation failed: {e}"))
|
self.log(f"ERROR: {LocaleStrings.MSGI["install_failed"]}{e}")
|
||||||
self.update_icon("error")
|
self.update_icon("error")
|
||||||
raise Exception(_(f"Installation 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"""
|
||||||
@ -70,7 +72,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"Unknown project: {project_key}"))
|
raise Exception(f"{LocaleStrings.MSGI["unknow_project"]}{project_key}")
|
||||||
|
|
||||||
def _create_wirepy_install_script(self):
|
def _create_wirepy_install_script(self):
|
||||||
"""Create Wire-Py installation script"""
|
"""Create Wire-Py installation script"""
|
||||||
@ -299,7 +301,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"Created install script: {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(
|
||||||
@ -319,12 +321,14 @@ echo "LogViewer installation completed!"
|
|||||||
os.unlink(script_file.name)
|
os.unlink(script_file.name)
|
||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise Exception(_(f"Installation script failed: {result.stderr}"))
|
raise Exception(
|
||||||
|
f"{LocaleStrings.MSGI["install_script_failed"]}{result.stderr}"
|
||||||
|
)
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
raise Exception(_("Installation timed out"))
|
raise Exception(LocaleStrings.MSGI["install_timeout"])
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise Exception(_(f"Installation 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:
|
||||||
@ -349,13 +353,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"Unknown 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(_(f"{project_info['name']} is not installed."))
|
raise Exception(
|
||||||
|
f"{project_info["name"]}{LocaleStrings.MSGO["not_installed"]}"
|
||||||
|
)
|
||||||
|
|
||||||
self.update_progress(_(f"Uninstalling {project_info['name']}..."))
|
self.update_progress(
|
||||||
self.log(_(f"=== Uninstalling {project_info['name']} ==="))
|
f"{LocaleStrings.MSGU["uninstall"]}{project_info['name']}..."
|
||||||
|
)
|
||||||
|
self.log(f"=== {LocaleStrings.MSGU["uninstall"]}{project_info['name']} ===")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Create uninstallation script
|
# Create uninstallation script
|
||||||
@ -364,12 +372,16 @@ class UninstallationManager:
|
|||||||
# Execute uninstallation
|
# Execute uninstallation
|
||||||
self._execute_uninstall_script(script_content)
|
self._execute_uninstall_script(script_content)
|
||||||
|
|
||||||
self.update_progress(_(f"{project_info['name']} uninstalled successfully!"))
|
self.update_progress(
|
||||||
self.log(_(f"=== {project_info['name']} uninstalled successfully ==="))
|
f"{project_info['name']}{LocaleStrings.MSGU["uninstall_success"]}"
|
||||||
|
)
|
||||||
|
self.log(
|
||||||
|
f"=== {project_info['name']}{LocaleStrings.MSGU["uninstall_success"]} ==="
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log(_(f"ERROR: Uninstallation failed: {e}"))
|
self.log(f"ERROR: {LocaleStrings.MSGU['uninstall_failed']}{e}")
|
||||||
raise Exception(_(f"Uninstallation 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"""
|
||||||
@ -378,7 +390,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"Unknown project: {project_key}"))
|
raise Exception(f"{LocaleStrings.MSGO["unknow_project"]}{project_key}")
|
||||||
|
|
||||||
def _create_wirepy_uninstall_script(self):
|
def _create_wirepy_uninstall_script(self):
|
||||||
"""Create Wire-Py uninstallation script"""
|
"""Create Wire-Py uninstallation script"""
|
||||||
@ -513,7 +525,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"Created uninstall script: {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(
|
||||||
@ -533,12 +545,14 @@ echo "LogViewer uninstallation completed!"
|
|||||||
os.unlink(script_file.name)
|
os.unlink(script_file.name)
|
||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise Exception(_(f"Uninstallation script failed: {result.stderr}"))
|
raise Exception(
|
||||||
|
f"{LocaleStrings.MSGU["uninstall_script_failed"]}{result.stderr}"
|
||||||
|
)
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
raise Exception(_("Uninstallation timed out"))
|
raise Exception(LocaleStrings.MSGU["uninstall_timeout"])
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise Exception(_(f"Uninstallation 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:
|
||||||
@ -555,13 +569,13 @@ class DownloadManager:
|
|||||||
"""Download and extract ZIP file"""
|
"""Download and extract ZIP file"""
|
||||||
try:
|
try:
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback(_(f"Downloading 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)
|
||||||
|
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback(_("Extracting files..."))
|
progress_callback(LocaleStrings.MSGO["extract_files"])
|
||||||
|
|
||||||
with zipfile.ZipFile(tmp_file.name, "r") as zip_ref:
|
with zipfile.ZipFile(tmp_file.name, "r") as zip_ref:
|
||||||
zip_ref.extractall(extract_to)
|
zip_ref.extractall(extract_to)
|
||||||
@ -571,7 +585,7 @@ class DownloadManager:
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback(_(f"Download failed: {str(e)}"))
|
progress_callback(f"{LocaleStrings.MSGO["download_failed"]}{e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@ -694,7 +708,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
tk.Label(
|
tk.Label(
|
||||||
text_frame,
|
text_frame,
|
||||||
text=f"v {LXToolsAppConfig.VERSION} • Linux App Installer",
|
text=f"v {LXToolsAppConfig.VERSION} • {LocaleStrings.MSGO["head_string3"]}",
|
||||||
font=("Helvetica", 9),
|
font=("Helvetica", 9),
|
||||||
fg="#bdc3c7",
|
fg="#bdc3c7",
|
||||||
bg="#2c3e50",
|
bg="#2c3e50",
|
||||||
@ -706,7 +720,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
tk.Label(
|
tk.Label(
|
||||||
right_side,
|
right_side,
|
||||||
text=f"System: {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",
|
||||||
@ -729,23 +743,29 @@ 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"""
|
||||||
# Prüfungen:
|
# Checks:
|
||||||
internet_ok = NetworkChecker.check_internet_connection()
|
internet_ok = NetworkChecker.check_internet_connection()
|
||||||
repo_ok = NetworkChecker.check_repository_access()
|
repo_ok = NetworkChecker.check_repository_access()
|
||||||
|
|
||||||
if internet_ok and repo_ok:
|
if internet_ok and repo_ok:
|
||||||
self.update_header_status(_("Ready for installation"), "#1abc9c") # Green
|
self.update_header_status(LocaleStrings.MSGO["ready"], "#1abc9c") # Green
|
||||||
elif not internet_ok:
|
elif not internet_ok:
|
||||||
self.update_header_status(_("No internet connection"), "#e74c3c") # Red
|
self.update_header_status(
|
||||||
|
LocaleStrings.MSGO["no_internet"], "#e74c3c"
|
||||||
|
) # Red
|
||||||
elif not repo_ok:
|
elif not repo_ok:
|
||||||
self.update_header_status(_("Repository unavailable"), "#f39c12") # Orange
|
self.update_header_status(
|
||||||
|
LocaleStrings.MSGO["repo_unavailable"], "#f39c12"
|
||||||
|
) # Orange
|
||||||
else:
|
else:
|
||||||
self.update_header_status(_("System checking..."), "#3498db") # Blue
|
self.update_header_status(
|
||||||
|
LocaleStrings.MSGO["system_check"], "#3498db"
|
||||||
|
) # Blue
|
||||||
|
|
||||||
def _create_projects_tab(self):
|
def _create_projects_tab(self):
|
||||||
"""Create projects tab with project cards"""
|
"""Create projects tab with project cards"""
|
||||||
projects_frame = ttk.Frame(self.notebook)
|
projects_frame = ttk.Frame(self.notebook)
|
||||||
self.notebook.add(projects_frame, text=_("Applications"))
|
self.notebook.add(projects_frame, text=LocaleStrings.MSGO["applications"])
|
||||||
|
|
||||||
# Scrollable frame
|
# Scrollable frame
|
||||||
canvas = tk.Canvas(projects_frame, bg=self.colors["bg"])
|
canvas = tk.Canvas(projects_frame, bg=self.colors["bg"])
|
||||||
@ -842,7 +862,7 @@ class LXToolsGUI:
|
|||||||
# Status label
|
# Status label
|
||||||
status_label = tk.Label(
|
status_label = tk.Label(
|
||||||
status_frame,
|
status_frame,
|
||||||
text="❓ 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",
|
||||||
@ -853,7 +873,7 @@ class LXToolsGUI:
|
|||||||
# Version label
|
# Version label
|
||||||
version_label = tk.Label(
|
version_label = tk.Label(
|
||||||
status_frame,
|
status_frame,
|
||||||
text="Version: Checking...",
|
text=LocaleStrings.MSGC["version_check"],
|
||||||
font=("Helvetica", 9),
|
font=("Helvetica", 9),
|
||||||
bg=self.colors["card_bg"],
|
bg=self.colors["card_bg"],
|
||||||
fg="#95a5a6",
|
fg="#95a5a6",
|
||||||
@ -936,12 +956,12 @@ 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"Selected project: {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"""
|
||||||
log_frame = ttk.Frame(self.notebook)
|
log_frame = ttk.Frame(self.notebook)
|
||||||
self.notebook.add(log_frame, text=_("Installation Log"))
|
self.notebook.add(log_frame, text=LocaleStrings.MSGL["log_name"])
|
||||||
|
|
||||||
# Log text with scrollbar
|
# Log text with scrollbar
|
||||||
log_container = tk.Frame(log_frame)
|
log_container = tk.Frame(log_frame)
|
||||||
@ -971,7 +991,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
# Clear log button
|
# Clear log button
|
||||||
clear_log_btn = ttk.Button(
|
clear_log_btn = ttk.Button(
|
||||||
log_controls, text=_("Clear Log"), command=self.clear_log
|
log_controls, text=LocaleStrings.MSGB["clear_log"], command=self.clear_log
|
||||||
)
|
)
|
||||||
clear_log_btn.pack(side="right")
|
clear_log_btn.pack(side="right")
|
||||||
|
|
||||||
@ -979,14 +999,18 @@ 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"Working directory: {LXToolsAppConfig.WORK_DIR}"))
|
self.log_message(f"{LocaleStrings.MSGL["work_dir"]}{LXToolsAppConfig.WORK_DIR}")
|
||||||
self.log_message(_(f"Icons directory: {LXToolsAppConfig.ICONS_DIR}"))
|
self.log_message(
|
||||||
self.log_message(_(f"Detected OS: {self.detected_os}"))
|
f"{LocaleStrings.MSGL["icons_dir"]}{LXToolsAppConfig.ICONS_DIR}"
|
||||||
self.log_message(_("Ready for installation..."))
|
)
|
||||||
|
self.log_message(f"{LocaleStrings.MSGL["detected_os"]}{self.detected_os}")
|
||||||
|
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"""
|
||||||
progress_frame = ttk.LabelFrame(self.root, text=_("Progress"), padding=10)
|
progress_frame = ttk.LabelFrame(
|
||||||
|
self.root, text=LocaleStrings.MSGO["progress"], padding=10
|
||||||
|
)
|
||||||
progress_frame.pack(fill="x", padx=15, pady=10)
|
progress_frame.pack(fill="x", padx=15, pady=10)
|
||||||
|
|
||||||
# Container for Icon and Progress
|
# Container for Icon and Progress
|
||||||
@ -1000,7 +1024,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=_("Ready for installation..."),
|
text=f"{LocaleStrings.MSGO["ready"]}...",
|
||||||
font=("Helvetica", 10),
|
font=("Helvetica", 10),
|
||||||
fg="blue",
|
fg="blue",
|
||||||
anchor="w",
|
anchor="w",
|
||||||
@ -1044,7 +1068,7 @@ class LXToolsGUI:
|
|||||||
# Create buttons
|
# Create buttons
|
||||||
install_btn = ttk.Button(
|
install_btn = ttk.Button(
|
||||||
button_frame,
|
button_frame,
|
||||||
text=_("Install/Update"),
|
text=LocaleStrings.MSGB["install"],
|
||||||
command=self.install_selected,
|
command=self.install_selected,
|
||||||
style="Install.TButton",
|
style="Install.TButton",
|
||||||
padding=8,
|
padding=8,
|
||||||
@ -1053,7 +1077,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
uninstall_btn = ttk.Button(
|
uninstall_btn = ttk.Button(
|
||||||
button_frame,
|
button_frame,
|
||||||
text=_("Uninstall"),
|
text=LocaleStrings.MSGB["uninstall"],
|
||||||
command=self.uninstall_selected,
|
command=self.uninstall_selected,
|
||||||
style="Uninstall.TButton",
|
style="Uninstall.TButton",
|
||||||
padding=8,
|
padding=8,
|
||||||
@ -1062,7 +1086,7 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
refresh_btn = ttk.Button(
|
refresh_btn = ttk.Button(
|
||||||
button_frame,
|
button_frame,
|
||||||
text=_("Refresh Status"),
|
text=LocaleStrings.MSGB["refresh"],
|
||||||
command=self.refresh_status,
|
command=self.refresh_status,
|
||||||
style="Refresh.TButton",
|
style="Refresh.TButton",
|
||||||
padding=8,
|
padding=8,
|
||||||
@ -1111,23 +1135,24 @@ class LXToolsGUI:
|
|||||||
|
|
||||||
def refresh_status(self):
|
def refresh_status(self):
|
||||||
"""Refresh application status and version information"""
|
"""Refresh application status and version information"""
|
||||||
self.update_progress(_("Refreshing status and checking versions..."))
|
self.update_progress(LocaleStrings.MSGI["refresh_and_check"])
|
||||||
self._reset_download_icon()
|
self._reset_download_icon()
|
||||||
self.log_message(_("=== Refreshing Status ==="))
|
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"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"✅ Installed ({installed_version})"), fg="green"
|
text=f"✅ {LocaleStrings.MSGI["installed"]}({installed_version})",
|
||||||
|
fg="green",
|
||||||
)
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
_(f"{project_info['name']}: Installed {installed_version}")
|
f"{project_info['name']}: {LocaleStrings.MSGI["installed"]}({installed_version})"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get latest version from API
|
# Get latest version from API
|
||||||
@ -1136,87 +1161,88 @@ 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=_(
|
text=f"{LocaleStrings.MSGC["latest"]}(v. {latest_version}) {LocaleStrings.MSGC["update_available"]}",
|
||||||
f"Latest: v. {latest_version} (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']}: Update available v. {latest_version}"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
version_label.config(
|
||||||
|
text=f"{LocaleStrings.MSGC["latest"]}: (v. {latest_version}) {LocaleStrings.MSGC["up_to_date"]}",
|
||||||
|
fg="green",
|
||||||
|
)
|
||||||
|
self.log_message(
|
||||||
|
f"{project_info['name']}: {LocaleStrings.MSGC["up_to_date"]}",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
version_label.config(
|
version_label.config(
|
||||||
text=f"Latest: v. {latest_version} (Up to date)",
|
text=LocaleStrings.MSGC["latest_unknown"], fg="gray"
|
||||||
fg="green",
|
|
||||||
)
|
)
|
||||||
self.log_message(f"{project_info['name']}: Up to date")
|
|
||||||
else:
|
|
||||||
version_label.config(text="Latest: Unknown", fg="gray")
|
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: Could not check latest version"
|
f"{project_info['name']}: {LocaleStrings.MSGC["could_not_check"]}"
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
version_label.config(text="Latest: Check failed", fg="gray")
|
version_label.config(
|
||||||
|
text=LocaleStrings.MSGC["check_last_failed"], fg="gray"
|
||||||
|
)
|
||||||
self.log_message(
|
self.log_message(
|
||||||
f"{project_info['name']}: Version check failed: {e}"
|
f"{project_info['name']}: {LocaleStrings.MSGC["version_check_failed"]}: {e}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
status_label.config(text="❌ Not installed", fg="red")
|
status_label.config(
|
||||||
self.log_message(_(f"{project_info['name']}: Not installed"))
|
text=f"❌ {LocaleStrings.MSGC["not_installed"]}", fg="red"
|
||||||
|
)
|
||||||
|
self.log_message(
|
||||||
|
f"{project_info['name']}: {LocaleStrings.MSGC["not_installed"]}"
|
||||||
|
)
|
||||||
|
|
||||||
# Still show latest available version
|
# Still show latest available version
|
||||||
try:
|
try:
|
||||||
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"Available: v {latest_version}"), fg="blue"
|
text=f"{project_info['name']} {LocaleStrings.MSGC["available"]}: v {latest_version}",
|
||||||
)
|
fg="blue",
|
||||||
self.log_message(
|
|
||||||
_(f"{project_info['name']}: Available v {latest_version}")
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
version_label.config(text=_("Available: Unknown"), fg="gray")
|
|
||||||
except Exception as e:
|
|
||||||
version_label.config(text=_("Available: Check failed"), fg="gray")
|
|
||||||
self.log_message(
|
|
||||||
_(f"{project_info['name']}: Version check failed: {e}")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.update_progress(_("Status refresh completed."))
|
self.log_message(
|
||||||
self.log_message(_("=== Status refresh completed ==="))
|
f"{project_info['name']} {LocaleStrings.MSGC["available"]}: v {latest_version}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
version_label.config(
|
||||||
|
text=LocaleStrings.MSGC["available_unknown"], fg="gray"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
version_label.config(
|
||||||
|
text=LocaleStrings.MSGC["available_check_unknown"], fg="gray"
|
||||||
|
)
|
||||||
|
self.log_message(
|
||||||
|
f" {project_info['name']}: {LocaleStrings.MSGC["version_check_failed"]}: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.update_progress(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):
|
||||||
"""Handle install button click"""
|
"""Handle install button click"""
|
||||||
if not self.selected_project:
|
if not self.selected_project:
|
||||||
MessageDialog("error", _("Please select a project to install."))
|
MessageDialog("error", LocaleStrings.MSGM["please_select"])
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check internet connection
|
# Check internet connection
|
||||||
if not NetworkChecker.check_internet_connection():
|
if not NetworkChecker.check_internet_connection():
|
||||||
self.update_download_icon("error")
|
self.update_download_icon("error")
|
||||||
MessageDialog(
|
MessageDialog("error", LocaleStrings.MSGM["network_error"])
|
||||||
"error",
|
|
||||||
_(
|
|
||||||
"Network Error",
|
|
||||||
"No internet connection available.\nPlease check your network connection.",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
return
|
return
|
||||||
|
|
||||||
if not NetworkChecker.check_repository_access():
|
if not NetworkChecker.check_repository_access():
|
||||||
self.update_download_icon("error")
|
self.update_download_icon("error")
|
||||||
MessageDialog(
|
MessageDialog("error", LocaleStrings.MSGM["repo_error"])
|
||||||
"error",
|
|
||||||
_(
|
|
||||||
"Repository Error",
|
|
||||||
"Cannot access repository.\nPlease try again later.",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1230,12 +1256,13 @@ class LXToolsGUI:
|
|||||||
self.update_download_icon("success")
|
self.update_download_icon("success")
|
||||||
MessageDialog(
|
MessageDialog(
|
||||||
"info",
|
"info",
|
||||||
_(f"{project_info['name']} has been successfully installed/updated."),
|
f"{project_info["name"]} {LocaleStrings.MSGM["has_success_update"]}",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.refresh_status()
|
self.refresh_status()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.update_download_icon("error")
|
self.update_download_icon("error")
|
||||||
MessageDialog("error", _(f"{e}"))
|
MessageDialog("error", f"{e}")
|
||||||
|
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
|
|
||||||
@ -1243,14 +1270,16 @@ class LXToolsGUI:
|
|||||||
"""Handle uninstall button click"""
|
"""Handle uninstall button click"""
|
||||||
|
|
||||||
if not self.selected_project:
|
if not self.selected_project:
|
||||||
MessageDialog("error", _("Please select a project to uninstall."))
|
MessageDialog("error", LocaleStrings.MSGM["please_select_uninstall"])
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
return
|
return
|
||||||
|
|
||||||
project_info = self.app_manager.get_project_info(self.selected_project)
|
project_info = self.app_manager.get_project_info(self.selected_project)
|
||||||
|
|
||||||
if not self.app_manager.is_installed(self.selected_project):
|
if not self.app_manager.is_installed(self.selected_project):
|
||||||
MessageDialog("error", _(f"{project_info['name']} is not installed."))
|
MessageDialog(
|
||||||
|
"error", f"{project_info["name"]} {LocaleStrings.MSGO["not_installed"]}"
|
||||||
|
)
|
||||||
self.root.focus_set()
|
self.root.focus_set()
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1258,14 +1287,13 @@ 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']} has been successfully uninstalled.",
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
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"Uninstallation 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):
|
||||||
@ -1273,7 +1301,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"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"""
|
||||||
@ -1283,13 +1311,13 @@ class LXToolsGUI:
|
|||||||
self.log_text.insert(tk.END, log_entry)
|
self.log_text.insert(tk.END, log_entry)
|
||||||
self.log_text.see(tk.END)
|
self.log_text.see(tk.END)
|
||||||
self.log_text.update()
|
self.log_text.update()
|
||||||
print(_(f"Log: {message}"))
|
print(f"Log: {message}")
|
||||||
|
|
||||||
def clear_log(self):
|
def clear_log(self):
|
||||||
"""Clear the log"""
|
"""Clear the log"""
|
||||||
if self.log_text:
|
if self.log_text:
|
||||||
self.log_text.delete(1.0, tk.END)
|
self.log_text.delete(1.0, tk.END)
|
||||||
self.log_message(_("Log cleared"))
|
self.log_message(MSGL["log_cleared"])
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Start the GUI application"""
|
"""Start the GUI application"""
|
||||||
@ -1300,21 +1328,19 @@ 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"Working directory: {os.getcwd()}"))
|
print(f"{LocaleStrings.MSGL["working_dir"]}{os.getcwd()}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Create and run the GUI
|
# Create and run the GUI
|
||||||
app = LXToolsGUI()
|
app = LXToolsGUI()
|
||||||
|
|
||||||
app.run()
|
app.run()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print(_("\nApplication interrupted by user."))
|
print(LocaleStrings.MSGL["user_interrupt"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(_(f"Fatal error: {e}"))
|
print(f"{LocaleStrings.MSGL["fatal_error"]}: {e}")
|
||||||
try:
|
try:
|
||||||
MessageDialog(
|
MessageDialog("error", f"{LocaleStrings.MSGL['fatal_app_error']}: {e}")
|
||||||
"error", _("Fatal Error", f"Application failed to start: {e}")
|
|
||||||
)
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
150
manager.py
@ -1,7 +1,6 @@
|
|||||||
import locale
|
import locale
|
||||||
import gettext
|
import gettext
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from pathlib import Path
|
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -10,10 +9,10 @@ from network import GiteaUpdate
|
|||||||
|
|
||||||
|
|
||||||
class LXToolsAppConfig:
|
class LXToolsAppConfig:
|
||||||
VERSION = "1.1.4"
|
VERSION = "1.1.5"
|
||||||
APP_NAME = "Lunix Tools Installer"
|
APP_NAME = "lxtoolsinstaller"
|
||||||
WINDOW_WIDTH = 450
|
WINDOW_WIDTH = 450
|
||||||
WINDOW_HEIGHT = 580
|
WINDOW_HEIGHT = 740
|
||||||
|
|
||||||
# Working directory
|
# Working directory
|
||||||
WORK_DIR = os.getcwd()
|
WORK_DIR = os.getcwd()
|
||||||
@ -21,7 +20,7 @@ class LXToolsAppConfig:
|
|||||||
THEMES_DIR = os.path.join(WORK_DIR, "TK-Themes")
|
THEMES_DIR = os.path.join(WORK_DIR, "TK-Themes")
|
||||||
|
|
||||||
# Locale settings
|
# Locale settings
|
||||||
LOCALE_DIR = Path("/usr/share/locale/")
|
LOCALE_DIR = "./locale/"
|
||||||
|
|
||||||
# Download URLs
|
# Download URLs
|
||||||
WIREPY_URL = "https://git.ilunix.de/punix/Wire-Py/archive/main.zip"
|
WIREPY_URL = "https://git.ilunix.de/punix/Wire-Py/archive/main.zip"
|
||||||
@ -94,7 +93,7 @@ class LXToolsAppConfig:
|
|||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def setup_translations():
|
def setup_translations() -> gettext.gettext:
|
||||||
"""Initialize translations and set the translation function"""
|
"""Initialize translations and set the translation function"""
|
||||||
try:
|
try:
|
||||||
locale.bindtextdomain(
|
locale.bindtextdomain(
|
||||||
@ -113,6 +112,117 @@ class LXToolsAppConfig:
|
|||||||
_ = LXToolsAppConfig.setup_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:
|
class OSDetector:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def detect_os():
|
def detect_os():
|
||||||
@ -148,8 +258,8 @@ class OSDetector:
|
|||||||
if detected_os in LXToolsAppConfig.TKINTER_INSTALL_COMMANDS:
|
if detected_os in LXToolsAppConfig.TKINTER_INSTALL_COMMANDS:
|
||||||
commands = LXToolsAppConfig.TKINTER_INSTALL_COMMANDS[detected_os]
|
commands = LXToolsAppConfig.TKINTER_INSTALL_COMMANDS[detected_os]
|
||||||
|
|
||||||
print(f"Installing tkinter for {detected_os}...")
|
print(f"{LocaleStrings.MSGP["tk_install"]}{detected_os}...")
|
||||||
print(_(f"Command: {' '.join(commands)}"))
|
print(f"{LocaleStrings.MSGP["command_string"]}{' '.join(commands)}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Use pkexec for privilege escalation
|
# Use pkexec for privilege escalation
|
||||||
@ -159,20 +269,20 @@ class OSDetector:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
print(_("TKinter installation completed successfully!"))
|
print(f"{LocaleStrings.MSGP["tk_succcess"]}")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
print(_(f"TKinter installation failed: {result.stderr}"))
|
print(f"{LocaleStrings.MSGP["tk_failed"]}{result.stderr}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
print(_("TKinter installation timed out"))
|
print(LocaleStrings.MSGP["tk_timeout"])
|
||||||
return False
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(_(f"Error installing tkinter: {e}"))
|
print(f"{LocaleStrings.MSGP['tk_install_error']}{str(e)}")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print(_(f"No tkinter installation command defined for {detected_os}"))
|
print(f"{LocaleStrings.MSGP["tk_command_error"]}{detected_os}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@ -307,7 +417,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"Failed to load image from {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
|
||||||
@ -356,11 +466,11 @@ class AppManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Debug logging
|
# Debug logging
|
||||||
print(_("LogViewer installation check:"))
|
print(LocaleStrings.MSGP["logviewer_check"])
|
||||||
print(_(f" Symlink exists: {symlink_exists}"))
|
print(f"{LocaleStrings.MSGP["symlink_exist"]}{symlink_exists}")
|
||||||
print(_(f" Executable exists: {executable_exists}"))
|
print(f"{LocaleStrings.MSGP["executable_exist"]}{executable_exists}")
|
||||||
print(_(f" Is executable: {executable_is_executable}"))
|
print(f"{LocaleStrings.MSGP["is_executable"]}{executable_is_executable}")
|
||||||
print(_(f" Final result: {is_installed}"))
|
print(f"{LocaleStrings.MSGP["final_result"]}{is_installed}")
|
||||||
|
|
||||||
return is_installed
|
return is_installed
|
||||||
|
|
||||||
@ -385,7 +495,7 @@ class AppManager:
|
|||||||
return version
|
return version
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(_(f"Error getting version for {project_key}: {e}"))
|
print(f"{LocaleStrings.MSGP["get_version_error"]}{project_key}: {e}")
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
|
|
||||||
def get_latest_version(self, project_key):
|
def get_latest_version(self, project_key):
|
||||||
|