From 3d4dca3b217909411b28652b3f0df04379fa6807 Mon Sep 17 00:00:00 2001 From: Azide Date: Thu, 21 Mar 2024 14:17:25 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E4=B8=BA=E5=90=84=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20repost=20=E7=9A=84=E6=B8=B2=E6=9F=93=20(#5?= =?UTF-8?q?05)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :bug: 为各主题添加 repost 的渲染 * :sparkles: 调整渲染结果 * :white_check_mark: 更新测试 --- nonebot_bison/theme/themes/basic/build.py | 20 ++++-- nonebot_bison/theme/themes/brief/build.py | 11 ++- nonebot_bison/theme/themes/ht2i/build.py | 30 +++++--- tests/post/test_generate.py | 2 +- tests/theme/test_themes.py | 83 +++++++++++++++++++++-- 5 files changed, 126 insertions(+), 20 deletions(-) diff --git a/nonebot_bison/theme/themes/basic/build.py b/nonebot_bison/theme/themes/basic/build.py index 6e045e7..93ed440 100644 --- a/nonebot_bison/theme/themes/basic/build.py +++ b/nonebot_bison/theme/themes/basic/build.py @@ -20,15 +20,27 @@ class BasicTheme(Theme): async def render(self, post: "Post") -> list[MessageSegmentFactory]: text = "" - if post.title: - text += f"{post.title}\n\n" + text += f"{post.title}\n\n" if post.title else "" 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: - text += f"详情: {post.url}" + urls.append(f"详情: {post.url}") + + if urls: + text += "\n".join(urls) msgs: list[MessageSegmentFactory] = [Text(text)] if post.images: diff --git a/nonebot_bison/theme/themes/brief/build.py b/nonebot_bison/theme/themes/brief/build.py index 8e876ab..2e9bf63 100644 --- a/nonebot_bison/theme/themes/brief/build.py +++ b/nonebot_bison/theme/themes/brief/build.py @@ -18,9 +18,16 @@ class BriefTheme(Theme): if not post.title: raise ThemeRenderUnsupportError("Post has no title") 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: - text += f"详情: {post.url}" + urls.append(f"详情: {post.url}") + + if urls: + text += "\n".join(urls) msgs: list[MessageSegmentFactory] = [Text(text)] if post.images: diff --git a/nonebot_bison/theme/themes/ht2i/build.py b/nonebot_bison/theme/themes/ht2i/build.py index 3ceb946..d03ce80 100644 --- a/nonebot_bison/theme/themes/ht2i/build.py +++ b/nonebot_bison/theme/themes/ht2i/build.py @@ -20,27 +20,39 @@ class Ht2iTheme(Theme): need_browser: bool = True async def _text_render(self, text: str): - from nonebot_plugin_htmlrender import text_to_pic + from nonebot_plugin_htmlrender import md_to_pic try: - return Image(await text_to_pic(text)) + return Image(await md_to_pic(text, width=400)) except Exception as e: raise ThemeRenderError(f"渲染文本失败: {e}") async def render(self, post: "Post"): - _text = "" + md_text = "" - if post.title: - _text += f"{post.title}\n\n" + md_text += f"## {post.title}\n\n" if post.title else "" - _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: - msgs.append(Text(f"详情: {post.url}")) + urls.append(f"详情: {post.url}") + + if urls: + msgs.append(Text("\n".join(urls))) + if post.images: pics = post.images if is_pics_mergable(pics): diff --git a/tests/post/test_generate.py b/tests/post/test_generate.py index bb3d3b9..7c985dc 100644 --- a/tests/post/test_generate.py +++ b/tests/post/test_generate.py @@ -179,7 +179,7 @@ async def test_generate_msg(mock_platform): res = await post.generate() assert len(res) == 1 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" assert post.get_config_theme() is None diff --git a/tests/theme/test_themes.py b/tests/theme/test_themes.py index addff30..3d35771 100644 --- a/tests/theme/test_themes.py +++ b/tests/theme/test_themes.py @@ -1,5 +1,6 @@ from time import time from typing import Any +from inspect import cleandoc import pytest from flaky import flaky @@ -70,7 +71,7 @@ def mock_post(app: App, mock_platform): from nonebot_bison.utils import ProcessContext return Post( - mock_platform(ProcessContext(), AsyncClient()), + m := mock_platform(ProcessContext(), AsyncClient()), "text", title="title", images=["http://t.tt/1.jpg"], @@ -79,6 +80,17 @@ def mock_post(app: App, mock_platform): avatar="http://t.tt/avatar.jpg", nickname="Mock", 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" res = await basic_theme.render(mock_post) 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) + 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 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" res = await brief_theme.render(mock_post) 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) + 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.asyncio @@ -219,4 +285,13 @@ async def test_ht2i_theme(app: App, mock_post): assert len(res) == 3 assert isinstance(res[0], 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")