mirror of
https://github.com/KeksPirates/SoftwareManager.git
synced 2026-08-04 01:49:42 +02:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b7188a515a | |||
| 7b2522438c | |||
| 0686c7aec2 | |||
| 6be1784903 | |||
| 4589322f0a |
@@ -13,6 +13,7 @@ from PySide6.QtWidgets import (
|
|||||||
QSpinBox,
|
QSpinBox,
|
||||||
QCheckBox,
|
QCheckBox,
|
||||||
QFileDialog,
|
QFileDialog,
|
||||||
|
QComboBox
|
||||||
)
|
)
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
@@ -56,7 +57,6 @@ def settings_dialog(self):
|
|||||||
|
|
||||||
autoresume_layout.addStretch()
|
autoresume_layout.addStretch()
|
||||||
autoresume_checkbox.setChecked(state.autoresume)
|
autoresume_checkbox.setChecked(state.autoresume)
|
||||||
autoresume_checkbox.toggled.connect(lambda checked: setattr(state, 'autoresume', checked))
|
|
||||||
autoresume_layout.addWidget(autoresume_checkbox)
|
autoresume_layout.addWidget(autoresume_checkbox)
|
||||||
dialog.layout().addWidget(autoresume_container)
|
dialog.layout().addWidget(autoresume_container)
|
||||||
|
|
||||||
@@ -206,6 +206,35 @@ def settings_dialog(self):
|
|||||||
max_downloads.setFixedHeight(30)
|
max_downloads.setFixedHeight(30)
|
||||||
dialog.layout().addWidget(max_downloads_container)
|
dialog.layout().addWidget(max_downloads_container)
|
||||||
|
|
||||||
|
#####################
|
||||||
|
# INTERFACE BINDING #
|
||||||
|
#####################
|
||||||
|
|
||||||
|
interface_container = QWidget()
|
||||||
|
interface_layout = QHBoxLayout()
|
||||||
|
|
||||||
|
interface_label = QLabel("Network Interface:")
|
||||||
|
interface_layout.addWidget(interface_label)
|
||||||
|
interface_select = QComboBox()
|
||||||
|
interface_select.addItems(["None"] + state.interfaces)
|
||||||
|
|
||||||
|
target = state.bound_interface if state.bound_interface else "None"
|
||||||
|
|
||||||
|
index = interface_select.findText(target)
|
||||||
|
if index >= 0:
|
||||||
|
interface_select.setCurrentIndex(index)
|
||||||
|
else:
|
||||||
|
interface_select.setCurrentIndex(0)
|
||||||
|
|
||||||
|
interface_select.setFixedWidth(180)
|
||||||
|
interface_select.setFixedHeight(30)
|
||||||
|
interface_select.setFixedWidth(180)
|
||||||
|
interface_select.setFixedHeight(30)
|
||||||
|
interface_layout.addWidget(interface_select)
|
||||||
|
interface_container.setLayout(interface_layout)
|
||||||
|
dialog.layout().addWidget(interface_container)
|
||||||
|
|
||||||
|
|
||||||
###############
|
###############
|
||||||
# SAVE/CANCEL #
|
# SAVE/CANCEL #
|
||||||
###############
|
###############
|
||||||
@@ -214,7 +243,17 @@ def settings_dialog(self):
|
|||||||
|
|
||||||
save_btn = QPushButton("Save")
|
save_btn = QPushButton("Save")
|
||||||
cancel_btn = QPushButton("Cancel")
|
cancel_btn = QPushButton("Cancel")
|
||||||
save_btn.clicked.connect(lambda: save_settings(close_settings, api_url.text(), download_path.text(), down_speed_limit.value(), up_speed_limit.value(), image_path.text(), None, max_connections.value(), max_downloads.value()))
|
save_btn.clicked.connect(lambda: save_settings(
|
||||||
|
close_settings,
|
||||||
|
api_url.text(),
|
||||||
|
download_path.text(),
|
||||||
|
down_speed_limit.value(),
|
||||||
|
up_speed_limit.value(),
|
||||||
|
image_path.text(),
|
||||||
|
autoresume_checkbox.isChecked(),
|
||||||
|
max_connections.value(),
|
||||||
|
max_downloads.value(),
|
||||||
|
interface_select.currentText()))
|
||||||
|
|
||||||
cancel_btn.clicked.connect(dialog.reject)
|
cancel_btn.clicked.connect(dialog.reject)
|
||||||
layout.addWidget(cancel_btn)
|
layout.addWidget(cancel_btn)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import libtorrent as lt
|
|||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
from core.utils.general.logs import consoleLog, remove_download_log
|
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
|
||||||
from core.utils.network.download import download_selected
|
from core.utils.network.download import download_selected
|
||||||
@@ -150,6 +150,8 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
|
|||||||
self.consoleLog = QTextEdit()
|
self.consoleLog = QTextEdit()
|
||||||
self.progressbar = QProgressBar()
|
self.progressbar = QProgressBar()
|
||||||
|
|
||||||
|
flush_log_buffer()
|
||||||
|
|
||||||
# Table Widget for Item List
|
# Table Widget for Item List
|
||||||
self.qtablewidget = QTableWidget()
|
self.qtablewidget = QTableWidget()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from core.utils.general.logs import consoleLog
|
from core.utils.general.logs import consoleLog
|
||||||
|
from core.utils.data.state import state
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
addrs = psutil.net_if_addrs()
|
addrs = psutil.net_if_addrs()
|
||||||
@@ -38,3 +39,14 @@ def list_interfaces() -> None:
|
|||||||
status = "INACTIVE"
|
status = "INACTIVE"
|
||||||
consoleLog(f"Found Interface: {interface} [{status}]")
|
consoleLog(f"Found Interface: {interface} [{status}]")
|
||||||
|
|
||||||
|
def init_interfaces():
|
||||||
|
state.interfaces = list(addrs.keys())
|
||||||
|
state.active_interfaces = get_active_interfaces()
|
||||||
|
|
||||||
|
def get_interface_ip(interface_name):
|
||||||
|
if interface_name in addrs:
|
||||||
|
for addr in addrs[interface_name]:
|
||||||
|
if addr.family == 2: # ipv4
|
||||||
|
if not addr.address.startswith("127.") and not addr.address.startswith("169.254"):
|
||||||
|
return addr.address
|
||||||
|
return None
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import time
|
import time
|
||||||
from core.utils.general.wrappers import run_thread
|
from core.utils.general.wrappers import run_thread
|
||||||
|
from core.network.interface import get_interface_ip
|
||||||
import threading
|
import threading
|
||||||
import libtorrent as lt
|
import libtorrent as lt
|
||||||
from core.utils.data.state import state
|
from core.utils.data.state import state
|
||||||
@@ -15,6 +16,7 @@ def init_session():
|
|||||||
|
|
||||||
state.dl_session = lt.session()
|
state.dl_session = lt.session()
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
@@ -27,7 +29,14 @@ def init_session():
|
|||||||
"active_downloads": state.max_downloads
|
"active_downloads": state.max_downloads
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if state.bound_interface:
|
||||||
|
interface_ip = get_interface_ip(state.bound_interface)
|
||||||
|
if interface_ip:
|
||||||
|
settings["outgoing_interfaces"] = interface_ip
|
||||||
|
settings["listen_interfaces"] = f"{interface_ip}:6881"
|
||||||
|
consoleLog(f"Binding to Interface IP: {interface_ip}")
|
||||||
|
else:
|
||||||
|
consoleLog(f"Error finding IP for Interface {state.bound_interface}")
|
||||||
|
|
||||||
state.dl_session.apply_settings(settings)
|
state.dl_session.apply_settings(settings)
|
||||||
|
|
||||||
@@ -45,7 +54,6 @@ def add_download(magnet_uri, dl_path=state.download_path):
|
|||||||
consoleLog("Skipping, download already running...")
|
consoleLog("Skipping, download already running...")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
magnetdl = lt.parse_magnet_uri(magnet_uri)
|
magnetdl = lt.parse_magnet_uri(magnet_uri)
|
||||||
magnetdl.save_path = dl_path
|
magnetdl.save_path = dl_path
|
||||||
|
|
||||||
@@ -99,5 +107,20 @@ def update_settings():
|
|||||||
"active_downloads": state.max_downloads
|
"active_downloads": state.max_downloads
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if state.bound_interface:
|
||||||
|
interface_ip = get_interface_ip(state.bound_interface)
|
||||||
|
if interface_ip:
|
||||||
|
settings["outgoing_interfaces"] = interface_ip
|
||||||
|
settings["listen_interfaces"] = f"{interface_ip}:6881"
|
||||||
|
consoleLog(f"Binding to Interface IP: {interface_ip}")
|
||||||
|
else:
|
||||||
|
consoleLog(f"Error finding IP for Interface {state.bound_interface}")
|
||||||
|
|
||||||
|
state.dl_session.apply_settings(settings)
|
||||||
|
|
||||||
|
def update_bound_interface():
|
||||||
|
|
||||||
|
settings = { "outgoing_interfaces": state.bound_interface }
|
||||||
|
|
||||||
state.dl_session.apply_settings(settings)
|
state.dl_session.apply_settings(settings)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from core.utils.general.logs import consoleLog
|
|||||||
from .config import create_config
|
from .config import create_config
|
||||||
|
|
||||||
|
|
||||||
def save_settings(close=lambda: None, apiurl=None, download_path=None, down_speed_limit=None, up_speed_limit=None, image_path=None, autoresume=None, max_connections=None, max_downloads=None):
|
def save_settings(close=lambda: None, apiurl=None, download_path=None, down_speed_limit=None, up_speed_limit=None, image_path=None, autoresume=None, max_connections=None, max_downloads=None, bound_interface=None):
|
||||||
if apiurl is not None:
|
if apiurl is not None:
|
||||||
state.api_url = apiurl
|
state.api_url = apiurl
|
||||||
if download_path is not None:
|
if download_path is not None:
|
||||||
@@ -21,6 +21,8 @@ def save_settings(close=lambda: None, apiurl=None, download_path=None, down_spee
|
|||||||
state.max_connections = max_connections
|
state.max_connections = max_connections
|
||||||
if max_downloads is not None:
|
if max_downloads is not None:
|
||||||
state.max_downloads = max_downloads
|
state.max_downloads = max_downloads
|
||||||
|
if bound_interface is not None:
|
||||||
|
state.bound_interface = None if bound_interface == "None" else bound_interface
|
||||||
|
|
||||||
|
|
||||||
update_settings()
|
update_settings()
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ class AppState(QObject):
|
|||||||
self.dl_session: Any = None
|
self.dl_session: Any = None
|
||||||
self.active_downloads: List[str] = {}
|
self.active_downloads: List[str] = {}
|
||||||
self.window_transparency: bool = False
|
self.window_transparency: bool = False
|
||||||
|
self.interfaces: List = []
|
||||||
|
self.active_interfaces: List = []
|
||||||
|
self.bound_interface: str = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image_path(self) -> str:
|
def image_path(self) -> str:
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import json
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
_log_buffer = []
|
||||||
|
|
||||||
|
|
||||||
def add_download_log(title, url, magnet_uri, completed) -> DownloadList:
|
def add_download_log(title, url, magnet_uri, completed) -> DownloadList:
|
||||||
downloads_file = os.path.join(state.settings_path, "downloads.json")
|
downloads_file = os.path.join(state.settings_path, "downloads.json")
|
||||||
@@ -189,15 +191,28 @@ def set_main_window(window):
|
|||||||
global _main_window
|
global _main_window
|
||||||
_main_window = window
|
_main_window = window
|
||||||
|
|
||||||
|
def flush_log_buffer(): # credits to claude
|
||||||
|
global _log_buffer
|
||||||
|
if _log_buffer:
|
||||||
|
try:
|
||||||
|
from core.interface.gui import MainWindow
|
||||||
|
for log_entry in _log_buffer:
|
||||||
|
MainWindow.add_log(log_entry)
|
||||||
|
_log_buffer = []
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def consoleLog(text, printAnyways = False):
|
def consoleLog(text, printAnyways = False):
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
current_time = now.strftime("%H:%M:%S")
|
current_time = now.strftime("%H:%M:%S")
|
||||||
|
formatted_text = f"[{current_time}] {text}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from core.interface.gui import MainWindow
|
from core.interface.gui import MainWindow
|
||||||
MainWindow.add_log(f"[{current_time}] {text}")
|
MainWindow.add_log(formatted_text)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
global _log_buffer
|
||||||
|
_log_buffer.append(formatted_text)
|
||||||
|
|
||||||
if state.debug or printAnyways:
|
if state.debug or printAnyways:
|
||||||
print(f"[{current_time}] {text}")
|
print(formatted_text)
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ from core.utils.general.logs import get_download_logs
|
|||||||
from core.utils.general.shutdown import closehelper, shutdown_event
|
from core.utils.general.shutdown import closehelper, shutdown_event
|
||||||
from core.utils.general.wrappers import run_thread
|
from core.utils.general.wrappers import run_thread
|
||||||
from core.utils.general.loghandler import split_data, check_completed
|
from core.utils.general.loghandler import split_data, check_completed
|
||||||
from core.network.interface import list_interfaces
|
from core.network.interface import list_interfaces, init_interfaces
|
||||||
|
from core.network.libtorrent_int import update_bound_interface
|
||||||
from core.utils.config.config import read_config
|
from core.utils.config.config import read_config
|
||||||
from PySide6 import QtWidgets
|
from PySide6 import QtWidgets
|
||||||
from PySide6.QtCore import Qt
|
from PySide6.QtCore import Qt
|
||||||
@@ -46,14 +47,18 @@ if __name__ == "__main__":
|
|||||||
if args.debug:
|
if args.debug:
|
||||||
state.debug = args.debug # override of read_config
|
state.debug = args.debug # override of read_config
|
||||||
signal.signal(signal.SIGINT, keyboardinterrupthandler)
|
signal.signal(signal.SIGINT, keyboardinterrupthandler)
|
||||||
run_thread(threading.Thread(target=send_notification, args=(shutdown_event,), daemon=True))
|
consoleLog("Starting SoftwareManager...")
|
||||||
consoleLog("Started send_notification thread")
|
|
||||||
run_thread(threading.Thread(target=update_log, args=(shutdown_event,), daemon=True))
|
|
||||||
consoleLog("Started update_log thread")
|
|
||||||
run_thread(threading.Thread(target=check_completed, args=(downloads, state.autoresume)))
|
|
||||||
consoleLog("Started check_completed thread")
|
|
||||||
consoleLog("Fetching Network Interfaces...")
|
consoleLog("Fetching Network Interfaces...")
|
||||||
list_interfaces()
|
list_interfaces()
|
||||||
|
consoleLog("Initialiting Interface variables...")
|
||||||
|
init_interfaces()
|
||||||
|
consoleLog(f"Current Bound: {state.bound_interface}")
|
||||||
|
run_thread(threading.Thread(target=send_notification, args=(shutdown_event,), daemon=True))
|
||||||
|
consoleLog("Started Thread: send_notification")
|
||||||
|
run_thread(threading.Thread(target=update_log, args=(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")
|
||||||
consoleLog("Launching GUI")
|
consoleLog("Launching GUI")
|
||||||
run_gui()
|
run_gui()
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
import psutil
|
|
||||||
|
|
||||||
addrs = psutil.net_if_addrs()
|
|
||||||
stats = psutil.net_if_stats()
|
|
||||||
|
|
||||||
|
|
||||||
def get_active_interfaces():
|
|
||||||
active = []
|
|
||||||
|
|
||||||
for interface, addr_list in addrs.items():
|
|
||||||
up = stats[interface].isup
|
|
||||||
for addr in addr_list:
|
|
||||||
if addr.family == 2: # ipv4
|
|
||||||
ipv4 = addr.address
|
|
||||||
if not ipv4.startswith("127.") and not ipv4.startswith("169.254") and up == True:
|
|
||||||
print(f'"{interface}": True')
|
|
||||||
active.append(interface)
|
|
||||||
print(active)
|
|
||||||
return active
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
get_active_interfaces()
|
|
||||||
|
|
||||||
# print(addrs)
|
|
||||||
# print()
|
|
||||||
# sigmer = list()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# for interface in stats.keys():
|
|
||||||
# print(f"{interface}: UP = {stats[interface].isup}")
|
|
||||||
# sigmer.append(f"{interface}: {stats[interface].isup}")
|
|
||||||
|
|
||||||
# print(sigmer)
|
|
||||||
Reference in New Issue
Block a user