mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2026-10-09 22:00:01 +08:00
✨ 重构自检ui
This commit is contained in:
Generated
+17
-1
@@ -3000,6 +3000,22 @@ type = "legacy"
|
|||||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||||
reference = "ali"
|
reference = "ali"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "py-cpuinfo"
|
||||||
|
version = "9.0.0"
|
||||||
|
description = "Get CPU info with pure Python"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
files = [
|
||||||
|
{file = "py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690"},
|
||||||
|
{file = "py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "legacy"
|
||||||
|
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||||
|
reference = "ali"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyasn1"
|
name = "pyasn1"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@@ -4909,4 +4925,4 @@ reference = "ali"
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
python-versions = "^3.10"
|
||||||
content-hash = "706cc73807663c91c3eed8d689e7f04f49fd6f0b6d2b3a2e7e4e078a2c3f89c0"
|
content-hash = "e66133515a2b17715ddf5f887ec31f128751acda1ea67736e9d27b29a9b16b65"
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ python-multipart = "^0.0.9"
|
|||||||
nonebot-plugin-alconna = "0.51.1"
|
nonebot-plugin-alconna = "0.51.1"
|
||||||
arclet-alconna = "1.8.23"
|
arclet-alconna = "1.8.23"
|
||||||
aiocache = "^0.12.2"
|
aiocache = "^0.12.2"
|
||||||
|
py-cpuinfo = "^9.0.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
nonebug = "^0.3.2"
|
nonebug = "^0.3.2"
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: fzrzFont;
|
||||||
|
/* 导入的字体文件 */
|
||||||
|
src: url("./res/font/fzrzExtraBold.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
|
position: absolute;
|
||||||
|
left: -8px;
|
||||||
|
top: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper{
|
||||||
|
height: 750px;
|
||||||
|
width: 395px;
|
||||||
|
background-color: antiquewhite;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-image {
|
||||||
|
height: 215px;
|
||||||
|
width: 395px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.abs-image {
|
||||||
|
height: 426px;
|
||||||
|
width: 93px;
|
||||||
|
position: absolute;
|
||||||
|
right: 39px;
|
||||||
|
top: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bot-text {
|
||||||
|
height: 55px;
|
||||||
|
width: 335px;
|
||||||
|
position: relative;
|
||||||
|
padding: 0 30px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
height: 448px;
|
||||||
|
width: 335px;
|
||||||
|
padding: 0 30px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
background-color: #EB869D;
|
||||||
|
height: 32px;
|
||||||
|
font-family: 'fzrzFont';
|
||||||
|
color: white;
|
||||||
|
width: max-content;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 0 10px;
|
||||||
|
float: left;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-n {
|
||||||
|
height: 23px;
|
||||||
|
width: 23px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: white;
|
||||||
|
position: absolute;
|
||||||
|
left: 36px;
|
||||||
|
top: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-a {
|
||||||
|
background-color: #ED859E;
|
||||||
|
height: 19px;
|
||||||
|
width: 19px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network {
|
||||||
|
display: flex;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-item {
|
||||||
|
font-family: 'fzrzFont';
|
||||||
|
color: #EC859F;
|
||||||
|
display: flex;
|
||||||
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-status {
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-text {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-item {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-status-item {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-status {
|
||||||
|
width: 100%;
|
||||||
|
height: 240px;
|
||||||
|
/* background-color:blueviolet; */
|
||||||
|
margin-top: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-status-item {
|
||||||
|
display: flex;
|
||||||
|
font-family: 'fzrzFont';
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18.5px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.process {
|
||||||
|
height: 28px;
|
||||||
|
width: 105px;
|
||||||
|
border: #ED859E 4px solid;
|
||||||
|
border-radius: 30px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.process-bar {
|
||||||
|
height: 28px;
|
||||||
|
width: 30px;
|
||||||
|
background-color: #EB869D;
|
||||||
|
border-top-right-radius: 30px;
|
||||||
|
border-bottom-right-radius: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-status-item-text {
|
||||||
|
margin-left: 10px;
|
||||||
|
color: #EC839D;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
background-color: #EC859F;
|
||||||
|
height: 2px;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
font-family: 'fzrzFont';
|
||||||
|
color: #EC859F;
|
||||||
|
height: 90px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text-title {
|
||||||
|
height: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
font-family: 'fzrzFont';
|
||||||
|
color: #ecbac7;
|
||||||
|
font-size: 10px;
|
||||||
|
position: absolute;
|
||||||
|
right: 5px;
|
||||||
|
bottom: 1px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
</html>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cn">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>test</title>
|
||||||
|
<!-- <link rel="stylesheet" href="./res/font-awesome/css/font-awesome.min.css"> -->
|
||||||
|
<link rel="stylesheet" href="main.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<img class="top-image" src="res/img/top.jpg"></img>
|
||||||
|
<img class="abs-image" src="res/img/bk.png"></img>
|
||||||
|
<div class="bot-text">
|
||||||
|
<div class="title">
|
||||||
|
<div class="title-n">
|
||||||
|
<div class="title-a"></div>
|
||||||
|
</div>
|
||||||
|
<span style="margin-left: 22px;">{{data.nickname}}自检</span>
|
||||||
|
</div>
|
||||||
|
<div class="network">
|
||||||
|
<div class="network-item">BaiDu<span class="network-status" style="background-color: {{data.baidu}}; border: 1px solid {{data.baidu}}"></span></div>
|
||||||
|
<div class="network-item">Google<span class="network-status" style="background-color: {{data.google}}; border: 1px solid {{data.google}}"></span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<div class="data-status">
|
||||||
|
<div class="data-status-item">
|
||||||
|
<div class="process">
|
||||||
|
<div class="process-bar" style="width: {{data.cpu_process}}%;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="data-status-item-text">
|
||||||
|
<div>CPU</div>
|
||||||
|
<!-- <div style="font-size: 13px;">0.8% - 3.5Ghz [14core]</div> -->
|
||||||
|
<div style="font-size: 13px;">{{data.cpu_info}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="data-status-item">
|
||||||
|
<div class="process">
|
||||||
|
<div class="process-bar" style="width: {{data.ram_process}}%;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="data-status-item-text">
|
||||||
|
<div>RAM</div>
|
||||||
|
<div>{{data.ram_info}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="data-status-item">
|
||||||
|
<div class="process">
|
||||||
|
<div class="process-bar" style="width: {{data.swap_process}}%;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="data-status-item-text">
|
||||||
|
<div>SWAP</div>
|
||||||
|
<div>{{data.swap_info}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="data-status-item">
|
||||||
|
<div class="process">
|
||||||
|
<div class="process-bar" style="width: {{data.disk_process}}%;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="data-status-item-text">
|
||||||
|
<div>DISK</div>
|
||||||
|
<div>{{data.disk_info}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="line"></div>
|
||||||
|
<div class="status-text">
|
||||||
|
<div>
|
||||||
|
<p class="status-text-title">CPU</p>
|
||||||
|
<p class="status-text-title">SYSTEM</p>
|
||||||
|
<p class="status-text-title">VERSION</p>
|
||||||
|
<p class="status-text-title">PLUGINS</p>
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 37px;">
|
||||||
|
<p class="status-text-title" style="font-size: 14px;line-height: 18.5px;">{{data.brand_raw}}</p>
|
||||||
|
<p class="status-text-title">{{data.system}}</p>
|
||||||
|
<p class="status-text-title">{{data.version}}</p>
|
||||||
|
<p class="status-text-title">{{data.plugin_count}} loaded</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tip">Create By Zhenxun</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script type="text/javascript" src="main.js">
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 209 KiB |
@@ -0,0 +1,53 @@
|
|||||||
|
from nonebot.rule import to_me
|
||||||
|
from nonebot.permission import SUPERUSER
|
||||||
|
from nonebot.plugin import PluginMetadata
|
||||||
|
from nonebot_plugin_session import EventSession
|
||||||
|
from nonebot_plugin_htmlrender import template_to_pic
|
||||||
|
from nonebot_plugin_alconna import Alconna, Arparma, on_alconna
|
||||||
|
|
||||||
|
from zhenxun.services.log import logger
|
||||||
|
from zhenxun.utils.enum import PluginType
|
||||||
|
from zhenxun.utils.message import MessageUtils
|
||||||
|
from zhenxun.configs.utils import PluginExtraData
|
||||||
|
from zhenxun.configs.path_config import TEMPLATE_PATH
|
||||||
|
|
||||||
|
from .data_source import get_status_info
|
||||||
|
|
||||||
|
__plugin_meta__ = PluginMetadata(
|
||||||
|
name="服务器自我检查",
|
||||||
|
description="查看服务器当前状态",
|
||||||
|
usage="""
|
||||||
|
查看服务器当前状态
|
||||||
|
指令:
|
||||||
|
自检
|
||||||
|
""".strip(),
|
||||||
|
extra=PluginExtraData(
|
||||||
|
author="HibiKier", version="0.1", plugin_type=PluginType.SUPERUSER
|
||||||
|
).dict(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_matcher = on_alconna(
|
||||||
|
Alconna("自检"), rule=to_me(), permission=SUPERUSER, block=True, priority=1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@_matcher.handle()
|
||||||
|
async def _(session: EventSession, arparma: Arparma):
|
||||||
|
try:
|
||||||
|
data = await get_status_info()
|
||||||
|
image = await template_to_pic(
|
||||||
|
template_path=str((TEMPLATE_PATH / "check").absolute()),
|
||||||
|
template_name="main.html",
|
||||||
|
templates={"data": data},
|
||||||
|
pages={
|
||||||
|
"viewport": {"width": 195, "height": 750},
|
||||||
|
"base_url": f"file://{TEMPLATE_PATH}",
|
||||||
|
},
|
||||||
|
wait=2,
|
||||||
|
)
|
||||||
|
await MessageUtils.build_message(image).send()
|
||||||
|
logger.info("自检", arparma.header_result, session=session)
|
||||||
|
except Exception as e:
|
||||||
|
await MessageUtils.build_message(f"自检失败: {e}").send()
|
||||||
|
logger.error("自检失败", arparma.header_result, session=session, e=e)
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
import platform
|
||||||
|
from pathlib import Path
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
import psutil
|
||||||
|
import cpuinfo
|
||||||
|
import nonebot
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from nonebot.utils import run_sync
|
||||||
|
from httpx import NetworkError, ConnectTimeout
|
||||||
|
|
||||||
|
from zhenxun.services.log import logger
|
||||||
|
from zhenxun.configs.config import BotConfig
|
||||||
|
from zhenxun.utils.http_utils import AsyncHttpx
|
||||||
|
|
||||||
|
BAIDU_URL = "https://www.baidu.com/"
|
||||||
|
GOOGLE_URL = "https://www.google.com/"
|
||||||
|
|
||||||
|
VERSION_FILE = Path() / "__version__"
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CPUInfo:
|
||||||
|
core: int
|
||||||
|
"""CPU 物理核心数"""
|
||||||
|
usage: float
|
||||||
|
"""CPU 占用百分比,取值范围(0,100]"""
|
||||||
|
freq: float
|
||||||
|
"""CPU 的时钟速度(单位:GHz)"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cpu_info(cls):
|
||||||
|
cpu_core = psutil.cpu_count(logical=False)
|
||||||
|
cpu_usage = psutil.cpu_percent(interval=1)
|
||||||
|
cpu_freq = round(psutil.cpu_freq().current / 1000, 2)
|
||||||
|
|
||||||
|
return CPUInfo(core=cpu_core, usage=cpu_usage, freq=cpu_freq)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RAMInfo:
|
||||||
|
"""RAM 信息(单位:GB)"""
|
||||||
|
|
||||||
|
total: float
|
||||||
|
"""RAM 总量"""
|
||||||
|
usage: float
|
||||||
|
"""当前 RAM 占用量/GB"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_ram_info(cls):
|
||||||
|
ram_total = round(psutil.virtual_memory().total / (1024**3), 2)
|
||||||
|
ram_usage = round(psutil.virtual_memory().used / (1024**3), 2)
|
||||||
|
|
||||||
|
return RAMInfo(total=ram_total, usage=ram_usage)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SwapMemory:
|
||||||
|
"""Swap 信息(单位:GB)"""
|
||||||
|
|
||||||
|
total: float
|
||||||
|
"""Swap 总量"""
|
||||||
|
usage: float
|
||||||
|
"""当前 Swap 占用量/GB"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_swap_info(cls):
|
||||||
|
swap_total = round(psutil.swap_memory().total / (1024**3), 2)
|
||||||
|
swap_usage = round(psutil.swap_memory().used / (1024**3), 2)
|
||||||
|
|
||||||
|
return SwapMemory(total=swap_total, usage=swap_usage)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DiskInfo:
|
||||||
|
"""硬盘信息"""
|
||||||
|
|
||||||
|
total: float
|
||||||
|
"""硬盘总量"""
|
||||||
|
usage: float
|
||||||
|
"""当前硬盘占用量/GB"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_disk_info(cls):
|
||||||
|
disk_total = round(psutil.disk_usage("/").total / (1024**3), 2)
|
||||||
|
disk_usage = round(psutil.disk_usage("/").used / (1024**3), 2)
|
||||||
|
|
||||||
|
return DiskInfo(total=disk_total, usage=disk_usage)
|
||||||
|
|
||||||
|
|
||||||
|
class SystemInfo(BaseModel):
|
||||||
|
"""系统信息"""
|
||||||
|
|
||||||
|
cpu: CPUInfo
|
||||||
|
"""CPU信息"""
|
||||||
|
ram: RAMInfo
|
||||||
|
"""RAM信息"""
|
||||||
|
swap: SwapMemory
|
||||||
|
"""SWAP信息"""
|
||||||
|
disk: DiskInfo
|
||||||
|
"""DISK信息"""
|
||||||
|
|
||||||
|
def get_system_info(self):
|
||||||
|
return {
|
||||||
|
"cpu_info": f"{self.cpu.usage}% - {self.cpu.freq}Ghz [{self.cpu.core} core]",
|
||||||
|
"cpu_process": psutil.cpu_percent(),
|
||||||
|
"ram_info": f"{self.ram.usage} / {self.ram.total} GB",
|
||||||
|
"ram_process": self.ram.usage / self.ram.total * 100,
|
||||||
|
"swap_info": f"{self.swap.usage} / {self.swap.total} GB",
|
||||||
|
"swap_process": self.swap.usage / self.swap.total * 100,
|
||||||
|
"disk_info": f"{self.disk.usage} / {self.disk.total} GB",
|
||||||
|
"disk_process": self.disk.usage / self.disk.total * 100,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@run_sync
|
||||||
|
def __build_status() -> dict:
|
||||||
|
"""获取 `CPU` `RAM` `SWAP` `DISK` 信息"""
|
||||||
|
cpu = CPUInfo.get_cpu_info()
|
||||||
|
ram = RAMInfo.get_ram_info()
|
||||||
|
swap = SwapMemory.get_swap_info()
|
||||||
|
disk = DiskInfo.get_disk_info()
|
||||||
|
|
||||||
|
return SystemInfo(cpu=cpu, ram=ram, swap=swap, disk=disk).get_system_info()
|
||||||
|
|
||||||
|
|
||||||
|
async def __get_network_info():
|
||||||
|
"""网络请求"""
|
||||||
|
baidu, google = True, True
|
||||||
|
try:
|
||||||
|
await AsyncHttpx.get(BAIDU_URL, timeout=5)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning("自检:百度无法访问...", e=e)
|
||||||
|
baidu = False
|
||||||
|
try:
|
||||||
|
await AsyncHttpx.get(GOOGLE_URL, timeout=5)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning("自检:谷歌无法访问...", e=e)
|
||||||
|
google = False
|
||||||
|
return baidu, google
|
||||||
|
|
||||||
|
|
||||||
|
def __get_version() -> str | None:
|
||||||
|
"""获取版本信息"""
|
||||||
|
with open(VERSION_FILE, encoding="utf-8") as f:
|
||||||
|
if text := f.read():
|
||||||
|
text.split(":")[-1]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
async def get_status_info() -> dict:
|
||||||
|
"""获取信息"""
|
||||||
|
data = await __build_status()
|
||||||
|
baidu, google = await __get_network_info()
|
||||||
|
data["baidu"] = "#8CC265" if baidu else "red"
|
||||||
|
data["google"] = "#8CC265" if google else "red"
|
||||||
|
system = platform.uname()
|
||||||
|
data["system"] = f"{system.system} {system.release}"
|
||||||
|
data["version"] = __get_version()
|
||||||
|
data["brand_raw"] = cpuinfo.get_cpu_info()["brand_raw"]
|
||||||
|
data["plugin_count"] = len(nonebot.get_loaded_plugins())
|
||||||
|
data["nickname"] = BotConfig.self_nickname
|
||||||
|
return data
|
||||||
@@ -1,27 +1,26 @@
|
|||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from nonebot.plugin import PluginMetadata
|
||||||
from nonebot import on_message, on_request
|
from nonebot import on_message, on_request
|
||||||
from nonebot.adapters.onebot.v11 import (
|
from nonebot_plugin_session import EventSession
|
||||||
ActionFailed,
|
from nonebot_plugin_apscheduler import scheduler
|
||||||
FriendRequestEvent,
|
|
||||||
GroupRequestEvent,
|
|
||||||
)
|
|
||||||
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
from nonebot.adapters.onebot.v11 import Bot as v11Bot
|
||||||
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
from nonebot.adapters.onebot.v12 import Bot as v12Bot
|
||||||
from nonebot.plugin import PluginMetadata
|
from nonebot.adapters.onebot.v11 import (
|
||||||
from nonebot_plugin_apscheduler import scheduler
|
ActionFailed,
|
||||||
from nonebot_plugin_session import EventSession
|
GroupRequestEvent,
|
||||||
|
FriendRequestEvent,
|
||||||
|
)
|
||||||
|
|
||||||
from zhenxun.configs.config import BotConfig, Config
|
|
||||||
from zhenxun.configs.utils import PluginExtraData, RegisterConfig
|
|
||||||
from zhenxun.models.fg_request import FgRequest
|
|
||||||
from zhenxun.models.friend_user import FriendUser
|
|
||||||
from zhenxun.models.group_console import GroupConsole
|
|
||||||
from zhenxun.services.log import logger
|
from zhenxun.services.log import logger
|
||||||
from zhenxun.utils.enum import PluginType, RequestHandleType, RequestType
|
from zhenxun.models.fg_request import FgRequest
|
||||||
from zhenxun.utils.message import MessageUtils
|
|
||||||
from zhenxun.utils.platform import PlatformUtils
|
from zhenxun.utils.platform import PlatformUtils
|
||||||
|
from zhenxun.models.friend_user import FriendUser
|
||||||
|
from zhenxun.configs.config import Config, BotConfig
|
||||||
|
from zhenxun.models.group_console import GroupConsole
|
||||||
|
from zhenxun.configs.utils import RegisterConfig, PluginExtraData
|
||||||
|
from zhenxun.utils.enum import PluginType, RequestType, RequestHandleType
|
||||||
|
|
||||||
base_config = Config.get("invite_manager")
|
base_config = Config.get("invite_manager")
|
||||||
|
|
||||||
@@ -119,91 +118,92 @@ async def _(bot: v12Bot | v11Bot, event: FriendRequestEvent, session: EventSessi
|
|||||||
|
|
||||||
@group_req.handle()
|
@group_req.handle()
|
||||||
async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSession):
|
async def _(bot: v12Bot | v11Bot, event: GroupRequestEvent, session: EventSession):
|
||||||
if event.sub_type == "invite":
|
if event.sub_type != "invite":
|
||||||
if str(event.user_id) in bot.config.superusers:
|
return
|
||||||
try:
|
if str(event.user_id) in bot.config.superusers:
|
||||||
logger.debug(
|
try:
|
||||||
"超级用户自动同意加入群聊",
|
|
||||||
"群聊请求",
|
|
||||||
session=event.user_id,
|
|
||||||
target=event.group_id,
|
|
||||||
)
|
|
||||||
group, _ = await GroupConsole.update_or_create(
|
|
||||||
group_id=str(event.group_id),
|
|
||||||
defaults={
|
|
||||||
"group_name": "",
|
|
||||||
"max_member_count": 0,
|
|
||||||
"member_count": 0,
|
|
||||||
"group_flag": 1,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
await bot.set_group_add_request(
|
|
||||||
flag=event.flag, sub_type="invite", approve=True
|
|
||||||
)
|
|
||||||
if isinstance(bot, v11Bot):
|
|
||||||
group_info = await bot.get_group_info(group_id=event.group_id)
|
|
||||||
max_member_count = group_info["max_member_count"]
|
|
||||||
member_count = group_info["member_count"]
|
|
||||||
else:
|
|
||||||
group_info = await bot.get_group_info(group_id=str(event.group_id))
|
|
||||||
max_member_count = 0
|
|
||||||
member_count = 0
|
|
||||||
group.max_member_count = max_member_count
|
|
||||||
group.member_count = member_count
|
|
||||||
group.group_name = group_info["group_name"]
|
|
||||||
await group.save(
|
|
||||||
update_fields=["group_name", "max_member_count", "member_count"]
|
|
||||||
)
|
|
||||||
except ActionFailed as e:
|
|
||||||
logger.error(
|
|
||||||
"超级用户自动同意加入群聊发生错误",
|
|
||||||
"群聊请求",
|
|
||||||
session=event.user_id,
|
|
||||||
target=event.group_id,
|
|
||||||
e=e,
|
|
||||||
)
|
|
||||||
elif Timer.check(f"{event.user_id}:{event.group_id}"):
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"收录 用户[{event.user_id}] 群聊[{event.group_id}] 群聊请求",
|
"超级用户自动同意加入群聊",
|
||||||
"群聊请求",
|
"群聊请求",
|
||||||
|
session=event.user_id,
|
||||||
target=event.group_id,
|
target=event.group_id,
|
||||||
)
|
)
|
||||||
nickname = await FriendUser.get_user_name(str(event.user_id))
|
group, _ = await GroupConsole.update_or_create(
|
||||||
await bot.send_private_msg(
|
|
||||||
user_id=event.user_id,
|
|
||||||
message=f"想要邀请我偷偷入群嘛~已经提醒{BotConfig.self_nickname}的管理员大人了\n"
|
|
||||||
"请确保已经群主或群管理沟通过!\n"
|
|
||||||
"等待管理员处理吧!",
|
|
||||||
)
|
|
||||||
# 旧请求全部设置为过期
|
|
||||||
await FgRequest.filter(
|
|
||||||
request_type=RequestType.GROUP,
|
|
||||||
user_id=str(event.user_id),
|
|
||||||
group_id=str(event.group_id),
|
|
||||||
handle_type__isnull=True,
|
|
||||||
).update(handle_type=RequestHandleType.EXPIRE)
|
|
||||||
f = await FgRequest.create(
|
|
||||||
request_type=RequestType.GROUP,
|
|
||||||
platform=session.platform,
|
|
||||||
bot_id=bot.self_id,
|
|
||||||
flag=event.flag,
|
|
||||||
user_id=str(event.user_id),
|
|
||||||
nickname=nickname,
|
|
||||||
group_id=str(event.group_id),
|
group_id=str(event.group_id),
|
||||||
|
defaults={
|
||||||
|
"group_name": "",
|
||||||
|
"max_member_count": 0,
|
||||||
|
"member_count": 0,
|
||||||
|
"group_flag": 1,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
await PlatformUtils.send_superuser(
|
await bot.set_group_add_request(
|
||||||
bot,
|
flag=event.flag, sub_type="invite", approve=True
|
||||||
f"*****一份入群申请*****\n"
|
|
||||||
"ID:{f.id}\n"
|
|
||||||
"申请人:{nickname}({event.user_id})\n群聊:"
|
|
||||||
f"{event.group_id}\n邀请日期:{datetime.now().replace(microsecond=0)}",
|
|
||||||
)
|
)
|
||||||
else:
|
if isinstance(bot, v11Bot):
|
||||||
logger.debug(
|
group_info = await bot.get_group_info(group_id=event.group_id)
|
||||||
"群聊请求五分钟内重复, 已忽略",
|
max_member_count = group_info["max_member_count"]
|
||||||
|
member_count = group_info["member_count"]
|
||||||
|
else:
|
||||||
|
group_info = await bot.get_group_info(group_id=str(event.group_id))
|
||||||
|
max_member_count = 0
|
||||||
|
member_count = 0
|
||||||
|
group.max_member_count = max_member_count
|
||||||
|
group.member_count = member_count
|
||||||
|
group.group_name = group_info["group_name"]
|
||||||
|
await group.save(
|
||||||
|
update_fields=["group_name", "max_member_count", "member_count"]
|
||||||
|
)
|
||||||
|
except ActionFailed as e:
|
||||||
|
logger.error(
|
||||||
|
"超级用户自动同意加入群聊发生错误",
|
||||||
"群聊请求",
|
"群聊请求",
|
||||||
target=f"{event.user_id}:{event.group_id}",
|
session=event.user_id,
|
||||||
|
target=event.group_id,
|
||||||
|
e=e,
|
||||||
)
|
)
|
||||||
|
elif Timer.check(f"{event.user_id}:{event.group_id}"):
|
||||||
|
logger.debug(
|
||||||
|
f"收录 用户[{event.user_id}] 群聊[{event.group_id}] 群聊请求",
|
||||||
|
"群聊请求",
|
||||||
|
target=event.group_id,
|
||||||
|
)
|
||||||
|
nickname = await FriendUser.get_user_name(str(event.user_id))
|
||||||
|
await bot.send_private_msg(
|
||||||
|
user_id=event.user_id,
|
||||||
|
message=f"想要邀请我偷偷入群嘛~已经提醒{BotConfig.self_nickname}的管理员大人了\n"
|
||||||
|
"请确保已经群主或群管理沟通过!\n"
|
||||||
|
"等待管理员处理吧!",
|
||||||
|
)
|
||||||
|
# 旧请求全部设置为过期
|
||||||
|
await FgRequest.filter(
|
||||||
|
request_type=RequestType.GROUP,
|
||||||
|
user_id=str(event.user_id),
|
||||||
|
group_id=str(event.group_id),
|
||||||
|
handle_type__isnull=True,
|
||||||
|
).update(handle_type=RequestHandleType.EXPIRE)
|
||||||
|
f = await FgRequest.create(
|
||||||
|
request_type=RequestType.GROUP,
|
||||||
|
platform=session.platform,
|
||||||
|
bot_id=bot.self_id,
|
||||||
|
flag=event.flag,
|
||||||
|
user_id=str(event.user_id),
|
||||||
|
nickname=nickname,
|
||||||
|
group_id=str(event.group_id),
|
||||||
|
)
|
||||||
|
await PlatformUtils.send_superuser(
|
||||||
|
bot,
|
||||||
|
f"*****一份入群申请*****\n"
|
||||||
|
f"ID:{f.id}\n"
|
||||||
|
f"申请人:{nickname}({event.user_id})\n群聊:"
|
||||||
|
f"{event.group_id}\n邀请日期:{datetime.now().replace(microsecond=0)}",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.debug(
|
||||||
|
"群聊请求五分钟内重复, 已忽略",
|
||||||
|
"群聊请求",
|
||||||
|
target=f"{event.user_id}:{event.group_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job(
|
@scheduler.scheduled_job(
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ class AsyncHttpx:
|
|||||||
cookies: dict[str, str] | None = None,
|
cookies: dict[str, str] | None = None,
|
||||||
timeout: int = 30,
|
timeout: int = 30,
|
||||||
stream: bool = False,
|
stream: bool = False,
|
||||||
|
follow_redirects: bool = True,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""下载文件
|
"""下载文件
|
||||||
@@ -204,7 +205,7 @@ class AsyncHttpx:
|
|||||||
use_proxy=use_proxy,
|
use_proxy=use_proxy,
|
||||||
proxy=proxy,
|
proxy=proxy,
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
follow_redirects=True,
|
follow_redirects=follow_redirects,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|||||||
Reference in New Issue
Block a user