refactor code, ẩn thông tin ssh

This commit is contained in:
2026-03-09 11:59:55 +07:00
parent 9f6bd8c35a
commit 1297511122
13 changed files with 1043 additions and 504 deletions

View File

@@ -1,18 +1,28 @@
"""
Workers module — chứa các QThread dùng cho tác vụ nền.
Scan:
ScanThread — quét mạng LAN tìm thiết bị OpenWrt.
Flash (tách thành 2 module riêng):
core.flash_new_worker → NewFlashThread (Nạp Mới FW)
core.flash_update_worker → UpdateFlashThread (Update FW)
"""
from PyQt6.QtCore import QThread, pyqtSignal
from concurrent.futures import ThreadPoolExecutor, as_completed
# We need these imports inside workers since they use them
from core.scanner import scan_network
from core.flasher import flash_device
from core.ssh_flasher import flash_device_ssh
from utils.network import _resolve_hostname
class ScanThread(QThread):
"""Run network scan in a background thread so UI doesn't freeze."""
finished = pyqtSignal(list)
error = pyqtSignal(str)
"""Quét mạng LAN trong background thread để không đóng băng UI."""
finished = pyqtSignal(list)
error = pyqtSignal(str)
scan_progress = pyqtSignal(int, int) # done, total (ping sweep)
stage = pyqtSignal(str) # current scan phase
stage = pyqtSignal(str) # tên giai đoạn hiện tại
def __init__(self, network):
super().__init__()
@@ -29,7 +39,8 @@ class ScanThread(QThread):
results = scan_network(self.network,
progress_cb=on_ping_progress,
stage_cb=on_stage)
# Resolve hostnames in parallel
# Resolve hostname song song
self.stage.emit("hostname")
with ThreadPoolExecutor(max_workers=50) as executor:
future_to_dev = {
@@ -42,61 +53,7 @@ class ScanThread(QThread):
dev["name"] = future.result(timeout=3)
except Exception:
dev["name"] = ""
self.finished.emit(results)
except Exception as e:
self.error.emit(str(e))
class FlashThread(QThread):
"""Run firmware flash in background so UI stays responsive."""
device_status = pyqtSignal(int, str) # index, status message
device_done = pyqtSignal(int, str) # index, result
all_done = pyqtSignal()
def __init__(self, devices, firmware_path, max_workers=10,
method="api", ssh_user="root", ssh_password="admin123a",
ssh_backup_password="", set_passwd=False):
super().__init__()
self.devices = devices
self.firmware_path = firmware_path
self.max_workers = max_workers
self.method = method
self.ssh_user = ssh_user
self.ssh_password = ssh_password
self.ssh_backup_password = ssh_backup_password
self.set_passwd = set_passwd
def run(self):
def _flash_one(i, dev):
try:
def on_status(msg):
self.device_status.emit(i, msg)
if self.method == "ssh":
result = flash_device_ssh(
dev["ip"], self.firmware_path,
user=self.ssh_user,
password=self.ssh_password,
backup_password=self.ssh_backup_password,
set_passwd=self.set_passwd,
status_cb=on_status
)
else:
result = flash_device(
dev["ip"], self.firmware_path,
status_cb=on_status
)
self.device_done.emit(i, result)
except Exception as e:
self.device_done.emit(i, f"FAIL: {e}")
# Use configured max_workers (0 = unlimited = one per device)
workers = self.max_workers if self.max_workers > 0 else len(self.devices)
with ThreadPoolExecutor(max_workers=workers) as executor:
futures = []
for i, dev in enumerate(self.devices):
futures.append(executor.submit(_flash_one, i, dev))
for f in futures:
f.result()
self.all_done.emit()