nonebot-plugin-parser 2.4.1__tar.gz → 2.4.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.4.1 → nonebot_plugin_parser-2.4.2}/PKG-INFO +1 -1
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/pyproject.toml +2 -2
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/base.py +12 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/twitter.py +82 -25
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/README.md +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/config.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/constants.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/download/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/download/task.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/download/ytdlp.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/exception.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/helper.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/matchers/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/matchers/filter.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/matchers/rule.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/acfun/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/acfun/video.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/article.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/common.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/dynamic.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/favlist.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/live.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/opus.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/bilibili/video.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/cookie.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/data.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/douyin/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/douyin/slides.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/douyin/video.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/kuaishou/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/kuaishou/states.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/nga.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/tiktok.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/weibo/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/weibo/article.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/weibo/common.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/weibo/show.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/xiaohongshu/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/xiaohongshu/common.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/xiaohongshu/discovery.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/xiaohongshu/explore.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/youtube/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/parsers/youtube/meta.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/__init__.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/base.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/common.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/default.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/htmlrender.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/HYSongYunLangHeiW.ttf +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/avatar.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/bilibili.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/douyin.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/kuaishou.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/play.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/tiktok.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/twitter.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/weibo.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/xiaohongshu.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/resources/youtube.png +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/templates/card.html.jinja +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/templates/weibo.html.jinja +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/renders/weibo.py +0 -0
- {nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.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.4.
|
|
3
|
+
Version: 2.4.2
|
|
4
4
|
Summary: NoneBot2 链接分享解析 Alconna 版, 现支持B站|抖音|快手|微博|小红书|YouTube|TikTok|Twitter|AcFun|NGA
|
|
5
5
|
Keywords: acfun,bilibili,douyin,kuaishou,nga,nonebot,nonebot2,tiktok,twitter,video,weibo,xiaohongshu,youtube
|
|
6
6
|
Author: fllesser
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nonebot-plugin-parser"
|
|
3
|
-
version = "2.4.
|
|
3
|
+
version = "2.4.2"
|
|
4
4
|
description = "NoneBot2 链接分享解析 Alconna 版, 现支持B站|抖音|快手|微博|小红书|YouTube|TikTok|Twitter|AcFun|NGA"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -119,7 +119,7 @@ nonebug = { git = "https://github.com/nonebot/nonebug" }
|
|
|
119
119
|
[tool.bumpversion]
|
|
120
120
|
tag = true
|
|
121
121
|
commit = true
|
|
122
|
-
current_version = "2.4.
|
|
122
|
+
current_version = "2.4.2"
|
|
123
123
|
message = "release: bump vesion from {current_version} to {new_version}"
|
|
124
124
|
|
|
125
125
|
[[tool.bumpversion.files]]
|
|
@@ -199,6 +199,18 @@ class BaseParser:
|
|
|
199
199
|
contents.append(ImageContent(task))
|
|
200
200
|
return contents
|
|
201
201
|
|
|
202
|
+
def create_image_content(
|
|
203
|
+
self,
|
|
204
|
+
url_or_task: str | Task[Path],
|
|
205
|
+
):
|
|
206
|
+
"""创建图片内容"""
|
|
207
|
+
from .data import ImageContent
|
|
208
|
+
|
|
209
|
+
if isinstance(url_or_task, str):
|
|
210
|
+
url_or_task = DOWNLOADER.download_img(url_or_task, ext_headers=self.headers)
|
|
211
|
+
|
|
212
|
+
return ImageContent(url_or_task)
|
|
213
|
+
|
|
202
214
|
def create_dynamic_contents(
|
|
203
215
|
self,
|
|
204
216
|
dynamic_urls: list[str],
|
|
@@ -3,31 +3,82 @@ from typing import Any, ClassVar
|
|
|
3
3
|
from itertools import chain
|
|
4
4
|
|
|
5
5
|
from httpx import AsyncClient
|
|
6
|
+
from msgspec import Struct, field
|
|
7
|
+
from msgspec.json import Decoder
|
|
6
8
|
|
|
7
9
|
from .base import BaseParser, PlatformEnum, handle
|
|
8
|
-
from .data import Platform, ParseResult
|
|
10
|
+
from .data import Platform, ParseResult, MediaContent
|
|
9
11
|
from ..exception import ParseException
|
|
10
12
|
|
|
11
13
|
|
|
14
|
+
class MediaElement(Struct):
|
|
15
|
+
type: str
|
|
16
|
+
"""媒体类型 video/image/gif"""
|
|
17
|
+
url: str
|
|
18
|
+
altText: str | None = None
|
|
19
|
+
thumbnail_url: str | None = None
|
|
20
|
+
duration_millis: int | None = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class VxTwitterResponse(Struct):
|
|
24
|
+
article: str | None
|
|
25
|
+
date_epoch: int
|
|
26
|
+
fetched_on: int
|
|
27
|
+
likes: int
|
|
28
|
+
text: str
|
|
29
|
+
user_name: str
|
|
30
|
+
user_screen_name: str
|
|
31
|
+
user_profile_image_url: str
|
|
32
|
+
qrt: "VxTwitterResponse | None" = None
|
|
33
|
+
qrtURL: str | None = None
|
|
34
|
+
media_extended: list[MediaElement] = field(default_factory=list)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
decoder = Decoder(VxTwitterResponse)
|
|
38
|
+
|
|
39
|
+
|
|
12
40
|
class TwitterParser(BaseParser):
|
|
13
41
|
platform: ClassVar[Platform] = Platform(name=PlatformEnum.TWITTER, display_name="小蓝鸟")
|
|
14
42
|
|
|
15
|
-
async def _req_xdown_api(self, url: str) -> dict[str, Any]:
|
|
16
|
-
headers = {
|
|
17
|
-
"Accept": "application/json, text/plain, */*",
|
|
18
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
19
|
-
"Origin": "https://xdown.app",
|
|
20
|
-
"Referer": "https://xdown.app/",
|
|
21
|
-
**self.headers,
|
|
22
|
-
}
|
|
23
|
-
data = {"q": url, "lang": "zh-cn"}
|
|
24
|
-
async with AsyncClient(headers=headers, timeout=self.timeout) as client:
|
|
25
|
-
url = "https://xdown.app/api/ajaxSearch"
|
|
26
|
-
response = await client.post(url, data=data)
|
|
27
|
-
return response.json()
|
|
28
|
-
|
|
29
43
|
@handle("x.com", r"x.com/[0-9-a-zA-Z_]{1,20}/status/([0-9]+)")
|
|
30
44
|
async def _parse(self, searched: re.Match[str]) -> ParseResult:
|
|
45
|
+
url = f"https://{searched.group(0)}"
|
|
46
|
+
return await self.parse_by_vxapi(url)
|
|
47
|
+
|
|
48
|
+
async def parse_by_vxapi(self, url: str):
|
|
49
|
+
"""使用 vxtwitter API 解析 Twitter 链接"""
|
|
50
|
+
|
|
51
|
+
api_url = url.replace("x.com", "api.vxtwitter.com")
|
|
52
|
+
async with AsyncClient(headers=self.headers, timeout=self.timeout) as client:
|
|
53
|
+
response = await client.get(api_url)
|
|
54
|
+
response.raise_for_status()
|
|
55
|
+
|
|
56
|
+
data = decoder.decode(response.content)
|
|
57
|
+
return self._collect_result(data)
|
|
58
|
+
|
|
59
|
+
def _collect_result(self, data: VxTwitterResponse) -> ParseResult:
|
|
60
|
+
author = self.create_author(data.user_screen_name, data.user_profile_image_url)
|
|
61
|
+
|
|
62
|
+
contents: list[MediaContent] = []
|
|
63
|
+
|
|
64
|
+
for media in data.media_extended:
|
|
65
|
+
if media.type in ("video", "gif"):
|
|
66
|
+
contents.append(self.create_video_content(media.url, media.thumbnail_url))
|
|
67
|
+
elif media.type == "image":
|
|
68
|
+
contents.append(self.create_image_content(media.url))
|
|
69
|
+
|
|
70
|
+
repost = self._collect_result(data.qrt) if data.qrt else None
|
|
71
|
+
|
|
72
|
+
return self.result(
|
|
73
|
+
author=author,
|
|
74
|
+
title=data.article,
|
|
75
|
+
text=data.text,
|
|
76
|
+
timestamp=data.date_epoch,
|
|
77
|
+
contents=contents,
|
|
78
|
+
repost=repost,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
async def _parse_old(self, searched: re.Match[str]) -> ParseResult:
|
|
31
82
|
# 从匹配对象中获取原始URL
|
|
32
83
|
url = f"https://{searched.group(0)}"
|
|
33
84
|
|
|
@@ -40,9 +91,23 @@ class TwitterParser(BaseParser):
|
|
|
40
91
|
if html_content is None:
|
|
41
92
|
raise ParseException("解析失败, 数据为空")
|
|
42
93
|
|
|
43
|
-
return self.
|
|
94
|
+
return self._parse_twitter_html(html_content)
|
|
95
|
+
|
|
96
|
+
async def _req_xdown_api(self, url: str) -> dict[str, Any]:
|
|
97
|
+
headers = {
|
|
98
|
+
"Accept": "application/json, text/plain, */*",
|
|
99
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
100
|
+
"Origin": "https://xdown.app",
|
|
101
|
+
"Referer": "https://xdown.app/",
|
|
102
|
+
**self.headers,
|
|
103
|
+
}
|
|
104
|
+
data = {"q": url, "lang": "zh-cn"}
|
|
105
|
+
async with AsyncClient(headers=headers, timeout=self.timeout) as client:
|
|
106
|
+
url = "https://xdown.app/api/ajaxSearch"
|
|
107
|
+
response = await client.post(url, data=data)
|
|
108
|
+
return response.json()
|
|
44
109
|
|
|
45
|
-
def
|
|
110
|
+
def _parse_twitter_html(self, html_content: str) -> ParseResult:
|
|
46
111
|
"""解析 Twitter HTML 内容"""
|
|
47
112
|
from bs4 import Tag, BeautifulSoup
|
|
48
113
|
|
|
@@ -106,11 +171,3 @@ class TwitterParser(BaseParser):
|
|
|
106
171
|
author=self.create_author("无用户名"),
|
|
107
172
|
contents=contents,
|
|
108
173
|
)
|
|
109
|
-
# # 4. 提取Twitter ID
|
|
110
|
-
# twitter_id_input = soup.find("input", {"id": "TwitterId"})
|
|
111
|
-
# if (
|
|
112
|
-
# twitter_id_input
|
|
113
|
-
# and isinstance(twitter_id_input, Tag)
|
|
114
|
-
# and (value := twitter_id_input.get("value"))
|
|
115
|
-
# and isinstance(value, str)
|
|
116
|
-
# ):
|
|
File without changes
|
{nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/__init__.py
RENAMED
|
File without changes
|
{nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/config.py
RENAMED
|
File without changes
|
{nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/constants.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/exception.py
RENAMED
|
File without changes
|
{nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/helper.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nonebot_plugin_parser-2.4.1 → nonebot_plugin_parser-2.4.2}/src/nonebot_plugin_parser/utils.py
RENAMED
|
File without changes
|