Files
Jackify/jackify/frontends/gui/screens/install_ttw_thread.py
2026-03-13 14:43:25 +00:00

156 lines
5.4 KiB
Python

"""TTW installation worker thread."""
from PySide6.QtCore import QThread, Signal
import time
from ..utils import strip_ansi_control_codes
class TTWInstallationThread(QThread):
output_batch_received = Signal(list)
progress_received = Signal(str)
installation_finished = Signal(bool, str)
def __init__(self, mpi_path, install_dir):
super().__init__()
self.mpi_path = mpi_path
self.install_dir = install_dir
self.cancelled = False
self.proc = None
self.output_buffer = []
self.last_emit_time = 0
def cancel(self):
self.cancelled = True
try:
if self.proc and self.proc.poll() is None:
self.proc.terminate()
except Exception:
pass
def process_and_buffer_line(self, raw_line):
"""Clean one output line and queue it for batched emit."""
cleaned = strip_ansi_control_codes(raw_line).strip()
filtered_chars = []
for char in cleaned:
code = ord(char)
is_emoji = (
(0x1F300 <= code <= 0x1F9FF) or
(0x1F600 <= code <= 0x1F64F) or
(0x2600 <= code <= 0x26FF) or
(0x2700 <= code <= 0x27BF)
)
if not is_emoji:
filtered_chars.append(char)
cleaned = ''.join(filtered_chars).strip()
if cleaned:
self.output_buffer.append(cleaned)
def flush_output_buffer(self):
"""Emit buffered lines as a batch."""
if self.output_buffer:
self.output_batch_received.emit(self.output_buffer[:])
self.output_buffer.clear()
self.last_emit_time = time.time()
def run(self):
try:
from jackify.backend.handlers.ttw_installer_handler import TTWInstallerHandler
from jackify.backend.handlers.filesystem_handler import FileSystemHandler
from jackify.backend.handlers.config_handler import ConfigHandler
from pathlib import Path
import tempfile
self.process_and_buffer_line("Initializing TTW installation...")
self.flush_output_buffer()
filesystem_handler = FileSystemHandler()
config_handler = ConfigHandler()
ttw_handler = TTWInstallerHandler(
steamdeck=False,
verbose=False,
filesystem_handler=filesystem_handler,
config_handler=config_handler,
)
output_file = tempfile.NamedTemporaryFile(
mode='w+', delete=False, suffix='.ttw_output', encoding='utf-8'
)
output_file_path = Path(output_file.name)
output_file.close()
self.process_and_buffer_line("Starting TTW installation...")
self.flush_output_buffer()
self.proc, error_msg = ttw_handler.start_ttw_installation(
Path(self.mpi_path),
Path(self.install_dir),
output_file_path,
)
if not self.proc:
self.installation_finished.emit(False, error_msg or "Failed to start TTW installation")
return
self.process_and_buffer_line("TTW_Linux_Installer process started, monitoring output...")
self.flush_output_buffer()
last_position = 0
BATCH_INTERVAL = 0.3
while self.proc.poll() is None:
if self.cancelled:
break
try:
with open(output_file_path, 'r', encoding='utf-8', errors='replace') as f:
f.seek(last_position)
new_lines = f.readlines()
last_position = f.tell()
for line in new_lines:
if self.cancelled:
break
self.process_and_buffer_line(line.rstrip())
if time.time() - self.last_emit_time >= BATCH_INTERVAL:
self.flush_output_buffer()
except Exception:
pass
time.sleep(0.1)
try:
with open(output_file_path, 'r', encoding='utf-8', errors='replace') as f:
f.seek(last_position)
for line in f.readlines():
self.process_and_buffer_line(line.rstrip())
self.flush_output_buffer()
except Exception:
pass
try:
output_file_path.unlink(missing_ok=True)
except Exception:
pass
ttw_handler.cleanup_ttw_process(self.proc)
returncode = self.proc.returncode if self.proc else -1
if self.cancelled:
self.installation_finished.emit(False, "Installation cancelled by user")
elif returncode == 0:
self.installation_finished.emit(True, "TTW installation completed successfully!")
else:
self.installation_finished.emit(
False,
f"TTW installer exited unexpectedly (code {returncode}). "
"Review the recent console output for the failing step."
)
except Exception as e:
import traceback
traceback.print_exc()
self.installation_finished.emit(False, f"Installation error: {str(e)}")