✨feature: Scan progress and timing features
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from .db import get_conn
|
||||
@@ -13,19 +14,73 @@ class ScanState:
|
||||
self._lock = threading.Lock()
|
||||
self.running = False
|
||||
self.current_scan_id: int | None = None
|
||||
self.subnet: str | None = None
|
||||
self.total_hosts = 0
|
||||
self.processed_hosts = 0
|
||||
self.saved_hosts = 0
|
||||
self.current_host: str | None = None
|
||||
self.started_monotonic: float | None = None
|
||||
|
||||
def start(self, scan_id: int) -> bool:
|
||||
def start(self, scan_id: int, subnet: str) -> bool:
|
||||
with self._lock:
|
||||
if self.running:
|
||||
return False
|
||||
self.running = True
|
||||
self.current_scan_id = scan_id
|
||||
self.subnet = subnet
|
||||
self.total_hosts = 0
|
||||
self.processed_hosts = 0
|
||||
self.saved_hosts = 0
|
||||
self.current_host = None
|
||||
self.started_monotonic = time.monotonic()
|
||||
return True
|
||||
|
||||
def set_total_hosts(self, total_hosts: int) -> None:
|
||||
with self._lock:
|
||||
self.total_hosts = max(total_hosts, 0)
|
||||
|
||||
def set_current_host(self, host_ip: str | None) -> None:
|
||||
with self._lock:
|
||||
self.current_host = host_ip
|
||||
|
||||
def update_progress(self, processed_hosts: int, saved_hosts: int) -> None:
|
||||
with self._lock:
|
||||
self.processed_hosts = max(processed_hosts, 0)
|
||||
self.saved_hosts = max(saved_hosts, 0)
|
||||
|
||||
def finish(self) -> None:
|
||||
with self._lock:
|
||||
self.running = False
|
||||
self.current_scan_id = None
|
||||
self.current_host = None
|
||||
self.started_monotonic = None
|
||||
|
||||
def snapshot(self) -> dict:
|
||||
with self._lock:
|
||||
percent = 0
|
||||
if self.total_hosts > 0:
|
||||
percent = int((self.processed_hosts / self.total_hosts) * 100)
|
||||
|
||||
elapsed_seconds = 0
|
||||
eta_seconds = None
|
||||
if self.running and self.started_monotonic is not None:
|
||||
elapsed_seconds = int(max(time.monotonic() - self.started_monotonic, 0))
|
||||
if self.processed_hosts > 0 and self.total_hosts > self.processed_hosts:
|
||||
rate = self.processed_hosts / max(elapsed_seconds, 1)
|
||||
remaining = self.total_hosts - self.processed_hosts
|
||||
eta_seconds = int(remaining / max(rate, 1e-9))
|
||||
return {
|
||||
"running": self.running,
|
||||
"scan_id": self.current_scan_id,
|
||||
"subnet": self.subnet,
|
||||
"total_hosts": self.total_hosts,
|
||||
"processed_hosts": self.processed_hosts,
|
||||
"saved_hosts": self.saved_hosts,
|
||||
"current_host": self.current_host,
|
||||
"percent": min(max(percent, 0), 100),
|
||||
"elapsed_seconds": elapsed_seconds,
|
||||
"eta_seconds": eta_seconds,
|
||||
}
|
||||
|
||||
|
||||
scan_state = ScanState()
|
||||
|
||||
Reference in New Issue
Block a user