Skip to content

Commit 001d9f7

Browse files
committed
♻️ 使用更纯粹的Post
1 parent b944e8d commit 001d9f7

24 files changed

+464
-269
lines changed

nonebot_bison/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
from nonebot.plugin import PluginMetadata, require
22

3+
from .delivery import send
4+
35
require("nonebot_plugin_apscheduler")
46
require("nonebot_plugin_datastore")
57
require("nonebot_plugin_saa")
68

79
import nonebot_plugin_saa
810

911
from .plugin_config import PlugConfig, plugin_config
10-
from . import post, send, theme, types, utils, config, platform, bootstrap, scheduler, admin_page, sub_manager
12+
from . import post, theme, types, utils, config, platform, bootstrap, scheduler, admin_page, sub_manager
1113

1214
__help__version__ = "0.8.2"
1315
nonebot_plugin_saa.enable_auto_select_bot()

nonebot_bison/delivery/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .send import send_msgs as send_msgs
2+
from .render import render_dispatch as render_dispatch

nonebot_bison/delivery/render.py

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from nonebot import logger
2+
from nonebot_plugin_saa import Text, MessageFactory, PlatformTarget, MessageSegmentFactory
3+
4+
from nonebot_bison.utils import text_to_image
5+
from nonebot_bison.post import Post, PostHeader
6+
from nonebot_bison.plugin_config import plugin_config
7+
from nonebot_bison.theme import (
8+
Parcel,
9+
ParcelHeader,
10+
ParcelPayload,
11+
ThemeRenderError,
12+
ThemeRenderUnsupportError,
13+
theme_manager,
14+
)
15+
16+
17+
def get_config_theme(platform_code: str) -> str | None:
18+
"""获取用户指定的theme"""
19+
return plugin_config.bison_platform_theme.get(platform_code)
20+
21+
22+
def get_theme_priority_list(header: PostHeader):
23+
"""获取渲染所使用的theme名列表,按照优先级排序"""
24+
themes_by_priority: list[str] = []
25+
# 最先使用用户指定的theme
26+
if user_theme := get_config_theme(header.platform_code):
27+
themes_by_priority.append(user_theme)
28+
# 然后使用平台默认的theme
29+
if header.recommend_theme not in themes_by_priority:
30+
themes_by_priority.append(header.recommend_theme)
31+
# 最后使用最基础的theme
32+
if "basic" not in themes_by_priority:
33+
themes_by_priority.append("basic")
34+
return themes_by_priority
35+
36+
37+
async def theme_render(post: Post, theme_priority_list: list[str]) -> list[MessageSegmentFactory]:
38+
"""按照 Theme 优先级列表渲染 Post,返回 MessageSegmentFactory 列表"""
39+
for theme_name in theme_priority_list:
40+
if theme := theme_manager[theme_name]:
41+
try:
42+
logger.debug(f"rendering post with theme {theme_name}")
43+
return await theme.do_render(post)
44+
except ThemeRenderUnsupportError as e:
45+
logger.warning(f"Theme {theme_name} does not support Post of {post.header.platform_code}: {e}")
46+
continue
47+
except ThemeRenderError as e:
48+
logger.exception(f"Theme {theme_name} render error: {e}")
49+
continue
50+
else:
51+
logger.error(f"Theme {theme_name} not found")
52+
continue
53+
else:
54+
raise ThemeRenderError(f"No theme can render Post of {post.header.platform_code}")
55+
56+
57+
async def render_post_process(
58+
post_header: PostHeader, msg_segments: list[MessageSegmentFactory]
59+
) -> list[MessageFactory]:
60+
"""对渲染后的 MessageSegmentFactory 列表进行处理"""
61+
62+
async def convert(msg: MessageSegmentFactory) -> MessageSegmentFactory:
63+
if isinstance(msg, Text):
64+
return await text_to_image(msg)
65+
else:
66+
return msg
67+
68+
if plugin_config.bison_use_pic:
69+
msg_segments = [await convert(msg) for msg in msg_segments]
70+
71+
if post_header.compress:
72+
msgs = [MessageFactory(msg_segments)]
73+
else:
74+
msgs = [MessageFactory(msg_segment) for msg_segment in msg_segments]
75+
76+
return msgs
77+
78+
79+
async def render_dispatch(to_send: list[tuple[PlatformTarget, list[Post]]]):
80+
"""分发 Post 渲染任务"""
81+
parcels: list[Parcel] = []
82+
for target, posts in to_send:
83+
for post in posts:
84+
post_header = post.header
85+
86+
themes_by_priority = get_theme_priority_list(post_header)
87+
logger.debug(f"themes_by_priority: {themes_by_priority}")
88+
89+
unprocessed_payload = await theme_render(post, themes_by_priority)
90+
processed_payload = await render_post_process(post_header, unprocessed_payload)
91+
92+
logger.info(f"send to {target}: {processed_payload}") # TODO: post 的 __str__ 方法,避免 bytes 刷屏
93+
parcels.append(
94+
Parcel(
95+
ParcelHeader(
96+
target=target,
97+
),
98+
ParcelPayload(
99+
content=processed_payload,
100+
),
101+
)
102+
)
103+
return parcels

