🐛 为各主题添加 repost 的渲染 (#505)

* 🐛 为各主题添加 repost 的渲染

*  调整渲染结果

*  更新测试
This commit is contained in:
Azide 2024-03-21 14:17:25 +08:00 committed by GitHub
parent c915b36499
commit 3d4dca3b21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 126 additions and 20 deletions

View File

@ -20,15 +20,27 @@ class BasicTheme(Theme):
async def render(self, post: "Post") -> list[MessageSegmentFactory]: async def render(self, post: "Post") -> list[MessageSegmentFactory]:
text = "" text = ""
if post.title: text += f"{post.title}\n\n" if post.title else ""
text += f"{post.title}\n\n"
text += post.content if len(post.content) < 500 else f"{post.content[:500]}..." text += post.content if len(post.content) < 500 else f"{post.content[:500]}..."
text += f"\n来源: {post.platform.name} {post.nickname or ''}\n" if rp := post.repost:
text += f"\n--------------\n转发自 {rp.nickname or ''}:\n"
text += f"{rp.title}\n\n" if rp.title else ""
text += rp.content if len(rp.content) < 500 else f"{rp.content[:500]}..."
text += "\n--------------\n"
text += f"来源: {post.platform.name} {post.nickname or ''}\n"
urls: list[str] = []
if rp and rp.url:
urls.append(f"转发详情:{rp.url}")
if post.url: if post.url:
text += f"详情: {post.url}" urls.append(f"详情: {post.url}")
if urls:
text += "\n".join(urls)
msgs: list[MessageSegmentFactory] = [Text(text)] msgs: list[MessageSegmentFactory] = [Text(text)]
if post.images: if post.images:

View File

@ -18,9 +18,16 @@ class BriefTheme(Theme):
if not post.title: if not post.title:
raise ThemeRenderUnsupportError("Post has no title") raise ThemeRenderUnsupportError("Post has no title")
text = f"{post.title}\n\n" text = f"{post.title}\n\n"
text += f"来源: {post.platform.name} {post.nickname or ''}\n" text += f"来源: {post.platform.name} {post.nickname or ''}{' 的转发' if post.repost else ''}\n"
urls: list[str] = []
if (rp := post.repost) and rp.url:
urls.append(f"转发详情: {rp.url}")
if post.url: if post.url:
text += f"详情: {post.url}" urls.append(f"详情: {post.url}")
if urls:
text += "\n".join(urls)
msgs: list[MessageSegmentFactory] = [Text(text)] msgs: list[MessageSegmentFactory] = [Text(text)]
if post.images: if post.images:

View File

@ -20,27 +20,39 @@ class Ht2iTheme(Theme):
need_browser: bool = True need_browser: bool = True
async def _text_render(self, text: str): async def _text_render(self, text: str):
from nonebot_plugin_htmlrender import text_to_pic from nonebot_plugin_htmlrender import md_to_pic
try: try:
return Image(await text_to_pic(text)) return Image(await md_to_pic(text, width=400))
except Exception as e: except Exception as e:
raise ThemeRenderError(f"渲染文本失败: {e}") raise ThemeRenderError(f"渲染文本失败: {e}")
async def render(self, post: "Post"): async def render(self, post: "Post"):
_text = "" md_text = ""
if post.title: md_text += f"## {post.title}\n\n" if post.title else ""
_text += f"{post.title}\n\n"
_text += post.content if len(post.content) < 500 else f"{post.content[:500]}..." md_text += post.content if len(post.content) < 500 else f"{post.content[:500]}..."
md_text += "\n\n"
if rp := post.repost:
md_text += f"> 转发自 {f'**{rp.nickname}**' if rp.nickname else ''}: \n"
md_text += f"> {rp.title} \n" if rp.title else ""
md_text += "> \n> " + rp.content if len(rp.content) < 500 else f"{rp.content[:500]}..." + " \n"
md_text += "\n\n"
_text += f"\n来源: {post.platform.name} {post.nickname or ''}\n" md_text += f"###### 来源: {post.platform.name} {post.nickname or ''}\n"
msgs: list[MessageSegmentFactory] = [await self._text_render(_text)] msgs: list[MessageSegmentFactory] = [await self._text_render(md_text)]
urls: list[str] = []
if rp and rp.url:
urls.append(f"转发详情: {rp.url}")
if post.url: if post.url:
msgs.append(Text(f"详情: {post.url}")) urls.append(f"详情: {post.url}")
if urls:
msgs.append(Text("\n".join(urls)))
if post.images: if post.images:
pics = post.images pics = post.images
if is_pics_mergable(pics): if is_pics_mergable(pics):

View File

@ -179,7 +179,7 @@ async def test_generate_msg(mock_platform):
res = await post.generate() res = await post.generate()
assert len(res) == 1 assert len(res) == 1
assert isinstance(res[0], Text) assert isinstance(res[0], Text)
assert str(res[0]) == "p1\n来源: Mock-Platform MockNick\n详情: http://t.tt/1" assert str(res[0]) == "p1\n--------------\n来源: Mock-Platform MockNick\n详情: http://t.tt/1"
post.platform.default_theme = "ht2i" post.platform.default_theme = "ht2i"
assert post.get_config_theme() is None assert post.get_config_theme() is None

View File

@ -1,5 +1,6 @@
from time import time from time import time
from typing import Any from typing import Any
from inspect import cleandoc
import pytest import pytest
from flaky import flaky from flaky import flaky
@ -70,7 +71,7 @@ def mock_post(app: App, mock_platform):
from nonebot_bison.utils import ProcessContext from nonebot_bison.utils import ProcessContext
return Post( return Post(
mock_platform(ProcessContext(), AsyncClient()), m := mock_platform(ProcessContext(), AsyncClient()),
"text", "text",
title="title", title="title",
images=["http://t.tt/1.jpg"], images=["http://t.tt/1.jpg"],
@ -79,6 +80,17 @@ def mock_post(app: App, mock_platform):
avatar="http://t.tt/avatar.jpg", avatar="http://t.tt/avatar.jpg",
nickname="Mock", nickname="Mock",
description="description", description="description",
repost=Post(
m,
"repost",
title="repost-title",
images=["http://t.tt/2.jpg"],
timestamp=1234567891,
url="http://t.tt/2",
avatar="http://t.tt/avatar-re.jpg",
nickname="re-Mock",
description="re-description",
),
) )
@ -161,9 +173,40 @@ async def test_basic_theme(app: App, mock_post):
assert basic_theme.name == "basic" assert basic_theme.name == "basic"
res = await basic_theme.render(mock_post) res = await basic_theme.render(mock_post)
assert len(res) == 2 assert len(res) == 2
assert res[0] == Text("title\n\ntext\n来源: Mock Platform Mock\n详情: http://t.tt/1") assert res[0] == Text(
cleandoc(
"""title
text
--------------
转发自 re-Mock:
repost-title
repost
--------------
来源: Mock Platform Mock
转发详情http://t.tt/2
详情: http://t.tt/1"""
)
)
assert isinstance(res[1], Image) assert isinstance(res[1], Image)
mock_post2 = mock_post
mock_post2.repost = None
mock_post2.images = []
res2 = await basic_theme.render(mock_post2)
assert len(res2) == 1
assert res2[0] == Text(
cleandoc(
"""title
text
--------------
来源: Mock Platform Mock
详情: http://t.tt/1"""
)
)
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_brief_theme(app: App, mock_post): async def test_brief_theme(app: App, mock_post):
@ -178,9 +221,32 @@ async def test_brief_theme(app: App, mock_post):
assert brief_theme.name == "brief" assert brief_theme.name == "brief"
res = await brief_theme.render(mock_post) res = await brief_theme.render(mock_post)
assert len(res) == 2 assert len(res) == 2
assert res[0] == Text("title\n\n来源: Mock Platform Mock\n详情: http://t.tt/1") assert res[0] == Text(
cleandoc(
"""title
来源: Mock Platform Mock 的转发
转发详情: http://t.tt/2
详情: http://t.tt/1
"""
)
)
assert isinstance(res[1], Image) assert isinstance(res[1], Image)
mock_post2 = mock_post
mock_post2.repost = None
mock_post2.images = []
res2 = await brief_theme.render(mock_post2)
assert len(res2) == 1
assert res2[0] == Text(
cleandoc(
"""title
来源: Mock Platform Mock
详情: http://t.tt/1"""
)
)
@pytest.mark.render @pytest.mark.render
@pytest.mark.asyncio @pytest.mark.asyncio
@ -219,4 +285,13 @@ async def test_ht2i_theme(app: App, mock_post):
assert len(res) == 3 assert len(res) == 3
assert isinstance(res[0], Image) assert isinstance(res[0], Image)
assert isinstance(res[2], Image) assert isinstance(res[2], Image)
assert res[1] == Text("详情: http://t.tt/1") assert res[1] == Text("转发详情: http://t.tt/2\n详情: http://t.tt/1")
mock_post2 = mock_post
mock_post2.repost = None
mock_post2.images = []
res2 = await ht2i_theme.render(mock_post2)
assert len(res2) == 2
assert res2[1] == Text("详情: http://t.tt/1")