Cateon Huo 9e5dcb3912
实现 Post.content 相关扩展协议 (#553)
*  `post` 新增 `get_content()` 方法

* 🚨 make linter happy

* 💄 auto fix by pre-commit hooks

* 🐛 fix: 调整函数使用

* 💄 auto fix by pre-commit hooks

*  转用函数处理文本

* 💄 auto fix by pre-commit hooks

* 🔨 使用`Dict`存储`content_handlers`

* 💄 auto fix by pre-commit hooks

* 🎨 fix

* :arts: 简化函数使用

* 🐛 移除`Theme`的过时参数

* 🗑️ 复用 `self.plain_content`

* 💄 auto fix by pre-commit hooks

*  注册式装饰器写法

* 💄 auto fix by pre-commit hooks

* 🐛 fix

* 💄 auto fix by pre-commit hooks

* :feat: 通用纯文本处理函数

* 💄 auto fix by pre-commit hooks

* :downgrade: 复用`==`处理标题

* 🎨 简化(?)写法

*  测试修复

* ♻️ via ContentSupport extensions

* 🐛 fix test

* 💄 auto fix by pre-commit hooks

* 🐛 for clean text

* 🐛 fix

* 💄 auto fix by pre-commit hooks

* fix: for xml

* 💄 auto fix by pre-commit hooks

* chore: art

* 💄 auto fix by pre-commit hooks

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-08-04 18:39:12 +08:00

81 lines
2.4 KiB
Python

from io import BytesIO
from pathlib import Path
from dataclasses import dataclass
from typing import TYPE_CHECKING, Literal
from nonebot_plugin_saa import Text, Image, MessageSegmentFactory
from nonebot_bison.utils import text_fletten
from nonebot_bison.theme.utils import web_embed_image
from nonebot_bison.theme import Theme, ThemeRenderError, ThemeRenderUnsupportError
if TYPE_CHECKING:
from nonebot_bison.platform.arknights import ArknightsPost
@dataclass
class ArkData:
announce_title: str
content: str
banner_image_url: str | Path | None
class ArknightsTheme(Theme):
"""Arknights 公告风格主题
需要安装`nonebot_plugin_htmlrender`插件
"""
name: Literal["arknights"] = "arknights"
need_browser: bool = True
template_path: Path = Path(__file__).parent / "templates"
template_name: str = "announce.html.jinja"
async def render(self, post: "ArknightsPost"):
from nonebot_plugin_htmlrender import template_to_pic
if not post.title:
raise ThemeRenderUnsupportError("标题为空")
banner = post.images[0] if post.images else None
match banner:
case bytes() | BytesIO():
banner = web_embed_image(banner)
case str() | Path() | None:
pass
case _:
raise ThemeRenderUnsupportError(
f"图片类型错误, 期望 str | Path | bytes | BytesIO | None, 实际为 {type(banner)}"
)
ark_data = ArkData(
announce_title=text_fletten(post.title),
content=await post.get_content(),
banner_image_url=banner,
)
try:
announce_pic = await template_to_pic(
template_path=self.template_path.as_posix(),
template_name=self.template_name,
templates={
"data": ark_data,
},
pages={
"viewport": {"width": 600, "height": 100},
"base_url": self.template_path.as_uri(),
},
)
except Exception as e:
raise ThemeRenderError(f"渲染文本失败: {e}")
msgs: list[MessageSegmentFactory] = []
msgs.append(Image(announce_pic))
if post.url:
msgs.append(Text(f"前往:{post.url}"))
if post.images:
msgs.extend(Image(img) for img in post.images[1:])
return msgs