refactor: restructure plugins per MTSS standard, consolidate assets to res/
Per docs/plugin-audit-report.md (plugins normalized to Trigger(handlers) → Service(services) → Model(repository/models) + utils): - Split monolithic __init__.py into handlers/services/utils across dailywife, deer_pipe, dice, galgame_card, helldivers_tools, huoziyinshua, learning_chat, makeaquote, mc_server_status, ncm_saying, picfinder_take, picstatus, random_jm_code, regif, steam_info, video_analysis, group_tools - Move static assets under res/: deer_pipe font/img, makeaquote font, helldivers img/templates, huoziyinshua HuoZiYinShua - Add config.py + register_config_items to ncm_saying, random_jm_code, group_tools; learning_chat unified config bridge - Remove deprecated: voice_trans plugin, bf_bot/test.py, dead code in dailywife/deer_pipe, empty dirs, debug scripts under helldivers temp - Disable brash_general_supercredits_tools (stub comment only) - bot.py: optional stdout/stderr redirect to log file for Web log viewer, force ANSI colorize on non-TTY sinks - Move runtime data (jm_code.json) out of plugin dir into hexi/data - Docs: plugin-audit-report.md; README reflects removed plugins Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,9 @@ except Exception: # pragma: no cover
|
||||
|
||||
_MODULE_START = time.time()
|
||||
|
||||
# 网络速率采样:记录上一次累计计数与时间,用于计算实时 bytes/s 用量
|
||||
_NET_LAST: dict = {"time": None, "sent": None, "recv": None}
|
||||
|
||||
|
||||
async def _collect_cpu() -> dict:
|
||||
try:
|
||||
@@ -91,6 +94,95 @@ async def _collect_process() -> dict:
|
||||
return info
|
||||
|
||||
|
||||
async def _collect_network() -> dict:
|
||||
"""采集网络流量累计值 + 实时速率(bytes/s)。"""
|
||||
global _NET_LAST
|
||||
now = time.time()
|
||||
try:
|
||||
io = psutil.net_io_counters(pernic=False)
|
||||
except Exception:
|
||||
return {
|
||||
"sent": 0,
|
||||
"recv": 0,
|
||||
"sent_rate": 0,
|
||||
"recv_rate": 0,
|
||||
"packets_sent": 0,
|
||||
"packets_recv": 0,
|
||||
"interfaces": [],
|
||||
}
|
||||
sent = int(io.bytes_sent)
|
||||
recv = int(io.bytes_recv)
|
||||
sent_rate = recv_rate = 0.0
|
||||
last = _NET_LAST
|
||||
if last["time"] is not None and last["sent"] is not None:
|
||||
dt = max(0.001, now - float(last["time"]))
|
||||
sent_rate = max(0.0, (sent - int(last["sent"])) / dt)
|
||||
recv_rate = max(0.0, (recv - int(last["recv"])) / dt)
|
||||
_NET_LAST = {"time": now, "sent": sent, "recv": recv}
|
||||
|
||||
# 逐网卡明细(含 IP / 友好名称)
|
||||
interfaces: list[dict] = []
|
||||
try:
|
||||
pernic = psutil.net_io_counters(pernic=True)
|
||||
addrs = psutil.net_if_addrs()
|
||||
stats = psutil.net_if_stats()
|
||||
for name, cnt in pernic.items():
|
||||
if not cnt.bytes_sent and not cnt.bytes_recv:
|
||||
continue
|
||||
ips = []
|
||||
for addr in addrs.get(name, []):
|
||||
ip = (addr.address or "").strip()
|
||||
# 只保留 IPv4(带点分十进制),忽略 MAC / IPv6
|
||||
if ip and ":" not in ip and ip.count(".") >= 3:
|
||||
ips.append(ip)
|
||||
up = bool(stats.get(name).isup) if name in stats else True
|
||||
interfaces.append({
|
||||
"name": name,
|
||||
"up": up,
|
||||
"sent": int(cnt.bytes_sent),
|
||||
"recv": int(cnt.bytes_recv),
|
||||
"ip": ", ".join(ips) if ips else "",
|
||||
})
|
||||
except Exception:
|
||||
interfaces = []
|
||||
|
||||
return {
|
||||
"sent": sent,
|
||||
"recv": recv,
|
||||
"sent_rate": round(sent_rate, 1),
|
||||
"recv_rate": round(recv_rate, 1),
|
||||
"packets_sent": int(io.packets_sent),
|
||||
"packets_recv": int(io.packets_recv),
|
||||
"interfaces": interfaces,
|
||||
}
|
||||
|
||||
|
||||
async def _collect_backend() -> dict:
|
||||
"""BOT 后端信息:NoneBot 版本 / 驱动方式 / 装载插件数。"""
|
||||
from nonebot import get_loaded_plugins
|
||||
|
||||
try:
|
||||
plugin_count = len(get_loaded_plugins())
|
||||
except Exception:
|
||||
plugin_count = 0
|
||||
info: dict = {
|
||||
"nonebot_version": _nonebot_version(),
|
||||
"plugin_count": plugin_count,
|
||||
"python": f"{platform.python_implementation()} {platform.python_version()}",
|
||||
"driver_type": "",
|
||||
"driver": "",
|
||||
}
|
||||
try:
|
||||
from nonebot import get_driver
|
||||
|
||||
driver = get_driver()
|
||||
info["driver_type"] = getattr(driver, "type", "") or ""
|
||||
info["driver"] = getattr(driver.config, "driver", "") or ""
|
||||
except Exception:
|
||||
pass
|
||||
return info
|
||||
|
||||
|
||||
async def _collect_system() -> dict:
|
||||
boot = psutil.boot_time()
|
||||
now = time.time()
|
||||
@@ -180,13 +272,15 @@ async def _collect_bots() -> list:
|
||||
|
||||
async def collect_dashboard() -> dict:
|
||||
"""聚合采集,失败字段降级,不阻塞整体返回。"""
|
||||
cpu, memory, process, system, disk, bots = await asyncio.gather(
|
||||
cpu, memory, process, system, disk, bots, network, backend = await asyncio.gather(
|
||||
_collect_cpu(),
|
||||
_collect_memory(),
|
||||
_collect_process(),
|
||||
_collect_system(),
|
||||
_collect_disk(),
|
||||
_collect_bots(),
|
||||
_collect_network(),
|
||||
_collect_backend(),
|
||||
)
|
||||
return {
|
||||
"bots": bots,
|
||||
@@ -195,4 +289,6 @@ async def collect_dashboard() -> dict:
|
||||
"memory": memory,
|
||||
"process": process,
|
||||
"disk": disk,
|
||||
"network": network,
|
||||
"backend": backend,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user