Compare commits

...

11 Commits

7 changed files with 105 additions and 104 deletions
+10 -26
View File
@@ -44,30 +44,22 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v6
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ env.PYTHON_VERSION }}
- name: Install system dependencies (Linux) - name: Install uv
if: runner.os == 'Linux' uses: astral-sh/setup-uv@v7
run: | with:
sudo apt-get update version: "0.9.7"
sudo apt-get install -y \ enable-cache: true
libxcb-xinerama0 \
libxkbcommon-x11-0 \
libxcb-cursor0 \
libxcb-keysyms1 \
libxcb-render-util0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-shape0 \
libxcb-util1
- name: Install Python dependencies - name: Install Python dependencies
run: | run: |
python -m pip install --upgrade pip uv pip install -r requirements.txt
pip install -r requirements.txt uv pip install pyinstaller backports.tarfile pillow
pip install pyinstaller backports.tarfile pillow env:
UV_SYSTEM_PYTHON: 1
- name: Generate version - name: Generate version
id: version id: version
@@ -90,13 +82,6 @@ jobs:
} }
EOF EOF
- name: Download aria2c (Windows)
if: runner.os == 'Windows'
run: |
mkdir -p deps
C:\msys64\usr\bin\wget.exe https://github.com/aria2/aria2/releases/download/release-1.37.0/aria2-1.37.0-win-64bit-build1.zip
unzip -j aria2-1.37.0-win-64bit-build1.zip aria2-1.37.0-win-64bit-build1/aria2c.exe -d deps/
- name: Build executable with PyInstaller (Windows) - name: Build executable with PyInstaller (Windows)
if: runner.os == 'Windows' if: runner.os == 'Windows'
shell: bash shell: bash
@@ -105,7 +90,6 @@ jobs:
--add-data "build_info.json;." \ --add-data "build_info.json;." \
--add-data "build_info.json;core" \ --add-data "build_info.json;core" \
--add-data "build_info.json;core/interface" \ --add-data "build_info.json;core/interface" \
--add-data "deps/aria2c.exe;." \
--add-data "core/interface/assets;core/interface/assets" \ --add-data "core/interface/assets;core/interface/assets" \
--icon "core/interface/assets/logo.png" \ --icon "core/interface/assets/logo.png" \
--exclude-module PyQt6 \ --exclude-module PyQt6 \
+24 -50
View File
@@ -60,31 +60,6 @@ def settings_dialog(self):
autoresume_layout.addWidget(autoresume_checkbox) autoresume_layout.addWidget(autoresume_checkbox)
dialog.layout().addWidget(autoresume_container) dialog.layout().addWidget(autoresume_container)
#####################
# DOWNLOAD SETTINGS #
#####################
thread_box = QSpinBox()
thread_box.setMinimum(1)
thread_box.setMaximum(16)
thread_box.setValue(state.aria2_threads)
# container for tight space
thread_container = QWidget()
thread_layout = QHBoxLayout()
thread_layout.addWidget(QLabel("Threads:"))
thread_layout.addWidget(thread_box)
thread_container.setLayout(thread_layout)
thread_container.setMaximumHeight(80)
# Dimensions
thread_box.setFixedWidth(90)
thread_box.setFixedHeight(30)
dialog.layout().addWidget(thread_container)
################## ##################
# SERVER SETTING # # SERVER SETTING #
################## ##################
@@ -124,6 +99,30 @@ def settings_dialog(self):
download_path_layout.addWidget(browse_button) download_path_layout.addWidget(browse_button)
browse_button.clicked.connect(browse_download_path) browse_button.clicked.connect(browse_download_path)
###############
# IMAGE PATH #
###############
image_path_container = QWidget()
image_path_layout = QHBoxLayout()
image_path = QLineEdit()
image_path_layout.addWidget(QLabel("Image Path (requires restart):"))
image_path_layout.addWidget(image_path)
image_path_container.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
image_path_container.setLayout(image_path_layout)
image_path.setText(state.image_path)
dialog.layout().addWidget(image_path_container)
def browse_image_path():
file_path = QFileDialog.getOpenFileName(dialog, "Select Image File", state.image_path, "Image Files (*.png *.jpg)")[0]
if file_path:
image_path.setText(file_path)
browse_button = QPushButton("📁")
image_path_layout.addWidget(browse_button)
browse_button.clicked.connect(browse_image_path)
################## ##################
# SPEED LIMITING # # SPEED LIMITING #
################## ##################
@@ -192,31 +191,6 @@ def settings_dialog(self):
max_downloads.setFixedHeight(30) max_downloads.setFixedHeight(30)
dialog.layout().addWidget(max_downloads_container) dialog.layout().addWidget(max_downloads_container)
###############
# IMAGE PATH #
###############
image_path_container = QWidget()
image_path_layout = QHBoxLayout()
image_path = QLineEdit()
image_path_layout.addWidget(QLabel("Image Path (requires restart):"))
image_path_layout.addWidget(image_path)
image_path_container.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
image_path_container.setLayout(image_path_layout)
image_path.setText(state.image_path)
dialog.layout().addWidget(image_path_container)
def browse_image_path():
file_path = QFileDialog.getOpenFileName(dialog, "Select Image File", state.image_path, "Image Files (*.png *.jpg)")[0]
if file_path:
image_path.setText(file_path)
browse_button = QPushButton("📁")
image_path_layout.addWidget(browse_button)
browse_button.clicked.connect(browse_image_path)
############### ###############
# SAVE/CANCEL # # SAVE/CANCEL #
############### ###############
+61 -22
View File
@@ -1,5 +1,5 @@
from PySide6 import QtWidgets from PySide6 import QtWidgets
from PySide6.QtCore import Qt, QTimer, QModelIndex, QAbstractTableModel, Signal, QEvent from PySide6.QtCore import Qt, QTimer, QModelIndex, QAbstractTableModel, Signal, QEvent, QSize
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QLineEdit, QLineEdit,
QTableView, QTableView,
@@ -161,6 +161,8 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.qtablewidget.verticalHeader().setVisible(False) self.qtablewidget.verticalHeader().setVisible(False)
self.qtablewidget.setHorizontalHeaderLabels(["Post Title", "Author"]) self.qtablewidget.setHorizontalHeaderLabels(["Post Title", "Author"])
header = self.qtablewidget.horizontalHeader() header = self.qtablewidget.horizontalHeader()
header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(0, QHeaderView.Stretch)
header.setSectionResizeMode(1, QHeaderView.Fixed) header.setSectionResizeMode(1, QHeaderView.Fixed)
@@ -197,6 +199,9 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
def data(self, index, role=Qt.DisplayRole): def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole: if role == Qt.DisplayRole:
col = index.column() col = index.column()
if index.row() >= len(state.active_downloads) or index.row() < 0:
return None
magnet_link = list(state.active_downloads.keys())[index.row()] magnet_link = list(state.active_downloads.keys())[index.row()]
magnetdl = state.active_downloads[magnet_link] magnetdl = state.active_downloads[magnet_link]
@@ -263,6 +268,10 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
return None return None
def toggle_pause_resume(self, row): def toggle_pause_resume(self, row):
if row >= len(state.active_downloads) or row < 0:
return
magnet_link = list(state.active_downloads.keys())[row] magnet_link = list(state.active_downloads.keys())[row]
magnetdl = state.active_downloads[magnet_link] magnetdl = state.active_downloads[magnet_link]
status = magnetdl.status() status = magnetdl.status()
@@ -291,10 +300,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
clicked = Signal(int) clicked = Signal(int)
def setEditorData(self, editor, index): def setEditorData(self, editor, index):
download = state.downloads[index.row()]
button = editor.findChild(QtWidgets.QPushButton) button = editor.findChild(QtWidgets.QPushButton)
paused = index.data(Qt.UserRole)
magnet_link = list(state.active_downloads.keys())[index.row()] magnet_link = list(state.active_downloads.keys())[index.row()]
magnetdl = state.active_downloads[magnet_link] magnetdl = state.active_downloads[magnet_link]
@@ -306,10 +312,10 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
else: else:
button.setText("▶︎" if status.paused else "⏸︎") button.setText("▶︎" if status.paused else "⏸︎")
def createEditor(self, parent, option, index): def createEditor(self, parent, option, index):
download = state.downloads[index.row()] magnet_link = list(state.active_downloads.keys())[index.row()]
magnetdl = state.active_downloads[magnet_link]
status = magnetdl.status()
widget = QWidget(parent) widget = QWidget(parent)
widget.setStyleSheet("border: none;") widget.setStyleSheet("border: none;")
@@ -358,7 +364,13 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
# Tabs # Tabs
self.tabs = QTabWidget() self.tabs = QTabWidget()
self.tabs.setStyleSheet("""
QTabBar::tab {
font-size: 11px;
padding: 2px 8px;
height: 25px;
}
""")
self.horizontal_layout = QHBoxLayout() self.horizontal_layout = QHBoxLayout()
self.horizontal_layout.addWidget(self.emptyResults, stretch=3) self.horizontal_layout.addWidget(self.emptyResults, stretch=3)
self.horizontal_layout.addWidget(self.qtablewidget) self.horizontal_layout.addWidget(self.qtablewidget)
@@ -381,33 +393,60 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
y = self.height() - self.overlay_label.height() - offset_y y = self.height() - self.overlay_label.height() - offset_y
self.overlay_label.move(x, y) self.overlay_label.move(x, y)
# temporarily disabled # temporarily disabled
# state.image_changed.connect(self.update_image_overlay) # state.image_changed.connect(self.update_image_overlay)
containerLayout.addWidget(self.tabs)
self.corner_widget = QWidget()
self.corner_layout = QHBoxLayout(self.corner_widget)
self.corner_layout.setContentsMargins(0, 0, 0, 0)
containerLayout.setAlignment(Qt.AlignmentFlag.AlignBottom)
toolbar = QToolBar("Main Toolbar")
self.addToolBar(toolbar)
toolbar.setLayoutDirection(Qt.RightToLeft)
self.tracker_list = QComboBox() self.tracker_list = QComboBox()
self.tracker_list.addItems(["rutracker", "uztracker", "m0nkrus"]) self.tracker_list.addItems(["rutracker", "uztracker", "m0nkrus"])
self.tracker_list.activated.connect(self.set_tracker) self.tracker_list.activated.connect(self.set_tracker)
self.corner_layout.addWidget(self.tracker_list)
self.settings_btn = QtWidgets.QToolButton()
self.settings_btn.setIconSize(QSize(21, 21))
self.settings_btn.setStyleSheet("background: transparent;")
if darkdetect.isDark(): if darkdetect.isDark():
settings_action = QAction(QIcon(get_asset_path("settings_white.png")), "Settings", self) self.settings_btn.setIcon(QIcon(get_asset_path("settings_white.png")))
else: else:
settings_action = QAction(QIcon(get_asset_path("settings_black.png")), "Settings", self) self.settings_btn.setIcon(QIcon(get_asset_path("settings_black.png")))
self.settings_btn.setToolTip("Settings")
self.settings_btn.clicked.connect(lambda: settings_dialog(self))
settings_action.triggered.connect(lambda: settings_dialog(self))
toolbar.addAction(settings_action)
toolbar.addWidget(self.tracker_list)
toolbar.setMovable(False)
self.corner_layout.addWidget(self.settings_btn)
self.tab_wrapper = QWidget()
self.tab_layout = QVBoxLayout()
self.tab_layout.setContentsMargins(0, 0, 0, 0)
self.tab_layout.setSpacing(0)
self.tab_bar_layout = QHBoxLayout()
self.tab_bar_layout.setContentsMargins(0, 0, 0, 0)
self.tab_bar_layout.setSpacing(0)
self.tab_bar_layout.addWidget(self.tabs.tabBar(), stretch=0)
self.tab_bar_layout.addStretch()
self.tab_bar_layout.addWidget(self.corner_widget, stretch=0)
self.tab_layout.addLayout(self.tab_bar_layout)
self.tab_layout.addWidget(self.tabs)
self.tab_wrapper.setLayout(self.tab_layout)
containerLayout.addWidget(self.tab_wrapper)
containerLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
# self.progressbar.setValue(0)
self.consoleLog.setReadOnly(True) self.consoleLog.setReadOnly(True)
self.consoleLog.setFixedHeight(150) self.consoleLog.setFixedHeight(150)
containerLayout.addWidget(self.consoleLog) containerLayout.addWidget(self.consoleLog)
@@ -475,4 +514,4 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
def resizeEvent(self, event): def resizeEvent(self, event):
super().resizeEvent(event) super().resizeEvent(event)
table_width = self.qtablewidget.viewport().width() table_width = self.qtablewidget.viewport().width()
self.qtablewidget.setColumnWidth(1, int(table_width * 0.3)) self.qtablewidget.setColumnWidth(1, int(table_width * 0.3))
+1 -1
View File
@@ -12,6 +12,6 @@ def create_tab(title, searchbar, software_list, tabs, dlbutton, layout2):
layout.addWidget(software_list) layout.addWidget(software_list)
if dlbutton: if dlbutton:
layout.addWidget(dlbutton) layout.addWidget(dlbutton)
tab.setLayout(layout) tab.setLayout(layout)
tabs.addTab(tab, title) tabs.addTab(tab, title)
return tab return tab
+4 -1
View File
@@ -89,6 +89,9 @@ def dl_status_loop():
def update_settings(): def update_settings():
if state.dl_session is None:
return
settings = { settings = {
"upload_rate_limit": state.up_speed_limit, "upload_rate_limit": state.up_speed_limit,
"download_rate_limit": state.down_speed_limit, "download_rate_limit": state.down_speed_limit,
@@ -97,4 +100,4 @@ def update_settings():
} }
state.dl_session.apply_settings(settings) state.dl_session.apply_settings(settings)
consoleLog("Updated Settings")
+5
View File
@@ -1,4 +1,6 @@
from core.network.libtorrent_int import update_settings
from core.utils.data.state import state from core.utils.data.state import state
from core.utils.general.logs import consoleLog
from .config import create_config from .config import create_config
@@ -20,5 +22,8 @@ def save_settings(close=lambda: None, apiurl=None, download_path=None, down_spee
if max_downloads is not None: if max_downloads is not None:
state.max_downloads = max_downloads state.max_downloads = max_downloads
update_settings()
consoleLog("Saved Settings")
create_config() create_config()
close() close()
-4
View File
@@ -23,10 +23,6 @@ class AppState(QObject):
self.down_speed_limit: int = 0 self.down_speed_limit: int = 0
self.max_connections: int = 200 self.max_connections: int = 200
self.max_downloads: int = 10 self.max_downloads: int = 10
self.aria2process: Optional[Any] = None
self.aria2: Any = None
self.aria2p: Any = None
self.aria2_threads: int = 4
self.settings_path: str = None self.settings_path: str = None
self.dl_session: Any = None self.dl_session: Any = None
self.active_downloads: List[str] = {} self.active_downloads: List[str] = {}