feat✨: 更新内置插件

This commit is contained in:
HibiKier
2024-02-25 03:18:34 +08:00
parent 131200a28e
commit eb0572ea77
83 changed files with 7588 additions and 450 deletions
@@ -0,0 +1,61 @@
from typing import Annotated
from nonebot import on_command
from nonebot.adapters import Bot
from nonebot.params import Command
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot_plugin_alconna import UniMsg
from nonebot_plugin_saa import Text
from nonebot_plugin_session import EventSession
from zhenxun.configs.config import Config
from zhenxun.configs.utils import PluginExtraData, RegisterConfig, Task
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
from ._data_source import BroadcastManage
__plugin_meta__ = PluginMetadata(
name="广播",
description="昭告天下!",
usage="""
广播 [消息] [图片]
示例:广播 你们好!
""".strip(),
extra=PluginExtraData(
author="HibiKier",
version="0.1",
plugin_type=PluginType.SUPERUSER,
configs=[
RegisterConfig(
module="_task",
key="DEFAULT_BROADCAST",
value=True,
help="被动 广播 进群默认开关状态",
default_value=True,
type=bool,
)
],
tasks=[Task(module="broadcast", name="广播")],
).dict(),
)
_matcher = on_command("广播", priority=1, permission=SUPERUSER, block=True)
@_matcher.handle()
async def _(
bot: Bot,
session: EventSession,
message: UniMsg,
command: Annotated[tuple[str, ...], Command()],
):
message[0].text = message[0].text.replace(command[0], "").strip()
# await Text("正在发送..请等一下哦!").send()
count, error_count = await BroadcastManage.send(bot, message, session)
result = f"成功广播 {count} 个群组"
if error_count:
result += f"\n广播失败 {error_count} 个群组"
await Text(f"发送广播完成!\n{result}").send(reply=True)
logger.info(f"发送广播信息: {message}", "广播", session=session)
@@ -0,0 +1,117 @@
import nonebot_plugin_alconna as alc
from nonebot.adapters import Bot
from nonebot.adapters.discord import Bot as DiscordBot
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_plugin_alconna import UniMsg
from nonebot_plugin_saa import (
Image,
MessageFactory,
TargetDoDoChannel,
TargetQQGroup,
Text,
)
from nonebot_plugin_session import EventSession
from pydantic import BaseModel
from zhenxun.models.group_console import GroupConsole
from zhenxun.services.log import logger
class GroupChannel(BaseModel):
group_id: str
"""群组id"""
channel_id: str | None = None
"""频道id"""
class BroadcastManage:
@classmethod
async def send(
cls, bot: Bot, message: UniMsg, session: EventSession
) -> tuple[int, int]:
"""发送广播消息
参数:
bot: Bot
message: 消息内容
session: Session
返回:
tuple[int, int]: 发送成功的群组数量, 发送失败的群组数量
"""
message_list = []
for msg in message:
if isinstance(msg, alc.Image) and msg.url:
message_list.append(Image(msg.url))
elif isinstance(msg, alc.Text):
message_list.append(Text(msg.text))
if group_list := await cls.__get_group_list(bot):
error_count = 0
for group in group_list:
try:
if not await GroupConsole.is_block_task(
group.group_id, "broadcast", group.channel_id
):
if isinstance(bot, (v11Bot, v12Bot)):
target = TargetQQGroup(group_id=int(group.group_id))
elif isinstance(bot, DodoBot):
target = TargetDoDoChannel(channel_id=group.channel_id) # type: ignore
await MessageFactory(message_list).send_to(target, bot)
logger.debug(
"发送成功",
"广播",
session=session,
target=f"{group.group_id}:{group.channel_id}",
)
except Exception as e:
error_count += 1
logger.error(
"发送失败",
"广播",
session=session,
target=f"{group.group_id}:{group.channel_id}",
e=e,
)
return len(group_list) - error_count, error_count
return 0, 0
@classmethod
async def __get_group_list(cls, bot: Bot) -> list[GroupChannel]:
"""获取群组id列表
参数:
bot: Bot
返回:
list[str]: 群组id列表
"""
if isinstance(bot, (v11Bot, v12Bot)):
group_list = await bot.get_group_list()
return [GroupChannel(group_id=str(g["group_id"])) for g in group_list]
if isinstance(bot, DodoBot):
island_list = await bot.get_island_list()
source_id_list = [
g.island_source_id for g in island_list if g.island_source_id
]
channel_id_list = []
for id in source_id_list:
channel_list = await bot.get_channel_list(island_source_id=id)
channel_id_list += [
GroupChannel(group_id=id, channel_id=c.channel_id)
for c in channel_list
]
return channel_id_list
if isinstance(bot, KaiheilaBot):
pass
# group_list = await bot.guild_list()
# if group_list.guilds:
# return [g.open_id for g in group_list.guilds if g.open_id]
if isinstance(bot, DiscordBot):
# TODO: discord获取群组列表
pass
return []
+1 -13
View File
@@ -1,21 +1,9 @@
from nonebot.adapters import Bot
from nonebot.adapters.kaiheila.exception import ApiNotAvailable
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot.rule import to_me
from nonebot_plugin_alconna import (
Alconna,
AlconnaMatch,
Arparma,
Match,
Query,
Subcommand,
UniMessage,
on_alconna,
store_true,
)
from nonebot_plugin_alconna import Alconna, on_alconna
from nonebot_plugin_alconna.matcher import AlconnaMatcher
from nonebot_plugin_saa import Text
from nonebot_plugin_session import EventSession
@@ -0,0 +1,161 @@
import nonebot
from arclet.alconna import Args, Option
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot_plugin_alconna import Alconna, Arparma, on_alconna
from nonebot_plugin_alconna.matcher import AlconnaMatcher
from nonebot_plugin_saa import Image, Text
from nonebot_plugin_session import EventSession
from zhenxun.configs.config import Config
from zhenxun.configs.path_config import DATA_PATH, IMAGE_PATH
from zhenxun.configs.utils import PluginExtraData, RegisterConfig
from zhenxun.models.plugin_info import PluginInfo
from zhenxun.models.task_info import TaskInfo
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
from zhenxun.utils.exception import EmptyError
from zhenxun.utils.image_utils import (
BuildImage,
build_sort_image,
group_image,
text2image,
)
from zhenxun.utils.rules import admin_check, ensure_group
__plugin_meta__ = PluginMetadata(
name="超级用户帮助",
description="超级用户帮助",
usage="""
超级用户帮助
""".strip(),
extra=PluginExtraData(
author="HibiKier",
version="0.1",
plugin_type=PluginType.SUPERUSER,
).dict(),
)
_matcher = on_alconna(
Alconna("超级用户帮助"),
permission=SUPERUSER,
priority=5,
block=True,
)
SUPERUSER_HELP_IMAGE = IMAGE_PATH / "SUPERUSER_HELP.png"
if SUPERUSER_HELP_IMAGE.exists():
SUPERUSER_HELP_IMAGE.unlink()
async def build_help() -> BuildImage:
"""构造超级用户帮助图片
异常:
EmptyError: 超级用户帮助为空
返回:
BuildImage: 超级用户帮助图片
"""
plugin_list = await PluginInfo.filter(plugin_type=PluginType.SUPERUSER).all()
data_list = []
for plugin in plugin_list:
if _plugin := nonebot.get_plugin_by_module_name(plugin.module_path):
if _plugin.metadata:
data_list.append({"plugin": plugin, "metadata": _plugin.metadata})
font = BuildImage.load_font("HYWenHei-85W.ttf", 20)
image_list = []
for data in data_list:
plugin = data["plugin"]
metadata = data["metadata"]
try:
usage = None
description = None
if metadata.usage:
usage = await text2image(
metadata.usage,
padding=5,
color=(255, 255, 255),
font_color=(0, 0, 0),
)
if metadata.description:
description = await text2image(
metadata.description,
padding=5,
color=(255, 255, 255),
font_color=(0, 0, 0),
)
width = 0
height = 100
if usage:
width = usage.width
height += usage.height
if description and description.width > width:
width = description.width
height += description.height
font_width, font_height = BuildImage.get_text_size(
plugin.name + f"[{plugin.level}]", font
)
if font_width > width:
width = font_width
A = BuildImage(width + 30, height + 120, "#EAEDF2")
await A.text((15, 10), plugin.name + f"[{plugin.level}]")
await A.text((15, 70), "简介:")
if not description:
description = BuildImage(A.width - 30, 30, (255, 255, 255))
await description.circle_corner(10)
await A.paste(description, (15, 100))
if not usage:
usage = BuildImage(A.width - 30, 30, (255, 255, 255))
await usage.circle_corner(10)
await A.text((15, description.height + 115), "用法:")
await A.paste(usage, (15, description.height + 145))
await A.circle_corner(10)
image_list.append(A)
except Exception as e:
logger.warning(
f"获取超级用户管理员插件 {plugin.module}: {plugin.name} 设置失败...",
"超级用户帮助",
e=e,
)
if task_list := await TaskInfo.all():
task_str = "\n".join([task.name for task in task_list])
task_str = "通过 开启/关闭 来控制群被动\n----------\n" + task_str
task_image = await text2image(task_str, padding=5, color=(255, 255, 255))
await task_image.circle_corner(10)
A = BuildImage(task_image.width + 50, task_image.height + 85, "#EAEDF2")
await A.text((25, 10), "被动技能")
await A.paste(task_image, (25, 50))
await A.circle_corner(10)
image_list.append(A)
if not image_list:
raise EmptyError()
image_group, _ = group_image(image_list)
A = await build_sort_image(image_group, color=(255, 255, 255), padding_top=160)
text = await BuildImage.build_text_image(
"超级用户帮助",
size=40,
)
tip = await BuildImage.build_text_image(
"注: ‘*’ 代表可有多个相同参数 ‘?’ 代表可省略该参数", size=25, font_color="red"
)
await A.paste(text, (50, 30))
await A.paste(tip, (50, 90))
await A.save(SUPERUSER_HELP_IMAGE)
return BuildImage(1, 1)
@_matcher.handle()
async def _(
session: EventSession,
matcher: AlconnaMatcher,
arparma: Arparma,
):
if not SUPERUSER_HELP_IMAGE.exists():
try:
await build_help()
except EmptyError:
await Text("超级用户帮助为空").finish(reply=True)
await Image(SUPERUSER_HELP_IMAGE).send()
logger.info("查看超级用户帮助", arparma.header_result, session=session)
@@ -1,119 +0,0 @@
from nonebot.adapters import Bot
from nonebot.adapters.kaiheila.exception import ApiNotAvailable
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot.rule import to_me
from nonebot_plugin_alconna import Alconna, Arparma, At, Match, on_alconna
from nonebot_plugin_saa import Mention, MessageFactory, Text
from nonebot_plugin_session import EventSession, SessionLevel
from zhenxun.configs.config import Config
from zhenxun.configs.utils import PluginExtraData
from zhenxun.models.friend_user import FriendUser
from zhenxun.models.group_info import GroupInfo
from zhenxun.models.level_user import LevelUser
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
__plugin_meta__ = PluginMetadata(
name="更新群组/好友信息",
description="更新群组/好友信息",
usage="""
更新群组信息
更新好友信息
""".strip(),
extra=PluginExtraData(
author="HibiKier",
version="0.1",
plugin_type=PluginType.SUPERUSER,
).dict(),
)
_group_matcher = on_alconna(
Alconna(
"更新群组信息",
),
permission=SUPERUSER,
rule=to_me(),
priority=1,
block=True,
)
_friend_matcher = on_alconna(
Alconna(
"更新好友信息",
),
permission=SUPERUSER,
rule=to_me(),
priority=1,
block=True,
)
# TODO: 其他adapter的更新操作
@_group_matcher.handle()
async def _(
bot: Bot,
session: EventSession,
arparma: Arparma,
):
try:
gl = await bot.get_group_list()
gl = [g["group_id"] for g in gl]
num = 0
for g in gl:
try:
group_info = await bot.get_group_info(group_id=g)
await GroupInfo.update_or_create(
group_id=str(group_info["group_id"]),
defaults={
"group_name": group_info["group_name"],
"max_member_count": group_info["max_member_count"],
"member_count": group_info["member_count"],
},
)
num += 1
logger.debug(
"群聊信息更新成功", "更新群信息", session=session, target=group_info["group_id"]
)
except Exception as e:
logger.error(
f"更新群聊信息失败",
arparma.header_result,
session=session,
target=g,
)
await Text(f"成功更新了 {len(gl)} 个群的信息").send()
logger.info(
f"更新群聊信息完成,共更新了 {len(gl)} 个群的信息", arparma.header_result, session=session
)
except (ApiNotAvailable, AttributeError) as e:
await Text("Api未实现...").send()
except Exception as e:
logger.error("更新好友信息发生错误", arparma.header_result, session=session, e=e)
await Text("其他未知错误...").send()
@_friend_matcher.assign("delete")
async def _(
bot: Bot,
session: EventSession,
arparma: Arparma,
):
num = 0
error_list = []
fl = await bot.get_friend_list()
for f in fl:
try:
await FriendUser.update_or_create(
user_id=str(f["user_id"]), defaults={"nickname": f["nickname"]}
)
logger.debug(f"更新好友信息成功", "更新好友信息", session=session, target=f["user_id"])
num += 1
except Exception as e:
logger.error(f"更新好友信息失败", "更新好友信息", session=session, target=f["user_id"], e=e)
await Text(f"成功更新了 {num} 个好友的信息!").send()
if error_list:
await Text(f"以下好友更新失败:\n" + "\n".join(error_list)).send()
logger.info(f"更新好友信息完成,共更新了 {num} 个群的信息", arparma.header_result, session=session)
@@ -0,0 +1,92 @@
from nonebot.adapters import Bot
from nonebot.adapters.kaiheila.exception import ApiNotAvailable
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 Text
from nonebot_plugin_session import EventSession
from zhenxun.configs.utils import PluginExtraData
from zhenxun.models.friend_user import FriendUser
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
from ._data_source import FgUpdateManage
__plugin_meta__ = PluginMetadata(
name="更新群组/好友信息",
description="更新群组/好友信息",
usage="""
更新群组信息
更新好友信息
""".strip(),
extra=PluginExtraData(
author="HibiKier",
version="0.1",
plugin_type=PluginType.SUPERUSER,
).dict(),
)
_group_matcher = on_alconna(
Alconna(
"更新群组信息",
),
permission=SUPERUSER,
rule=to_me(),
priority=1,
block=True,
)
_friend_matcher = on_alconna(
Alconna(
"更新好友信息",
),
permission=SUPERUSER,
rule=to_me(),
priority=1,
block=True,
)
@_group_matcher.handle()
async def _(
bot: Bot,
session: EventSession,
arparma: Arparma,
):
try:
num = await FgUpdateManage.update_group(bot, session.platform)
logger.info(
f"更新群聊信息完成,共更新了 {num} 个群组的信息!",
arparma.header_result,
session=session,
)
await Text(f"成功更新了 {num} 个群组的信息").send()
except Exception as e:
logger.error(
"更新群组信息发生错误", arparma.header_result, session=session, e=e
)
await Text("其他未知错误...").send()
@_friend_matcher.handle()
async def _(
bot: Bot,
session: EventSession,
arparma: Arparma,
):
try:
num = await FgUpdateManage.update_friend(bot, session.platform)
logger.info(
f"更新好友信息完成,共更新了 {num} 个好友的信息!",
arparma.header_result,
session=session,
)
await Text(f"成功更新了 {num} 个好友的信息").send()
except Exception as e:
logger.error(
"更新好友信息发生错误", arparma.header_result, session=session, e=e
)
await Text("其他未知错误...").send()
@@ -0,0 +1,156 @@
from nonebot.adapters import Bot
from nonebot.adapters.discord import Bot as DiscordBot
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 zhenxun.models.friend_user import FriendUser
from zhenxun.models.group_console import GroupConsole
from zhenxun.services.log import logger
class FgUpdateManage:
@classmethod
async def update_group(cls, bot: Bot, platform: str) -> int:
"""更新群组信息
参数:
bot: Bot
platform: 平台
返回:
int: 更新个数
"""
create_list = []
if group_list := await cls.__get_group_list(bot):
exists_group_list = await GroupConsole.all().values_list(
"group_id", "channel_id"
)
for group in group_list:
group.platform = platform
if (group.group_id, group.channel_id) not in exists_group_list:
create_list.append(group)
logger.debug(
"群聊信息更新成功",
"更新群信息",
target=f"{group.group_id}:{group.channel_id}",
)
if create_list:
await GroupConsole.bulk_create(create_list, 10)
return len(create_list)
@classmethod
async def __get_group_list(cls, bot: Bot) -> list[GroupConsole]:
"""获取群组列表
参数:
bot: Bot
返回:
list[GroupConsole]: 群组列表
"""
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
]
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
]
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 += [
GroupConsole(
group_id=id, group_name=c.channel_name, channel_id=c.channel_id
)
for c in channel_list
]
return group_list
if isinstance(bot, KaiheilaBot):
# TODO: kaiheila群组列表
pass
if isinstance(bot, DiscordBot):
# TODO: discord群组列表
pass
return []
@classmethod
async def update_friend(cls, bot: Bot, platform: str) -> int:
"""更新好友信息
参数:
bot: Bot
platform: 平台
返回:
int: 更新个数
"""
create_list = []
if friend_list := await cls.__get_friend_list(bot):
user_id_list = await FriendUser.all().values_list("user_id", flat=True)
for friend in friend_list:
friend.platform = platform
if friend.user_id not in user_id_list:
create_list.append(friend)
if create_list:
await FriendUser.bulk_create(create_list, 10)
return len(create_list)
@classmethod
async def __get_friend_list(cls, bot: Bot) -> list[FriendUser]:
"""获取好友列表
参数:
bot: Bot
返回:
list[FriendUser]: 好友列表
"""
if isinstance(bot, v11Bot):
friend_list = await bot.get_friend_list()
return [
FriendUser(user_id=str(f["user_id"]), user_name=f["nickname"])
for f in friend_list
]
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
]
if isinstance(bot, DodoBot):
# TODO: dodo好友列表
pass
if isinstance(bot, KaiheilaBot):
# TODO: kaiheila好友列表
pass
if isinstance(bot, DiscordBot):
# TODO: discord好友列表
pass
return []