55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
from typing import Any
|
|
|
|
import psutil
|
|
from psutil._ntuples import sdiskio
|
|
|
|
|
|
def counters() -> dict[str, sdiskio]:
|
|
return psutil.disk_io_counters(perdisk=True) or {}
|
|
|
|
|
|
def rates(prev: dict[str, sdiskio], dt: float) -> tuple[float, float]:
|
|
cur = counters()
|
|
r = 0
|
|
w = 0
|
|
for name, c in cur.items():
|
|
p = prev.get(name)
|
|
if p is not None and dt > 0:
|
|
r += max(0, int(c.read_bytes) - int(p.read_bytes))
|
|
w += max(0, int(c.write_bytes) - int(p.write_bytes))
|
|
return (r / dt if dt > 0 else 0.0, w / dt if dt > 0 else 0.0)
|
|
|
|
|
|
def partitions() -> list[dict[str, Any]]:
|
|
groups: dict[str, dict[str, Any]] = {}
|
|
order: list[str] = []
|
|
for p in psutil.disk_partitions(all=False):
|
|
if p.device in groups:
|
|
g = groups[p.device]
|
|
if p.mountpoint not in g["mounts"]:
|
|
g["mounts"].append(p.mountpoint)
|
|
continue
|
|
try:
|
|
u = psutil.disk_usage(p.mountpoint)
|
|
except (OSError, PermissionError):
|
|
continue
|
|
g = {
|
|
"device": p.device,
|
|
"fstype": p.fstype,
|
|
"total": u.total,
|
|
"used": u.used,
|
|
"free": u.free,
|
|
"pct": u.percent,
|
|
"mounts": [p.mountpoint],
|
|
}
|
|
groups[p.device] = g
|
|
order.append(p.device)
|
|
out = [groups[d] for d in sorted(order)]
|
|
for g in out:
|
|
g["mounts"] = sorted(g["mounts"])
|
|
mounts = g["mounts"]
|
|
if len(mounts) > 3:
|
|
g["mounts_disp"] = " · ".join(mounts[:3]) + f" +{len(mounts) - 3} more"
|
|
else:
|
|
g["mounts_disp"] = " · ".join(mounts)
|
|
return out
|