From 891c5a86c1d69d9a2cdb57cd5d22c12403bb8e29 Mon Sep 17 00:00:00 2001 From: Vxrtrauter <101264710+Vxrtrauter@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:55:23 +0100 Subject: [PATCH] feat: enhance update process with progress dialog and install path detection --- installer.iss | 6 ++ src/core/interface/gui.py | 131 ++++++++++++++++++++++++++++++++------ 2 files changed, 119 insertions(+), 18 deletions(-) diff --git a/installer.iss b/installer.iss index bf95032..60e6034 100644 --- a/installer.iss +++ b/installer.iss @@ -27,24 +27,30 @@ AppId={{8F2E4B6A-1C3D-4E5F-9A7B-0D8E6F2C4A1B} AppName={#MyAppName} AppVersion={#MyAppVersion} +AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL}/issues +AppUpdatesURL={#MyAppURL}/releases DefaultDirName={autopf}\{#MyAppName} DefaultGroupName={#MyAppName} AllowNoIcons=yes +LicenseFile=LICENSE OutputDir={#MyOutputDir} OutputBaseFilename={#MyOutputFilename} Compression=lzma2 SolidCompression=yes WizardStyle=modern +DisableWelcomePage=no PrivilegesRequired=lowest PrivilegesRequiredOverridesAllowed=dialog UninstallDisplayIcon={app}\{#MyAppExeName} +UninstallDisplayName={#MyAppName} ArchitecturesAllowed=x64compatible ArchitecturesInstallIn64BitMode=x64compatible CloseApplications=yes RestartApplications=yes +ShowLanguageDialog=auto [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" diff --git a/src/core/interface/gui.py b/src/core/interface/gui.py index 2855f84..485d3b1 100644 --- a/src/core/interface/gui.py +++ b/src/core/interface/gui.py @@ -27,10 +27,10 @@ import requests as r import os import subprocess import libtorrent as lt -import time import sys import json import base64 +import winreg from core.utils.logging.logs import consoleLog, remove_download_log, flush_log_buffer from core.utils.general.wrappers import run_thread from core.utils.data.state import state @@ -134,26 +134,80 @@ SVG_PAUSE = ' 0: + progress.setValue(int(downloaded * 100 / total)) + QtWidgets.QApplication.processEvents() + + with open(new_filename, "wb") as f: + for chunk in chunks: + f.write(chunk) + + if not os.path.exists(new_filename): + progress.close() + raise FileNotFoundError("Executable not found") + + progress.setLabelText("Installing update...") + progress.setValue(100) + QtWidgets.QApplication.processEvents() + + proc = subprocess.Popen([new_filename, "/VERYSILENT", "/SUPPRESSMSGBOXES", "/SP-", "/CLOSEAPPLICATIONS", "/NORESTART"]) + while proc.poll() is None: + QtWidgets.QApplication.processEvents() + import time + time.sleep(0.1) + + progress.close() + + try: + os.remove(new_filename) + except OSError: + pass + + install_path = _find_install_path() + if not install_path: + raise FileNotFoundError("Could not find SoftwareManager install location in registry") + subprocess.Popen([os.path.join(install_path, "SoftwareManager.exe")]) sys.exit(0) @@ -163,11 +217,13 @@ def windowCloseHelper(): class MainWindow(QtWidgets.QMainWindow, QWidget): log_signal = Signal(str) # Thread-safe signal for logging + search_finished_signal = Signal() # Thread-safe signal for search completion def __init__(self): super().__init__() MainWindow._instance = self self.log_signal.connect(self._on_log_signal) + self.search_finished_signal.connect(self._on_search_finished) pixmap = QPixmap() image_data = base64.b64decode(logo_base64) @@ -217,7 +273,16 @@ class MainWindow(QtWidgets.QMainWindow, QWidget): self.searchbar.setPlaceholderText("Search for software...") self.searchbar.setClearButtonEnabled(True) self.searchbar.setMinimumHeight(30) - self.searchbar.returnPressed.connect(lambda: run_thread(threading.Thread(target=return_pressed, args=(self,)))) # Triggers data function thread on enter + self.searchbar.returnPressed.connect(self._start_search) + + self._spinner_label = QLabel() + self._spinner_label.setFixedSize(20, 20) + self._spinner_label.setAlignment(Qt.AlignmentFlag.AlignCenter) + self._spinner_label.hide() + self._spinner_angle = 0 + self._spinner_timer = QTimer() + self._spinner_timer.setInterval(80) + self._spinner_timer.timeout.connect(self._update_spinner) self.dlbutton = QtWidgets.QPushButton("Download") self.dlbutton.setCursor(Qt.CursorShape.PointingHandCursor) @@ -300,7 +365,11 @@ class MainWindow(QtWidgets.QMainWindow, QWidget): container = QWidget() containerLayout = QVBoxLayout() - containerLayout.addWidget(self.searchbar) + + search_row = QHBoxLayout() + search_row.addWidget(self.searchbar) + search_row.addWidget(self._spinner_label) + containerLayout.addLayout(search_row) containerLayout.addWidget(state.tracker_list[state.tracker]) class DownloadModel(QAbstractTableModel): @@ -663,6 +732,32 @@ class MainWindow(QtWidgets.QMainWindow, QWidget): self.context_menu.addAction("Cancel Download", self.cancelDownloadAction) self.context_menu.addAction("Delete File", self.deleteFileAction) + def _start_search(self): + self._spinner_label.show() + self._spinner_angle = 0 + self._spinner_timer.start() + self._update_spinner() + self.searchbar.setEnabled(False) + def _search_thread(): + try: + return_pressed(self) + finally: + self.search_finished_signal.emit() + run_thread(threading.Thread(target=_search_thread)) + + def _on_search_finished(self): + self._spinner_timer.stop() + self._spinner_label.hide() + self.searchbar.setEnabled(True) + self.searchbar.setFocus() + + def _update_spinner(self): + frames = ["◐", "◓", "◑", "◒"] + idx = (self._spinner_angle // 1) % len(frames) + self._spinner_label.setText(frames[idx]) + self._spinner_label.setStyleSheet("font-size: 16px; color: gray;") + self._spinner_angle += 1 + @staticmethod def add_log(text): if MainWindow._instance: