From 6b79106cd19b21d6f8d12af1a9a57feb608acc9d Mon Sep 17 00:00:00 2001 From: Mix <32300164+mnixry@users.noreply.github.com> Date: Sun, 3 Oct 2021 16:26:55 +0800 Subject: [PATCH 1/3] :sparkles: support use `MessageSegment` method as template format spec --- nonebot/adapters/_template.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nonebot/adapters/_template.py b/nonebot/adapters/_template.py index 38a2dbc1..d914ee8a 100644 --- a/nonebot/adapters/_template.py +++ b/nonebot/adapters/_template.py @@ -1,3 +1,4 @@ +import inspect import functools from string import Formatter from typing import (TYPE_CHECKING, Any, Set, List, Type, Tuple, Union, Generic, @@ -114,8 +115,14 @@ class MessageTemplate(Formatter, Generic[TM]): [""])), auto_arg_index def format_field(self, value: Any, format_spec: str) -> Any: - return super().format_field(value, - format_spec) if format_spec else value + segment_class: Type[MessageSegment] = self.factory.get_segment_class() + method = getattr(segment_class, format_spec, None) + method_type = inspect.getattr_static(segment_class, format_spec, None) + return (super().format_field(value, format_spec) if + ((method is None) or + (not isinstance(method_type, (classmethod, staticmethod)) + ) # Only Call staticmethod or classmethod + ) else method(value)) if format_spec else value def _add(self, a: Any, b: Any) -> Any: try: From b9c91dc5c3a64f7e5c15c93b9ab4a1429f91decb Mon Sep 17 00:00:00 2001 From: Mix <32300164+mnixry@users.noreply.github.com> Date: Sun, 3 Oct 2021 16:39:43 +0800 Subject: [PATCH 2/3] :bulb: add document for extended format spec --- nonebot/adapters/_message.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/nonebot/adapters/_message.py b/nonebot/adapters/_message.py index 6f209343..3c8ee79e 100644 --- a/nonebot/adapters/_message.py +++ b/nonebot/adapters/_message.py @@ -109,22 +109,24 @@ class Message(List[TMS], abc.ABC): :说明: 根据创建消息模板, 用法和 ``str.format`` 大致相同, 但是可以输出消息对象, 并且支持以 ``Message`` 对象作为消息模板 + 并且提供了拓展的格式化控制符, 可以用适用于该消息类型的 ``MessageSegment`` 的工厂方法创建消息 :示例: .. code-block:: python - >>> Message.template("{} {}").format("hello", "world") + >>> Message.template("{} {}").format("hello", "world") # 基础演示 Message(MessageSegment(type='text', data={'text': 'hello world'})) - >>> Message.template("{} {}").format(MessageSegment.image("file///..."), "world") + >>> Message.template("{} {}").format(MessageSegment.image("file///..."), "world") # 支持消息段等对象 Message(MessageSegment(type='image', data={'file': 'file///...'}), MessageSegment(type='text', data={'text': 'world'})) - >>> Message.template( + >>> Message.template( # 支持以Message对象作为消息模板 ... MessageSegment.text('test {event.user_id}') + MessageSegment.face(233) + - ... MessageSegment.text('test {event.message}')).format(event={'user_id':123456, 'message':'hello world'} - ... ) + ... MessageSegment.text('test {event.message}')).format(event={'user_id':123456, 'message':'hello world'}) Message(MessageSegment(type='text', data={'text': 'test 123456'}), MessageSegment(type='face', data={'face': 233}), MessageSegment(type='text', data={'text': 'test hello world'})) + >>> Message.template("{link:image}").format(link='https://...') # 支持拓展格式化控制符 + Message(MessageSegment(type='image', data={'file': 'https://...'})) :参数: From 2a08f6bdf69547388842c5e631810af8850ff607 Mon Sep 17 00:00:00 2001 From: nonebot Date: Sun, 3 Oct 2021 08:41:04 +0000 Subject: [PATCH 3/3] :memo: update api docs --- docs/api/adapters/README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/api/adapters/README.md b/docs/api/adapters/README.md index 3c1bcc8b..f9c99f6b 100644 --- a/docs/api/adapters/README.md +++ b/docs/api/adapters/README.md @@ -306,6 +306,7 @@ await bot.send_msg(message="hello world") * **说明** 根据创建消息模板, 用法和 `str.format` 大致相同, 但是可以输出消息对象, 并且支持以 `Message` 对象作为消息模板 + 并且提供了拓展的格式化控制符, 可以用适用于该消息类型的 `MessageSegment` 的工厂方法创建消息 @@ -313,17 +314,18 @@ await bot.send_msg(message="hello world") ```python ->>> Message.template("{} {}").format("hello", "world") +>>> Message.template("{} {}").format("hello", "world") # 基础演示 Message(MessageSegment(type='text', data={'text': 'hello world'})) ->>> Message.template("{} {}").format(MessageSegment.image("file///..."), "world") +>>> Message.template("{} {}").format(MessageSegment.image("file///..."), "world") # 支持消息段等对象 Message(MessageSegment(type='image', data={'file': 'file///...'}), MessageSegment(type='text', data={'text': 'world'})) ->>> Message.template( +>>> Message.template( # 支持以Message对象作为消息模板 ... MessageSegment.text('test {event.user_id}') + MessageSegment.face(233) + -... MessageSegment.text('test {event.message}')).format(event={'user_id':123456, 'message':'hello world'} -... ) +... MessageSegment.text('test {event.message}')).format(event={'user_id':123456, 'message':'hello world'}) Message(MessageSegment(type='text', data={'text': 'test 123456'}), MessageSegment(type='face', data={'face': 233}), MessageSegment(type='text', data={'text': 'test hello world'})) +>>> Message.template("{link:image}").format(link='https://...') # 支持拓展格式化控制符 +Message(MessageSegment(type='image', data={'file': 'https://...'})) ```