status适配satori

This commit is contained in:
Expliyh 2024-05-16 21:17:10 +08:00
parent 7abdac7c9c
commit eaf57f2c33
No known key found for this signature in database
GPG Key ID: F30DE0CFF6157916
9 changed files with 191 additions and 107 deletions

View File

@ -5,12 +5,18 @@ from liteyuki.utils.base.ly_typing import T_MessageEvent
from liteyuki.utils import satori_utils from liteyuki.utils import satori_utils
from nonebot.adapters import satori from nonebot.adapters import satori
from nonebot_plugin_alconna.typings import Event from nonebot_plugin_alconna.typings import Event
from liteyuki.plugins.liteyuki_status.counter_for_satori import satori_counter
@event_preprocessor @event_preprocessor
async def pre_handle(event: Event): async def pre_handle(event: Event):
print("UPDATE_USER") print("UPDATE_USER")
print(event.__dict__)
if isinstance(event, satori.MessageEvent): if isinstance(event, satori.MessageEvent):
if event.user.id == event.self_id:
satori_counter.msg_sent += 1
else:
satori_counter.msg_received += 1
if event.user.name is not None: if event.user.name is not None:
await satori_utils.user_infos.put(event.user) await satori_utils.user_infos.put(event.user)
print(event.user) print(event.user)

View File

@ -9,7 +9,21 @@ from liteyuki.utils.message.npl import convert_seconds_to_time
from contextvars import ContextVar from contextvars import ContextVar
async def get_stat_msg_image(duration: int, period: int, group_id: str = None, bot_id: str = None, ulang: Language = Language()) -> bytes: async def count_msg_by_bot_id(bot_id: str) -> int:
condition = " AND bot_id = ?"
condition_args = [bot_id]
msg_rows = msg_db.where_all(
MessageEventModel(),
condition,
*condition_args
)
return len(msg_rows)
async def get_stat_msg_image(duration: int, period: int, group_id: str = None, bot_id: str = None,
ulang: Language = Language()) -> bytes:
""" """
获取统计消息 获取统计消息
Args: Args:
@ -58,15 +72,15 @@ async def get_stat_msg_image(duration: int, period: int, group_id: str = None, b
msg_count[index] += 1 msg_count[index] += 1
templates = { templates = {
"data": [ "data": [
{ {
"name" : ulang.get("stat.message") "name": ulang.get("stat.message")
+ f" Period {convert_seconds_to_time(period)}" + f" Duration {convert_seconds_to_time(duration)}" + f" Period {convert_seconds_to_time(period)}" + f" Duration {convert_seconds_to_time(duration)}"
+ (f" Group {group_id}" if group_id else "") + (f" Bot {bot_id}" if bot_id else ""), + (f" Group {group_id}" if group_id else "") + (f" Bot {bot_id}" if bot_id else ""),
"times" : timestamps, "times": timestamps,
"counts": msg_count "counts": msg_count
} }
] ]
} }
return await template2image(get_path("templates/stat_msg.html"), templates, debug=True) return await template2image(get_path("templates/stat_msg.html"), templates, debug=True)

View File

@ -6,15 +6,22 @@ from nonebot.message import event_postprocessor
from liteyuki.utils.base.data import Database, LiteModel from liteyuki.utils.base.data import Database, LiteModel
from liteyuki.utils.base.ly_typing import v11, satori from liteyuki.utils.base.ly_typing import v11, satori
from liteyuki.utils.base.ly_typing import T_Bot, T_MessageEvent
from .common import MessageEventModel, msg_db from .common import MessageEventModel, msg_db
from ...utils import satori_utils
require("nonebot_plugin_alconna") require("nonebot_plugin_alconna")
@event_postprocessor @event_postprocessor
async def general_event_monitor(bot: T_Bot, event: T_MessageEvent):
if isinstance(bot, satori.Bot):
return await satori_event_monitor(bot, event)
else:
return await onebot_v11_event_monitor(bot, event)
async def onebot_v11_event_monitor(bot: v11.Bot, event: v11.MessageEvent): async def onebot_v11_event_monitor(bot: v11.Bot, event: v11.MessageEvent):
if event.message_type == "group": if event.message_type == "group":
event: v11.GroupMessageEvent event: v11.GroupMessageEvent
@ -56,6 +63,6 @@ async def satori_event_monitor(bot: satori.Bot, event: satori.MessageEvent):
message=event.message, message=event.message,
message_text=event.message.content, message_text=event.message.content,
message_type=event.message_type, message_type=satori_utils.get_message_type(event),
) )
msg_db.save(mem) msg_db.save(mem)

