♻️ use saa

This commit is contained in:
felinae98
2023-03-24 21:17:52 +08:00
parent 4118329bb0
commit da8e988ee9
15 changed files with 223 additions and 308 deletions
+11 -9
View File
@@ -3,7 +3,7 @@ from dataclasses import dataclass, field
from functools import reduce
from typing import Optional
from nonebot.adapters.onebot.v11.message import Message, MessageSegment
from nonebot_plugin_saa import MessageFactory, MessageSegmentFactory
from ..plugin_config import plugin_config
@@ -11,13 +11,13 @@ from ..plugin_config import plugin_config
@dataclass
class BasePost:
@abstractmethod
async def generate_text_messages(self) -> list[MessageSegment]:
"Generate Message list from this instance"
async def generate_text_messages(self) -> list[MessageSegmentFactory]:
"Generate MessageFactory list from this instance"
...
@abstractmethod
async def generate_pic_messages(self) -> list[MessageSegment]:
"Generate Message list from this instance with `use_pic`"
async def generate_pic_messages(self) -> list[MessageSegmentFactory]:
"Generate MessageFactory list from this instance with `use_pic`"
...
@@ -27,7 +27,7 @@ class OptionalMixin:
override_use_pic: Optional[bool] = None
compress: bool = False
extra_msg: list[Message] = field(default_factory=list)
extra_msg: list[MessageFactory] = field(default_factory=list)
def _use_pic(self):
if not self.override_use_pic is None:
@@ -37,17 +37,19 @@ class OptionalMixin:
@dataclass
class AbstractPost(OptionalMixin, BasePost):
async def generate_messages(self) -> list[Message]:
async def generate_messages(self) -> list[MessageFactory]:
if self._use_pic():
msg_segments = await self.generate_pic_messages()
else:
msg_segments = await self.generate_text_messages()
if msg_segments:
if self.compress:
msgs = [reduce(lambda x, y: x.append(y), msg_segments, Message())]
msgs = [
reduce(lambda x, y: x.append(y), msg_segments, MessageFactory([]))
]
else:
msgs = list(
map(lambda msg_segment: Message([msg_segment]), msg_segments)
map(lambda msg_segment: MessageFactory([msg_segment]), msg_segments)
)
else:
msgs = []
+22 -24
View File
@@ -1,10 +1,10 @@
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional
from nonebot.adapters.onebot.v11.message import Message, MessageSegment
from nonebot.adapters.onebot.v11 import MessageSegment
from nonebot.log import logger
from nonebot.plugin import require
from nonebot_plugin_saa import Image, MessageFactory, MessageSegmentFactory, Text
from .abstract_post import AbstractPost, BasePost
@@ -12,37 +12,35 @@ from .abstract_post import AbstractPost, BasePost
@dataclass
class _CustomPost(BasePost):
message_segments: list[MessageSegment] = field(default_factory=list)
ms_factories: list[MessageSegmentFactory] = field(default_factory=list)
css_path: Optional[str] = None # 模板文件所用css路径
async def generate_text_messages(self) -> list[MessageSegment]:
return self.message_segments
async def generate_text_messages(self) -> list[MessageSegmentFactory]:
return self.ms_factories
async def generate_pic_messages(self) -> list[MessageSegment]:
async def generate_pic_messages(self) -> list[MessageSegmentFactory]:
require("nonebot_plugin_htmlrender")
from nonebot_plugin_htmlrender import md_to_pic
pic_bytes = await md_to_pic(md=self._generate_md(), css_path=self.css_path)
return [MessageSegment.image(pic_bytes)]
return [Image(pic_bytes)]
def _generate_md(self) -> str:
md = ""
for message_segment in self.message_segments:
if message_segment.type == "text":
md += "{}<br>".format(message_segment.data.get("text", ""))
elif message_segment.type == "image":
# 先尝试获取file的值,没有再尝试获取url的值,都没有则为空
pic_res = message_segment.data.get("file") or message_segment.data.get(
"url", ""
)
if not pic_res:
logger.warning("无法获取到图片资源:MessageSegment.image中file/url字段均为空")
else:
md += "![Image]({})\n".format(pic_res)
else:
logger.warning("custom_post不支持处理类型:{}".format(message_segment.type))
continue
for message_segment in self.ms_factories:
match message_segment:
case Text(data={"text": text}):
md += "{}<br>".format(text)
case Image(data={"image": image}):
# use onebot v11 to convert image into url
ob11_image = MessageSegment.image(image)
md += "![Image]({})\n".format(ob11_image.data["file"])
case _:
logger.warning(
"custom_post不支持处理类型:{}".format(type(message_segment))
)
continue
return md
@@ -52,14 +50,14 @@ class CustomPost(_CustomPost, AbstractPost):
"""基于 markdown 语法的,自由度较高的推送内容格式
简介:
支持处理text/image两种MessageSegment,
支持处理text/image两种MessageSegmentFactory,
通过将text/image转换成对应的markdown语法以生成markdown文本。
理论上text类型中可以直接使用markdown语法,例如`##第一章`。
但会导致不启用`override_use_pic`时, 发送不会被渲染的纯文本消息。
图片渲染最终由htmlrender执行。
注意:
每一个MessageSegment元素都会被解释为单独的一行
每一个MessageSegmentFactory元素都会被解释为单独的一行
可选参数:
`override_use_pic`:是否覆盖`bison_use_pic`全局配置
+12 -11
View File
@@ -3,8 +3,9 @@ from functools import reduce
from io import BytesIO
from typing import Optional, Union
from nonebot.adapters.onebot.v11.message import Message, MessageSegment
import nonebot_plugin_saa as saa
from nonebot.log import logger
from nonebot_plugin_saa.utils import MessageFactory, MessageSegmentFactory
from PIL import Image
from ..utils import http_client, parse_text
@@ -20,8 +21,8 @@ class _Post(BasePost):
target_name: Optional[str] = None
pics: list[Union[str, bytes]] = field(default_factory=list)
_message: Optional[list[MessageSegment]] = None
_pic_message: Optional[list[MessageSegment]] = None
_message: Optional[list[MessageSegmentFactory]] = None
_pic_message: Optional[list[MessageSegmentFactory]] = None
async def _pic_url_to_image(self, data: Union[str, bytes]) -> Image.Image:
pic_buffer = BytesIO()
@@ -99,11 +100,11 @@ class _Post(BasePost):
self.pics = self.pics[matrix[0] * matrix[1] :]
self.pics.insert(0, target_io.getvalue())
async def generate_text_messages(self) -> list[MessageSegment]:
async def generate_text_messages(self) -> list[MessageSegmentFactory]:
if self._message is None:
await self._pic_merge()
msg_segments: list[MessageSegment] = []
msg_segments: list[MessageSegmentFactory] = []
text = ""
if self.text:
text += "{}".format(
@@ -116,17 +117,17 @@ class _Post(BasePost):
text += " {}".format(self.target_name)
if self.url:
text += " \n详情: {}".format(self.url)
msg_segments.append(MessageSegment.text(text))
msg_segments.append(saa.Text(text))
for pic in self.pics:
msg_segments.append(MessageSegment.image(pic))
msg_segments.append(saa.Image(pic))
self._message = msg_segments
return self._message
async def generate_pic_messages(self) -> list[MessageSegment]:
async def generate_pic_messages(self) -> list[MessageSegmentFactory]:
if self._pic_message is None:
await self._pic_merge()
msg_segments: list[MessageSegment] = []
msg_segments: list[MessageSegmentFactory] = []
text = ""
if self.text:
text += "{}".format(self.text)
@@ -136,9 +137,9 @@ class _Post(BasePost):
text += " {}".format(self.target_name)
msg_segments.append(await parse_text(text))
if not self.target_type == "rss" and self.url:
msg_segments.append(MessageSegment.text(self.url))
msg_segments.append(saa.Text(self.url))
for pic in self.pics:
msg_segments.append(MessageSegment.image(pic))
msg_segments.append(saa.Image(pic))
self._pic_message = msg_segments
return self._pic_message