nonebot_bison/send.py nonebot_bison/delivery/send.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from nonebot.adapters.onebot.v11.exception import ActionFailed
77
from nonebot_plugin_saa import MessageFactory, PlatformTarget, AggregatedMessageFactory
88

9-
from .plugin_config import plugin_config
9+
from ..plugin_config import plugin_config
1010

1111
Sendable = MessageFactory | AggregatedMessageFactory
1212

nonebot_bison/platform/arknights.py

+60-28
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from typing import Any
2-
from functools import partial
32

43
from httpx import AsyncClient
54
from bs4 import BeautifulSoup as bs
65
from pydantic import Field, BaseModel
76

8-
from ..post import Post
97
from ..types import Target, RawPost, Category
108
from .platform import NewMessage, StatusChange
9+
from ..post import Post, PostHeader, PostPayload
1110
from ..utils.scheduler_config import SchedulerConfig
1211

1312

@@ -106,14 +105,20 @@ def title_escape(text: str) -> str:
106105
title = title_escape(data.title)
107106

108107
return Post(
109-
self,
110-
content=data.content,
111-
title=title,
112-
nickname="明日方舟游戏内公告",
113-
images=[data.banner_image_url] if data.banner_image_url else None,
114-
url=data.jump_link or None,
115-
timestamp=data.updated_at,
116-
compress=True,
108+
PostHeader(
109+
platform_code=self.platform_name,
110+
http_client=self.client,
111+
recommend_theme=self.default_theme,
112+
compress=True,
113+
),
114+
PostPayload(
115+
content=data.content,
116+
title=title,
117+
author="明日方舟游戏内公告",
118+
images=[data.banner_image_url] if data.banner_image_url else None,
119+
url=data.jump_link or None,
120+
timestamp=data.updated_at,
121+
),
117122
)
118123

119124

@@ -143,15 +148,30 @@ async def get_status(self, _):
143148

144149
def compare_status(self, _, old_status, new_status):
145150
res = []
146-
ArkUpdatePost = partial(Post, self, "", nickname="明日方舟更新信息")
151+
152+
def make_ark_update_post(title: str):
153+
return Post(
154+
PostHeader(
155+
platform_code=self.platform_name,
156+
http_client=self.client,
157+
recommend_theme=self.default_theme,
158+
compress=True,
159+
),
160+
PostPayload(
161+
content="",
162+
title=title,
163+
author="明日方舟游戏信息",
164+
),
165+
)
166+
147167
if old_status.get("preAnnounceType") == 2 and new_status.get("preAnnounceType") == 0:
148-
res.append(ArkUpdatePost(title="登录界面维护公告上线(大概是开始维护了)"))
168+
res.append(make_ark_update_post(title="登录界面维护公告上线(大概是开始维护了)"))
149169
elif old_status.get("preAnnounceType") == 0 and new_status.get("preAnnounceType") == 2:
150-
res.append(ArkUpdatePost(title="登录界面维护公告下线(大概是开服了,冲!)"))
170+
res.append(make_ark_update_post(title="登录界面维护公告下线(大概是开服了,冲!)"))
151171
if old_status.get("clientVersion") != new_status.get("clientVersion"):
152-
res.append(ArkUpdatePost(title="游戏本体更新(大更新)"))
172+
res.append(make_ark_update_post(title="游戏本体更新(大更新)"))
153173
if old_status.get("resVersion") != new_status.get("resVersion"):
154-
res.append(ArkUpdatePost(title="游戏资源更新(小更新)"))
174+
res.append(make_ark_update_post(title="游戏资源更新(小更新)"))
155175
return res
156176

157177
def get_category(self, _):
@@ -198,12 +218,18 @@ async def parse(self, raw_post: RawPost) -> Post:
198218
imgs = [x["src"] for x in soup("img")]
199219
text = f'{raw_post["title"]}\n{soup.text.strip()}'
200220
return Post(
201-
self,
202-
text,
203-
images=imgs,
204-
url=url,
205-
nickname="塞壬唱片新闻",
206-
compress=True,
221+
PostHeader(
222+
platform_code=self.platform_name,
223+
http_client=self.client,
224+
recommend_theme=self.default_theme,
225+
compress=True,
226+
),
227+
PostPayload(
228+
content=text,
229+
images=imgs,
230+
url=url,
231+
author="塞壬唱片新闻",
232+
),
207233
)
208234

