Compare commits

..

2 Commits

Author SHA1 Message Date
Vxrtrauter 9f8111ac73 refactor: streamline update check logic and enhance log handling 2026-02-11 03:27:49 +01:00
Vxrtrauter e5b809d6d4 # This is a combination of 9 commits.
# This is the 1st commit message:

fix: update Python version to 3.12 and switch from PyInstaller to Nuitka for building executables

# This is the commit message #2:

fix: correct UPX path for Windows installation in CI workflow

# This is the commit message #3:

fix: update UPX installation path handling for Windows and Linux in CI workflow

# This is the commit message #4:

fix: enhance UPX installation by setting UPX_BINARY environment variable for better compatibility

# This is the commit message #5:

fix: add --assume-yes-for-downloads option to Nuitka build commands for improved automation

# This is the commit message #6:

fix: update asset path handling in MainWindow for improved compatibility with frozen applications

# This is the commit message #7:

fix: update Nuitka build options and refine PySide6 dependency for improved compatibility

# This is the commit message #8:

fix: add Windows icon conversion step and update Nuitka build options for improved compatibility

# This is the commit message #9:

fix: refactor Nuitka and UPX installation steps for improved clarity and compatibility
2026-02-11 03:01:31 +01:00
2 changed files with 84 additions and 111 deletions
+64 -92
View File
@@ -57,7 +57,13 @@ jobs:
- name: Install Python dependencies - name: Install Python dependencies
run: | run: |
uv pip install -r requirements.txt uv pip install -r requirements.txt
uv pip install nuitka uv pip install Pillow
env:
UV_SYSTEM_PYTHON: 1
- name: Install Nuitka (Windows only)
if: runner.os == 'Windows'
run: uv pip install nuitka
env: env:
UV_SYSTEM_PYTHON: 1 UV_SYSTEM_PYTHON: 1
@@ -82,29 +88,29 @@ jobs:
} }
EOF EOF
- name: Install UPX - name: Install UPX (Windows)
if: runner.os == 'Windows'
shell: bash shell: bash
run: | run: |
if [ "$RUNNER_OS" == "Windows" ]; then curl -sL https://github.com/upx/upx/releases/download/v5.1.0/upx-5.1.0-win64.zip -o upx.zip
curl -sL https://github.com/upx/upx/releases/download/v5.1.0/upx-5.1.0-win64.zip -o upx.zip 7z x upx.zip -oupx-dir
7z x upx.zip -oupx-dir UPX_DIR="$(pwd)/upx-dir/upx-5.1.0-win64"
UPX_DIR="$(pwd)/upx-dir/upx-5.1.0-win64" echo "$UPX_DIR" >> $GITHUB_PATH
echo "$UPX_DIR" >> $GITHUB_PATH export PATH="$UPX_DIR:$PATH"
export PATH="$UPX_DIR:$PATH" echo "UPX_BINARY=$UPX_DIR/upx.exe" >> $GITHUB_ENV
echo "UPX_BINARY=$UPX_DIR/upx.exe" >> $GITHUB_ENV
elif [ "$RUNNER_OS" == "Linux" ]; then
curl -sL https://github.com/upx/upx/releases/download/v5.1.0/upx-5.1.0-amd64_linux.tar.xz -o upx.tar.xz
tar xf upx.tar.xz
UPX_DIR="$(pwd)/upx-5.1.0-amd64_linux"
echo "$UPX_DIR" >> $GITHUB_PATH
export PATH="$UPX_DIR:$PATH"
echo "UPX_BINARY=$UPX_DIR/upx" >> $GITHUB_ENV
else
brew install upx
echo "UPX_BINARY=$(which upx)" >> $GITHUB_ENV
fi
upx --version | head -1 upx --version | head -1
- name: Convert icon for Windows
if: runner.os == 'Windows'
shell: bash
run: |
python -c "
from PIL import Image
img = Image.open('core/interface/assets/logo.png')
img.save('app_icon.ico', format='ICO', sizes=[(256,256),(128,128),(64,64),(48,48),(32,32),(16,16)])
print('Icon converted successfully')
"
- name: Build with Nuitka (Windows) - name: Build with Nuitka (Windows)
if: runner.os == 'Windows' if: runner.os == 'Windows'
shell: bash shell: bash
@@ -115,23 +121,11 @@ jobs:
--onefile-tempdir-spec="{CACHE_DIR}/${{ env.APP_NAME }}/${{ env.VERSION }}" \ --onefile-tempdir-spec="{CACHE_DIR}/${{ env.APP_NAME }}/${{ env.VERSION }}" \
--assume-yes-for-downloads \ --assume-yes-for-downloads \
--windows-console-mode=disable \ --windows-console-mode=disable \
--windows-icon-from-ico=app_icon.ico \
--enable-plugin=pyside6 \ --enable-plugin=pyside6 \
--enable-plugin=upx \ --enable-plugin=upx \
--upx-binary="${{ env.UPX_BINARY }}" \ --upx-binary="${{ env.UPX_BINARY }}" \
--noinclude-qt-translations \ --noinclude-qt-translations \
--noinclude-dlls='Qt6WebEngine*' \
--noinclude-dlls='Qt6Multimedia*' \
--noinclude-dlls='Qt6Quick*' \
--noinclude-dlls='Qt6Qml*' \
--noinclude-dlls='Qt6Designer*' \
--noinclude-dlls='Qt63D*' \
--noinclude-dlls='Qt6Bluetooth*' \
--noinclude-dlls='Qt6Nfc*' \
--noinclude-dlls='Qt6Sensors*' \
--noinclude-dlls='Qt6Serial*' \
--noinclude-dlls='Qt6Test*' \
--noinclude-dlls='Qt6Location*' \
--noinclude-dlls='Qt6Pdf*' \
--include-data-dir=core/interface/assets=core/interface/assets \ --include-data-dir=core/interface/assets=core/interface/assets \
--include-data-files=build_info.json=build_info.json \ --include-data-files=build_info.json=build_info.json \
--include-data-files=build_info.json=core/build_info.json \ --include-data-files=build_info.json=core/build_info.json \
@@ -139,85 +133,63 @@ jobs:
--output-filename=${{ env.APP_NAME }}.exe \ --output-filename=${{ env.APP_NAME }}.exe \
main.py main.py
- name: Build with Nuitka (Linux) - name: Build with PyInstaller (Linux)
if: runner.os == 'Linux' if: runner.os == 'Linux'
shell: bash shell: bash
run: | run: |
python -m nuitka \ pyinstaller --onefile --windowed \
--onefile \ --add-data "build_info.json:." \
--onefile-tempdir-spec="{CACHE_DIR}/${{ env.APP_NAME }}/${{ env.VERSION }}" \ --add-data "build_info.json:core" \
--assume-yes-for-downloads \ --add-data "build_info.json:core/interface" \
--enable-plugin=pyside6 \ --add-data "core/interface/assets:core/interface/assets" \
--enable-plugin=upx \ --icon "core/interface/assets/logo.png" \
--upx-binary="${{ env.UPX_BINARY }}" \ --exclude-module PyQt6 \
--noinclude-qt-translations \ --exclude-module PyQt5 \
--noinclude-dlls='libQt6WebEngine*' \ --hidden-import=backports.tarfile \
--noinclude-dlls='libQt6Multimedia*' \ --hidden-import=backports \
--noinclude-dlls='libQt6Quick*' \ --hidden-import=jaraco.context \
--noinclude-dlls='libQt6Qml*' \ --hidden-import=jaraco.text \
--noinclude-dlls='libQt6Designer*' \ --hidden-import=jaraco.functools \
--noinclude-dlls='libQt63D*' \ --name ${{ env.APP_NAME }} \
--noinclude-dlls='libQt6Bluetooth*' \
--noinclude-dlls='libQt6Nfc*' \
--noinclude-dlls='libQt6Sensors*' \
--noinclude-dlls='libQt6Serial*' \
--noinclude-dlls='libQt6Test*' \
--noinclude-dlls='libQt6Location*' \
--noinclude-dlls='libQt6Pdf*' \
--include-data-dir=core/interface/assets=core/interface/assets \
--include-data-files=build_info.json=build_info.json \
--include-data-files=build_info.json=core/build_info.json \
--include-data-files=build_info.json=core/interface/build_info.json \
--output-filename=${{ env.APP_NAME }} \
main.py main.py
- name: Build with Nuitka (macOS) - name: Build with PyInstaller (macOS)
if: runner.os == 'macOS' if: runner.os == 'macOS'
shell: bash shell: bash
run: | run: |
python -m nuitka \ pyinstaller --onefile \
--onefile \ --add-data "build_info.json:." \
--onefile-tempdir-spec="{CACHE_DIR}/${{ env.APP_NAME }}/${{ env.VERSION }}" \ --add-data "build_info.json:core" \
--assume-yes-for-downloads \ --add-data "build_info.json:core/interface" \
--enable-plugin=pyside6 \ --add-data "core/interface/assets:core/interface/assets" \
--noinclude-qt-translations \ --icon "core/interface/assets/logo.png" \
--noinclude-dlls='libQt6WebEngine*' \ --exclude-module PyQt6 \
--noinclude-dlls='libQt6Multimedia*' \ --exclude-module PyQt5 \
--noinclude-dlls='libQt6Quick*' \ --hidden-import=backports.tarfile \
--noinclude-dlls='libQt6Qml*' \ --hidden-import=backports \
--noinclude-dlls='libQt6Designer*' \ --hidden-import=jaraco.context \
--noinclude-dlls='libQt63D*' \ --hidden-import=jaraco.text \
--noinclude-dlls='libQt6Bluetooth*' \ --hidden-import=jaraco.functools \
--noinclude-dlls='libQt6Nfc*' \ --name ${{ env.APP_NAME }} \
--noinclude-dlls='libQt6Sensors*' \
--noinclude-dlls='libQt6Serial*' \
--noinclude-dlls='libQt6Test*' \
--noinclude-dlls='libQt6Location*' \
--noinclude-dlls='libQt6Pdf*' \
--include-data-dir=core/interface/assets=core/interface/assets \
--include-data-files=build_info.json=build_info.json \
--include-data-files=build_info.json=core/build_info.json \
--include-data-files=build_info.json=core/interface/build_info.json \
--output-filename=${{ env.APP_NAME }} \
main.py main.py
- name: Prepare artifact - name: Rename artifact
shell: bash shell: bash
run: | run: |
mkdir -p dist mkdir -p dist-final
if [ "$RUNNER_OS" == "Windows" ]; then if [ "$RUNNER_OS" == "Windows" ]; then
mv ${{ env.APP_NAME }}.exe dist/${{ matrix.artifact_name }} mv ${{ env.APP_NAME }}.exe dist-final/${{ matrix.artifact_name }}
else else
mv ${{ env.APP_NAME }} dist/${{ matrix.artifact_name }} chmod +x dist/${{ env.APP_NAME }}
chmod +x dist/${{ matrix.artifact_name }} mv dist/${{ env.APP_NAME }} dist-final/${{ matrix.artifact_name }}
fi fi
ls -la dist/ ls -la dist-final/
- name: Upload build artifact - name: Upload build artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.os }}-build name: ${{ matrix.os }}-build
path: dist/${{ matrix.artifact_name }} path: dist-final/${{ matrix.artifact_name }}
retention-days: 1 retention-days: 1
release: release:
+20 -19
View File
@@ -29,6 +29,7 @@ import libtorrent as lt
import time import time
import sys import sys
import json import json
import asyncio
from core.utils.general.logs import consoleLog, remove_download_log, flush_log_buffer from core.utils.general.logs import consoleLog, remove_download_log, flush_log_buffer
from core.utils.general.wrappers import run_thread from core.utils.general.wrappers import run_thread
from core.utils.data.state import state from core.utils.data.state import state
@@ -103,23 +104,22 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
state.version = build_info.get("version") state.version = build_info.get("version")
# Check for updates on Windows # Check for updates on Windows
if state.ignore_updates is False: if state.ignore_updates is False and platform.system() == "Windows":
if platform.system() == "Windows": result = check_for_updates()
result = check_for_updates() if result != (None, None):
if result != (None, None): assets, latest_version = result
assets, latest_version = result
if assets: if assets:
msg = QMessageBox() msg = QMessageBox()
msg.setIcon(QMessageBox.Icon.Information) msg.setIcon(QMessageBox.Icon.Information)
msg.setWindowTitle("Update Available") msg.setWindowTitle("Update Available")
msg.setText("A new version is available.") msg.setText("A new version is available.")
msg.setInformativeText("Press Ok to download the update.") msg.setInformativeText("Press Ok to download the update.")
msg.setStandardButtons(QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Ignore) msg.setStandardButtons(QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Ignore)
response = msg.exec_() response = msg.exec_()
if response == QMessageBox.StandardButton.Ok: if response == QMessageBox.StandardButton.Ok:
download_update(latest_version) download_update(latest_version)
self.setWindowTitle("Software Manager") self.setWindowTitle("Software Manager")
self.setGeometry(100, 100, 800, 600) self.setGeometry(100, 100, 800, 600)
@@ -476,10 +476,11 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
MainWindow._instance.log_signal.emit(text) MainWindow._instance.log_signal.emit(text)
def _on_log_signal(self, text): def _on_log_signal(self, text):
self.consoleLog.append(text) if hasattr(self, 'consoleLog'):
self.consoleLog.verticalScrollBar().setValue( self.consoleLog.append(text)
self.consoleLog.verticalScrollBar().maximum() self.consoleLog.verticalScrollBar().setValue(
) self.consoleLog.verticalScrollBar().maximum()
)
def update_image_overlay(self, new_image_path): def update_image_overlay(self, new_image_path):
self.image = QImage(new_image_path) self.image = QImage(new_image_path)