Skip to content

Commit

Permalink
feat: 支持多适配器 (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
MeetWq authored Nov 22, 2023
1 parent c470c5a commit aa7de5d
Show file tree
Hide file tree
Showing 8 changed files with 855 additions and 905 deletions.
188 changes: 69 additions & 119 deletions nonebot_plugin_memes_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,32 @@
import random
import traceback
from itertools import chain
from typing import Any, Dict, List, NoReturn, Type, Union
from typing import Annotated, Any, Dict, List, NoReturn, Type

from nonebot import on_command, on_message, require
from nonebot.adapters.onebot.v11 import Bot as V11Bot
from nonebot.adapters.onebot.v11 import GroupMessageEvent as V11GMEvent
from nonebot.adapters.onebot.v11 import Message as V11Msg
from nonebot.adapters.onebot.v11 import MessageEvent as V11MEvent
from nonebot.adapters.onebot.v11 import MessageSegment as V11MsgSeg
from nonebot.adapters.onebot.v11.permission import (
GROUP_ADMIN,
GROUP_OWNER,
PRIVATE_FRIEND,
)
from nonebot.adapters.onebot.v12 import Bot as V12Bot
from nonebot.adapters.onebot.v12 import ChannelMessageEvent as V12CMEvent
from nonebot.adapters.onebot.v12 import GroupMessageEvent as V12GMEvent
from nonebot.adapters.onebot.v12 import Message as V12Msg
from nonebot.adapters.onebot.v12 import MessageEvent as V12MEvent
from nonebot.adapters.onebot.v12 import MessageSegment as V12MsgSeg
from nonebot.adapters.onebot.v12.permission import PRIVATE
from nonebot.adapters import Message
from nonebot.exception import AdapterException
from nonebot.log import logger
from nonebot.matcher import Matcher
from nonebot.params import CommandArg, Depends
from nonebot.permission import SUPERUSER
from nonebot.plugin import PluginMetadata
from nonebot.params import CommandArg
from nonebot.permission import SUPERUSER, Permission
from nonebot.plugin import PluginMetadata, inherit_supported_adapters
from nonebot.typing import T_Handler, T_State
from pypinyin import Style, pinyin

require("nonebot_plugin_saa")
require("nonebot_plugin_alconna")
require("nonebot_plugin_session")
require("nonebot_plugin_userinfo")
require("nonebot_plugin_localstore")

from nonebot_plugin_localstore import get_cache_dir
from nonebot_plugin_saa import Image, MessageFactory
from nonebot_plugin_session import EventSession, SessionId, SessionIdType, SessionLevel
from nonebot_plugin_userinfo import ImageSource, UserInfo

from .config import Config, memes_config
from .data_source import ImageSource, User, UserInfo
from .depends import (
IMAGE_SOURCES_KEY,
TEXTS_KEY,
USERS_KEY,
split_msg_v11,
split_msg_v12,
)
from .depends import IMAGE_SOURCES_KEY, TEXTS_KEY, USER_INFOS_KEY, split_msg
from .exception import *
from .manager import ActionResult, MemeMode, meme_manager
from .request import (
Expand All @@ -66,20 +50,38 @@
type="application",
homepage="https://github.com/noneplugin/nonebot-plugin-memes-api",
config=Config,
supported_adapters={"~onebot.v11", "~onebot.v12"},
supported_adapters=inherit_supported_adapters(
"nonebot_plugin_saa",
"nonebot_plugin_alconna",
"nonebot_plugin_session",
"nonebot_plugin_userinfo",
),
extra={
"unique_name": "memes_api",
"author": "meetwq <meetwq@gmail.com>",
"version": "0.1.5",
"version": "0.2.0",
},
)

memes_cache_dir = get_cache_dir("nonebot_plugin_memes_api")


PERM_EDIT = GROUP_ADMIN | GROUP_OWNER | PRIVATE_FRIEND | PRIVATE | SUPERUSER
def _is_private(session: EventSession) -> bool:
return session.level == SessionLevel.LEVEL1


PERM_EDIT = SUPERUSER | Permission(_is_private)
PERM_GLOBAL = SUPERUSER


try:
from nonebot.adapters.onebot.v11.permission import GROUP_ADMIN, GROUP_OWNER

PERM_EDIT |= GROUP_ADMIN | GROUP_OWNER
except ImportError:
pass


help_cmd = on_command("表情包制作", aliases={"头像表情包", "文字表情包"}, block=True, priority=11)
info_cmd = on_command("表情详情", aliases={"表情帮助", "表情示例"}, block=True, priority=11)
block_cmd = on_command("禁用表情", block=True, priority=11, permission=PERM_EDIT)
Expand All @@ -88,28 +90,11 @@
unblock_cmd_gl = on_command("全局启用表情", block=True, priority=11, permission=PERM_GLOBAL)


def get_user_id():
def dependency(
bot: Union[V11Bot, V12Bot], event: Union[V11MEvent, V12MEvent]
) -> str:
if isinstance(event, V11MEvent):
cid = f"{bot.self_id}_{event.message_type}_"
else:
cid = f"{bot.self_id}_{event.detail_type}_"

if isinstance(event, V11GMEvent) or isinstance(event, V12GMEvent):
cid += str(event.group_id)
elif isinstance(event, V12CMEvent):
cid += f"{event.guild_id}_{event.channel_id}"
else:
cid += str(event.user_id)
return cid

return Depends(dependency)
UserId = Annotated[str, SessionId(SessionIdType.GROUP, include_bot_type=False)]


@help_cmd.handle()
async def _(bot: Union[V11Bot, V12Bot], matcher: Matcher, user_id: str = get_user_id()):
async def _(user_id: UserId):
memes = sorted(
meme_manager.memes,
key=lambda meme: "".join(
Expand Down Expand Up @@ -138,23 +123,14 @@ async def _(bot: Union[V11Bot, V12Bot], matcher: Matcher, user_id: str = get_use
else:
img = meme_list_cache_file.read_bytes()

msg = "触发方式:“关键词 + 图片/文字”\n发送 “表情详情 + 关键词” 查看表情参数和预览\n目前支持的表情列表:"

if isinstance(bot, V11Bot):
await matcher.finish(msg + V11MsgSeg.image(img))
else:
resp = await bot.upload_file(type="data", name="memes", data=img)
file_id = resp["file_id"]
await matcher.finish(msg + V12MsgSeg.image(file_id))
msg = MessageFactory("触发方式:“关键词 + 图片/文字”\n发送 “表情详情 + 关键词” 查看表情参数和预览\n目前支持的表情列表:")
msg.append(Image(img))
await msg.send()


@info_cmd.handle()
async def _(
bot: Union[V11Bot, V12Bot],
matcher: Matcher,
msg: Union[V11Msg, V12Msg] = CommandArg(),
):
meme_name = msg.extract_plain_text().strip()
async def _(matcher: Matcher, arg: Message = CommandArg()):
meme_name = arg.extract_plain_text().strip()
if not meme_name:
matcher.block = False
await matcher.finish()
Expand All @@ -166,21 +142,14 @@ async def _(
info += "表情预览:\n"
img = await generate_meme_preview(meme.key)

if isinstance(bot, V11Bot):
await matcher.finish(info + V11MsgSeg.image(img))
else:
resp = await bot.upload_file(type="data", name="memes", data=img)
file_id = resp["file_id"]
await matcher.finish(info + V12MsgSeg.image(file_id))
msg = MessageFactory(info)
msg.append(Image(img))
await msg.send()


@block_cmd.handle()
async def _(
matcher: Matcher,
msg: Union[V11Msg, V12Msg] = CommandArg(),
user_id: str = get_user_id(),
):
meme_names = msg.extract_plain_text().strip().split()
async def _(matcher: Matcher, user_id: UserId, arg: Message = CommandArg()):
meme_names = arg.extract_plain_text().strip().split()
if not meme_names:
matcher.block = False
await matcher.finish()
Expand All @@ -198,12 +167,8 @@ async def _(


@unblock_cmd.handle()
async def _(
matcher: Matcher,
msg: Union[V11Msg, V12Msg] = CommandArg(),
user_id: str = get_user_id(),
):
meme_names = msg.extract_plain_text().strip().split()
async def _(matcher: Matcher, user_id: UserId, arg: Message = CommandArg()):
meme_names = arg.extract_plain_text().strip().split()
if not meme_names:
matcher.block = False
await matcher.finish()
Expand All @@ -221,8 +186,8 @@ async def _(


@block_cmd_gl.handle()
async def _(matcher: Matcher, msg: Union[V11Msg, V12Msg] = CommandArg()):
meme_names = msg.extract_plain_text().strip().split()
async def _(matcher: Matcher, arg: Message = CommandArg()):
meme_names = arg.extract_plain_text().strip().split()
if not meme_names:
matcher.block = False
await matcher.finish()
Expand All @@ -240,8 +205,8 @@ async def _(matcher: Matcher, msg: Union[V11Msg, V12Msg] = CommandArg()):


@unblock_cmd_gl.handle()
async def _(matcher: Matcher, msg: Union[V11Msg, V12Msg] = CommandArg()):
meme_names = msg.extract_plain_text().strip().split()
async def _(matcher: Matcher, arg: Message = CommandArg()):
meme_names = arg.extract_plain_text().strip().split()
if not meme_names:
matcher.block = False
await matcher.finish()
Expand All @@ -259,16 +224,14 @@ async def _(matcher: Matcher, msg: Union[V11Msg, V12Msg] = CommandArg()):


async def process(
bot: Union[V11Bot, V12Bot],
matcher: Matcher,
meme: MemeInfo,
image_sources: List[ImageSource],
texts: List[str],
users: List[User],
user_infos: List[UserInfo],
args: Dict[str, Any] = {},
):
images: List[bytes] = []
user_infos: List[UserInfo] = []

try:
for image_source in image_sources:
Expand All @@ -279,12 +242,13 @@ async def process(
logger.warning(traceback.format_exc())
await matcher.finish("图片下载出错,请稍后再试")

try:
for user in users:
user_infos.append(await user.get_info())
args["user_infos"] = user_infos
except (NetworkError, AdapterException):
logger.warning("用户信息获取失败\n" + traceback.format_exc())
args["user_infos"] = [
{
"name": user_info.user_displayname or user_info.user_name,
"gender": user_info.user_gender,
}
for user_info in user_infos
]

try:
result = await generate_meme(meme.key, images=images, texts=texts, args=args)
Expand All @@ -298,26 +262,16 @@ async def process(
logger.warning(traceback.format_exc())
await matcher.finish("出错了,请稍后再试")

if isinstance(bot, V11Bot):
await matcher.finish(V11MsgSeg.image(result))
else:
resp = await bot.upload_file(type="data", name="memes", data=result)
file_id = resp["file_id"]
await matcher.finish(V12MsgSeg.image(file_id))
await MessageFactory([Image(result)]).send()


def handler(meme: MemeInfo) -> T_Handler:
async def handle(
bot: Union[V11Bot, V12Bot],
state: T_State,
matcher: Matcher,
user_id: str = get_user_id(),
):
async def handle(state: T_State, matcher: Matcher, user_id: UserId):
if not meme_manager.check(user_id, meme.key):
return

raw_texts: List[str] = state[TEXTS_KEY]
users: List[User] = state[USERS_KEY]
user_infos: List[UserInfo] = state[USER_INFOS_KEY]
image_sources: List[ImageSource] = state[IMAGE_SOURCES_KEY]

texts: List[str] = []
Expand Down Expand Up @@ -361,14 +315,14 @@ async def finish(msg: str) -> NoReturn:
)

matcher.stop_propagation()
await process(bot, matcher, meme, image_sources, texts, users, args)
await process(matcher, meme, image_sources, texts, user_infos, args)

return handle


async def random_handler(bot: Union[V11Bot, V12Bot], state: T_State, matcher: Matcher):
async def random_handler(state: T_State, matcher: Matcher):
texts: List[str] = state[TEXTS_KEY]
users: List[User] = state[USERS_KEY]
user_infos: List[UserInfo] = state[USER_INFOS_KEY]
image_sources: List[ImageSource] = state[IMAGE_SOURCES_KEY]

random_meme = random.choice(
Expand All @@ -381,13 +335,12 @@ async def random_handler(bot: Union[V11Bot, V12Bot], state: T_State, matcher: Ma
)
]
)
await process(bot, matcher, random_meme, image_sources, texts, users)
await process(matcher, random_meme, image_sources, texts, user_infos)


random_matcher = on_message(command_rule(["随机表情"]), block=False, priority=12)
fake_meme = MemeInfo(key="_fake")
random_matcher.append_handler(random_handler, parameterless=[split_msg_v11(fake_meme)])
random_matcher.append_handler(random_handler, parameterless=[split_msg_v12(fake_meme)])
random_matcher.append_handler(random_handler, parameterless=[split_msg(fake_meme)])


matchers: Dict[str, List[Type[Matcher]]] = {}
Expand All @@ -406,10 +359,7 @@ def create_matchers():
)

for matcher in matchers[meme.key]:
matcher.plugin = random_matcher.plugin
matcher.plugin_name = random_matcher.plugin_name
matcher.append_handler(handler(meme), parameterless=[split_msg_v11(meme)])
matcher.append_handler(handler(meme), parameterless=[split_msg_v12(meme)])
matcher.append_handler(handler(meme), parameterless=[split_msg(meme)])


def destroy_matchers():
Expand Down
3 changes: 0 additions & 3 deletions nonebot_plugin_memes_api/data_source/__init__.py

This file was deleted.

Loading

0 comments on commit aa7de5d

Please sign in to comment.