nonebot-plugin-htmlrender 0.5.0__tar.gz → 0.6.0__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_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/.github/workflows/publish.yml +6 -1
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/.gitignore +3 -0
- nonebot_plugin_htmlrender-0.6.0/.pre-commit-config.yaml +16 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/PKG-INFO +37 -22
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/README.md +34 -20
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/__init__.py +12 -10
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/utils.py +6 -5
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/__init__.py +55 -0
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/browser.py +169 -0
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/config.py +80 -0
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/consts.py +38 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/data_source.py +24 -24
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/install.py +230 -0
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/process.py +165 -0
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/signal.py +138 -0
- nonebot_plugin_htmlrender-0.6.0/nonebot_plugin_htmlrender/utils.py +148 -0
- nonebot_plugin_htmlrender-0.6.0/pyproject.toml +105 -0
- nonebot_plugin_htmlrender-0.6.0/tests/test_browser.py +296 -0
- nonebot_plugin_htmlrender-0.6.0/tests/test_config_custom_validation.py +120 -0
- nonebot_plugin_htmlrender-0.6.0/tests/test_deprecated_decorator.py +61 -0
- nonebot_plugin_htmlrender-0.6.0/tests/test_htmlrender.py +139 -0
- nonebot_plugin_htmlrender-0.6.0/tests/test_install.py +131 -0
- nonebot_plugin_htmlrender-0.6.0/tests/test_process.py +185 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/uv.lock +128 -1
- nonebot_plugin_htmlrender-0.5.0/.flake8 +0 -3
- nonebot_plugin_htmlrender-0.5.0/nonebot_plugin_htmlrender/__init__.py +0 -60
- nonebot_plugin_htmlrender-0.5.0/nonebot_plugin_htmlrender/browser.py +0 -356
- nonebot_plugin_htmlrender-0.5.0/nonebot_plugin_htmlrender/config.py +0 -17
- nonebot_plugin_htmlrender-0.5.0/pyproject.toml +0 -40
- nonebot_plugin_htmlrender-0.5.0/tests/test_htmlrender.py +0 -86
- nonebot_plugin_htmlrender-0.5.0/tests/utils.py +0 -10
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/.github/workflows/codecov.yml +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/.python-version +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/LICENSE +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/docs/example.md +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/docs/html2pic.png +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/docs/md2pic.png +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/docs/template2pic.png +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/docs/text2pic.png +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/.env.dev +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/bot.py +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/html2pic.html +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/templates/markdown.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/templates/mystyle.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/templates/progress.html.jinja2 +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/templates/text.html +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/github-markdown-light.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/katex/katex.min.b64_fonts.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/katex/katex.min.js +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/katex/mathtex-script-type.min.js +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/katex/mhchem.min.js +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/markdown.html +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/pygments-default.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/text.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/nonebot_plugin_htmlrender/templates/text.html +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/tests/__init__.py +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/tests/conftest.py +0 -0
- {nonebot_plugin_htmlrender-0.5.0/tests → nonebot_plugin_htmlrender-0.6.0/tests/resources}/test_template_filter.png +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/tests/templates/markdown.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/tests/templates/mystyle.css +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/tests/templates/progress.html.jinja2 +0 -0
- {nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/tests/templates/text.html +0 -0
{nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/.github/workflows/publish.yml
RENAMED
|
@@ -43,8 +43,13 @@ jobs:
|
|
|
43
43
|
- name: Build Package
|
|
44
44
|
run: uv build
|
|
45
45
|
|
|
46
|
+
- uses: actions/upload-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: artifact
|
|
49
|
+
path: dist/ # or path/to/artifact
|
|
50
|
+
|
|
46
51
|
- name: pypi-publish
|
|
47
|
-
uses: pypa/gh-action-pypi-publish@v1.
|
|
52
|
+
uses: pypa/gh-action-pypi-publish@v1.12.3
|
|
48
53
|
|
|
49
54
|
# - name: Publish Package to PyPI
|
|
50
55
|
# run: uv publish
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
default_install_hook_types: [pre-commit]
|
|
2
|
+
ci:
|
|
3
|
+
autofix_commit_msg: ":rotating_light: auto fix by pre-commit hooks"
|
|
4
|
+
autofix_prs: true
|
|
5
|
+
autoupdate_branch: main
|
|
6
|
+
autoupdate_schedule: monthly
|
|
7
|
+
autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks"
|
|
8
|
+
repos:
|
|
9
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
10
|
+
rev: v0.8.2
|
|
11
|
+
hooks:
|
|
12
|
+
- id: ruff
|
|
13
|
+
args: [--fix]
|
|
14
|
+
stages: [pre-commit]
|
|
15
|
+
- id: ruff-format
|
|
16
|
+
stages: [pre-commit]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: nonebot-plugin-htmlrender
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: 通过浏览器渲染图片
|
|
5
5
|
Project-URL: Homepage, https://github.com/kexue-z/nonebot-plugin-htmlrender
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/kexue-z/nonebot-plugin-htmlrender/issues
|
|
@@ -26,6 +26,7 @@ License: MIT License
|
|
|
26
26
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
27
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
28
|
SOFTWARE.
|
|
29
|
+
License-File: LICENSE
|
|
29
30
|
Requires-Python: <4.0,>=3.9
|
|
30
31
|
Requires-Dist: aiofiles>=0.8.0
|
|
31
32
|
Requires-Dist: jinja2>=3.0.3
|
|
@@ -55,6 +56,7 @@ Description-Content-Type: text/markdown
|
|
|
55
56
|
|
|
56
57
|
```py
|
|
57
58
|
from nonebot import require
|
|
59
|
+
|
|
58
60
|
require("nonebot_plugin_htmlrender")
|
|
59
61
|
# 注意顺序,先require再 from ... import ...
|
|
60
62
|
# 注意顺序,先require再 from ... import ...
|
|
@@ -72,32 +74,44 @@ from nonebot_plugin_htmlrender import (
|
|
|
72
74
|
|
|
73
75
|
# 配置
|
|
74
76
|
|
|
77
|
+
## .env 配置项说明
|
|
78
|
+
|
|
75
79
|
```ini
|
|
76
|
-
#
|
|
80
|
+
# Playwright 浏览器引擎类型
|
|
81
|
+
# 可不填,默认为 "chromium"
|
|
77
82
|
htmlrender_browser = "chromium"
|
|
78
|
-
# 使用 firefox
|
|
79
|
-
htmlrender_browser = "firefox"
|
|
80
83
|
|
|
81
|
-
#
|
|
84
|
+
# Playwright 浏览器下载地址
|
|
85
|
+
# 可选,用于自定义浏览器下载源
|
|
82
86
|
htmlrender_download_host = ""
|
|
83
87
|
|
|
84
|
-
#
|
|
85
|
-
|
|
88
|
+
# Playwright 浏览器下载代理
|
|
89
|
+
# 可选,用于配置下载浏览器时的代理
|
|
90
|
+
htmlrender_download_proxy = ""
|
|
91
|
+
|
|
92
|
+
# Playwright 浏览器代理地址
|
|
93
|
+
# 可选,用于配置浏览器访问时的代理
|
|
94
|
+
# 示例: htmlrender_proxy_host = "http://127.0.0.1:7890"
|
|
95
|
+
|
|
96
|
+
# Playwright 浏览器代理绕过地址
|
|
97
|
+
# 可选,指定不使用代理的地址
|
|
98
|
+
htmlrender_proxy_host_bypass = ""
|
|
86
99
|
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
# "
|
|
90
|
-
#
|
|
91
|
-
#
|
|
100
|
+
# Playwright 浏览器通道
|
|
101
|
+
# 可选,支持以下值:
|
|
102
|
+
# - Chrome: "chrome", "chrome-beta", "chrome-dev", "chrome-canary"
|
|
103
|
+
# - Edge: "msedge", "msedge-beta", "msedge-dev", "msedge-canary"
|
|
104
|
+
# 配置后可直接使用系统浏览器,无需下载 Chromium
|
|
92
105
|
htmlrender_browser_channel = ""
|
|
93
106
|
|
|
94
|
-
#
|
|
107
|
+
# Playwright 浏览器可执行文件路径
|
|
108
|
+
# 可选,用于指定浏览器程序位置
|
|
95
109
|
htmlrender_browser_executable_path = ""
|
|
96
110
|
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
htmlrender_connect_over_cdp = "http://127.0.0.1:
|
|
111
|
+
# CDP 远程调试地址
|
|
112
|
+
# 可选,用于连接已运行的浏览器实例
|
|
113
|
+
# 使用时需要在启动浏览器时添加参数 --remote-debugging-port=端口号
|
|
114
|
+
htmlrender_connect_over_cdp = "http://127.0.0.1:9222"
|
|
101
115
|
```
|
|
102
116
|
|
|
103
117
|
## markdown 转 图片
|
|
@@ -106,8 +120,8 @@ htmlrender_connect_over_cdp = "http://127.0.0.1:1234"
|
|
|
106
120
|
- 支持绝大部分 md 语法
|
|
107
121
|
- 代码高亮
|
|
108
122
|
- latex 数学公式 (感谢@[MeetWq](https://github.com/MeetWq))
|
|
109
|
-
|
|
110
|
-
|
|
123
|
+
- 使用 `$$...$$` 来输入独立公式
|
|
124
|
+
- 使用 `$...$` 来输入行内公式
|
|
111
125
|
- 图片需要使用外部连接并使用`html`格式 否则文末会超出截图范围
|
|
112
126
|
- 图片可使用 md 语法 路径可为 `绝对路径`(建议), 或 `相对于template_path` 的路径
|
|
113
127
|
|
|
@@ -165,10 +179,11 @@ LC_ALL zh_CN.UTF-8
|
|
|
165
179
|
### CentOS 使用 `yum`
|
|
166
180
|
|
|
167
181
|
- ~~小心 CentOS~~
|
|
168
|
-
-
|
|
182
|
+
-
|
|
183
|
+
参考[CentOS Dockerfile](https://github.com/kumaraditya303/playwright-centos/blob/master/Dockerfile)
|
|
169
184
|
- 添加中文字体库
|
|
170
185
|
- ~~最佳解决办法~~
|
|
171
|
-
|
|
186
|
+
- 使用 Docker 然后用 Python 镜像 按照上面 Ubuntu 的写 `dockerfile`
|
|
172
187
|
|
|
173
188
|
下面这个依赖运行一下 也许就可以用了
|
|
174
189
|
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
```py
|
|
18
18
|
from nonebot import require
|
|
19
|
+
|
|
19
20
|
require("nonebot_plugin_htmlrender")
|
|
20
21
|
# 注意顺序,先require再 from ... import ...
|
|
21
22
|
# 注意顺序,先require再 from ... import ...
|
|
@@ -33,32 +34,44 @@ from nonebot_plugin_htmlrender import (
|
|
|
33
34
|
|
|
34
35
|
# 配置
|
|
35
36
|
|
|
37
|
+
## .env 配置项说明
|
|
38
|
+
|
|
36
39
|
```ini
|
|
37
|
-
#
|
|
40
|
+
# Playwright 浏览器引擎类型
|
|
41
|
+
# 可不填,默认为 "chromium"
|
|
38
42
|
htmlrender_browser = "chromium"
|
|
39
|
-
# 使用 firefox
|
|
40
|
-
htmlrender_browser = "firefox"
|
|
41
43
|
|
|
42
|
-
#
|
|
44
|
+
# Playwright 浏览器下载地址
|
|
45
|
+
# 可选,用于自定义浏览器下载源
|
|
43
46
|
htmlrender_download_host = ""
|
|
44
47
|
|
|
45
|
-
#
|
|
46
|
-
|
|
48
|
+
# Playwright 浏览器下载代理
|
|
49
|
+
# 可选,用于配置下载浏览器时的代理
|
|
50
|
+
htmlrender_download_proxy = ""
|
|
51
|
+
|
|
52
|
+
# Playwright 浏览器代理地址
|
|
53
|
+
# 可选,用于配置浏览器访问时的代理
|
|
54
|
+
# 示例: htmlrender_proxy_host = "http://127.0.0.1:7890"
|
|
55
|
+
|
|
56
|
+
# Playwright 浏览器代理绕过地址
|
|
57
|
+
# 可选,指定不使用代理的地址
|
|
58
|
+
htmlrender_proxy_host_bypass = ""
|
|
47
59
|
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
# "
|
|
51
|
-
#
|
|
52
|
-
#
|
|
60
|
+
# Playwright 浏览器通道
|
|
61
|
+
# 可选,支持以下值:
|
|
62
|
+
# - Chrome: "chrome", "chrome-beta", "chrome-dev", "chrome-canary"
|
|
63
|
+
# - Edge: "msedge", "msedge-beta", "msedge-dev", "msedge-canary"
|
|
64
|
+
# 配置后可直接使用系统浏览器,无需下载 Chromium
|
|
53
65
|
htmlrender_browser_channel = ""
|
|
54
66
|
|
|
55
|
-
#
|
|
67
|
+
# Playwright 浏览器可执行文件路径
|
|
68
|
+
# 可选,用于指定浏览器程序位置
|
|
56
69
|
htmlrender_browser_executable_path = ""
|
|
57
70
|
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
htmlrender_connect_over_cdp = "http://127.0.0.1:
|
|
71
|
+
# CDP 远程调试地址
|
|
72
|
+
# 可选,用于连接已运行的浏览器实例
|
|
73
|
+
# 使用时需要在启动浏览器时添加参数 --remote-debugging-port=端口号
|
|
74
|
+
htmlrender_connect_over_cdp = "http://127.0.0.1:9222"
|
|
62
75
|
```
|
|
63
76
|
|
|
64
77
|
## markdown 转 图片
|
|
@@ -67,8 +80,8 @@ htmlrender_connect_over_cdp = "http://127.0.0.1:1234"
|
|
|
67
80
|
- 支持绝大部分 md 语法
|
|
68
81
|
- 代码高亮
|
|
69
82
|
- latex 数学公式 (感谢@[MeetWq](https://github.com/MeetWq))
|
|
70
|
-
|
|
71
|
-
|
|
83
|
+
- 使用 `$$...$$` 来输入独立公式
|
|
84
|
+
- 使用 `$...$` 来输入行内公式
|
|
72
85
|
- 图片需要使用外部连接并使用`html`格式 否则文末会超出截图范围
|
|
73
86
|
- 图片可使用 md 语法 路径可为 `绝对路径`(建议), 或 `相对于template_path` 的路径
|
|
74
87
|
|
|
@@ -126,10 +139,11 @@ LC_ALL zh_CN.UTF-8
|
|
|
126
139
|
### CentOS 使用 `yum`
|
|
127
140
|
|
|
128
141
|
- ~~小心 CentOS~~
|
|
129
|
-
-
|
|
142
|
+
-
|
|
143
|
+
参考[CentOS Dockerfile](https://github.com/kumaraditya303/playwright-centos/blob/master/Dockerfile)
|
|
130
144
|
- 添加中文字体库
|
|
131
145
|
- ~~最佳解决办法~~
|
|
132
|
-
|
|
146
|
+
- 使用 Docker 然后用 Python 镜像 按照上面 Ubuntu 的写 `dockerfile`
|
|
133
147
|
|
|
134
148
|
下面这个依赖运行一下 也许就可以用了
|
|
135
149
|
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
from nonebot import require
|
|
2
|
+
|
|
2
3
|
require("nonebot_plugin_htmlrender")
|
|
3
4
|
# 注意顺序,先require再 from ... import ...
|
|
4
5
|
# 注意顺序,先require再 from ... import ...
|
|
5
6
|
# 注意顺序,先require再 from ... import ...
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
md_to_pic,
|
|
9
|
-
template_to_pic,
|
|
10
|
-
get_new_page,
|
|
11
|
-
)
|
|
7
|
+
import io
|
|
8
|
+
|
|
12
9
|
# 注意顺序,先require再 from ... import ...
|
|
13
10
|
# 注意顺序,先require再 from ... import ...
|
|
14
11
|
# 注意顺序,先require再 from ... import ...
|
|
15
|
-
|
|
16
12
|
from nonebot import on_command
|
|
17
13
|
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment
|
|
18
14
|
from PIL import Image
|
|
19
|
-
|
|
15
|
+
|
|
16
|
+
from nonebot_plugin_htmlrender import (
|
|
17
|
+
get_new_page,
|
|
18
|
+
md_to_pic,
|
|
19
|
+
template_to_pic,
|
|
20
|
+
text_to_pic,
|
|
21
|
+
)
|
|
20
22
|
|
|
21
23
|
from .utils import count_to_color
|
|
22
24
|
|
|
@@ -109,7 +111,7 @@ async def _():
|
|
|
109
111
|
pages={
|
|
110
112
|
"viewport": {"width": 600, "height": 300},
|
|
111
113
|
"base_url": f"file://{template_path}",
|
|
112
|
-
}
|
|
114
|
+
},
|
|
113
115
|
)
|
|
114
116
|
|
|
115
117
|
a = Image.open(io.BytesIO(pic))
|
|
@@ -124,7 +126,7 @@ md2pic = on_command("md2pic")
|
|
|
124
126
|
|
|
125
127
|
@md2pic.handle()
|
|
126
128
|
async def _md2pic(bot: Bot, event: MessageEvent):
|
|
127
|
-
from pathlib import Path
|
|
129
|
+
# from pathlib import Path
|
|
128
130
|
|
|
129
131
|
# 如果是直接获取消息内容 需要 unescape
|
|
130
132
|
from nonebot.adapters.onebot.v11 import unescape
|
{nonebot_plugin_htmlrender-0.5.0 → nonebot_plugin_htmlrender-0.6.0}/example/plugins/render/utils.py
RENAMED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from nonebot.log import logger
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
def count_to_color(count: str) -> str:
|
|
4
|
-
logger.debug(f"Filtering count: {count}")
|
|
5
|
-
if count ==
|
|
5
|
+
logger.debug(f"Filtering count: {count}")
|
|
6
|
+
if count == "1":
|
|
6
7
|
return "#facc15"
|
|
7
|
-
elif count ==
|
|
8
|
+
elif count == "2":
|
|
8
9
|
return "#f87171"
|
|
9
|
-
elif count ==
|
|
10
|
+
elif count == "3":
|
|
10
11
|
return "#c084fc"
|
|
11
12
|
else:
|
|
12
|
-
return "#60a5fa"
|
|
13
|
+
return "#60a5fa"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import nonebot
|
|
2
|
+
from nonebot.log import logger
|
|
3
|
+
from nonebot.plugin import PluginMetadata
|
|
4
|
+
|
|
5
|
+
from nonebot_plugin_htmlrender.browser import get_browser as get_browser
|
|
6
|
+
from nonebot_plugin_htmlrender.browser import get_new_page as get_new_page
|
|
7
|
+
from nonebot_plugin_htmlrender.browser import init_browser as init_browser
|
|
8
|
+
from nonebot_plugin_htmlrender.browser import shutdown_browser as shutdown_browser
|
|
9
|
+
from nonebot_plugin_htmlrender.browser import start_browser as start_browser
|
|
10
|
+
from nonebot_plugin_htmlrender.config import Config
|
|
11
|
+
from nonebot_plugin_htmlrender.data_source import capture_element as capture_element
|
|
12
|
+
from nonebot_plugin_htmlrender.data_source import html_to_pic as html_to_pic
|
|
13
|
+
from nonebot_plugin_htmlrender.data_source import md_to_pic as md_to_pic
|
|
14
|
+
from nonebot_plugin_htmlrender.data_source import template_to_html as template_to_html
|
|
15
|
+
from nonebot_plugin_htmlrender.data_source import template_to_pic as template_to_pic
|
|
16
|
+
from nonebot_plugin_htmlrender.data_source import text_to_pic as text_to_pic
|
|
17
|
+
|
|
18
|
+
__plugin_meta__ = PluginMetadata(
|
|
19
|
+
name="nonebot-plugin-htmlrender",
|
|
20
|
+
description="通过浏览器渲染图片",
|
|
21
|
+
usage="",
|
|
22
|
+
type="library",
|
|
23
|
+
config=Config,
|
|
24
|
+
homepage="https://github.com/kexue-z/nonebot-plugin-htmlrender",
|
|
25
|
+
extra={},
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
driver = nonebot.get_driver()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@driver.on_startup
|
|
32
|
+
async def init(**kwargs):
|
|
33
|
+
logger.info("htmlrender启动中...")
|
|
34
|
+
await init_browser(**kwargs)
|
|
35
|
+
logger.info("htmlrender已启动.")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@driver.on_shutdown
|
|
39
|
+
async def shutdown():
|
|
40
|
+
logger.info("htmlrender关闭中...")
|
|
41
|
+
await shutdown_browser()
|
|
42
|
+
logger.info("htmlrender已关闭.")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
"capture_element",
|
|
47
|
+
"get_new_page",
|
|
48
|
+
"html_to_pic",
|
|
49
|
+
"md_to_pic",
|
|
50
|
+
"shutdown_browser",
|
|
51
|
+
"start_browser",
|
|
52
|
+
"template_to_html",
|
|
53
|
+
"template_to_pic",
|
|
54
|
+
"text_to_pic",
|
|
55
|
+
]
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
from collections.abc import AsyncIterator
|
|
2
|
+
from contextlib import asynccontextmanager
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from nonebot.log import logger
|
|
6
|
+
from playwright.async_api import (
|
|
7
|
+
Browser,
|
|
8
|
+
BrowserType,
|
|
9
|
+
Error,
|
|
10
|
+
Page,
|
|
11
|
+
Playwright,
|
|
12
|
+
async_playwright,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from nonebot_plugin_htmlrender.config import BrowserEngineType, plugin_config
|
|
16
|
+
from nonebot_plugin_htmlrender.install import install_browser
|
|
17
|
+
from nonebot_plugin_htmlrender.utils import proxy_settings, suppress_and_log
|
|
18
|
+
|
|
19
|
+
_browser: Optional[Browser] = None
|
|
20
|
+
_playwright: Optional[Playwright] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def _launch(browser_type: BrowserEngineType, **kwargs) -> Browser:
|
|
24
|
+
"""
|
|
25
|
+
启动浏览器实例。
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
browser_type (BrowserEngineType): 浏览器类型。
|
|
29
|
+
**kwargs: 传递给`playwright.launch`的关键字参数。
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Browser: 启动的浏览器实例。
|
|
33
|
+
"""
|
|
34
|
+
_browser_cls: BrowserType = getattr(_playwright, browser_type)
|
|
35
|
+
logger.opt(colors=True).debug(
|
|
36
|
+
f"<cyan>{browser_type.capitalize()}</cyan> launching with kwargs: {kwargs}"
|
|
37
|
+
)
|
|
38
|
+
logger.opt(colors=True).debug(
|
|
39
|
+
f"Looking for Browser in path: <blue>{_browser_cls.executable_path}</blue>"
|
|
40
|
+
)
|
|
41
|
+
return await _browser_cls.launch(**kwargs)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
async def init_browser(**kwargs) -> Browser:
|
|
45
|
+
"""
|
|
46
|
+
初始化浏览器实例。
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
**kwargs: 传递给`playwright.launch`的关键字参数。
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Browser: 浏览器实例。
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
RuntimeError: 如果浏览器无法启动或安装失败。
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
return await start_browser(**kwargs)
|
|
59
|
+
except (Error, Exception) as e:
|
|
60
|
+
if "Executable doesn't exist" not in str(e):
|
|
61
|
+
raise RuntimeError("无法启动浏览器实例") from e
|
|
62
|
+
try:
|
|
63
|
+
if await install_browser():
|
|
64
|
+
return await start_browser(**kwargs)
|
|
65
|
+
else:
|
|
66
|
+
raise RuntimeError("无法启动浏览器实例且尝试安装失败") from e
|
|
67
|
+
except Exception as e:
|
|
68
|
+
raise RuntimeError("无法启动浏览器实例") from e
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@asynccontextmanager
|
|
72
|
+
async def get_new_page(device_scale_factor: float = 2, **kwargs) -> AsyncIterator[Page]:
|
|
73
|
+
"""
|
|
74
|
+
获取一个新的页面的上下文管理器。
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
device_scale_factor (float): 设备缩放因子。
|
|
78
|
+
**kwargs: 传递给`browser.new_context`的关键字参数。
|
|
79
|
+
|
|
80
|
+
Yields:
|
|
81
|
+
Page: 页面对象。
|
|
82
|
+
"""
|
|
83
|
+
ctx = await get_browser()
|
|
84
|
+
page = await ctx.new_page(device_scale_factor=device_scale_factor, **kwargs)
|
|
85
|
+
try:
|
|
86
|
+
yield page
|
|
87
|
+
finally:
|
|
88
|
+
await page.close()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async def get_browser(**kwargs) -> Browser:
|
|
92
|
+
"""
|
|
93
|
+
获取浏览器实例。
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
**kwargs: 传递给`playwright.launch`的关键字参数。
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Browser: 浏览器实例。
|
|
100
|
+
"""
|
|
101
|
+
if _browser and _browser.is_connected():
|
|
102
|
+
return _browser
|
|
103
|
+
|
|
104
|
+
return await init_browser(**kwargs)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
async def _connect_via_cdp(**kwargs) -> Browser:
|
|
108
|
+
"""
|
|
109
|
+
通过 CDP 连接 Chromium 浏览器。
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
**kwargs: 传递给`chromium.connect_over_cdp`的关键字参数。
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
Browser: 通过 CDP 连接的浏览器实例。
|
|
116
|
+
|
|
117
|
+
Raises:
|
|
118
|
+
RuntimeError: 如果 Playwright 未初始化。
|
|
119
|
+
"""
|
|
120
|
+
kwargs["endpoint_url"] = plugin_config.htmlrender_connect_over_cdp
|
|
121
|
+
logger.info(
|
|
122
|
+
f"正在使用 CDP 连接 Chromium({plugin_config.htmlrender_connect_over_cdp})"
|
|
123
|
+
)
|
|
124
|
+
if _playwright is not None:
|
|
125
|
+
return await _playwright.chromium.connect_over_cdp(**kwargs)
|
|
126
|
+
else:
|
|
127
|
+
raise RuntimeError("Playwright 未初始化")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
async def start_browser(**kwargs) -> Browser:
|
|
131
|
+
"""
|
|
132
|
+
启动 Playwright 浏览器实例。
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
**kwargs: 传递给`playwright.launch`的关键字参数。
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
Browser: 启动的浏览器实例。
|
|
139
|
+
"""
|
|
140
|
+
global _browser, _playwright
|
|
141
|
+
_playwright = await async_playwright().start()
|
|
142
|
+
|
|
143
|
+
if (
|
|
144
|
+
plugin_config.htmlrender_browser == "chromium"
|
|
145
|
+
and plugin_config.htmlrender_connect_over_cdp
|
|
146
|
+
):
|
|
147
|
+
return await _connect_via_cdp(**kwargs)
|
|
148
|
+
|
|
149
|
+
if plugin_config.htmlrender_browser_channel:
|
|
150
|
+
kwargs["channel"] = plugin_config.htmlrender_browser_channel
|
|
151
|
+
|
|
152
|
+
if plugin_config.htmlrender_proxy_host:
|
|
153
|
+
kwargs["proxy"] = proxy_settings(plugin_config.htmlrender_proxy_host)
|
|
154
|
+
|
|
155
|
+
if plugin_config.htmlrender_browser_executable_path:
|
|
156
|
+
kwargs["executable_path"] = plugin_config.htmlrender_browser_executable_path
|
|
157
|
+
|
|
158
|
+
_browser = await _launch(plugin_config.htmlrender_browser, **kwargs)
|
|
159
|
+
return _browser
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
async def shutdown_browser() -> None:
|
|
163
|
+
"""关闭浏览器和 Playwright 实例。"""
|
|
164
|
+
if _browser:
|
|
165
|
+
with suppress_and_log():
|
|
166
|
+
await _browser.close()
|
|
167
|
+
if _playwright:
|
|
168
|
+
with suppress_and_log():
|
|
169
|
+
await _playwright.stop()
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from collections.abc import Generator
|
|
2
|
+
from typing import Any, Callable, ClassVar, Optional
|
|
3
|
+
|
|
4
|
+
from nonebot import get_driver, get_plugin_config
|
|
5
|
+
from nonebot.compat import custom_validation
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from nonebot_plugin_htmlrender.consts import BROWSER_CHANNEL_TYPES, BROWSER_ENGINE_TYPES
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@custom_validation
|
|
12
|
+
class BrowserEngineType(str):
|
|
13
|
+
"""Playwright浏览器引擎类型,支持的值由 BROWSER_ENGINE_TYPES 定义。"""
|
|
14
|
+
|
|
15
|
+
ALLOWED_VALUES: ClassVar = BROWSER_ENGINE_TYPES
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def __get_validators__(cls) -> Generator[Callable[..., Any], None, None]:
|
|
19
|
+
yield cls.validate
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def validate(cls, value: Any) -> str:
|
|
23
|
+
if value not in cls.ALLOWED_VALUES:
|
|
24
|
+
raise ValueError(
|
|
25
|
+
f"Invalid browser type: {value!r}, must be one of {cls.ALLOWED_VALUES}"
|
|
26
|
+
)
|
|
27
|
+
return value
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@custom_validation
|
|
31
|
+
class BrowserChannelType(str):
|
|
32
|
+
"""Playwright浏览器通道类型,支持的值由 BROWSER_CHANNEL_TYPES 定义。"""
|
|
33
|
+
|
|
34
|
+
ALLOWED_VALUES: ClassVar = BROWSER_CHANNEL_TYPES
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def __get_validators__(cls) -> Generator[Callable[..., Any], None, None]:
|
|
38
|
+
yield cls.validate
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def validate(cls, value: Any) -> str:
|
|
42
|
+
if value not in cls.ALLOWED_VALUES:
|
|
43
|
+
raise ValueError(
|
|
44
|
+
f"Invalid channel: {value!r}, must be one of {cls.ALLOWED_VALUES}"
|
|
45
|
+
)
|
|
46
|
+
return value
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class Config(BaseModel):
|
|
50
|
+
"""插件配置类。"""
|
|
51
|
+
|
|
52
|
+
htmlrender_browser: BrowserEngineType = Field(
|
|
53
|
+
default="chromium",
|
|
54
|
+
description="Playwright浏览器引擎类型,默认值为 'chromium'。",
|
|
55
|
+
)
|
|
56
|
+
htmlrender_download_host: Optional[str] = Field(
|
|
57
|
+
default=None, description="下载Playwright浏览器时的主机地址。"
|
|
58
|
+
)
|
|
59
|
+
htmlrender_download_proxy: Optional[str] = Field(
|
|
60
|
+
default=None, description="下载Playwright浏览器时的代理设置。"
|
|
61
|
+
)
|
|
62
|
+
htmlrender_proxy_host: Optional[str] = Field(
|
|
63
|
+
default=None, description="Playwright浏览器使用的代理主机地址。"
|
|
64
|
+
)
|
|
65
|
+
htmlrender_proxy_host_bypass: Optional[str] = Field(
|
|
66
|
+
default=None, description="Playwright浏览器代理的绕过地址。"
|
|
67
|
+
)
|
|
68
|
+
htmlrender_browser_channel: Optional[BrowserChannelType] = Field(
|
|
69
|
+
default=None, description="Playwright浏览器通道类型。"
|
|
70
|
+
)
|
|
71
|
+
htmlrender_browser_executable_path: Optional[str] = Field(
|
|
72
|
+
default=None, description="Playwright浏览器可执行文件的路径。"
|
|
73
|
+
)
|
|
74
|
+
htmlrender_connect_over_cdp: Optional[str] = Field(
|
|
75
|
+
default=None, description="通过 CDP 连接Playwright浏览器的端点地址。"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
global_config = get_driver().config
|
|
80
|
+
plugin_config = get_plugin_config(Config)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True)
|
|
7
|
+
class MirrorSource:
|
|
8
|
+
name: str
|
|
9
|
+
url: str
|
|
10
|
+
priority: int
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# consts
|
|
14
|
+
PLUGINS_GROUP = "nonebot_plugin_htmlrender"
|
|
15
|
+
SCRIPTS_GROUP = "nonebot_plugin_htmlrender_scripts"
|
|
16
|
+
REQUIRES_PYTHON = (3, 9)
|
|
17
|
+
# SHELL = os.getenv("SHELL", "")
|
|
18
|
+
WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt")
|
|
19
|
+
# MINGW = sysconfig.get_platform().startswith("mingw")
|
|
20
|
+
# MACOS = sys.platform == "darwin"
|
|
21
|
+
MIRRORS = [
|
|
22
|
+
MirrorSource("官方", "https://playwright.azureedge.net", 1),
|
|
23
|
+
MirrorSource("淘宝", "https://registry.npmmirror.com/-/binary/playwright", 2),
|
|
24
|
+
]
|
|
25
|
+
BROWSER_ENGINE_TYPES = ["chromium", "firefox", "webkit"]
|
|
26
|
+
BROWSER_CHANNEL_TYPES = [
|
|
27
|
+
"chromium",
|
|
28
|
+
"chrome",
|
|
29
|
+
"chrome-beta",
|
|
30
|
+
"chrome-dev",
|
|
31
|
+
"chrome-canary",
|
|
32
|
+
"msedge",
|
|
33
|
+
"msedge-beta",
|
|
34
|
+
"msedge-dev",
|
|
35
|
+
"msedge-canary",
|
|
36
|
+
"firefox",
|
|
37
|
+
"webkit",
|
|
38
|
+
]
|