Files
HeXi/hexi/plugins/nonebot_plugin_picstatus/services/collectors/misc.py
T
sansenhoshiandClaude 9371a28e35 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>
2026-09-03 00:44:38 +08:00

131 lines
3.5 KiB
Python

import os
import platform
import time
from datetime import datetime
from pathlib import Path
import nonebot
import psutil
from ...misc_statistics import nonebot_run_time
from ...util import format_time_delta_ps
from . import first_time_collector, normal_collector, periodic_collector
def parse_env(env: str) -> dict[str, str | None]:
env_lines = env.strip().splitlines()
env_dict: dict[str, str | None] = {}
for line in env_lines:
if "=" not in line:
env_dict[line.upper()] = None
continue
key, value = line.split("=", 1)
env_dict[key.upper()] = value.strip("\"'").strip()
return env_dict
def parse_env_file(env_file: str | Path) -> dict[str, str | None] | None:
if not isinstance(env_file, Path):
env_file = Path(env_file)
if not env_file.exists():
return None
content = env_file.read_text(encoding="u8")
return parse_env(content)
# Thanks to https://github.com/nonedesktop/nonebot-plugin-guestool/blob/main/nonebot_plugin_guestool/info.py
def get_linux_name_version() -> tuple[str, str] | None:
env = parse_env_file("/etc/os-release")
if env and (name := env.get("NAME")) and (version_id := env.get("VERSION_ID")):
return name, version_id
env = parse_env_file("/etc/lsb-release")
if (
env
and (name := env.get("DISTRIB_ID"))
and (version_id := env.get("DISTRIB_RELEASE"))
):
return name, version_id
return None
@normal_collector("nonebot_run_time")
async def nonebot_run_time_str() -> str:
now_time = datetime.now().astimezone()
return (
format_time_delta_ps(now_time - nonebot_run_time)
if nonebot_run_time
else "未知"
)
@normal_collector()
async def system_run_time() -> str:
now_time = datetime.now().astimezone()
return format_time_delta_ps(
now_time - datetime.fromtimestamp(psutil.boot_time()).astimezone(),
)
@first_time_collector()
async def nonebot_version() -> str:
return nonebot.__version__
@first_time_collector()
async def ps_version() -> str:
from ... import __version__
return __version__
async def get_time_str() -> str:
return time.strftime("%Y-%m-%d %H:%M:%S")
normal_collector("time")(get_time_str)
periodic_collector("time_periodic")(get_time_str)
@first_time_collector()
async def python_version() -> str:
return f"{platform.python_implementation()} {platform.python_version()}"
@first_time_collector()
async def system_name():
system, _, release, version, machine, _ = platform.uname()
system, release, version = platform.system_alias(system, release, version)
if system == "Java":
_, _, _, (system, release, machine) = platform.java_ver()
if system == "Darwin":
return f"MacOS {platform.mac_ver()[0]} {machine}"
if system == "Windows":
return f"Windows {release} {platform.win32_edition()} {machine}"
if system == "Linux":
if (pfx := os.getenv("PREFIX")) and "termux" in pfx:
system = f"Termux (Android) {release}" # a strange platform
elif os.getenv("ANDROID_ROOT") == "/system":
system = f"Linux (Android) {release}"
elif ver := get_linux_name_version():
name, version_id = ver
version = release if version_id.lower() == "rolling" else version_id
system = f"{name} {version}"
else:
system = f"未知 Linux {release}"
return f"{system} {machine}"
return f"{system} {release}"