-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path__init__.py
188 lines (159 loc) · 6.64 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import time
from collections import deque
from datetime import datetime
from pathlib import Path
import psutil
from creart import create
from graia.ariadne.app import Ariadne
from graia.ariadne.event.message import FriendMessage, GroupMessage
from graia.ariadne.message.chain import MessageChain
from graia.ariadne.message.element import Source
from graia.ariadne.message.parser.twilight import FullMatch, SpacePolicy, Twilight
from graia.ariadne.model import Friend, Group
from graia.ariadne.util.saya import decorate, dispatch, listen
from graia.saya import Channel, Saya
from graia.scheduler import timers
from graia.scheduler.saya import SchedulerSchema
from core.bot import Umaru
from core.config import GlobalConfig
from core.control import Distribute, FrequencyLimitation, Function, Permission
from core.models import response_model, saya_model
from utils.version_info import get_full_version_info
config = create(GlobalConfig)
core = create(Umaru)
module_controller = saya_model.get_module_controller()
account_controller = response_model.get_acc_controller()
saya = Saya.current()
channel = Channel.current()
channel.meta["name"] = "Status"
channel.meta["description"] = "查询BOT运行状态"
channel.meta["author"] = "13"
channel.metadata = module_controller.get_metadata_from_path(Path(__file__))
class MessageCount:
"""
用于管理和检索消息计数统计信息的类。
"""
def __init__(self):
"""
初始化 MessageCount 实例。
"""
self.receive_queue: deque[tuple[int, float]] = deque()
self.send_queue: deque[tuple[int, float]] = deque()
async def update_message_counts(self) -> None:
"""
更新消息计数。
参数:
- core: 包含消息计数数据的对象。
注意:
- 为更新消息计数日志,应定期调用此方法。
"""
self.receive_queue.append((core.received_count, time.time()))
self.send_queue.append((core.sent_count, time.time()))
def get_receive_count(self, time_limit: int | float = 60) -> int:
"""
获取过去指定时间内接收到的消息数量。
参数:
- time_limit: Union[int, float], 指定的时间范围,单位为秒,默认为60秒。
返回:
- int: 过去指定时间内接收到的消息数量。
"""
current_time = time.time()
# 从队列前端移除超过60秒的条目
while (
self.receive_queue and current_time - self.receive_queue[0][1] > time_limit
):
self.receive_queue.popleft()
# 计算并返回过去一分钟内消息计数的差值
return (
self.receive_queue[-1][0] - self.receive_queue[0][0]
if self.receive_queue
else 0
)
def get_send_count(self, time_limit: int | float = 60) -> int:
"""
获取过去指定时间内发送的消息数量。
参数:
- time_limit: Union[int, float], 指定的时间范围,单位为秒,默认为60秒。
返回:
- int: 过去指定时间内发送的消息数量。
"""
current_time = time.time()
# 从队列前端移除超过60秒的条目
while self.send_queue and current_time - self.send_queue[0][1] > time_limit:
self.send_queue.popleft()
# 计算并返回过去一分钟内消息计数的差值
return self.send_queue[-1][0] - self.send_queue[0][0] if self.send_queue else 0
message_count = MessageCount()
@channel.use(SchedulerSchema(timers.every_custom_seconds(3)))
async def message_counter():
await message_count.update_message_counts()
# 接收事件
@listen(GroupMessage, FriendMessage)
@decorate(
Distribute.require(),
Function.require(channel.module),
FrequencyLimitation.require(channel.module),
Permission.group_require(channel.metadata.level, if_noticed=True),
Permission.user_require(Permission.User, if_noticed=True),
)
@dispatch(Twilight([FullMatch("-bot").space(SpacePolicy.PRESERVE)]))
async def status(app: Ariadne, src_place: Group | Friend, source: Source):
# 获取版本信息
version, git_info, b2v_info = get_full_version_info()
# 运行时长
time_start = int(time.mktime(core.launch_time.timetuple()))
m, s = divmod(int(time.time()) - time_start, 60)
h, m = divmod(m, 60)
d, h = divmod(h, 24)
work_time = f"{d}天{h}小时{m}分{s}秒"
# 内存占用
mem = psutil.virtual_memory()
# 系统总计内存(单位字节)
# 系统已经使用内存(单位字节)
ysy = float(mem.used)
# 系统空闲内存(单位字节)
# 内存占比
zb = float(mem.percent)
# cpu占用
zb2 = f"{str(psutil.cpu_percent(interval=None, percpu=False))}%"
# 磁盘
cp = str(psutil.disk_usage("/").percent) + "%"
launch_time = datetime.fromtimestamp(core.launch_time.timestamp()).strftime(
"%Y年%m月%d日%H时%M分%S秒"
)
real_time_received_message_count = message_count.get_receive_count()
real_time_sent_message_count = message_count.get_send_count()
# 版本信息块
version_info = f"版本信息:v{version}\n"
if git_info["commit_short"] != "未知":
version_info += f"Git分支:{git_info['branch']}\n"
version_info += (
f"最新提交:{git_info['commit_short']} ({git_info['commit_author']})\n"
)
version_info += f"提交信息:{git_info['commit_message']}\n"
# 构建信息块
build_info = ""
if b2v_info["build_number"] != "开发环境":
build_info = f"构建编号:{b2v_info['build_number']}\n"
if b2v_info["build_date"]:
build_info += f"构建日期:{b2v_info['build_date']}\n"
build_info += f"构建类型:{b2v_info['build_type']}\n"
await app.send_message(
src_place,
MessageChain(
f"开机时间:{launch_time}\n",
f"运行时长:{work_time}\n",
f"接收消息:{core.received_count}条 (实时:{real_time_received_message_count}条/m)\n"
f"发送消息:{core.sent_count + 1}条 (实时:{real_time_sent_message_count}条/m)\n"
f"内存使用:{ysy / 1024 / 1024:.0f}MB ({zb:.0f}%)\n",
f"CPU占比:{zb2}\n",
f"磁盘占比:{cp}\n",
f"在线bot数量:{len([app_item for app_item in core.apps if Ariadne.current(app_item.account).connection.status.available])}/"
f"{len(core.apps)}\n",
f"活动群组数量:{len(account_controller.total_groups.keys())}\n",
version_info,
build_info,
"项目地址:https://github.com/g1331/xiaomai-bot",
),
quote=source,
)