Compare commits

...

11 Commits

6 changed files with 82 additions and 31 deletions
+3 -3
View File
@@ -24,7 +24,7 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- os: ubuntu-latest - os: ubuntu-22.04
artifact_name: SoftwareManager-dev-${{ github.sha }}-linux artifact_name: SoftwareManager-dev-${{ github.sha }}-linux
asset_name: SoftwareManager-dev-${{ github.sha }}-linux asset_name: SoftwareManager-dev-${{ github.sha }}-linux
- os: windows-latest - os: windows-latest
@@ -159,7 +159,7 @@ jobs:
release: release:
name: Create Release name: Create Release
needs: build needs: build
runs-on: ubuntu-latest runs-on: ubuntu-22.04
if: success() if: success()
steps: steps:
@@ -172,7 +172,7 @@ jobs:
run: | run: |
mkdir -p release mkdir -p release
SHORT_SHA="${{ needs.build.outputs.short_sha }}" SHORT_SHA="${{ needs.build.outputs.short_sha }}"
cp artifacts/ubuntu-latest-build/SoftwareManager-dev-*-linux release/SoftwareManager-dev-${SHORT_SHA}-linux cp artifacts/ubuntu-22.04-build/SoftwareManager-dev-*-linux release/SoftwareManager-dev-${SHORT_SHA}-linux
cp artifacts/windows-latest-build/SoftwareManager-dev-*-windows.exe release/SoftwareManager-dev-${SHORT_SHA}-windows.exe cp artifacts/windows-latest-build/SoftwareManager-dev-*-windows.exe release/SoftwareManager-dev-${SHORT_SHA}-windows.exe
cp artifacts/macos-latest-build/SoftwareManager-dev-*-macos release/SoftwareManager-dev-${SHORT_SHA}-macos cp artifacts/macos-latest-build/SoftwareManager-dev-*-macos release/SoftwareManager-dev-${SHORT_SHA}-macos
chmod +x release/SoftwareManager-dev-*-linux release/SoftwareManager-dev-*-macos chmod +x release/SoftwareManager-dev-*-linux release/SoftwareManager-dev-*-macos
+3
View File
@@ -13,6 +13,7 @@ from PySide6.QtWidgets import (
QSpinBox, QSpinBox,
QCheckBox, QCheckBox,
) )
import platform
def settings_dialog(self): def settings_dialog(self):
@@ -32,6 +33,8 @@ def settings_dialog(self):
update_checkbox_layout = QHBoxLayout() update_checkbox_layout = QHBoxLayout()
# ignore updates checkbox # ignore updates checkbox
if platform.system() == "Windows":
update_checkbox = QCheckBox() update_checkbox = QCheckBox()
update_checkbox_container.setLayout(update_checkbox_layout) update_checkbox_container.setLayout(update_checkbox_layout)
update_checkbox_layout.addWidget(QLabel("Ignore Updates: ")) update_checkbox_layout.addWidget(QLabel("Ignore Updates: "))
+45 -15
View File
@@ -20,7 +20,7 @@ from PySide6.QtWidgets import (
QStyleOptionButton, QStyleOptionButton,
QStyledItemDelegate, QStyledItemDelegate,
QApplication, QApplication,
) )
from PySide6.QtGui import QIcon, QAction, QCloseEvent, QImage, QPixmap from PySide6.QtGui import QIcon, QAction, QCloseEvent, QImage, QPixmap
import darkdetect import darkdetect
@@ -93,8 +93,8 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
if platform.system() == "Windows": if platform.system() == "Windows":
try: try:
import ctypes import ctypes
myappid = 'SoftwareManager.App.1' appid = 'SoftwareManager'
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(appid)
except Exception as e: except Exception as e:
consoleLog(f"Could not set app ID: {e}") consoleLog(f"Could not set app ID: {e}")
@@ -147,6 +147,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.downloadList = QTableView() self.downloadList = QTableView()
self.emptyLibrary = QLabel("No items in library.") self.emptyLibrary = QLabel("No items in library.")
self.emptyDownload = QLabel("No items in downloads.") self.emptyDownload = QLabel("No items in downloads.")
self.emptyDownload.setAlignment(Qt.AlignCenter)
self.consoleLog = QTextEdit() self.consoleLog = QTextEdit()
self.progressbar = QProgressBar() self.progressbar = QProgressBar()
@@ -199,7 +200,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
col = index.column() col = index.column()
if col == 0: if col == 0:
return "Resume" if download.is_paused else "Pause" return "▶︎" if download.is_paused else "⏸︎"
elif col == 1: elif col == 1:
return download.name return download.name
elif col == 2: elif col == 2:
@@ -209,9 +210,11 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
elif col == 4: elif col == 4:
return f"{download.download_speed_string()}" return f"{download.download_speed_string()}"
elif col == 5: elif col == 5:
pass return f"{download.completed_length_string()}"
elif col == 6: elif col == 6:
return f"{download.total_length_string()}" return f"{download.total_length_string()}"
elif col == 7:
return f"{download.eta_string()}"
if role == Qt.UserRole and col == 0: if role == Qt.UserRole and col == 0:
return download.is_paused return download.is_paused
@@ -220,12 +223,27 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
def toggle_pause_resume(self, row): def toggle_pause_resume(self, row):
download = state.downloads[row] download = state.downloads[row]
if download.progress == 100:
if state.download_path is not None and os.path.exists(state.download_path):
if platform.system() == "Windows":
os.startfile(os.path.normpath(state.download_path))
elif platform.system() == "Linux":
subprocess.Popen(["xdg-open", state.download_path])
else:
if platform.system() == "Windows":
os.startfile(os.path.normpath(os.getcwd()))
elif platform.system() == "Linux":
subprocess.Popen(["xdg-open", os.getcwd()])
return
if download.is_paused: if download.is_paused:
download.resume() download.resume()
consoleLog(f"Resumed download: {download.name}", True)
else: else:
download.pause() download.pause()
consoleLog(f"Paused download: {download.name}", True)
idx = self.index(row, 0) idx = self.index(row, 0)
self.dataChanged.emit(idx, idx, [Qt.DisplayRole, Qt.UserRole]) self.dataChanged.emit(idx, idx, [Qt.ItemDataRole.DisplayRole, Qt.ItemDataRole.UserRole])
class PauseResumeDelegate(QStyledItemDelegate): class PauseResumeDelegate(QStyledItemDelegate):
clicked = Signal(int) clicked = Signal(int)
@@ -236,10 +254,16 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
return return
paused = index.data(Qt.UserRole) paused = index.data(Qt.UserRole)
download = state.downloads[index.row()]
button = QStyleOptionButton() button = QStyleOptionButton()
button.rect = option.rect button.rect = option.rect
button.text = "Resume" if paused else "Pause"
if download.progress == 100:
button.text = "📁"
else:
button.text = "▶︎" if paused else "⏸︎"
button.state = QStyle.State_Enabled button.state = QStyle.State_Enabled
QApplication.style().drawControl( QApplication.style().drawControl(
@@ -255,7 +279,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.download_model = DownloadModel() self.download_model = DownloadModel()
self.downloadList.setModel(self.download_model) self.downloadList.setModel(self.download_model)
self.downloadList.horizontalHeader().setStretchLastSection(False) self.downloadList.horizontalHeader().setStretchLastSection(False)
self.downloadList.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.downloadList.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
self.downloadList.setSelectionBehavior(QTableView.SelectRows) self.downloadList.setSelectionBehavior(QTableView.SelectRows)
self.downloadList.setAttribute(Qt.WA_TranslucentBackground) self.downloadList.setAttribute(Qt.WA_TranslucentBackground)
self.downloadList.viewport().setAttribute(Qt.WA_TranslucentBackground) self.downloadList.viewport().setAttribute(Qt.WA_TranslucentBackground)
@@ -265,12 +289,6 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
def on_pause_resume_clicked(row): def on_pause_resume_clicked(row):
download_model.toggle_pause_resume(row) download_model.toggle_pause_resume(row)
download = state.downloads[row]
if download.is_paused:
download.pause()
else:
download.resume()
delegate = PauseResumeDelegate(self.downloadList) delegate = PauseResumeDelegate(self.downloadList)
self.downloadList.setItemDelegateForColumn(0, delegate) self.downloadList.setItemDelegateForColumn(0, delegate)
delegate.clicked.connect(on_pause_resume_clicked) delegate.clicked.connect(on_pause_resume_clicked)
@@ -345,6 +363,10 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.download_timer.timeout.connect(lambda: run_thread(threading.Thread(target=self.download_list_update))) self.download_timer.timeout.connect(lambda: run_thread(threading.Thread(target=self.download_list_update)))
self.download_timer.start(500) self.download_timer.start(500)
self.active_timer = QTimer()
self.active_timer.timeout.connect(self.show_empty_downloads)
self.active_timer.start(500)
@staticmethod @staticmethod
def add_log(text): def add_log(text):
if MainWindow._instance: if MainWindow._instance:
@@ -368,6 +390,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.download_model.layoutAboutToBeChanged.emit() self.download_model.layoutAboutToBeChanged.emit()
self.download_model.layoutChanged.emit() self.download_model.layoutChanged.emit()
def closeEvent(self, event: QCloseEvent): def closeEvent(self, event: QCloseEvent):
closehelper() closehelper()
event.accept() event.accept()
@@ -384,9 +407,16 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.qtablewidget.hide() self.qtablewidget.hide()
self.emptyResults.show() self.emptyResults.show()
else: else:
self.emptyResults.hide()
self.qtablewidget.show() self.qtablewidget.show()
self.emptyResults.hide()
def show_empty_downloads(self):
if len(state.downloads) > 0:
self.emptyDownload.hide()
self.downloadList.show()
else:
self.emptyDownload.show()
self.downloadList.hide()
# thank you claude # thank you claude
def resizeEvent(self, event): def resizeEvent(self, event):
+16
View File
@@ -4,6 +4,7 @@ from core.utils.data.state import state
from core.utils.general.logs import update_download_completed_by_hash from core.utils.general.logs import update_download_completed_by_hash
from core.utils.general.logs import consoleLog from core.utils.general.logs import consoleLog
from plyer import notification from plyer import notification
import socket
import time import time
import sys import sys
@@ -42,6 +43,21 @@ def aria2server():
stderr=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0 creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0
) )
max_checks = 50
for check in range(max_checks):
try:
sock = socket.socket()
sock.settimeout(0.1)
sock.connect(("localhost", 6800))
sock.close()
break
except(ConnectionRefusedError, socket.timeout):
time.sleep(0.1)
else:
raise RuntimeError("Aria2 Server failed to start")
consoleLog("Aria2 Server started")
return aria2server return aria2server
def dlprogress(): def dlprogress():
+3
View File
@@ -8,8 +8,11 @@ def start_client():
consoleLog("Started Aria2p") consoleLog("Started Aria2p")
def add_magnet(uri): def add_magnet(uri):
if uri is not None and uri.startswith("magnet:?"):
aria2.add_magnet(uri) aria2.add_magnet(uri)
consoleLog("Magnet URI added to Aria2") consoleLog("Magnet URI added to Aria2")
else:
consoleLog(f"Invalid Magnet Link: {uri}")
-1
View File
@@ -1,4 +1,3 @@
from core.utils.data.state import state
from core.utils.general.logs import consoleLog from core.utils.general.logs import consoleLog
from core.utils.network.download import run_download_direct from core.utils.network.download import run_download_direct