60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
"""
|
|
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
|
|
|
|
from core.scanner import scan_network
|
|
from utils.network import _resolve_hostname
|
|
|
|
|
|
class ScanThread(QThread):
|
|
"""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) # tên giai đoạn hiện tại
|
|
|
|
def __init__(self, network):
|
|
super().__init__()
|
|
self.network = network
|
|
|
|
def run(self):
|
|
try:
|
|
def on_ping_progress(done, total):
|
|
self.scan_progress.emit(done, total)
|
|
|
|
def on_stage(s):
|
|
self.stage.emit(s)
|
|
|
|
results = scan_network(self.network,
|
|
progress_cb=on_ping_progress,
|
|
stage_cb=on_stage)
|
|
|
|
# Resolve hostname song song
|
|
self.stage.emit("hostname")
|
|
with ThreadPoolExecutor(max_workers=50) as executor:
|
|
future_to_dev = {
|
|
executor.submit(_resolve_hostname, d["ip"]): d
|
|
for d in results
|
|
}
|
|
for future in as_completed(future_to_dev):
|
|
dev = future_to_dev[future]
|
|
try:
|
|
dev["name"] = future.result(timeout=3)
|
|
except Exception:
|
|
dev["name"] = ""
|
|
|
|
self.finished.emit(results)
|
|
except Exception as e:
|
|
self.error.emit(str(e))
|