View File

@ -5,23 +5,27 @@ import nonebot
import psutil import psutil
from cpuinfo import cpuinfo from cpuinfo import cpuinfo
from nonebot import require from nonebot import require
from nonebot.adapters import satori
from liteyuki.utils import __NAME__, __VERSION__ from liteyuki.utils import __NAME__, __VERSION__
from liteyuki.utils.base.config import get_config from liteyuki.utils.base.config import get_config
from liteyuki.utils.base.data_manager import TempConfig, common_db from liteyuki.utils.base.data_manager import TempConfig, common_db
from liteyuki.utils.base.language import Language from liteyuki.utils.base.language import Language
from liteyuki.utils.base.resource import get_loaded_resource_packs, get_path from liteyuki.utils.base.resource import get_loaded_resource_packs, get_path
from liteyuki.utils.message.html_tool import template2image from liteyuki.utils.message.html_tool import template2image
from liteyuki.utils import satori_utils
from .counter_for_satori import satori_counter
require("nonebot_plugin_apscheduler") require("nonebot_plugin_apscheduler")
from nonebot_plugin_apscheduler import scheduler from nonebot_plugin_apscheduler import scheduler
protocol_names = { protocol_names = {
0: "iPad", 0: "iPad",
1: "Android Phone", 1: "Android Phone",
2: "Android Watch", 2: "Android Watch",
3: "Mac", 3: "Mac",
5: "iPad", 5: "iPad",
6: "Android Pad", 6: "Android Pad",
} }
""" """
@ -77,17 +81,18 @@ async def refresh_status_card():
) )
async def generate_status_card(bot: dict, hardware: dict, liteyuki: dict, lang="zh-CN", bot_id="0", use_cache=False) -> bytes: async def generate_status_card(bot: dict, hardware: dict, liteyuki: dict, lang="zh-CN", bot_id="0",
use_cache=False) -> bytes:
if not use_cache: if not use_cache:
return await template2image( return await template2image(
get_path("templates/status.html", abs_path=True), get_path("templates/status.html", abs_path=True),
{ {
"data": { "data": {
"bot" : bot, "bot": bot,
"hardware" : hardware, "hardware": hardware,
"liteyuki" : liteyuki, "liteyuki": liteyuki,
"localization": get_local_data(lang) "localization": get_local_data(lang)
} }
}, },
debug=True debug=True
) )
@ -100,32 +105,32 @@ async def generate_status_card(bot: dict, hardware: dict, liteyuki: dict, lang="
def get_local_data(lang_code) -> dict: def get_local_data(lang_code) -> dict:
lang = Language(lang_code) lang = Language(lang_code)
return { return {
"friends" : lang.get("status.friends"), "friends": lang.get("status.friends"),
"groups" : lang.get("status.groups"), "groups": lang.get("status.groups"),
"plugins" : lang.get("status.plugins"), "plugins": lang.get("status.plugins"),
"bots" : lang.get("status.bots"), "bots": lang.get("status.bots"),
"message_sent" : lang.get("status.message_sent"), "message_sent": lang.get("status.message_sent"),
"message_received": lang.get("status.message_received"), "message_received": lang.get("status.message_received"),
"cpu" : lang.get("status.cpu"), "cpu": lang.get("status.cpu"),
"memory" : lang.get("status.memory"), "memory": lang.get("status.memory"),
"swap" : lang.get("status.swap"), "swap": lang.get("status.swap"),
"disk" : lang.get("status.disk"), "disk": lang.get("status.disk"),
"usage" : lang.get("status.usage"), "usage": lang.get("status.usage"),
"total" : lang.get("status.total"), "total": lang.get("status.total"),
"used" : lang.get("status.used"), "used": lang.get("status.used"),
"free" : lang.get("status.free"), "free": lang.get("status.free"),
"days" : lang.get("status.days"), "days": lang.get("status.days"),
"hours" : lang.get("status.hours"), "hours": lang.get("status.hours"),
"minutes" : lang.get("status.minutes"), "minutes": lang.get("status.minutes"),
"seconds" : lang.get("status.seconds"), "seconds": lang.get("status.seconds"),
"runtime" : lang.get("status.runtime"), "runtime": lang.get("status.runtime"),
"threads" : lang.get("status.threads"), "threads": lang.get("status.threads"),
"cores" : lang.get("status.cores"), "cores": lang.get("status.cores"),
"process" : lang.get("status.process"), "process": lang.get("status.process"),
"resources" : lang.get("status.resources"), "resources": lang.get("status.resources"),
"description" : lang.get("status.description"), "description": lang.get("status.description"),
} }
@ -134,8 +139,8 @@ async def get_bots_data(self_id: str = "0") -> dict:
Returns: Returns:
""" """
result = { result = {
"self_id": self_id, "self_id": self_id,
"bots" : [], "bots": [],
} }
for bot_id, bot in nonebot.get_bots().items(): for bot_id, bot in nonebot.get_bots().items():
groups = 0 groups = 0
@ -143,32 +148,45 @@ async def get_bots_data(self_id: str = "0") -> dict:
status = {} status = {}
bot_name = bot_id bot_name = bot_id
version_info = {} version_info = {}
try: if isinstance(bot, satori.Bot):
# API fetch try:
bot_name = (await bot.get_login_info())["nickname"] bot_name = (await satori_utils.user_infos.get(bot.self_id)).name
groups = len(await bot.get_group_list()) groups = str(await satori_utils.count_groups(bot))
friends = len(await bot.get_friend_list()) friends = str(await satori_utils.count_friends(bot))
status = await bot.get_status() status = {}
version_info = await bot.get_version_info() version_info = await bot.get_version_info()
except Exception: except Exception:
pass pass
else:
try:
# API fetch
bot_name = (await bot.get_login_info())["nickname"]
groups = len(await bot.get_group_list())
friends = len(await bot.get_friend_list())
status = await bot.get_status()
version_info = await bot.get_version_info()
except Exception:
pass
statistics = status.get("stat", {}) statistics = status.get("stat", {})
app_name = version_info.get("app_name", "UnknownImplementation") app_name = version_info.get("app_name", "UnknownImplementation")
if app_name in ["Lagrange.OneBot", "LLOneBot", "Shamrock"]: if app_name in ["Lagrange.OneBot", "LLOneBot", "Shamrock"]:
icon = f"https://q.qlogo.cn/g?b=qq&nk={bot_id}&s=640" icon = f"https://q.qlogo.cn/g?b=qq&nk={bot_id}&s=640"
elif isinstance(bot, satori.Bot):
app_name = "Satori"
icon = (await bot.login_get()).user.avatar
else: else:
icon = None icon = None
bot_data = { bot_data = {
"name" : bot_name, "name": bot_name,
"icon" : icon, "icon": icon,
"id" : bot_id, "id": bot_id,
"protocol_name" : protocol_names.get(version_info.get("protocol_name"), "Online"), "protocol_name": protocol_names.get(version_info.get("protocol_name"), "Online"),
"groups" : groups, "groups": groups,
"friends" : friends, "friends": friends,
"message_sent" : statistics.get("message_sent", 0), "message_sent": satori_counter.msg_sent if isinstance(bot, satori.Bot) else statistics.get("message_sent", 0),
"message_received": statistics.get("message_received", 0), "message_received": satori_counter.msg_received if isinstance(bot, satori.Bot) else statistics.get("message_received", 0),
"app_name" : app_name "app_name": app_name
} }
result["bots"].append(bot_data) result["bots"].append(bot_data)
@ -200,27 +218,27 @@ async def get_hardware_data() -> dict:
else: else:
brand = "Unknown" brand = "Unknown"
result = { result = {
"cpu" : { "cpu": {
"percent": psutil.cpu_percent(), "percent": psutil.cpu_percent(),
"name" : f"{brand} {cpuinfo.get_cpu_info().get('arch', 'Unknown')}", "name": f"{brand} {cpuinfo.get_cpu_info().get('arch', 'Unknown')}",
"cores" : psutil.cpu_count(logical=False), "cores": psutil.cpu_count(logical=False),
"threads": psutil.cpu_count(logical=True), "threads": psutil.cpu_count(logical=True),
"freq" : psutil.cpu_freq().current # MHz "freq": psutil.cpu_freq().current # MHz
}, },
"memory": { "memory": {
"percent" : mem.percent, "percent": mem.percent,
"total" : mem.total, "total": mem.total,
"used" : mem.used, "used": mem.used,
"free" : mem.free, "free": mem.free,
"usedProcess": mem_used_process, "usedProcess": mem_used_process,
}, },
"swap" : { "swap": {
"percent": swap.percent, "percent": swap.percent,
"total" : swap.total, "total": swap.total,
"used" : swap.used, "used": swap.used,
"free" : swap.free "free": swap.free
}, },
"disk" : [], "disk": [],
} }
for disk in psutil.disk_partitions(all=True): for disk in psutil.disk_partitions(all=True):
@ -229,11 +247,11 @@ async def get_hardware_data() -> dict:
if disk_usage.total == 0: if disk_usage.total == 0:
continue # 虚拟磁盘 continue # 虚拟磁盘
result["disk"].append({ result["disk"].append({
"name" : disk.mountpoint, "name": disk.mountpoint,
"percent": disk_usage.percent, "percent": disk_usage.percent,
"total" : disk_usage.total, "total": disk_usage.total,
"used" : disk_usage.used, "used": disk_usage.used,
"free" : disk_usage.free "free": disk_usage.free
}) })
except: except:
pass pass
@ -244,14 +262,14 @@ async def get_hardware_data() -> dict:
async def get_liteyuki_data() -> dict: async def get_liteyuki_data() -> dict:
temp_data: TempConfig = common_db.where_one(TempConfig(), default=TempConfig()) temp_data: TempConfig = common_db.where_one(TempConfig(), default=TempConfig())
result = { result = {
"name" : list(get_config("nickname", [__NAME__]))[0], "name": list(get_config("nickname", [__NAME__]))[0],
"version" : __VERSION__, "version": __VERSION__,
"plugins" : len(nonebot.get_loaded_plugins()), "plugins": len(nonebot.get_loaded_plugins()),
"resources": len(get_loaded_resource_packs()), "resources": len(get_loaded_resource_packs()),
"nonebot" : f"{nonebot.__version__}", "nonebot": f"{nonebot.__version__}",
"python" : f"{platform.python_implementation()} {platform.python_version()}", "python": f"{platform.python_implementation()} {platform.python_version()}",
"system" : f"{platform.system()} {platform.release()}", "system": f"{platform.system()} {platform.release()}",
"runtime" : time.time() - temp_data.data.get("start_time", time.time()), # 运行时间秒数 "runtime": time.time() - temp_data.data.get("start_time", time.time()), # 运行时间秒数
"bots" : len(nonebot.get_bots()) "bots": len(nonebot.get_bots())
} }
return result return result

View File

@ -0,0 +1,10 @@
class SatoriCounter:
msg_sent: int
msg_received: int
def __init__(self):
self.msg_sent = 0
self.msg_received = 0
satori_counter = SatoriCounter()

View File

@ -4,6 +4,7 @@ from liteyuki.utils.base.resource import get_path
from liteyuki.utils.message.html_tool import template2image from liteyuki.utils.message.html_tool import template2image
from liteyuki.utils.base.language import get_user_lang from liteyuki.utils.base.language import get_user_lang
from .api import * from .api import *
from ...utils import satori_utils
from ...utils.base.ly_typing import T_Bot, T_MessageEvent from ...utils.base.ly_typing import T_Bot, T_MessageEvent
require("nonebot_plugin_alconna") require("nonebot_plugin_alconna")
@ -27,7 +28,7 @@ status_alc = on_alconna(
@status_alc.handle() @status_alc.handle()
async def _(event: T_MessageEvent, bot: T_Bot): async def _(event: T_MessageEvent, bot: T_Bot):
ulang = get_user_lang(event.user_id) ulang = get_user_lang(satori_utils.get_user_id(event))
if ulang.lang_code in status_card_cache: if ulang.lang_code in status_card_cache:
image = status_card_cache[ulang.lang_code] image = status_card_cache[ulang.lang_code]
else: else:

View File

@ -1,3 +1,5 @@
from .user_info import user_infos from .user_info import user_infos
from .get_message_type import get_message_type from .get_message_type import get_message_type
from .event_tools import * from .event_tools import *
from .count_friends import count_friends
from .count_groups import count_groups

View File

@ -0,0 +1,13 @@
from nonebot.adapters import satori
async def count_friends(bot: satori.Bot) -> int:
cnt: int = 0
friend_response = await bot.friend_list()
while friend_response.next is not None:
cnt += len(friend_response.data)
friend_response = await bot.friend_list(next_token=friend_response.next)
cnt += len(friend_response.data)
return cnt - 1

View File

@ -0,0 +1,13 @@
from nonebot.adapters import satori
async def count_groups(bot: satori.Bot) -> int:
cnt: int = 0
group_response = await bot.guild_list()
while group_response.next is not None:
cnt += len(group_response.data)
group_response = await bot.friend_list(next_token=group_response.next)
cnt += len(group_response.data)
return cnt - 1