perf👌: 广播与全局插件/被动管理

This commit is contained in:
HibiKier
2024-02-29 03:07:31 +08:00
parent 88bda9ce2c
commit a2d6c7f951
8 changed files with 433 additions and 138 deletions
@@ -1,6 +1,6 @@
from nonebot.adapters import Bot
from nonebot.plugin import PluginMetadata
from nonebot_plugin_alconna import Arparma, Match
from nonebot_plugin_alconna import AlconnaQuery, Arparma, Match, Query
from nonebot_plugin_saa import Image, Text
from nonebot_plugin_session import EventSession
@@ -21,14 +21,16 @@ __plugin_meta__ = PluginMetadata(
usage="""
普通管理员
格式:
开启/关闭[功能名称] : 开关功能
群被动状态 : 查看被动技能开关状态
醒来 : 结束休眠
休息吧 : 群组休眠, 不会再响应命令
开启/关闭[功能名称] : 开关功能
开启/关闭群被动[被动名称] : 群被动开关
群被动状态 : 查看被动技能开关状态
醒来 : 结束休眠
休息吧 : 群组休眠, 不会再响应命令
示例:
开启签到 : 开启签到
关闭签到 : 关闭签到
开启群被动早晚安 : 关闭被动任务早晚安
超级管理员额外命令
格式:
@@ -61,26 +63,21 @@ __plugin_meta__ = PluginMetadata(
@_status_matcher.assign("$main")
async def _(bot: Bot, session: EventSession, arparma: Arparma):
async def _(
bot: Bot,
session: EventSession,
arparma: Arparma,
task: Query[bool] = AlconnaQuery("task.value", False),
):
image = None
if session.id1 in bot.config.superusers:
if task.result:
image = await build_task(session.id3 or session.id2)
elif session.id1 in bot.config.superusers:
image = await build_plugin()
if image:
await Image(image.pic2bytes()).send(reply=True)
logger.info(
f"查看功能列表",
arparma.header_result,
session=session,
)
@_status_matcher.assign("task")
async def _(bot: Bot, session: EventSession, arparma: Arparma):
image = None
if image := await build_task(session.id3 or session.id2):
await Image(image.pic2bytes()).send(reply=True)
logger.info(
f"查看被动列表",
f"查看{'功能' if arparma.find('task') else '被动'}列表",
arparma.header_result,
session=session,
)
@@ -93,21 +90,35 @@ async def _(
arparma: Arparma,
name: str,
group: Match[str],
task: Query[bool] = AlconnaQuery("task.value", False),
):
if gid := session.id3 or session.id2:
result = await PluginManage.block_group_plugin(name, gid)
if task.result:
result = await PluginManage.unblock_group_task(name, gid)
else:
result = await PluginManage.block_group_plugin(name, gid)
await Text(result).send(reply=True)
logger.info(f"开启功能 {name}", arparma.header_result, session=session)
elif session.id1 in bot.config.superusers:
group_id = group.result if group.available else None
result = await PluginManage.superuser_block(name, None, group_id)
await Text(result).send(reply=True)
logger.info(
f"超级用户开启功能 {name}",
arparma.header_result,
session=session,
target=group_id,
)
if task.result:
result = await PluginManage.superuser_task_handle(name, group_id, True)
await Text(result).send(reply=True)
logger.info(
f"超级用户开启被动技能 {name}",
arparma.header_result,
session=session,
target=group_id,
)
else:
result = await PluginManage.superuser_block(name, None, group_id)
await Text(result).send(reply=True)
logger.info(
f"超级用户开启功能 {name}",
arparma.header_result,
session=session,
target=group_id,
)
@_status_matcher.assign("close")
@@ -118,27 +129,41 @@ async def _(
name: str,
block_type: Match[str],
group: Match[str],
task: Query[bool] = AlconnaQuery("task.value", False),
):
if gid := session.id3 or session.id2:
result = await PluginManage.unblock_group_plugin(name, gid)
if task.result:
result = await PluginManage.block_group_task(name, gid)
else:
result = await PluginManage.unblock_group_plugin(name, gid)
await Text(result).send(reply=True)
logger.info(f"关闭功能 {name}", arparma.header_result, session=session)
elif session.id1 in bot.config.superusers:
group_id = group.result if group.available else None
_type = BlockType.ALL
if block_type.available:
if block_type.result in ["p", "private"]:
_type = BlockType.PRIVATE
elif block_type.result in ["g", "group"]:
_type = BlockType.GROUP
result = await PluginManage.superuser_block(name, _type, group_id)
await Text(result).send(reply=True)
logger.info(
f"超级用户关闭功能 {name}, 禁用类型: {_type}",
arparma.header_result,
session=session,
target=group_id,
)
if task.result:
result = await PluginManage.superuser_task_handle(name, group_id, False)
await Text(result).send(reply=True)
logger.info(
f"超级用户关闭被动技能 {name}",
arparma.header_result,
session=session,
target=group_id,
)
else:
_type = BlockType.ALL
if block_type.available:
if block_type.result in ["p", "private"]:
_type = BlockType.PRIVATE
elif block_type.result in ["g", "group"]:
_type = BlockType.GROUP
result = await PluginManage.superuser_block(name, _type, group_id)
await Text(result).send(reply=True)
logger.info(
f"超级用户关闭功能 {name}, 禁用类型: {_type}",
arparma.header_result,
session=session,
target=group_id,
)
@_group_status_matcher.handle()
@@ -104,7 +104,9 @@ async def build_task(group_id: str | None) -> BuildImage:
column_name = ["ID", "模块", "名称", "群组状态", "全局状态", "运行时间"]
group = None
if group_id:
group = await GroupConsole.get_or_none(group_id=group_id)
group = await GroupConsole.get_or_none(
group_id=group_id, channel_id__isnull=True
)
if not group:
raise GroupInfoNotFound()
else:
@@ -145,17 +147,23 @@ class PluginManage:
@classmethod
async def is_wake(cls, group_id: str) -> bool:
if c := await GroupConsole.get_or_none(group_id=group_id):
if c := await GroupConsole.get_or_none(
group_id=group_id, channel_id__isnull=True
):
return c.status
return False
@classmethod
async def sleep(cls, group_id: str):
await GroupConsole.filter(group_id=group_id).update(status=False)
await GroupConsole.filter(group_id=group_id, channel_id__isnull=True).update(
status=False
)
@classmethod
async def wake(cls, group_id: str):
await GroupConsole.filter(group_id=group_id).update(status=True)
await GroupConsole.filter(group_id=group_id, channel_id__isnull=True).update(
status=True
)
@classmethod
async def block(cls, module: str):
@@ -178,6 +186,32 @@ class PluginManage:
"""
return await cls._change_group_plugin(plugin_name, group_id, True)
@classmethod
async def unblock_group_task(cls, task_name: str, group_id: str) -> str:
"""启用被动技能
参数:
task_name: 被动技能名称
group_id: 群组id
返回:
str: 返回信息
"""
return await cls._change_group_task(task_name, group_id, False)
@classmethod
async def block_group_task(cls, task_name: str, group_id: str) -> str:
"""禁用被动技能
参数:
task_name: 被动技能名称
group_id: 群组id
返回:
str: 返回信息
"""
return await cls._change_group_task(task_name, group_id, True)
@classmethod
async def unblock_group_plugin(cls, plugin_name: str, group_id: str) -> str:
"""启用群组插件
@@ -191,6 +225,33 @@ class PluginManage:
"""
return await cls._change_group_plugin(plugin_name, group_id, False)
@classmethod
async def _change_group_task(
cls, task_name: str, group_id: str, status: bool
) -> str:
"""改变群组被动技能状态
参数:
task_name: 被动技能名称
group_id: 群组Id
status: 状态
返回:
str: 返回信息
"""
if task := await TaskInfo.get_or_none(name=task_name):
status_str = "关闭" if status else "开启"
group, _ = await GroupConsole.get_or_create(
group_id=group_id, channel_id__isnull=True
)
if status:
group.block_task += f"{task.module},"
else:
group.block_task = group.block_task.replace(f"{task.module},", "")
await group.save(update_fields=["block_task"])
return f"已成功{status_str} {task_name} 被动技能!"
return "没有找到这个被动技能喔..."
@classmethod
async def _change_group_plugin(
cls, plugin_name: str, group_id: str, status: bool
@@ -212,7 +273,9 @@ class PluginManage:
plugin = await PluginInfo.get_or_none(name=plugin_name)
status_str = "开启" if status else "关闭"
if plugin:
group, _ = await GroupConsole.get_or_create(group_id=group_id)
group, _ = await GroupConsole.get_or_create(
group_id=group_id, channel_id__isnull=True
)
if status:
if plugin.module in group.block_plugin:
group.block_plugin = group.block_plugin.replace(
@@ -228,11 +291,44 @@ class PluginManage:
return f"该功能已经{status_str}了喔,不要重复{status_str}..."
return "没有找到这个功能喔..."
@classmethod
async def superuser_task_handle(
cls, task_name: str, group_id: str | None, status: bool
) -> str:
"""超级用户禁用被动技能
参数:
task_name: 被动技能名称
group_id: 群组id
status: 状态
返回:
str: 返回信息
"""
if task := await TaskInfo.get_or_none(name=task_name):
status_str = "开启" if status else "关闭"
if group_id:
group, _ = await GroupConsole.get_or_create(
group_id=group_id, channel_id__isnull=True
)
if status:
group.block_task = group.block_task.replace(
f"super:{task.module},", ""
)
else:
group.block_task += f"super:{task.module},"
await group.save(update_fields=["block_task"])
else:
task.status = status
await task.save(update_fields=["status"])
return f"已成功将被动技能 {task_name} 全局{status_str}!"
return "没有找到这个功能喔..."
@classmethod
async def superuser_block(
cls, plugin_name: str, block_type: BlockType | None, group_id: str | None
) -> str:
"""超级用户禁用
"""超级用户禁用插件
参数:
plugin_name: 插件名称
@@ -248,7 +344,9 @@ class PluginManage:
plugin = await PluginInfo.get_or_none(name=plugin_name)
if plugin:
if group_id:
if group := await GroupConsole.get_or_none(group_id=group_id):
if group := await GroupConsole.get_or_none(
group_id=group_id, channel_id__isnull=True
):
if f"super:{plugin.module}," not in group.block_plugin:
group.block_plugin += f"super:{plugin.module},"
await group.save(update_fields=["block_plugin"])
@@ -63,6 +63,15 @@ _status_matcher.shortcut(
prefix=True,
)
_status_matcher.shortcut(
r"开启群被动(?P<name>.+)",
command="switch",
arguments=["open", "{name}", "--task"],
prefix=True,
)
_status_matcher.shortcut(
r"开启(?P<name>.+)",
command="switch",
@@ -70,6 +79,13 @@ _status_matcher.shortcut(
prefix=True,
)
_status_matcher.shortcut(
r"关闭群被动(?P<name>.+)",
command="switch",
arguments=["close", "{name}", "--task"],
prefix=True,
)
_status_matcher.shortcut(
r"关闭(?P<name>.+)",
command="switch",
@@ -77,6 +93,7 @@ _status_matcher.shortcut(
prefix=True,
)
_group_status_matcher.shortcut(
r"醒来",
command="group-status",
+69 -22
View File
@@ -1,28 +1,75 @@
import nonebot
from nonebot.plugin import PluginMetadata
from nonebot_plugin_apscheduler import scheduler
from nonebot_plugin_saa import Image
# TODO: 消息发送
from zhenxun.configs.config import NICKNAME
from zhenxun.configs.path_config import IMAGE_PATH
from zhenxun.configs.utils import PluginExtraData, Task
from zhenxun.models.group_console import GroupConsole
from zhenxun.models.task_info import TaskInfo
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
from zhenxun.utils.platform import broadcast_group
# # 早上好
# @scheduler.scheduled_job(
# "cron",
# hour=6,
# minute=1,
# )
# async def _():
# img = image(IMAGE_PATH / "zhenxun" / "zao.jpg")
# await broadcast_group("[[_task|zwa]]早上好" + img, log_cmd="被动早晚安")
# logger.info("每日早安发送...")
__plugin_meta__ = PluginMetadata(
name="早晚安被动技能",
description="早晚安被动技能",
usage="",
extra=PluginExtraData(
author="HibiKier",
version="0.1",
plugin_type=PluginType.HIDDEN,
tasks=[
Task(module="group_welcome", name="进群欢迎"),
Task(module="refund_group_remind", name="退群提醒"),
],
).dict(),
)
driver = nonebot.get_driver()
@driver.on_startup
async def _():
if not await TaskInfo.exists(module="morning_goodnight"):
await TaskInfo.create(
module="morning_goodnight",
name="早晚安",
status=True,
)
async def check(group_id: str, channel_id: str | None) -> bool:
task = await TaskInfo.get_or_none(module="morning_goodnight")
if not task or not task.status:
return False
return await GroupConsole.is_block_task(group_id, "morning_goodnight")
# 早上好
@scheduler.scheduled_job(
"cron",
hour=6,
minute=1,
)
async def _():
img = Image(IMAGE_PATH / "zhenxun" / "zao.jpg")
await broadcast_group("早上好" + img, log_cmd="被动早晚安", check_func=check)
logger.info("每日早安发送...")
# # 睡觉了
# @scheduler.scheduled_job(
# "cron",
# hour=23,
# minute=59,
# )
# async def _():
# img = image(IMAGE_PATH / "zhenxun" / "sleep.jpg")
# await broadcast_group(
# f"[[_task|zwa]]{NICKNAME}要睡觉了,你们也要早点睡呀" + img, log_cmd="被动早晚安"
# )
# logger.info("每日晚安发送...")
@scheduler.scheduled_job(
"cron",
hour=23,
minute=59,
)
async def _():
img = Image(IMAGE_PATH / "zhenxun" / "sleep.jpg")
await broadcast_group(
f"{NICKNAME}要睡觉了,你们也要早点睡呀" + img,
log_cmd="被动早晚安",
check_func=check,
)
logger.info("每日晚安发送...")
@@ -5,6 +5,7 @@ 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 Text as alcText
from nonebot_plugin_alconna import UniMsg
from nonebot_plugin_saa import Text
from nonebot_plugin_session import EventSession
@@ -51,8 +52,11 @@ async def _(
message: UniMsg,
command: Annotated[tuple[str, ...], Command()],
):
message[0].text = message[0].text.replace(command[0], "").strip()
# await Text("正在发送..请等一下哦!").send()
for msg in message:
if isinstance(msg, alcText) and msg.text.strip().startswith(command[0]):
msg.text = msg.text.replace(command[0], "", 1).strip()
break
await Text("正在发送..请等一下哦!").send()
count, error_count = await BroadcastManage.send(bot, message, session)
result = f"成功广播 {count} 个群组"
if error_count:
@@ -9,23 +9,13 @@ 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"""
from zhenxun.utils.platform import PlatformManage
class BroadcastManage:
@@ -50,24 +40,27 @@ class BroadcastManage:
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):
group_list, _ = await PlatformManage.get_group_list(bot)
if group_list:
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}",
target = PlatformManage.get_target(
bot, group.group_id, group.channel_id
)
if target:
await MessageFactory(message_list).send_to(target, bot)
logger.debug(
"发送成功",
"广播",
session=session,
target=f"{group.group_id}:{group.channel_id}",
)
else:
logger.warning("target为空", "广播", session=session)
except Exception as e:
error_count += 1
logger.error(
@@ -79,40 +72,3 @@ class BroadcastManage:
)
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):
# TODO: kaiheila获取群组列表
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 []