209235

@@ -238,11 +264,17 @@ def get_category(self, _) -> Category:
238264
async def parse(self, raw_post: RawPost) -> Post:
239265
url = f'https://terra-historicus.hypergryph.com/comic/{raw_post["comicCid"]}/episode/{raw_post["episodeCid"]}'
240266
return Post(
241-
self,
242-
raw_post["subtitle"],
243-
title=f'{raw_post["title"]} - {raw_post["episodeShortTitle"]}',
244-
images=[raw_post["coverUrl"]],
245-
url=url,
246-
nickname="泰拉记事社漫画",
247-
compress=True,
267+
PostHeader(
268+
platform_code=self.platform_name,
269+
http_client=self.client,
270+
recommend_theme=self.default_theme,
271+
compress=True,
272+
),
273+
PostPayload(
274+
content=raw_post["subtitle"],
275+
title=f'{raw_post["title"]} - {raw_post["episodeShortTitle"]}',
276+
images=[raw_post["coverUrl"]],
277+
url=url,
278+
author="泰拉记事社漫画",
279+
),
248280
)

nonebot_bison/platform/bilibili.py

+42-16
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from nonebot.log import logger
1111
from pydantic import Field, BaseModel
1212

13-
from ..post import Post
13+
from ..post import Post, PostHeader, PostPayload
1414
from ..utils import SchedulerConfig, text_similarity
1515
from ..types import Tag, Target, RawPost, ApiError, Category
1616
from .platform import NewMessage, StatusChange, CategoryNotSupport, CategoryNotRecognize
@@ -193,7 +193,21 @@ async def parse(self, raw_post: RawPost) -> Post:
193193
text += orig_text
194194
else:
195195
raise CategoryNotSupport(post_type)
196-
return Post(self, text, url=url, images=pic, nickname=target_name)
196+
197+
return Post(
198+
PostHeader(
199+
platform_code=self.platform_name,
200+
http_client=self.client,
201+
recommend_theme=self.default_theme,
202+
compress=True,
203+
),
204+
PostPayload(
205+
content=text,
206+
images=pic,
207+
url=url,
208+
author=target_name,
209+
),
210+
)
197211

198212

199213
class Bilibililive(StatusChange):
@@ -335,13 +349,19 @@ async def parse(self, raw_post: Info) -> Post:
335349
title = f"[{self.categories[raw_post.category].rstrip('提醒')}] {raw_post.title}"
336350
target_name = f"{raw_post.uname} {raw_post.area_name}"
337351
return Post(
338-
self,
339-
"",
340-
title=title,
341-
url=url,
342-
images=list(pic),
343-
nickname=target_name,
344-
compress=True,
352+
PostHeader(
353+
platform_code=self.platform_name,
354+
http_client=self.client,
355+
recommend_theme=self.default_theme,
356+
compress=True,
357+
),
358+
PostPayload(
359+
content="",
360+
title=title,
361+
url=url,
362+
images=list(pic),
363+
author=target_name,
364+
),
345365
)
346366

347367

@@ -418,13 +438,19 @@ async def parse(self, raw_post: RawPost) -> Post:
418438
content = raw_post["index_show"]
419439
title = lastest_episode["share_copy"]
420440
return Post(
421-
self,
422-
content,
423-
title=title,
424-
url=url,
425-
images=list(pic),
426-
nickname=target_name,
427-
compress=True,
441+
PostHeader(
442+
platform_code=self.platform_name,
443+
http_client=self.client,
444+
recommend_theme=self.default_theme,
445+
compress=True,
446+
),
447+
PostPayload(
448+
content=content,
449+
title=title,
450+
url=url,
451+
images=list(pic),
452+
author=target_name,
453+
),
428454
)
429455

430456

nonebot_bison/platform/ff14.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
from httpx import AsyncClient
44

5-
from ..post import Post
65
from ..utils import scheduler
76
from .platform import NewMessage
87
from ..types import Target, RawPost
8+
from ..post import Post, PostHeader, PostPayload
99

1010

1111
class FF14(NewMessage):
@@ -43,4 +43,17 @@ async def parse(self, raw_post: RawPost) -> Post:
4343
title = raw_post["Title"]
4444
text = raw_post["Summary"]
4545
url = raw_post["Author"]
46-
return Post(self, text, title=title, url=url, nickname="最终幻想XIV官方公告")
46+
return Post(
47+
PostHeader(
48+
platform_code=self.platform_name,
49+
http_client=self.client,
50+
recommend_theme=self.default_theme,
51+
compress=True,
52+
),
53+
PostPayload(
54+
content=text,
55+
title=title,
56+
url=url,
57+
author="最终幻想XIV官方公告",
58+
),
59+
)

0 commit comments

Comments
 (0)