nonebot-plugin-parser 2.0.1__tar.gz → 2.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/PKG-INFO +2 -3
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/README.md +1 -2
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/pyproject.toml +2 -2
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/exception.py +9 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/helper.py +1 -2
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/matchers/__init__.py +19 -17
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/data.py +2 -45
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/twitter.py +21 -24
- nonebot_plugin_parser-2.0.2/src/nonebot_plugin_parser/renders/base.py +73 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/renders/default.py +7 -1
- nonebot_plugin_parser-2.0.1/src/nonebot_plugin_parser/renders/base.py +0 -54
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/__init__.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/config.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/constants.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/download/__init__.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/download/task.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/download/ytdlp.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/matchers/filter.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/matchers/preprocess.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/__init__.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/acfun.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/base.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/bilibili/__init__.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/bilibili/opus.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/bilibili/video.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/cookie.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/douyin/__init__.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/douyin/slides.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/douyin/video.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/kuaishou.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/nga.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/tiktok.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/weibo.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/xiaohongshu.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/youtube.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/renders/__init__.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/renders/common.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/renders/fonts/HYSongYunLangHeiW-1.ttf +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/renders/templates/weibo.html.jinja +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/renders/weibo.py +0 -0
- {nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: nonebot-plugin-parser
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: NoneBot2 链接分享解析器自动解析, BV号/链接/小程序/卡片 | B站/抖音/快手/微博/小红书/youtube/tiktok/twitter/acfun
|
|
5
5
|
Keywords: nonebot,nonebot2,video,bilibili,youtube,tiktok,twitter,kuaishou,acfun,weibo,xiaohongshu,nga,douyin
|
|
6
6
|
Author: fllesser
|
|
@@ -42,8 +42,7 @@ Description-Content-Type: text/markdown
|
|
|
42
42
|
<br/>
|
|
43
43
|
[](https://results.pre-commit.ci/latest/github/fllesser/nonebot-plugin-parser/master)
|
|
44
44
|
[](https://codecov.io/gh/fllesser/nonebot-plugin-parser)
|
|
45
|
-
[](https://qm.qq.com/q/y4T4CjHimc)
|
|
47
46
|
</div>
|
|
48
47
|
|
|
49
48
|
> [!IMPORTANT]
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
<br/>
|
|
13
13
|
[](https://results.pre-commit.ci/latest/github/fllesser/nonebot-plugin-parser/master)
|
|
14
14
|
[](https://codecov.io/gh/fllesser/nonebot-plugin-parser)
|
|
15
|
-
[](https://qm.qq.com/q/y4T4CjHimc)
|
|
17
16
|
</div>
|
|
18
17
|
|
|
19
18
|
> [!IMPORTANT]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nonebot-plugin-parser"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.2"
|
|
4
4
|
description = "NoneBot2 链接分享解析器自动解析, BV号/链接/小程序/卡片 | B站/抖音/快手/微博/小红书/youtube/tiktok/twitter/acfun"
|
|
5
5
|
authors = [{ "name" = "fllesser", "email" = "fllessive@gmail.com" }]
|
|
6
6
|
readme = "README.md"
|
|
@@ -185,7 +185,7 @@ build-backend = "uv_build"
|
|
|
185
185
|
|
|
186
186
|
|
|
187
187
|
[tool.bumpversion]
|
|
188
|
-
current_version = "2.0.
|
|
188
|
+
current_version = "2.0.2"
|
|
189
189
|
commit = true
|
|
190
190
|
message = "🔖 release: bump vesion from {current_version} to {new_version}"
|
|
191
191
|
tag = true
|
{nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/exception.py
RENAMED
|
@@ -18,3 +18,12 @@ class DownloadSizeLimitException(DownloadException):
|
|
|
18
18
|
def __init__(self):
|
|
19
19
|
self.message = "媒体大小超过配置限制,取消下载"
|
|
20
20
|
super().__init__(self.message)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MultiException(ParseException):
|
|
24
|
+
"""多个异常"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, exceptions: list[ParseException]):
|
|
27
|
+
self.exceptions = exceptions
|
|
28
|
+
message = ",".join([e.message for e in exceptions])
|
|
29
|
+
super().__init__(f"[{message}]")
|
{nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/helper.py
RENAMED
|
@@ -7,7 +7,6 @@ from nonebot_plugin_alconna.uniseg import Segment, UniMessage, Voice
|
|
|
7
7
|
from nonebot_plugin_alconna.uniseg.segment import CustomNode, Reference
|
|
8
8
|
|
|
9
9
|
from .config import pconfig
|
|
10
|
-
from .exception import ParseException
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class UniHelper:
|
|
@@ -103,7 +102,7 @@ class UniHelper:
|
|
|
103
102
|
# 检测文件大小
|
|
104
103
|
file_size_byte_count = int(video_path.stat().st_size)
|
|
105
104
|
if file_size_byte_count == 0:
|
|
106
|
-
|
|
105
|
+
return Text("视频文件大小为 0")
|
|
107
106
|
elif file_size_byte_count > 100 * 1024 * 1024:
|
|
108
107
|
# 转为文件 Seg
|
|
109
108
|
return cls.file_seg(video_path, display_name=video_path.name)
|
|
@@ -62,15 +62,11 @@ async def _(
|
|
|
62
62
|
await _message_reaction(event, "resolving")
|
|
63
63
|
|
|
64
64
|
cache_key = matched.group(0)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
# 获取对应平台 parser
|
|
69
|
-
parser = KEYWORD_PARSER_MAP
|
|
70
|
-
|
|
71
|
-
if parser is None:
|
|
72
|
-
logger.warning("没有找到对应平台的 Parser")
|
|
73
|
-
return
|
|
65
|
+
# 1. 获取缓存结果
|
|
66
|
+
result = RESULT_CACHE.get(cache_key)
|
|
67
|
+
if result is None:
|
|
68
|
+
# 2. 获取对应平台 parser
|
|
69
|
+
parser = KEYWORD_PARSER_MAP[keyword]
|
|
74
70
|
|
|
75
71
|
try:
|
|
76
72
|
result = await parser.parse(matched)
|
|
@@ -78,16 +74,22 @@ async def _(
|
|
|
78
74
|
# await UniMessage(str(e)).send()
|
|
79
75
|
await _message_reaction(event, "fail")
|
|
80
76
|
raise
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
RESULT_CACHE[cache_key] = result
|
|
77
|
+
else:
|
|
78
|
+
logger.debug(f"命中缓存: {cache_key}, 结果: {result}")
|
|
84
79
|
|
|
85
80
|
# 3. 渲染内容消息并发送
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
81
|
+
try:
|
|
82
|
+
renderer = get_renderer(result.platform.name)
|
|
83
|
+
async for message in renderer.render_messages(result):
|
|
84
|
+
await message.send()
|
|
85
|
+
except Exception:
|
|
86
|
+
await _message_reaction(event, "fail")
|
|
87
|
+
raise
|
|
88
|
+
|
|
89
|
+
# 4. 无 raise 再缓存解析结果
|
|
90
|
+
RESULT_CACHE[cache_key] = result
|
|
91
|
+
|
|
92
|
+
# 5. 添加成功的消息响应
|
|
91
93
|
await _message_reaction(event, "done")
|
|
92
94
|
|
|
93
95
|
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
from asyncio import Task
|
|
2
2
|
from dataclasses import dataclass, field
|
|
3
3
|
from datetime import datetime
|
|
4
|
-
from itertools import chain
|
|
5
4
|
from pathlib import Path
|
|
6
5
|
from typing import Any
|
|
7
6
|
|
|
8
|
-
from ..exception import ParseException
|
|
9
|
-
from ..helper import Segment, UniHelper, UniMessage
|
|
10
|
-
|
|
11
7
|
|
|
12
8
|
@dataclass(repr=False)
|
|
13
9
|
class MediaContent:
|
|
@@ -137,15 +133,6 @@ class ParseResult:
|
|
|
137
133
|
repost: "ParseResult | None" = None
|
|
138
134
|
"""转发的内容"""
|
|
139
135
|
|
|
140
|
-
def __hash__(self) -> int:
|
|
141
|
-
return hash(
|
|
142
|
-
(
|
|
143
|
-
self.platform.name,
|
|
144
|
-
self.timestamp,
|
|
145
|
-
self.url,
|
|
146
|
-
)
|
|
147
|
-
)
|
|
148
|
-
|
|
149
136
|
@property
|
|
150
137
|
def header(self) -> str:
|
|
151
138
|
header = self.platform.display_name
|
|
@@ -167,9 +154,6 @@ class ParseResult:
|
|
|
167
154
|
def extra_info(self) -> str:
|
|
168
155
|
return self.extra.get("info", "")
|
|
169
156
|
|
|
170
|
-
def formart_datetime(self, fmt: str = "%Y-%m-%d %H:%M:%S") -> str:
|
|
171
|
-
return datetime.fromtimestamp(self.timestamp).strftime(fmt) if self.timestamp else ""
|
|
172
|
-
|
|
173
157
|
@property
|
|
174
158
|
def video_contents(self) -> list[VideoContent]:
|
|
175
159
|
return [cont for cont in self.contents if isinstance(cont, VideoContent)]
|
|
@@ -197,35 +181,8 @@ class ParseResult:
|
|
|
197
181
|
return await cont.get_cover_path()
|
|
198
182
|
return None
|
|
199
183
|
|
|
200
|
-
|
|
201
|
-
""
|
|
202
|
-
|
|
203
|
-
Returns:
|
|
204
|
-
tuple[list[Segment], list[str | Segment | UniMessage]]: 消息段
|
|
205
|
-
separate_segs: 必须单独发送的消息段(视频、语音、文件)
|
|
206
|
-
forwardable_segs: 可以合并转发的消息段(文本和图片)
|
|
207
|
-
"""
|
|
208
|
-
separate_segs: list[Segment] = []
|
|
209
|
-
forwardable_segs: list[str | Segment | UniMessage] = []
|
|
210
|
-
|
|
211
|
-
for cont in chain(self.contents, self.repost.contents if self.repost else ()):
|
|
212
|
-
try:
|
|
213
|
-
path = await cont.get_path()
|
|
214
|
-
match cont:
|
|
215
|
-
case VideoContent():
|
|
216
|
-
separate_segs.append(UniHelper.video_seg(path))
|
|
217
|
-
case ImageContent():
|
|
218
|
-
forwardable_segs.append(UniHelper.img_seg(path))
|
|
219
|
-
case AudioContent():
|
|
220
|
-
separate_segs.append(UniHelper.record_seg(path))
|
|
221
|
-
case DynamicContent():
|
|
222
|
-
forwardable_segs.append(UniHelper.video_seg(path))
|
|
223
|
-
case GraphicsContent(_, text):
|
|
224
|
-
forwardable_segs.append(text + UniHelper.img_seg(path))
|
|
225
|
-
except ParseException as e:
|
|
226
|
-
forwardable_segs.append(e.message)
|
|
227
|
-
|
|
228
|
-
return separate_segs, forwardable_segs
|
|
184
|
+
def formart_datetime(self, fmt: str = "%Y-%m-%d %H:%M:%S") -> str:
|
|
185
|
+
return datetime.fromtimestamp(self.timestamp).strftime(fmt) if self.timestamp else ""
|
|
229
186
|
|
|
230
187
|
def __str__(self) -> str:
|
|
231
188
|
return f"title: {self.title}\nplatform: {self.platform}\nauthor: {self.author}\ncontents: {self.contents}"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from itertools import chain
|
|
1
2
|
import re
|
|
2
3
|
from typing import Any, ClassVar
|
|
3
4
|
|
|
@@ -73,41 +74,40 @@ class TwitterParser(BaseParser):
|
|
|
73
74
|
from .data import ParseData
|
|
74
75
|
|
|
75
76
|
soup = BeautifulSoup(html_content, "html.parser")
|
|
76
|
-
data = ParseData()
|
|
77
|
+
data = ParseData(name="无用户名")
|
|
77
78
|
|
|
78
79
|
# 1. 提取缩略图链接
|
|
79
|
-
|
|
80
|
-
if
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
data.cover_url = src
|
|
80
|
+
thumb_tag = soup.find("img")
|
|
81
|
+
if isinstance(thumb_tag, Tag):
|
|
82
|
+
if cover := thumb_tag.get("src"):
|
|
83
|
+
data.cover_url = str(cover)
|
|
84
84
|
|
|
85
85
|
# 2. 提取下载链接
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
tw_button_tags = soup.find_all("a", class_="tw-button-dl")
|
|
87
|
+
abutton_tags = soup.find_all("a", class_="abutton")
|
|
88
|
+
for tag in chain(tw_button_tags, abutton_tags):
|
|
89
|
+
if not isinstance(tag, Tag):
|
|
90
|
+
continue
|
|
91
|
+
href = tag.get("href")
|
|
92
|
+
if href is None:
|
|
93
93
|
continue
|
|
94
|
-
text = link.get_text(strip=True)
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
elif "下载 gif" in text:
|
|
100
|
-
data.dynamic_urls.append(href) # GIF和MP4是同一个文件
|
|
101
|
-
elif "下载 MP4" in text:
|
|
102
|
-
# 从GIF/MP4下载链接中提取原始视频URL
|
|
95
|
+
href = str(href)
|
|
96
|
+
text = tag.get_text(strip=True)
|
|
97
|
+
if "下载 MP4" in text:
|
|
103
98
|
data.video_url = href
|
|
104
99
|
break
|
|
100
|
+
elif "下载图片" in text:
|
|
101
|
+
data.images_urls.append(href)
|
|
102
|
+
elif "下载 gif" in text:
|
|
103
|
+
data.dynamic_urls.append(href)
|
|
105
104
|
|
|
106
105
|
# 3. 提取标题
|
|
107
106
|
title_tag = soup.find("h3")
|
|
108
107
|
if title_tag:
|
|
109
108
|
data.title = title_tag.get_text(strip=True)
|
|
110
109
|
|
|
110
|
+
return data
|
|
111
111
|
# # 4. 提取Twitter ID
|
|
112
112
|
# twitter_id_input = soup.find("input", {"id": "TwitterId"})
|
|
113
113
|
# if (
|
|
@@ -116,6 +116,3 @@ class TwitterParser(BaseParser):
|
|
|
116
116
|
# and (value := twitter_id_input.get("value"))
|
|
117
117
|
# and isinstance(value, str)
|
|
118
118
|
# ):
|
|
119
|
-
data.name = "暂时无法获取用户名"
|
|
120
|
-
|
|
121
|
-
return data
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from collections.abc import AsyncGenerator
|
|
3
|
+
from itertools import chain
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, ClassVar
|
|
6
|
+
|
|
7
|
+
from ..exception import MultiException, ParseException
|
|
8
|
+
from ..helper import Segment, UniHelper, UniMessage
|
|
9
|
+
from ..parsers import ParseResult
|
|
10
|
+
from ..parsers.data import AudioContent, DynamicContent, GraphicsContent, ImageContent, VideoContent
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BaseRenderer(ABC):
|
|
14
|
+
"""统一的渲染器,将解析结果转换为消息"""
|
|
15
|
+
|
|
16
|
+
templates_dir: ClassVar[Path] = Path(__file__).parent / "templates"
|
|
17
|
+
"""模板目录"""
|
|
18
|
+
|
|
19
|
+
@abstractmethod
|
|
20
|
+
async def render_messages(self, result: ParseResult) -> AsyncGenerator[UniMessage[Any], None]:
|
|
21
|
+
"""消息生成器
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
result (ParseResult): 解析结果
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
AsyncGenerator[UniMessage[Any], None]: 消息生成器
|
|
28
|
+
"""
|
|
29
|
+
if False:
|
|
30
|
+
yield
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
|
|
33
|
+
async def render_contents(self, result: ParseResult) -> AsyncGenerator[UniMessage[Any], None]:
|
|
34
|
+
"""渲染媒体内容消息
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
result (ParseResult): 解析结果
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
AsyncGenerator[UniMessage[Any], None]: 消息生成器
|
|
41
|
+
"""
|
|
42
|
+
raises: list[ParseException] = []
|
|
43
|
+
forwardable_segs: list[str | Segment | UniMessage] = []
|
|
44
|
+
for cont in chain(result.contents, result.repost.contents if result.repost else ()):
|
|
45
|
+
try:
|
|
46
|
+
path = await cont.get_path()
|
|
47
|
+
except ParseException as e:
|
|
48
|
+
forwardable_segs.append(e.message)
|
|
49
|
+
raises.append(e)
|
|
50
|
+
# 继续渲染其他内容
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
match cont:
|
|
54
|
+
case VideoContent():
|
|
55
|
+
yield UniMessage(UniHelper.video_seg(path))
|
|
56
|
+
case AudioContent():
|
|
57
|
+
yield UniMessage(UniHelper.record_seg(path))
|
|
58
|
+
case ImageContent():
|
|
59
|
+
forwardable_segs.append(UniHelper.img_seg(path))
|
|
60
|
+
case DynamicContent():
|
|
61
|
+
forwardable_segs.append(UniHelper.video_seg(path))
|
|
62
|
+
case GraphicsContent(_, text):
|
|
63
|
+
forwardable_segs.append(text + UniHelper.img_seg(path))
|
|
64
|
+
|
|
65
|
+
if forwardable_segs:
|
|
66
|
+
if all(isinstance(seg, str) for seg in forwardable_segs):
|
|
67
|
+
yield UniMessage(forwardable_segs)
|
|
68
|
+
else:
|
|
69
|
+
forward_msg = UniHelper.construct_forward_message(forwardable_segs)
|
|
70
|
+
yield UniMessage(forward_msg)
|
|
71
|
+
|
|
72
|
+
if raises:
|
|
73
|
+
raise MultiException(raises)
|
|
@@ -19,7 +19,13 @@ class DefaultRenderer(BaseRenderer):
|
|
|
19
19
|
Generator[UniMessage[Any], None, None]: 消息生成器
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
texts: list[str] = [
|
|
22
|
+
texts: list[str] = [
|
|
23
|
+
result.header,
|
|
24
|
+
result.text,
|
|
25
|
+
result.extra_info,
|
|
26
|
+
result.display_url,
|
|
27
|
+
result.repost_display_url,
|
|
28
|
+
]
|
|
23
29
|
texts = [text for text in texts if text]
|
|
24
30
|
texts[:-1] = [seg + "\n" for seg in texts[:-1]]
|
|
25
31
|
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
|
-
from collections.abc import AsyncGenerator
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Any, ClassVar
|
|
5
|
-
|
|
6
|
-
from ..helper import UniHelper as UniHelper
|
|
7
|
-
from ..helper import UniMessage as UniMessage
|
|
8
|
-
from ..parsers import ParseResult as ParseResult
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class BaseRenderer(ABC):
|
|
12
|
-
"""统一的渲染器,将解析结果转换为消息"""
|
|
13
|
-
|
|
14
|
-
templates_dir: ClassVar[Path] = Path(__file__).parent / "templates"
|
|
15
|
-
"""模板目录"""
|
|
16
|
-
|
|
17
|
-
@abstractmethod
|
|
18
|
-
async def render_messages(self, result: ParseResult) -> AsyncGenerator[UniMessage[Any], None]:
|
|
19
|
-
"""消息生成器
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
result (ParseResult): 解析结果
|
|
23
|
-
|
|
24
|
-
Returns:
|
|
25
|
-
AsyncGenerator[UniMessage[Any], None]: 消息生成器
|
|
26
|
-
"""
|
|
27
|
-
if False:
|
|
28
|
-
yield
|
|
29
|
-
raise NotImplementedError
|
|
30
|
-
|
|
31
|
-
async def render_contents(self, result: ParseResult) -> AsyncGenerator[UniMessage[Any], None]:
|
|
32
|
-
"""渲染内容消息
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
result (ParseResult): 解析结果
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
AsyncGenerator[UniMessage[Any], None]: 消息生成器
|
|
39
|
-
"""
|
|
40
|
-
separate_segs, forwardable_segs = await result.contents_to_segs()
|
|
41
|
-
|
|
42
|
-
# 处理可以合并转发的消息段
|
|
43
|
-
if forwardable_segs:
|
|
44
|
-
# 如果只有 str 类型, 则不使用转发消息
|
|
45
|
-
if all(isinstance(seg, str) for seg in forwardable_segs):
|
|
46
|
-
yield UniMessage(forwardable_segs)
|
|
47
|
-
else:
|
|
48
|
-
forward_msg = UniHelper.construct_forward_message(forwardable_segs)
|
|
49
|
-
yield UniMessage(forward_msg)
|
|
50
|
-
|
|
51
|
-
# 处理必须单独发送的消息段
|
|
52
|
-
if separate_segs:
|
|
53
|
-
for seg in separate_segs:
|
|
54
|
-
yield UniMessage(seg)
|
{nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/__init__.py
RENAMED
|
File without changes
|
{nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/config.py
RENAMED
|
File without changes
|
{nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/parsers/nga.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_parser-2.0.1 → nonebot_plugin_parser-2.0.2}/src/nonebot_plugin_parser/utils.py
RENAMED
|
File without changes
|