Skip to content

Commit

Permalink
🐛 fix button in qq adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed Jul 17, 2024
1 parent 40809de commit 844c8af
Show file tree
Hide file tree
Showing 12 changed files with 396 additions and 16 deletions.
26 changes: 25 additions & 1 deletion pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ dev = [
"nonebot-plugin-filehost>=1.1.1",
"nonebot-plugin-send-anything-anywhere>=0.6.1",
"pytest-mock>=3.14.0",
"pytest-sugar>=1.0.0",
]
[tool.pdm.build]
includes = ["src/nonebot_plugin_alconna"]
Expand Down
2 changes: 2 additions & 0 deletions src/nonebot_plugin_alconna/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
from .typings import Style as Style
from .params import assign as assign
from .rule import alconna as alconna
from .uniseg import Button as Button
from .uniseg import SCOPES as SCOPES
from .uniseg import Target as Target
from .uniseg import UniMsg as UniMsg
Expand All @@ -72,6 +73,7 @@
from .uniseg import get_bot as get_bot
from .matcher import Command as Command
from .typings import Spoiler as Spoiler
from .uniseg import Keyboard as Keyboard
from .matcher import referent as referent
from .params import AlcResult as AlcResult
from .uniseg import MessageId as MessageId
Expand Down
2 changes: 2 additions & 0 deletions src/nonebot_plugin_alconna/uniseg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
from .params import UniMsg as UniMsg
from .target import SCOPES as SCOPES
from .target import Target as Target
from .segment import Button as Button
from .tools import get_bot as get_bot
from .message import Receipt as Receipt
from .segment import RefNode as RefNode
from .segment import Segment as Segment
from .segment import Keyboard as Keyboard
from .params import MessageId as MessageId
from .params import MsgTarget as MsgTarget
from .segment import Reference as Reference
Expand Down
20 changes: 15 additions & 5 deletions src/nonebot_plugin_alconna/uniseg/adapters/discord/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,10 @@ def _button(self, seg: Button, bot: Union[Bot, None]):
label = str(seg.label)
if seg.flag == "link" and seg.url:
return ButtonModel(style=styles.get(seg.style or "", ButtonStyle.Primary), label=label, url=seg.url)
if seg.flag == "action" and seg.id:
return ButtonModel(style=styles.get(seg.style or "", ButtonStyle.Primary), label=label, custom_id=seg.id)
if seg.flag == "action":
return ButtonModel(
style=styles.get(seg.style or "", ButtonStyle.Primary), label=label, custom_id=seg.id or label
)
if seg.text:
return TextInput(
custom_id=seg.id or label,
Expand All @@ -150,11 +152,19 @@ def _button(self, seg: Button, bot: Union[Bot, None]):
async def button(self, seg: Button, bot: Union[Bot, None]) -> "MessageSegment":
return MessageSegment.component(self._button(seg, bot))

@export
async def keyboard(self, seg: Keyboard, bot: Union[Bot, None]) -> "MessageSegment":
@export # type: ignore
async def keyboard(self, seg: Keyboard, bot: Union[Bot, None]):
if not seg.children:
raise SerializeFailed(lang.require("nbp-uniseg", "invalid_segment").format(type="keyboard", seg=seg))
return MessageSegment.component(ActionRow(components=[self._button(but, bot) for but in seg.children]))

if not seg.row:
return MessageSegment.component(ActionRow(components=[self._button(but, bot) for but in seg.children]))

buttons = [self._button(but, bot) for but in seg.children]
return [
MessageSegment.component(ActionRow(components=buttons[i : i + seg.row])) # type: ignore
for i in range(0, len(buttons), seg.row)
]

async def send_to(self, target: Union[Target, Event], bot: Bot, message: Message):
assert isinstance(bot, DiscordBot)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pathlib import Path
from secrets import token_urlsafe
from typing import TYPE_CHECKING, Any, Union

from tarina import lang
Expand Down Expand Up @@ -199,7 +198,7 @@ def _button(self, seg: Button, bot: Union[Bot, None]):
perm = ButtonActionPermission(type=0, user_ids=[i.target for i in seg.permission])
label = str(seg.label)
return ButtonModel(
id=seg.id or token_urlsafe(4),
id=seg.id or label,
render_data=ButtonRender(
label=label,
visited_label=seg.clicked_label or label,
Expand Down
6 changes: 3 additions & 3 deletions src/nonebot_plugin_alconna/uniseg/adapters/qq/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,16 +305,16 @@ def _button(self, seg: Button, bot: Union[Bot, None]):
perm = Permission(type=0, specify_user_ids=[i.target for i in seg.permission])
label = str(seg.label)
return ButtonModel(
id=seg.id,
id=seg.id or label,
render_data=RenderData(
label=label,
visited_label=seg.clicked_label or label,
style=0 if seg.style == "secondary" else 1,
),
action=Action(
type=0 if seg.flag == "link" else 1 if seg.flag == "action" else 2,
data=seg.url or seg.text or label,
enter=seg.flag == "enter",
data=seg.url or seg.text or (label if seg.flag != "action" else None),
enter=True if seg.flag == "enter" else False if seg.flag == "input" else None,
unsupport_tips="该版本暂不支持查看此消息,请升级至最新版本。",
permission=perm,
),
Expand Down
7 changes: 3 additions & 4 deletions src/nonebot_plugin_alconna/uniseg/adapters/satori/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,12 @@ async def at_all(self, seg: AtAll, bot: Union[Bot, None]) -> "MessageSegment":

@export
async def button(self, seg: Button, bot: Union[Bot, None]) -> "MessageSegment":
label = str(seg.label)
if seg.flag == "action" and seg.id:
return MessageSegment.action_button(seg.id, label, seg.style)
return MessageSegment.action_button(seg.id, seg.style)(await self.export(seg.children, bot, True)) # type: ignore
elif seg.flag == "link" and seg.url:
return MessageSegment.link_button(seg.url, label, seg.style)
return MessageSegment.link_button(seg.url, seg.style)(await self.export(seg.children, bot, True)) # type: ignore
elif seg.text:
return MessageSegment.input_button(seg.text, label, seg.style)
return MessageSegment.input_button(seg.text, seg.style)(await self.export(seg.children, bot, True)) # type: ignore
else:
raise SerializeFailed(lang.require("nbp-uniseg", "invalid_segment").format(type="button", seg=seg))

Expand Down
78 changes: 77 additions & 1 deletion src/nonebot_plugin_alconna/uniseg/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,26 @@
from .template import UniMessageTemplate
from .adapters import BUILDER_MAPPING, EXPORTER_MAPPING
from .fallback import FallbackMessage, FallbackStrategy
from .segment import At, File, I18n, Text, AtAll, Audio, Emoji, Hyper, Image, Reply, Video, Voice, Segment
from .segment import (
At,
File,
I18n,
Text,
AtAll,
Audio,
Emoji,
Hyper,
Image,
Reply,
Video,
Voice,
Button,
RefNode,
Segment,
Keyboard,
Reference,
CustomNode,
)

T = TypeVar("T")
TS = TypeVar("TS", bound=Segment)
Expand Down Expand Up @@ -286,6 +305,42 @@ def hyper(
"""
...

@classmethod
def reference(
cls_or_self: Union["UniMessage[TS1]", type["UniMessage[TS1]"]], # type: ignore
*nodes: Union[RefNode, CustomNode],
id: Optional[str] = None,
) -> "UniMessage[Union[TS1, Reference]]":
"""创建转发消息
参数:
nodes: 转发消息节点
id: 此处不一定是消息ID,可能是其他ID,如消息序号等
返回:
构建的消息
"""
...

@classmethod
def keyboard(
cls_or_self: Union["UniMessage[TS1]", type["UniMessage[TS1]"]], # type: ignore
*buttons: Button,
id: Optional[str] = None,
row: Optional[int] = None,
) -> "UniMessage[Union[TS1, Keyboard]]":
"""创建转发消息
参数:
buttons: 按钮
id: 此处一般用来表示模板id,特殊情况下可能表示例如 bot_appid 等
row: 当消息中只写有一个 Keyboard 时可根据此参数约定按钮组的列数
返回:
构建的消息
"""
...

@classmethod
def i18n(
cls_or_self: Union["UniMessage[TS1]", type["UniMessage[TS1]"]], # type: ignore
Expand Down Expand Up @@ -432,6 +487,27 @@ def hyper(cls_or_self, flag: Literal["xml", "json"], content: str) -> "UniMessag
return cls_or_self
return UniMessage(Hyper(flag, content))

@_method
def reference(
cls_or_self, *nodes: Union[RefNode, CustomNode], id: Optional[str] = None
) -> "UniMessage[Union[TS1, Reference]]":
if isinstance(cls_or_self, UniMessage):
cls_or_self.append(Reference(id=id, nodes=list(nodes)))
return cls_or_self
return UniMessage(Reference(id=id, nodes=list(nodes)))

@_method
def keyboard(
cls_or_self,
*buttons: Button,
id: Optional[str] = None,
row: Optional[int] = None,
) -> "UniMessage[Union[TS1, Keyboard]]":
if isinstance(cls_or_self, UniMessage):
cls_or_self.append(Keyboard(id=id, buttons=list(buttons), row=row))
return cls_or_self
return UniMessage(Keyboard(id=id, buttons=list(buttons), row=row))

@_method
def i18n(
cls_or_self,
Expand Down
1 change: 1 addition & 0 deletions src/nonebot_plugin_alconna/uniseg/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ def __post_init__(self):
self.style = "secondary"
elif self.style == "blue":
self.style = "primary"
self._children.insert(0, Text(self.label) if isinstance(self.label, str) else self.label)


@dataclass
Expand Down
42 changes: 42 additions & 0 deletions tests/fake.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime
from typing import TYPE_CHECKING, Literal

from nonebot.compat import type_validate_python
from nonebot.adapters.satori.models import Login, LoginStatus

FAKE_SATORI_LOGIN = Login(status=LoginStatus.ONLINE)
Expand All @@ -11,6 +12,7 @@
from nonebot.adapters.discord.event import ApplicationCommandInteractionEvent
from nonebot.adapters.onebot.v11 import GroupMessageEvent as GroupMessageEventV11
from nonebot.adapters.onebot.v11 import PrivateMessageEvent as PrivateMessageEventV11
from nonebot.adapters.discord.event import GuildMessageCreateEvent as DiscordMessageEvent


def fake_group_message_event_v11(**field) -> "GroupMessageEventV11":
Expand Down Expand Up @@ -89,6 +91,46 @@ class FakeEvent(_Fake):
return FakeEvent(**field)


def fake_message_event_discord(content: str) -> "DiscordMessageEvent":
from nonebot.adapters.discord.api.model import User
from nonebot.adapters.discord.api import MessageFlag, MessageType
from nonebot.adapters.discord.event import GuildMessageCreateEvent

return type_validate_python(
GuildMessageCreateEvent,
{
"id": 11234,
"channel_id": 5566,
"guild_id": 6677,
"author": User(
**{
"id": 3344,
"username": "MyUser",
"discriminator": "0",
"avatar": "xxx",
}
),
"content": content,
"timestamp": 123456,
"edited_timestamp": None,
"tts": False,
"mention_everyone": False,
"mentions": [],
"mention_roles": [],
"attachments": [],
"embeds": [],
"nonce": 3210,
"pinned": False,
"type": MessageType(0),
"flags": MessageFlag(0),
"referenced_message": None,
"components": [],
"to_me": False,
"reply": None,
},
)


def fake_message_event_satori(**field) -> "SatoriMessageEvent":
from pydantic import create_model
from nonebot.adapters.satori import Message
Expand Down
Loading

0 comments on commit 844c8af

Please sign in to comment.