mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-15 06:12:53 +08:00
perf👌: 完善系统管理api
This commit is contained in:
parent
45acf4a094
commit
b656f89c8e
@ -20,6 +20,7 @@ from .api.tabs.main import ws_router as status_routes
|
||||
from .api.tabs.manage import router as manage_router
|
||||
from .api.tabs.manage import ws_router as chat_routes
|
||||
from .api.tabs.plugin_manage import router as plugin_router
|
||||
from .api.tabs.system import router as system_router
|
||||
from .auth import router as auth_router
|
||||
|
||||
driver = nonebot.get_driver()
|
||||
@ -37,6 +38,7 @@ BaseApiRouter.include_router(main_router)
|
||||
BaseApiRouter.include_router(manage_router)
|
||||
BaseApiRouter.include_router(database_router)
|
||||
BaseApiRouter.include_router(plugin_router)
|
||||
BaseApiRouter.include_router(system_router)
|
||||
|
||||
|
||||
WsApiRouter = APIRouter(prefix="/zhenxun/socket")
|
||||
|
||||
@ -1,228 +0,0 @@
|
||||
# import asyncio
|
||||
# import os
|
||||
# from datetime import datetime
|
||||
# from pathlib import Path
|
||||
# from typing import Dict, Optional, Union
|
||||
|
||||
# import psutil
|
||||
# import ujson as json
|
||||
# from fastapi import APIRouter
|
||||
|
||||
# from configs.path_config import (
|
||||
# DATA_PATH,
|
||||
# FONT_PATH,
|
||||
# IMAGE_PATH,
|
||||
# LOG_PATH,
|
||||
# RECORD_PATH,
|
||||
# TEMP_PATH,
|
||||
# TEXT_PATH,
|
||||
# )
|
||||
# from services.log import logger
|
||||
# from utils.http_utils import AsyncHttpx
|
||||
|
||||
# from ..base_model import (
|
||||
# Result,
|
||||
# SystemFolderSize,
|
||||
# SystemNetwork,
|
||||
# SystemResult,
|
||||
# SystemStatus,
|
||||
# SystemStatusList,
|
||||
# )
|
||||
# from ..utils import authentication
|
||||
|
||||
# CPU_DATA_PATH = DATA_PATH / "system" / "cpu.json"
|
||||
# MEMORY_DATA_PATH = DATA_PATH / "system" / "memory.json"
|
||||
# DISK_DATA_PATH = DATA_PATH / "system" / "disk.json"
|
||||
# CPU_DATA_PATH.parent.mkdir(exist_ok=True, parents=True)
|
||||
# cpu_data = {"data": []}
|
||||
# memory_data = {"data": []}
|
||||
# disk_data = {"data": []}
|
||||
|
||||
# router = APIRouter()
|
||||
|
||||
|
||||
# @router.get("/system", dependencies=[authentication()])
|
||||
# async def _() -> Result:
|
||||
# return await get_system_data()
|
||||
|
||||
|
||||
# @router.get("/status", dependencies=[authentication()])
|
||||
# async def _() -> Result:
|
||||
# return Result.ok(
|
||||
# await asyncio.get_event_loop().run_in_executor(None, _get_system_status),
|
||||
# )
|
||||
|
||||
|
||||
# @router.get("/system/disk", dependencies=[authentication()])
|
||||
# async def _(type_: Optional[str] = None) -> Result:
|
||||
# return Result.ok(
|
||||
# data=await asyncio.get_event_loop().run_in_executor(
|
||||
# None, _get_system_disk, type_
|
||||
# ),
|
||||
# )
|
||||
|
||||
|
||||
# @router.get("/system/statusList", dependencies=[authentication()])
|
||||
# async def _() -> Result:
|
||||
# global cpu_data, memory_data, disk_data
|
||||
# await asyncio.get_event_loop().run_in_executor(None, _get_system_status)
|
||||
# cpu_rst = cpu_data["data"][-10:] if len(cpu_data["data"]) > 10 else cpu_data["data"]
|
||||
# memory_rst = (
|
||||
# memory_data["data"][-10:]
|
||||
# if len(memory_data["data"]) > 10
|
||||
# else memory_data["data"]
|
||||
# )
|
||||
# disk_rst = (
|
||||
# disk_data["data"][-10:] if len(disk_data["data"]) > 10 else disk_data["data"]
|
||||
# )
|
||||
# return Result.ok(
|
||||
# SystemStatusList(
|
||||
# cpu_data=cpu_rst,
|
||||
# memory_data=memory_rst,
|
||||
# disk_data=disk_rst,
|
||||
# ),
|
||||
# )
|
||||
|
||||
|
||||
# async def get_system_data():
|
||||
# """
|
||||
# 说明:
|
||||
# 获取系统信息,资源文件大小,网络状态等
|
||||
# """
|
||||
# baidu = 200
|
||||
# google = 200
|
||||
# try:
|
||||
# await AsyncHttpx.get("https://www.baidu.com/", timeout=5)
|
||||
# except Exception as e:
|
||||
# logger.warning(f"访问BaiDu失败... {type(e)}: {e}")
|
||||
# baidu = 404
|
||||
# try:
|
||||
# await AsyncHttpx.get("https://www.google.com/", timeout=5)
|
||||
# except Exception as e:
|
||||
# logger.warning(f"访问Google失败... {type(e)}: {e}")
|
||||
# google = 404
|
||||
# network = SystemNetwork(baidu=baidu, google=google)
|
||||
# disk = await asyncio.get_event_loop().run_in_executor(None, _get_system_disk, None)
|
||||
# status = await asyncio.get_event_loop().run_in_executor(None, _get_system_status)
|
||||
# return Result.ok(
|
||||
# SystemResult(
|
||||
# status=status,
|
||||
# network=network,
|
||||
# disk=disk, # type: ignore
|
||||
# check_time=datetime.now().replace(microsecond=0),
|
||||
# ),
|
||||
# )
|
||||
|
||||
|
||||
# def _get_system_status() -> SystemStatus:
|
||||
# """
|
||||
# 说明:
|
||||
# 获取系统信息等
|
||||
# """
|
||||
# cpu = psutil.cpu_percent()
|
||||
# memory = psutil.virtual_memory().percent
|
||||
# disk = psutil.disk_usage("/").percent
|
||||
# save_system_data(cpu, memory, disk)
|
||||
# return SystemStatus(
|
||||
# cpu=cpu,
|
||||
# memory=memory,
|
||||
# disk=disk,
|
||||
# check_time=datetime.now().replace(microsecond=0),
|
||||
# )
|
||||
|
||||
|
||||
# def _get_system_disk(
|
||||
# type_: Optional[str],
|
||||
# ) -> Union[SystemFolderSize, Dict[str, Union[float, datetime]]]:
|
||||
# """
|
||||
# 说明:
|
||||
# 获取资源文件大小等
|
||||
# """
|
||||
# if not type_:
|
||||
# disk = SystemFolderSize(
|
||||
# font_dir_size=_get_dir_size(FONT_PATH) / 1024 / 1024,
|
||||
# image_dir_size=_get_dir_size(IMAGE_PATH) / 1024 / 1024,
|
||||
# text_dir_size=_get_dir_size(TEXT_PATH) / 1024 / 1024,
|
||||
# record_dir_size=_get_dir_size(RECORD_PATH) / 1024 / 1024,
|
||||
# temp_dir_size=_get_dir_size(TEMP_PATH) / 1024 / 102,
|
||||
# data_dir_size=_get_dir_size(DATA_PATH) / 1024 / 1024,
|
||||
# log_dir_size=_get_dir_size(LOG_PATH) / 1024 / 1024,
|
||||
# check_time=datetime.now().replace(microsecond=0),
|
||||
# )
|
||||
# return disk
|
||||
# else:
|
||||
# if type_ == "image":
|
||||
# dir_path = IMAGE_PATH
|
||||
# elif type_ == "font":
|
||||
# dir_path = FONT_PATH
|
||||
# elif type_ == "text":
|
||||
# dir_path = TEXT_PATH
|
||||
# elif type_ == "record":
|
||||
# dir_path = RECORD_PATH
|
||||
# elif type_ == "data":
|
||||
# dir_path = DATA_PATH
|
||||
# elif type_ == "temp":
|
||||
# dir_path = TEMP_PATH
|
||||
# else:
|
||||
# dir_path = LOG_PATH
|
||||
# dir_map = {}
|
||||
# other_file_size = 0
|
||||
# for file in os.listdir(dir_path):
|
||||
# file = Path(dir_path / file)
|
||||
# if file.is_dir():
|
||||
# dir_map[file.name] = _get_dir_size(file) / 1024 / 1024
|
||||
# else:
|
||||
# other_file_size += os.path.getsize(file) / 1024 / 1024
|
||||
# dir_map["其他文件"] = other_file_size
|
||||
# dir_map["check_time"] = datetime.now().replace(microsecond=0)
|
||||
# return dir_map
|
||||
|
||||
|
||||
# def _get_dir_size(dir_path: Path) -> float:
|
||||
# """
|
||||
# 说明:
|
||||
# 获取文件夹大小
|
||||
# 参数:
|
||||
# :param dir_path: 文件夹路径
|
||||
# """
|
||||
# size = 0
|
||||
# for root, dirs, files in os.walk(dir_path):
|
||||
# size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
|
||||
# return size
|
||||
|
||||
|
||||
# def save_system_data(cpu: float, memory: float, disk: float):
|
||||
# """
|
||||
# 说明:
|
||||
# 保存一些系统信息
|
||||
# 参数:
|
||||
# :param cpu: cpu
|
||||
# :param memory: memory
|
||||
# :param disk: disk
|
||||
# """
|
||||
# global cpu_data, memory_data, disk_data
|
||||
# if CPU_DATA_PATH.exists() and not cpu_data["data"]:
|
||||
# with open(CPU_DATA_PATH, "r") as f:
|
||||
# cpu_data = json.load(f)
|
||||
# if MEMORY_DATA_PATH.exists() and not memory_data["data"]:
|
||||
# with open(MEMORY_DATA_PATH, "r") as f:
|
||||
# memory_data = json.load(f)
|
||||
# if DISK_DATA_PATH.exists() and not disk_data["data"]:
|
||||
# with open(DISK_DATA_PATH, "r") as f:
|
||||
# disk_data = json.load(f)
|
||||
# now = str(datetime.now().time().replace(microsecond=0))
|
||||
# cpu_data["data"].append({"time": now, "data": cpu})
|
||||
# memory_data["data"].append({"time": now, "data": memory})
|
||||
# disk_data["data"].append({"time": now, "data": disk})
|
||||
# if len(cpu_data["data"]) > 50:
|
||||
# cpu_data["data"] = cpu_data["data"][-50:]
|
||||
# if len(memory_data["data"]) > 50:
|
||||
# memory_data["data"] = memory_data["data"][-50:]
|
||||
# if len(disk_data["data"]) > 50:
|
||||
# disk_data["data"] = disk_data["data"][-50:]
|
||||
# with open(CPU_DATA_PATH, "w") as f:
|
||||
# json.dump(cpu_data, f, indent=4, ensure_ascii=False)
|
||||
# with open(MEMORY_DATA_PATH, "w") as f:
|
||||
# json.dump(memory_data, f, indent=4, ensure_ascii=False)
|
||||
# with open(DISK_DATA_PATH, "w") as f:
|
||||
# json.dump(disk_data, f, indent=4, ensure_ascii=False)
|
||||
@ -2,3 +2,4 @@ from .database import *
|
||||
from .main import *
|
||||
from .manage import *
|
||||
from .plugin_manage import *
|
||||
from .system import *
|
||||
|
||||
@ -101,4 +101,4 @@ async def _(query: QueryModel) -> Result:
|
||||
async def _(plugin_name: Optional[str] = None) -> Result:
|
||||
if plugin_name:
|
||||
return Result.ok(SQL_DICT.get(plugin_name))
|
||||
return Result.ok(SQL_DICT)
|
||||
return Result.ok(str(SQL_DICT))
|
||||
|
||||
@ -246,14 +246,14 @@ async def _(date_type: Optional[QueryDateType] = None) -> Result:
|
||||
|
||||
|
||||
@ws_router.websocket("/system_status")
|
||||
async def system_logs_realtime(websocket: WebSocket):
|
||||
async def system_logs_realtime(websocket: WebSocket, sleep: Optional[int] = 5):
|
||||
await websocket.accept()
|
||||
logger.debug("ws system_status is connect")
|
||||
try:
|
||||
while websocket.client_state == WebSocketState.CONNECTED:
|
||||
system_status = await get_system_status()
|
||||
await websocket.send_text(system_status.json())
|
||||
await asyncio.sleep(5)
|
||||
await asyncio.sleep(sleep)
|
||||
except (WebSocketDisconnect, ConnectionClosedError, ConnectionClosedOK):
|
||||
pass
|
||||
return
|
||||
|
||||
26
plugins/web_ui/api/tabs/system/__init__.py
Normal file
26
plugins/web_ui/api/tabs/system/__init__.py
Normal file
@ -0,0 +1,26 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from ....base_model import Result
|
||||
from ....utils import authentication, get_system_disk
|
||||
from .model import DirFile
|
||||
|
||||
router = APIRouter(prefix="/system")
|
||||
|
||||
|
||||
|
||||
@router.get("/get_dir_list", dependencies=[authentication()], description="获取文件列表")
|
||||
async def _(path: Optional[str] = None) -> Result:
|
||||
base_path = Path(path) if path else Path()
|
||||
data_list = []
|
||||
for file in os.listdir(base_path):
|
||||
data_list.append(DirFile(is_file=not (base_path / file).is_dir(), name=file, parent=path))
|
||||
return Result.ok(data_list)
|
||||
|
||||
|
||||
@router.get("/get_resources_size", dependencies=[authentication()], description="获取文件列表")
|
||||
async def _(type: Optional[str] = None) -> Result:
|
||||
return Result.ok(await get_system_disk(type))
|
||||
35
plugins/web_ui/api/tabs/system/model.py
Normal file
35
plugins/web_ui/api/tabs/system/model.py
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Literal, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class DirFile(BaseModel):
|
||||
|
||||
"""
|
||||
文件或文件夹
|
||||
"""
|
||||
|
||||
is_file: bool
|
||||
"""是否为文件"""
|
||||
name: str
|
||||
"""文件夹或文件名称"""
|
||||
parent: Optional[str] = None
|
||||
"""父级"""
|
||||
|
||||
class SystemFolderSize(BaseModel):
|
||||
"""
|
||||
资源文件占比
|
||||
"""
|
||||
|
||||
font_dir_size: float
|
||||
image_dir_size: float
|
||||
text_dir_size: float
|
||||
record_dir_size: float
|
||||
temp_dir_size: float
|
||||
data_dir_size: float
|
||||
log_dir_size: float
|
||||
check_time: datetime
|
||||
@ -87,20 +87,6 @@ class BaseResultModel(BaseModel):
|
||||
"""数据"""
|
||||
|
||||
|
||||
class PluginConfig(BaseModel):
|
||||
"""
|
||||
插件配置项
|
||||
"""
|
||||
|
||||
module: str
|
||||
key: str
|
||||
value: Optional[Any]
|
||||
help: Optional[str]
|
||||
default_value: Optional[Any]
|
||||
has_type: bool
|
||||
|
||||
|
||||
|
||||
class SystemStatus(BaseModel):
|
||||
"""
|
||||
系统状态
|
||||
@ -112,13 +98,6 @@ class SystemStatus(BaseModel):
|
||||
check_time: datetime
|
||||
|
||||
|
||||
class SystemNetwork(BaseModel):
|
||||
"""
|
||||
系统网络状态
|
||||
"""
|
||||
|
||||
baidu: int
|
||||
google: int
|
||||
|
||||
|
||||
class SystemFolderSize(BaseModel):
|
||||
@ -136,22 +115,3 @@ class SystemFolderSize(BaseModel):
|
||||
check_time: datetime
|
||||
|
||||
|
||||
class SystemStatusList(BaseModel):
|
||||
"""
|
||||
状态记录
|
||||
"""
|
||||
|
||||
cpu_data: List[Dict[str, Union[float, str]]]
|
||||
memory_data: List[Dict[str, Union[float, str]]]
|
||||
disk_data: List[Dict[str, Union[float, str]]]
|
||||
|
||||
|
||||
class SystemResult(BaseModel):
|
||||
"""
|
||||
系统api返回
|
||||
"""
|
||||
|
||||
status: SystemStatus
|
||||
network: SystemNetwork
|
||||
disk: SystemFolderSize
|
||||
check_time: datetime
|
||||
|
||||
@ -21,15 +21,7 @@ from configs.path_config import (
|
||||
TEXT_PATH,
|
||||
)
|
||||
|
||||
from .base_model import (
|
||||
Result,
|
||||
SystemFolderSize,
|
||||
SystemNetwork,
|
||||
SystemResult,
|
||||
SystemStatus,
|
||||
SystemStatusList,
|
||||
User,
|
||||
)
|
||||
from .base_model import SystemFolderSize, SystemStatus, User
|
||||
|
||||
SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
|
||||
ALGORITHM = "HS256"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user