diff --git a/poetry.lock b/poetry.lock index c5c9a8b9..a0e7fedb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1813,6 +1813,39 @@ type = "legacy" url = "https://mirrors.aliyun.com/pypi/simple" reference = "ali" +[[package]] +name = "psutil" +version = "5.9.8" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, + {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, + {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, + {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, + {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, + {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, + {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, + {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, + {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, + {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[package.source] +type = "legacy" +url = "https://mirrors.aliyun.com/pypi/simple" +reference = "ali" + [[package]] name = "pydantic" version = "1.10.14" @@ -3138,4 +3171,4 @@ reference = "ali" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "28cd8bd2a5d3b00dc4c53dd5d259c5095b741494c7bb17a88927bfacb31cf452" +content-hash = "1d5f9655208fe3bde4ebf3e4f39979dcc961d338d3735d001eb234acfe58f8e3" diff --git a/pyproject.toml b/pyproject.toml index d75f1afd..678d2d0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,7 @@ nonebot-plugin-alconna = "^0.37.1" pypinyin = "^0.51.0" beautifulsoup4 = "^4.12.3" lxml = "^5.1.0" +psutil = "^5.9.8" [tool.poetry.dev-dependencies] diff --git a/zhenxun/plugins/bt/__init__.py b/zhenxun/plugins/bt/__init__.py index ee0e8643..96d82308 100644 --- a/zhenxun/plugins/bt/__init__.py +++ b/zhenxun/plugins/bt/__init__.py @@ -19,8 +19,8 @@ __plugin_meta__ = PluginMetadata( * 拒绝反冲斗士! * 指令: bt [关键词] ?[页数] - 示例:bt 钢铁侠 - 示例:bt 钢铁侠 3 + 示例: bt 钢铁侠 + 示例: bt 钢铁侠 3 """.strip(), extra=PluginExtraData( author="HibiKier", diff --git a/zhenxun/plugins/check/__init__.py b/zhenxun/plugins/check/__init__.py new file mode 100644 index 00000000..8e8b91d7 --- /dev/null +++ b/zhenxun/plugins/check/__init__.py @@ -0,0 +1,40 @@ +from nonebot.permission import SUPERUSER +from nonebot.plugin import PluginMetadata +from nonebot.rule import to_me +from nonebot_plugin_alconna import Alconna, Arparma, on_alconna +from nonebot_plugin_saa import Image +from nonebot_plugin_session import EventSession + +from zhenxun.configs.utils import PluginExtraData +from zhenxun.services.log import logger +from zhenxun.utils.enum import PluginType + +from .data_source import Check + +__plugin_meta__ = PluginMetadata( + name="服务器自我检查", + description="查看服务器当前状态", + usage=""" + 查看服务器当前状态 + 指令: + 自检 + """.strip(), + extra=PluginExtraData( + author="HibiKier", version="0.1", plugin_type=PluginType.SUPERUSER + ).dict(), +) + + +check = Check() + + +_matcher = on_alconna( + Alconna("自检"), rule=to_me(), permission=SUPERUSER, block=True, priority=1 +) + + +@_matcher.handle() +async def _(session: EventSession, arparma: Arparma): + image = await check.show() + await Image(image.pic2bytes()).send() + logger.info("自检", arparma.header_result, session=session) diff --git a/zhenxun/plugins/check/data_source.py b/zhenxun/plugins/check/data_source.py new file mode 100644 index 00000000..78fbe7ba --- /dev/null +++ b/zhenxun/plugins/check/data_source.py @@ -0,0 +1,83 @@ +import asyncio +import time +from datetime import datetime + +import psutil + +from zhenxun.configs.path_config import IMAGE_PATH +from zhenxun.services.log import logger +from zhenxun.utils.http_utils import AsyncHttpx +from zhenxun.utils.image_utils import BuildImage + + +class Check: + def __init__(self): + self.cpu = None + self.memory = None + self.disk = None + self.user = None + self.baidu = 200 + self.google = 200 + + async def check_all(self): + await self.check_network() + await asyncio.sleep(0.1) + self.check_system() + self.check_user() + + def check_system(self): + self.cpu = psutil.cpu_percent() + self.memory = psutil.virtual_memory().percent + self.disk = psutil.disk_usage("/").percent + + async def check_network(self): + try: + await AsyncHttpx.get("https://www.baidu.com/", timeout=5) + except Exception as e: + logger.warning(f"访问BaiDu失败... {type(e)}: {e}") + self.baidu = 404 + try: + await AsyncHttpx.get("https://www.google.com/", timeout=5) + except Exception as e: + logger.warning(f"访问Google失败... {type(e)}: {e}") + self.google = 404 + + def check_user(self): + result = "" + for user in psutil.users(): + result += f'[{user.name}] {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(user.started))}\n' + self.user = result[:-1] + + async def show(self) -> BuildImage: + await self.check_all() + font = BuildImage.load_font(font_size=24) + result = ( + f'[Time] {str(datetime.now()).split(".")[0]}\n' + f"-----System-----\n" + f"[CPU] {self.cpu}%\n" + f"[Memory] {self.memory}%\n" + f"[Disk] {self.disk}%\n" + f"-----Network-----\n" + f"[BaiDu] {self.baidu}\n" + f"[Google] {self.google}\n" + ) + if self.user: + result += "-----User-----\n" + self.user + width = 0 + height = 0 + for x in result.split("\n"): + w, h = BuildImage.get_text_size(x, font) + if w > width: + width = w + height += 30 + A = BuildImage(width + 50, height + 10, font_size=24) + await A.transparent(1) + await A.text((10, 10), result) + max_width = max(width, height) + bk = BuildImage( + max_width + 100, + max_width + 100, + background=IMAGE_PATH / "background" / "check" / "0.jpg", + ) + await bk.paste(A, center_type="center") + return bk