Fix OpenWrt rate/lease mapping and queue pending
This commit is contained in:
@@ -38,7 +38,11 @@ def _format_rate(rate: Any) -> str:
|
|||||||
return "?"
|
return "?"
|
||||||
if val <= 0:
|
if val <= 0:
|
||||||
return "?"
|
return "?"
|
||||||
return f"{val / 1000:.1f}M"
|
if val >= 1_000_000:
|
||||||
|
return f"{val / 1_000_000:.1f}M"
|
||||||
|
if val >= 1_000:
|
||||||
|
return f"{val / 1_000:.1f}K"
|
||||||
|
return f"{val:.0f}b"
|
||||||
|
|
||||||
|
|
||||||
def _extract_wan_ip(wan: dict[str, Any]) -> str | None:
|
def _extract_wan_ip(wan: dict[str, Any]) -> str | None:
|
||||||
@@ -128,6 +132,18 @@ def _extract_lease_name_map(leases: Any) -> dict[str, str]:
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_lease_name_map_fallback(raw: str) -> dict[str, str]:
|
||||||
|
out: dict[str, str] = {}
|
||||||
|
for line in raw.splitlines():
|
||||||
|
parts = line.strip().split()
|
||||||
|
if len(parts) < 4:
|
||||||
|
continue
|
||||||
|
_expiry, mac, _ipaddr, host = parts[:4]
|
||||||
|
host = host if host != "*" else "unknown"
|
||||||
|
out[str(mac).lower()] = str(host)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
def _extract_ifnames(wireless: dict[str, Any]) -> list[str]:
|
def _extract_ifnames(wireless: dict[str, Any]) -> list[str]:
|
||||||
ifnames: list[str] = []
|
ifnames: list[str] = []
|
||||||
if not isinstance(wireless, dict):
|
if not isinstance(wireless, dict):
|
||||||
@@ -360,6 +376,8 @@ async def get_openwrt_status(cfg: dict[str, Any]) -> str:
|
|||||||
ifnames.extend(_extract_hostapd_ifnames(out_l))
|
ifnames.extend(_extract_hostapd_ifnames(out_l))
|
||||||
ifnames = sorted({name for name in ifnames if name})
|
ifnames = sorted({name for name in ifnames if name})
|
||||||
lease_name_map = _extract_lease_name_map(leases or {})
|
lease_name_map = _extract_lease_name_map(leases or {})
|
||||||
|
if leases_fallback:
|
||||||
|
lease_name_map.update(_extract_lease_name_map_fallback(leases_fallback))
|
||||||
if ifnames:
|
if ifnames:
|
||||||
for ifname in ifnames:
|
for ifname in ifnames:
|
||||||
cmd_clients = ssh_cmd + ["ubus", "call", f"hostapd.{ifname}", "get_clients"]
|
cmd_clients = ssh_cmd + ["ubus", "call", f"hostapd.{ifname}", "get_clients"]
|
||||||
|
|||||||
@@ -1,22 +1,34 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import time
|
import time
|
||||||
|
from collections import deque
|
||||||
from typing import Awaitable, Callable, Any
|
from typing import Awaitable, Callable, Any
|
||||||
|
|
||||||
|
|
||||||
_queue: asyncio.Queue = asyncio.Queue()
|
_queue: asyncio.Queue = asyncio.Queue()
|
||||||
_current_label: str | None = None
|
_current_label: str | None = None
|
||||||
_current_meta: dict[str, Any] | None = None
|
_current_meta: dict[str, Any] | None = None
|
||||||
|
_pending: deque[tuple[str, float]] = deque()
|
||||||
|
|
||||||
|
|
||||||
async def enqueue(label: str, job: Callable[[], Awaitable[None]]) -> int:
|
async def enqueue(label: str, job: Callable[[], Awaitable[None]]) -> int:
|
||||||
await _queue.put((label, job, time.time()))
|
enqueued_at = time.time()
|
||||||
return _queue.qsize()
|
await _queue.put((label, job, enqueued_at))
|
||||||
|
_pending.append((label, enqueued_at))
|
||||||
|
return len(_pending)
|
||||||
|
|
||||||
|
|
||||||
async def worker():
|
async def worker():
|
||||||
global _current_label, _current_meta
|
global _current_label, _current_meta
|
||||||
while True:
|
while True:
|
||||||
label, job, enqueued_at = await _queue.get()
|
label, job, enqueued_at = await _queue.get()
|
||||||
|
if _pending:
|
||||||
|
if _pending[0] == (label, enqueued_at):
|
||||||
|
_pending.popleft()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
_pending.remove((label, enqueued_at))
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
_current_label = label
|
_current_label = label
|
||||||
_current_meta = {"enqueued_at": enqueued_at, "started_at": time.time()}
|
_current_meta = {"enqueued_at": enqueued_at, "started_at": time.time()}
|
||||||
try:
|
try:
|
||||||
@@ -28,31 +40,33 @@ async def worker():
|
|||||||
|
|
||||||
|
|
||||||
def format_status() -> str:
|
def format_status() -> str:
|
||||||
pending = list(_queue._queue)
|
pending = list(_pending)
|
||||||
lines = ["🧾 Queue"]
|
lines = ["?? Queue"]
|
||||||
lines.append(f"🔄 Running: {_current_label or 'idle'}")
|
lines.append(f"?? Running: {_current_label or 'idle'}")
|
||||||
lines.append(f"⏳ Pending: {len(pending)}")
|
lines.append(f"? Pending: {len(pending)}")
|
||||||
if pending:
|
if pending:
|
||||||
preview = ", ".join([p[0] for p in pending[:5]])
|
preview = ", ".join([p[0] for p in pending[:5]])
|
||||||
lines.append(f"➡️ Next: {preview}")
|
lines.append(f"?? Next: {preview}")
|
||||||
return "\n".join(lines)
|
return "
|
||||||
|
".join(lines)
|
||||||
|
|
||||||
|
|
||||||
def format_details(limit: int = 10) -> str:
|
def format_details(limit: int = 10) -> str:
|
||||||
now = time.time()
|
now = time.time()
|
||||||
lines = ["🧾 Queue details"]
|
lines = ["?? Queue details"]
|
||||||
if _current_label:
|
if _current_label:
|
||||||
started_at = _current_meta.get("started_at") if _current_meta else None
|
started_at = _current_meta.get("started_at") if _current_meta else None
|
||||||
runtime = f"{int(now - started_at)}s" if started_at else "n/a"
|
runtime = f"{int(now - started_at)}s" if started_at else "n/a"
|
||||||
lines.append(f"🔄 Running: {_current_label} ({runtime})")
|
lines.append(f"?? Running: {_current_label} ({runtime})")
|
||||||
else:
|
else:
|
||||||
lines.append("🔄 Running: idle")
|
lines.append("?? Running: idle")
|
||||||
|
|
||||||
pending = list(_queue._queue)
|
pending = list(_pending)
|
||||||
lines.append(f"⏳ Pending: {len(pending)}")
|
lines.append(f"? Pending: {len(pending)}")
|
||||||
if pending:
|
if pending:
|
||||||
lines.append("🔢 Position | Label | Wait")
|
lines.append("?? Position | Label | Wait")
|
||||||
for i, (label, _job, enqueued_at) in enumerate(pending[:limit], start=1):
|
for i, (label, enqueued_at) in enumerate(pending[:limit], start=1):
|
||||||
wait = int(now - enqueued_at)
|
wait = int(now - enqueued_at)
|
||||||
lines.append(f"{i:>3} | {label} | {wait}s")
|
lines.append(f"{i:>3} | {label} | {wait}s")
|
||||||
return "\n".join(lines)
|
return "
|
||||||
|
".join(lines)
|
||||||
|
|||||||
Reference in New Issue
Block a user