重构webui适配 (#1801)

* ♻️ 使用Uninfo重构PlatformUtils基础方法

* 🩹 优化插件加载与模块格式转换逻辑

* 🚑 修复商店道具无法使用

* 🚑 修复道具无法正常使用

* 🔧 增加Bot状态管理及模块禁用功能

* 🎨  优化Web UI代码结构,修改target方法

* 🚨 auto fix by pre-commit hooks

* 🎨 添加菜单API及优化异常处理

* 🐛 优化菜单API及模型结构,修复WebUi插件列表Api

* 📝 更新仓库readme

* 🚨 add mdlint file

* 📝 Add help chapter.

* 🐛 修复优化AuthChecker逻辑

* 🐛 优化数据库API,移除冗余导入及修正SQL_DICT引用

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: BalconyJH <balconyjh@gmail.com>
This commit is contained in:
HibiKier
2024-12-25 12:03:49 +08:00
committed by GitHub
co-authored by pre-commit-ci[bot] BalconyJH
parent ebf05fd884
commit 35014e4048
32 changed files with 1939 additions and 1754 deletions
+106 -220
View File
@@ -5,14 +5,11 @@ from typing import Literal
import httpx
import nonebot
from nonebot.adapters import Bot
from nonebot.adapters.dodo import Bot as DodoBot
from nonebot.adapters.kaiheila import Bot as KaiheilaBot
from nonebot.adapters.onebot.v11 import Bot as v11Bot
from nonebot.adapters.onebot.v12 import Bot as v12Bot
from nonebot.utils import is_coroutine_callable
from nonebot_plugin_alconna import SupportScope
from nonebot_plugin_alconna.uniseg import Receipt, Target, UniMessage
from nonebot_plugin_uninfo import Uninfo, get_interface
from nonebot_plugin_uninfo import SceneType, Uninfo, get_interface
from nonebot_plugin_uninfo.model import Member
from pydantic import BaseModel
from zhenxun.configs.config import BotConfig
@@ -35,6 +32,8 @@ class UserData(BaseModel):
"""用户id"""
group_id: str | None = None
"""群组id"""
channel_id: str | None = None
"""频道id"""
role: str | None = None
"""角色"""
avatar_url: str | None = None
@@ -68,7 +67,7 @@ class PlatformUtils:
group_id: 群组id
duration: 禁言时长(分钟)
"""
if isinstance(bot, v11Bot):
if cls.get_platform(bot) == "qq":
await bot.set_group_ban(
group_id=int(group_id),
user_id=int(user_id),
@@ -116,148 +115,80 @@ class PlatformUtils:
返回:
list[UserData]: 用户数据列表
"""
if isinstance(bot, v11Bot):
if member_list := await bot.get_group_member_list(group_id=int(group_id)):
return [
UserData(
name=user["nickname"],
card=user["card"],
user_id=user["user_id"],
group_id=user["group_id"],
role=user["role"],
join_time=user["join_time"],
)
for user in member_list
]
if isinstance(bot, v12Bot):
if member_list := await bot.get_group_member_list(group_id=group_id):
return [
UserData(
name=user["user_name"],
card=user["user_displayname"],
user_id=user["user_id"],
group_id=group_id,
)
for user in member_list
]
if isinstance(bot, DodoBot):
if result_data := await bot.get_member_list(
island_source_id=group_id, page_size=100, max_id=0
):
max_id = result_data.max_id
result_list = result_data.list
while max_id == 100:
result_data = await bot.get_member_list(
island_source_id=group_id, page_size=100, max_id=0
)
result_list += result_data.list
max_id = result_data.max_id
return [
UserData(
name=user.nick_name,
card=user.personal_nick_name,
avatar_url=user.avatar_url,
user_id=user.dodo_source_id,
group_id=user.island_source_id,
join_time=int(user.join_time.timestamp()),
)
for user in result_list
]
if isinstance(bot, KaiheilaBot):
if result_data := await bot.guild_userList(guild_id=group_id):
if result_data.users:
data_list = []
for user in result_data.users:
second = None
if user.joined_at:
second = int(user.joined_at / 1000)
data_list.append(
UserData(
name=user.nickname or "",
avatar_url=user.avatar,
user_id=user.id_, # type: ignore
group_id=group_id,
join_time=second,
)
)
return data_list
if interface := get_interface(bot):
members: list[Member] = await interface.get_members(
SceneType.GROUP, group_id
)
return [
UserData(
name=member.user.name or "",
card=member.nick,
user_id=member.user.id,
group_id=group_id,
role=member.role.id if member.role else "",
avatar_url=member.user.avatar,
join_time=int(member.joined_at.timestamp())
if member.joined_at
else None,
)
for member in members
]
return []
@classmethod
async def get_user(
cls, bot: Bot, user_id: str, group_id: str | None = None
cls,
bot: Bot,
user_id: str,
group_id: str | None = None,
channel_id: str | None = None,
) -> UserData | None:
"""获取用户信息
参数:
bot: Bot
user_id: 用户id
group_id: 群组/频道id.
group_id: 群组id.
channel_id: 频道id.
返回:
UserData | None: 用户数据
"""
if isinstance(bot, v11Bot):
if group_id:
if user := await bot.get_group_member_info(
group_id=int(group_id), user_id=int(user_id)
):
return UserData(
name=user["nickname"],
card=user["card"],
user_id=user["user_id"],
group_id=user["group_id"],
role=user["role"],
join_time=user["join_time"],
)
elif friend_list := await bot.get_friend_list():
for f in friend_list:
if f["user_id"] == int(user_id):
return UserData(
name=f["nickname"],
card=f["remark"],
user_id=f["user_id"],
)
if isinstance(bot, v12Bot):
if group_id:
if user := await bot.get_group_member_info(
group_id=group_id, user_id=user_id
):
return UserData(
name=user["user_name"],
card=user["user_displayname"],
user_id=user["user_id"],
group_id=group_id,
)
elif friend_list := await bot.get_friend_list():
for f in friend_list:
if f["user_id"] == int(user_id):
return UserData(
name=f["user_name"],
card=f["user_remark"],
user_id=f["user_id"],
)
if isinstance(bot, DodoBot) and group_id:
if user := await bot.get_member_info(
island_source_id=group_id, dodo_source_id=user_id
):
return UserData(
name=user.nick_name,
card=user.personal_nick_name,
avatar_url=user.avatar_url,
user_id=user.dodo_source_id,
group_id=user.island_source_id,
join_time=int(user.join_time.timestamp()),
if interface := get_interface(bot):
member = None
user = None
if channel_id:
member = await interface.get_member(
SceneType.CHANNEL_TEXT, channel_id, user_id
)
if isinstance(bot, KaiheilaBot) and group_id:
if user := await bot.user_view(guild_id=group_id, user_id=user_id):
second = int(user.joined_at / 1000) if user.joined_at else None
if member:
user = member.user
elif group_id:
member = await interface.get_member(SceneType.GROUP, group_id, user_id)
if member:
user = member.user
else:
user = await interface.get_user(user_id)
if not user:
return None
if member:
return UserData(
name=user.nickname or "",
avatar_url=user.avatar,
user_id=user_id,
name=user.name or "",
card=member.nick,
user_id=user.id,
group_id=group_id,
join_time=second,
channel_id=channel_id,
role=member.role.id if member.role else None,
join_time=int(member.joined_at.timestamp())
if member.joined_at
else None,
)
else:
return UserData(
name=user.name or "",
user_id=user.id,
group_id=group_id,
channel_id=channel_id,
)
return None
@@ -337,7 +268,7 @@ class PlatformUtils:
返回:
Receipt | None: 是否发送成功
"""
if target := cls.get_target(bot, user_id, group_id):
if target := cls.get_target(user_id=user_id, group_id=group_id):
send_message = (
MessageUtils.build_message(message)
if isinstance(message, str)
@@ -361,7 +292,9 @@ class PlatformUtils:
group_list, platform = await cls.get_group_list(bot)
if group_list:
db_group = await GroupConsole.all()
db_group_id = [(group.group_id, group.channel_id) for group in db_group]
db_group_id: list[tuple[str, str]] = [
(group.group_id, group.channel_id) for group in db_group
]
for group in group_list:
group.platform = platform
if (group.group_id, group.channel_id) not in db_group_id:
@@ -411,69 +344,43 @@ class PlatformUtils:
return "unknown"
@classmethod
async def get_group_list(cls, bot: Bot) -> tuple[list[GroupConsole], str]:
async def get_group_list(
cls, bot: Bot, only_group: bool = False
) -> tuple[list[GroupConsole], str]:
"""获取群组列表
参数:
bot: Bot
only_group: 是否只获取群组(不获取channel)
返回:
tuple[list[GroupConsole], str]: 群组列表, 平台
"""
if isinstance(bot, v11Bot):
group_list = await bot.get_group_list()
return [
GroupConsole(
group_id=str(g["group_id"]),
group_name=g["group_name"],
max_member_count=g["max_member_count"],
member_count=g["member_count"],
)
for g in group_list
], "qq"
if isinstance(bot, v12Bot):
group_list = await bot.get_group_list()
return [
GroupConsole(
group_id=g.group_id, # type: ignore
user_name=g.group_name, # type: ignore
)
for g in group_list
], "qq"
if isinstance(bot, DodoBot):
island_list = await bot.get_island_list()
source_id_list = [
(g.island_source_id, g.island_name)
for g in island_list
if g.island_source_id
]
group_list = []
for id, name in source_id_list:
channel_list = await bot.get_channel_list(island_source_id=id)
group_list.append(GroupConsole(group_id=id, group_name=name))
group_list += [
if interface := get_interface(bot):
platform = cls.get_platform(bot)
result_list = []
scenes = await interface.get_scenes(SceneType.GROUP)
for scene in scenes:
group_id = scene.id
result_list.append(
GroupConsole(
group_id=id, group_name=c.channel_name, channel_id=c.channel_id
group_id=scene.id,
group_name=scene.name,
)
for c in channel_list
]
return group_list, "dodo"
if isinstance(bot, KaiheilaBot):
group_list = []
guilds = await bot.guild_list()
if guilds.guilds:
for guild_id, name in [(g.id_, g.name) for g in guilds.guilds if g.id_]:
view = await bot.guild_view(guild_id=guild_id)
group_list.append(GroupConsole(group_id=guild_id, group_name=name))
if view.channels:
group_list += [
GroupConsole(
group_id=guild_id, group_name=c.name, channel_id=c.id_
)
if not only_group and platform != "qq":
if channel_list := await interface.get_scenes(
parent_scene_id=group_id
):
for channel in channel_list:
result_list.append(
GroupConsole(
group_id=scene.id,
group_name=channel.name,
channel_id=channel.id,
)
)
for c in view.channels
if c.type != 0
]
return group_list, "kaiheila"
return result_list, platform
return [], ""
@classmethod
@@ -508,36 +415,17 @@ class PlatformUtils:
返回:
list[FriendUser]: 好友列表
"""
if isinstance(bot, v11Bot):
friend_list = await bot.get_friend_list()
if interface := get_interface(bot):
user_list = await interface.get_users()
return [
FriendUser(user_id=str(f["user_id"]), user_name=f["nickname"])
for f in friend_list
], "qq"
if isinstance(bot, v12Bot):
friend_list = await bot.get_friend_list()
return [
FriendUser(
user_id=f.user_id, # type: ignore
user_name=f.user_displayname or f.user_remark or f.user_name, # type: ignore
)
for f in friend_list
], "qq"
# if isinstance(bot, DodoBot):
# # TODO: dodo好友列表
# pass
# if isinstance(bot, KaiheilaBot):
# # TODO: kaiheila好友列表
# pass
# if isinstance(bot, DiscordBot):
# # TODO: discord好友列表
# pass
FriendUser(user_id=u.id, user_name=u.name) for u in user_list
], cls.get_platform(bot)
return [], ""
@classmethod
def get_target(
cls,
bot: Bot,
*,
user_id: str | None = None,
group_id: str | None = None,
channel_id: str | None = None,
@@ -554,16 +442,12 @@ class PlatformUtils:
target: 对应平台Target
"""
target = None
if isinstance(bot, v11Bot | v12Bot):
if group_id:
target = Target(group_id)
elif user_id:
target = Target(user_id, private=True)
elif isinstance(bot, DodoBot | KaiheilaBot):
if group_id and channel_id:
target = Target(channel_id, parent_id=group_id, channel=True)
elif user_id:
target = Target(user_id, private=True)
if group_id and channel_id:
target = Target(channel_id, parent_id=group_id, channel=True)
elif group_id:
target = Target(group_id)
elif user_id:
target = Target(user_id, private=True)
return target
@@ -646,7 +530,9 @@ async def broadcast_group(
)
continue
target = PlatformUtils.get_target(
_bot, None, group.group_id, group.channel_id
user_id=None,
group_id=group.group_id,
channel_id=group.channel_id,
)
if target:
_used_group.append(key)