Merge pull request #47 from KeksPirates/fix/invalid-version-detection

Fix invalid version detection
This commit is contained in:
shayaa
2026-03-16 02:45:46 +01:00
committed by GitHub
8 changed files with 63 additions and 30 deletions
-6
View File
@@ -125,8 +125,6 @@ jobs:
--upx-binary="${{ env.UPX_BINARY }}" \ --upx-binary="${{ env.UPX_BINARY }}" \
--noinclude-qt-translations \ --noinclude-qt-translations \
--include-data-files=build_info.json=build_info.json \ --include-data-files=build_info.json=build_info.json \
--include-data-files=build_info.json=src/build_info.json \
--include-data-files=build_info.json=src/core/interface/build_info.json \
--output-filename=${{ env.APP_NAME }}.exe \ --output-filename=${{ env.APP_NAME }}.exe \
--output-dir=nuitka-build \ --output-dir=nuitka-build \
src/main.py src/main.py
@@ -137,8 +135,6 @@ jobs:
run: | run: |
pyinstaller --onefile --windowed \ pyinstaller --onefile --windowed \
--add-data "build_info.json:." \ --add-data "build_info.json:." \
--add-data "build_info.json:src/core" \
--add-data "build_info.json:src/core/interface" \
--exclude-module PyQt6 \ --exclude-module PyQt6 \
--exclude-module PyQt5 \ --exclude-module PyQt5 \
--hidden-import=backports.tarfile \ --hidden-import=backports.tarfile \
@@ -155,8 +151,6 @@ jobs:
run: | run: |
pyinstaller --onefile \ pyinstaller --onefile \
--add-data "build_info.json:." \ --add-data "build_info.json:." \
--add-data "build_info.json:src/core" \
--add-data "build_info.json:src/core/interface" \
--exclude-module PyQt6 \ --exclude-module PyQt6 \
--exclude-module PyQt5 \ --exclude-module PyQt5 \
--hidden-import=backports.tarfile \ --hidden-import=backports.tarfile \
+20 -3
View File
@@ -1,18 +1,35 @@
from core.utils.network.update_checker import get_updates from core.utils.network.update_checker import get_updates
from core.utils.network.updater import download_update from core.utils.network.updater import download_update
from PySide6.QtWidgets import QDialog, QMessageBox from PySide6.QtWidgets import QDialog, QMessageBox
from core.utils.logging.logs import consoleLog
from core.utils.data.state import state from core.utils.data.state import state
from pathlib import Path
import platform import platform
import json import json
import os import os
def check_version(): def _get_build_info_path() -> (Path | None):
build_info_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "build_info.json") current_dir = Path(__file__).resolve().parent
for _ in range(6): # Climb max 6 directories
file = current_dir / "build_info.json"
if file.exists():
return file
# Go up one directory if file isn't found
current_dir = current_dir.parent
return None
def get_version() -> None:
# Get build info filepath
build_info_path = _get_build_info_path()
if os.path.exists(build_info_path): if os.path.exists(build_info_path):
with open(build_info_path, "r") as f: with open(build_info_path, "r") as f:
build_info = json.load(f) build_info = json.load(f)
state.version = build_info.get("version") state.version = build_info.get("version")
else:
consoleLog(f"Could not find build info file (Path: {build_info_path})")
class UpdateDialog(QDialog): class UpdateDialog(QDialog):
def __init__(self, parent=None): def __init__(self, parent=None):
+18 -8
View File
@@ -13,14 +13,13 @@ from core.interface.assets.base64_icons import logo_base64
from core.interface.dialogs.eventfilter import eventFilter from core.interface.dialogs.eventfilter import eventFilter
from core.utils.network.download import download_selected from core.utils.network.download import download_selected
from core.interface.utils.tabhelper import create_tab from core.interface.utils.tabhelper import create_tab
from core.interface.dialogs.update import get_version
from core.utils.general.shutdown import closehelper from core.utils.general.shutdown import closehelper
from core.utils.general.wrappers import run_thread from core.utils.general.wrappers import run_thread
from core.interface.dialogs.image import Image from core.interface.dialogs.image import Image
from core.utils.data.state import state from core.utils.data.state import state
import core.interface.dialogs.hoverrowdelegate
import core.interface.dialogs.contextmenu import core.interface.dialogs.contextmenu
import core.interface.dialogs.update
from PySide6 import QtWidgets from PySide6 import QtWidgets
from PySide6.QtCore import ( from PySide6.QtCore import (
@@ -77,7 +76,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
pixmap.loadFromData(image_data) pixmap.loadFromData(image_data)
self.setWindowIcon(QIcon(pixmap)) self.setWindowIcon(QIcon(pixmap))
# set appid on windows # Set AppID on Windows
if platform.system() == "Windows": if platform.system() == "Windows":
try: try:
import ctypes import ctypes
@@ -86,23 +85,29 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
except Exception as e: except Exception as e:
consoleLog(f"Could not set app ID: {e}") consoleLog(f"Could not set app ID: {e}")
# Get current version
# core.interface.dialogs.update # core.interface.dialogs.update
get_version()
# Initialize Window
self.setWindowTitle("Software Manager") self.setWindowTitle("Software Manager")
self.setGeometry(100, 100, 800, 600) self.setGeometry(100, 100, 800, 600)
self.controls = QWidget() self.controls = QWidget()
self.controlsLayout = QVBoxLayout() self.controlsLayout = QVBoxLayout()
# Searchbar
self.searchbar = QLineEdit() self.searchbar = QLineEdit()
self.searchbar.setPlaceholderText("Search for software...") self.searchbar.setPlaceholderText("Search for software...")
self.searchbar.setClearButtonEnabled(True) self.searchbar.setClearButtonEnabled(True)
self.searchbar.setMinimumHeight(30) self.searchbar.setMinimumHeight(30)
self.searchbar.returnPressed.connect(self._start_search) self.searchbar.returnPressed.connect(self._start_search)
# Download Button
self.dlbutton = QtWidgets.QPushButton("Download") self.dlbutton = QtWidgets.QPushButton("Download")
self.dlbutton.setCursor(Qt.CursorShape.PointingHandCursor) self.dlbutton.setCursor(Qt.CursorShape.PointingHandCursor)
# Dialog for empty results
self.emptyResults = QLabel("No Results") self.emptyResults = QLabel("No Results")
self.emptyResults.setAlignment(Qt.AlignmentFlag.AlignCenter) self.emptyResults.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.emptyResults.hide() self.emptyResults.hide()
@@ -157,23 +162,32 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.horizontal_layout.addWidget(self.emptyResults, stretch=3) self.horizontal_layout.addWidget(self.emptyResults, stretch=3)
self.horizontal_layout.addWidget(state.trackertable) self.horizontal_layout.addWidget(state.trackertable)
# Tabs
self.tab1 = create_tab("Search", self.searchbar, state.trackertable, self.tabs, self.dlbutton, self.horizontal_layout) self.tab1 = create_tab("Search", self.searchbar, state.trackertable, self.tabs, self.dlbutton, self.horizontal_layout)
self.tab2 = create_tab("Downloads", self.emptyDownload, self.downloadList, self.tabs, None, None) self.tab2 = create_tab("Downloads", self.emptyDownload, self.downloadList, self.tabs, None, None)
# Corner Widget (Settings Button, Tracker list, Tab button container)
self.corner_widget = QWidget() self.corner_widget = QWidget()
self.corner_layout = QHBoxLayout(self.corner_widget) self.corner_layout = QHBoxLayout(self.corner_widget)
self.corner_layout.setContentsMargins(0, 0, 0, 0) self.corner_layout.setContentsMargins(0, 0, 0, 0)
# Tracker list
self.tracker_list = QComboBox() self.tracker_list = QComboBox()
self.tracker_list.addItems(list(state.trackers.keys())) self.tracker_list.addItems(list(state.trackers.keys()))
self.tracker_list.setCursor(Qt.CursorShape.PointingHandCursor) self.tracker_list.setCursor(Qt.CursorShape.PointingHandCursor)
self.tracker_list.activated.connect(self.set_tracker) self.tracker_list.activated.connect(self.set_tracker)
self.corner_layout.addWidget(self.tracker_list) self.corner_layout.addWidget(self.tracker_list)
# Settings button
self.settings_btn = QtWidgets.QToolButton() self.settings_btn = QtWidgets.QToolButton()
self.settings_btn.setIconSize(QSize(21, 21)) self.settings_btn.setIconSize(QSize(21, 21))
self.settings_btn.setStyleSheet("background: transparent;") self.settings_btn.setStyleSheet("background: transparent;")
self.settings_btn.setToolTip("Settings")
self.settings_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.settings_btn.clicked.connect(lambda: settings_dialog(self))
self.corner_layout.addWidget(self.settings_btn)
# Adjust theme based on system preferences
if darkdetect.isDark(): if darkdetect.isDark():
settings_white_pixmap = QPixmap() settings_white_pixmap = QPixmap()
settings_white = base64.b64decode(settings_white_base64) settings_white = base64.b64decode(settings_white_base64)
@@ -185,11 +199,6 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
settings_black_pixmap.loadFromData(settings_black) settings_black_pixmap.loadFromData(settings_black)
self.settings_btn.setIcon(QIcon(settings_black_pixmap)) self.settings_btn.setIcon(QIcon(settings_black_pixmap))
self.settings_btn.setToolTip("Settings")
self.settings_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.settings_btn.clicked.connect(lambda: settings_dialog(self))
self.corner_layout.addWidget(self.settings_btn)
self.tab_wrapper = QWidget() self.tab_wrapper = QWidget()
self.tab_layout = QVBoxLayout() self.tab_layout = QVBoxLayout()
self.tab_layout.setContentsMargins(0, 0, 0, 0) self.tab_layout.setContentsMargins(0, 0, 0, 0)
@@ -221,6 +230,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.version = QLabel(f"Version: {state.version}") self.version = QLabel(f"Version: {state.version}")
self.statusbar.addPermanentWidget(self.version, Qt.AlignmentFlag.AlignLeft) self.statusbar.addPermanentWidget(self.version, Qt.AlignmentFlag.AlignLeft)
# (\u2193) Arrow down, (\u2191) Arrow up
self.speed_label = QLabel("\u2193 0.0 kB/s \u2191 0.0 kB/s") self.speed_label = QLabel("\u2193 0.0 kB/s \u2191 0.0 kB/s")
self.speed_label.setStyleSheet("padding-right: 6px;") self.speed_label.setStyleSheet("padding-right: 6px;")
self.statusbar.addPermanentWidget(self.speed_label) self.statusbar.addPermanentWidget(self.speed_label)
+2
View File
@@ -29,6 +29,7 @@ def get_active_interfaces():
def list_interfaces() -> None: def list_interfaces() -> None:
consoleLog("Fetching Network Interfaces...")
addrs = psutil.net_if_addrs() addrs = psutil.net_if_addrs()
stats = psutil.net_if_stats() stats = psutil.net_if_stats()
@@ -45,6 +46,7 @@ def list_interfaces() -> None:
consoleLog(f"Found Interface: {interface} [{status}]") consoleLog(f"Found Interface: {interface} [{status}]")
def init_interfaces(): def init_interfaces():
consoleLog("Initializing Interface variables...")
addrs = psutil.net_if_addrs() addrs = psutil.net_if_addrs()
state.interfaces = list(addrs.keys()) state.interfaces = list(addrs.keys())
state.active_interfaces = get_active_interfaces() state.active_interfaces = get_active_interfaces()
+1 -1
View File
@@ -1,3 +1,4 @@
from core.network.libtorrent_misc import cleanup_session
from core.utils.logging.logs import consoleLog from core.utils.logging.logs import consoleLog
from core.utils.data.state import state from core.utils.data.state import state
import os import os
@@ -5,7 +6,6 @@ import os
def closehelper(): def closehelper():
state.shutdown_event.set() state.shutdown_event.set()
try: try:
from core.network.libtorrent_misc import cleanup_session
cleanup_session() cleanup_session()
except Exception as e: except Exception as e:
consoleLog(f"Exception while cleaning up LibTorrent Session: {e}") consoleLog(f"Exception while cleaning up LibTorrent Session: {e}")
+8 -1
View File
@@ -1,2 +1,9 @@
from core.utils.logging.logs import consoleLog
def run_thread(thread): def run_thread(thread):
thread.start() target_name = thread._target.__name__
try:
thread.start()
consoleLog(f"Started Thread: {target_name}")
except Exception as e:
consoleLog(f"Exception while starting thread {target_name}: {e}")
+13 -10
View File
@@ -2,8 +2,10 @@ from core.network.libtorrent_misc import send_notification, update_log, check_de
from core.utils.logging.loghandler import split_data, check_completed, check_downloads from core.utils.logging.loghandler import split_data, check_completed, check_downloads
from core.network.interface import list_interfaces, init_interfaces from core.network.interface import list_interfaces, init_interfaces
from core.utils.logging.logs import get_download_logs from core.utils.logging.logs import get_download_logs
from core.utils.logging.logs import set_main_window
from core.utils.general.shutdown import closehelper from core.utils.general.shutdown import closehelper
from core.utils.general.wrappers import run_thread from core.utils.general.wrappers import run_thread
from core.utils.general.shutdown import force_exit
from core.utils.config.config import read_config from core.utils.config.config import read_config
from core.utils.logging.logs import consoleLog from core.utils.logging.logs import consoleLog
from core.interface.gui import MainWindow from core.interface.gui import MainWindow
@@ -22,44 +24,45 @@ def run_gui():
qdarktheme.setup_theme("auto") qdarktheme.setup_theme("auto")
widget = MainWindow() widget = MainWindow()
# Check OS for window transparency compatibility and apply
if state.window_transparency and platform.system() != "Windows": if state.window_transparency and platform.system() != "Windows":
widget.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) widget.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
qdarktheme.setup_theme("auto", custom_colors={"background": "#00000000"}) qdarktheme.setup_theme("auto", custom_colors={"background": "#00000000"})
from core.utils.logging.logs import set_main_window
set_main_window(widget) set_main_window(widget)
widget.show() widget.show()
sys.exit(app.exec()) sys.exit(app.exec())
def keyboardinterrupthandler(signum, frame): def keyboardinterrupthandler(signum, frame):
closehelper() closehelper()
from core.utils.general.shutdown import force_exit
force_exit() force_exit()
def main(): def main():
# Begin counting startup time
start_time = time.perf_counter() start_time = time.perf_counter()
# Parse saved files
read_config() read_config()
logs = get_download_logs() logs = get_download_logs()
_, downloads = split_data(logs) _, downloads = split_data(logs)
# Initialize Keyboardinterrupt signal
signal.signal(signal.SIGINT, keyboardinterrupthandler) signal.signal(signal.SIGINT, keyboardinterrupthandler)
consoleLog("Starting SoftwareManager...") consoleLog("Starting SoftwareManager...")
consoleLog("Fetching Network Interfaces...") # Get network interface info
list_interfaces() list_interfaces()
consoleLog("Initializing Interface variables...")
init_interfaces() init_interfaces()
consoleLog(f"Current Bound: {state.bound_interface}") consoleLog(f"Current Bound: {state.bound_interface}")
# Start background daemon threads
run_thread(threading.Thread(target=send_notification, args=(state.shutdown_event,), daemon=True)) run_thread(threading.Thread(target=send_notification, args=(state.shutdown_event,), daemon=True))
consoleLog("Started Thread: send_notification")
run_thread(threading.Thread(target=update_log, args=(state.shutdown_event,), daemon=True)) run_thread(threading.Thread(target=update_log, args=(state.shutdown_event,), daemon=True))
consoleLog("Started Thread: update_log")
run_thread(threading.Thread(target=check_completed, args=(downloads, state.autoresume)))
consoleLog("Started Thread: check_completed")
run_thread(threading.Thread(target=check_deleted_files, args=(state.shutdown_event,), daemon=True)) run_thread(threading.Thread(target=check_deleted_files, args=(state.shutdown_event,), daemon=True))
consoleLog("Started Thread: check_deleted_files") # Start background non-daemon threads
run_thread(threading.Thread(target=check_completed, args=(downloads, state.autoresume)))
run_thread(threading.Thread(target=check_downloads, args=(downloads,))) run_thread(threading.Thread(target=check_downloads, args=(downloads,)))
consoleLog("Started Thread: check_downloads") # Finish counting startup time
elapsed = time.perf_counter() - start_time elapsed = time.perf_counter() - start_time
consoleLog(f"Initialization completed in {elapsed:.2f}s. Launching GUI") consoleLog(f"Initialization completed in {elapsed:.2f}s. Launching GUI")
# Launch GUI
run_gui() run_gui()
if __name__ == "__main__": if __name__ == "__main__":