nonebot-plugin-htmlrender 0.6.7__py3-none-any.whl → 0.7.0__py3-none-any.whl
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/__init__.py +146 -21
- nonebot_plugin_htmlrender/_bootstrap.py +81 -0
- nonebot_plugin_htmlrender/_compat.py +286 -0
- nonebot_plugin_htmlrender/backend/__init__.py +42 -0
- nonebot_plugin_htmlrender/backend/base.py +217 -0
- nonebot_plugin_htmlrender/backend/factory.py +194 -0
- nonebot_plugin_htmlrender/backend/playwright/__init__.py +98 -0
- nonebot_plugin_htmlrender/backend/playwright/_page.py +258 -0
- nonebot_plugin_htmlrender/backend/playwright/config.py +244 -0
- nonebot_plugin_htmlrender/backend/playwright/data_source.py +90 -0
- nonebot_plugin_htmlrender/backend/playwright/install.py +161 -0
- nonebot_plugin_htmlrender/backend/playwright/models.py +432 -0
- nonebot_plugin_htmlrender/backend/playwright/operations.py +671 -0
- nonebot_plugin_htmlrender/backend/playwright/render.py +764 -0
- nonebot_plugin_htmlrender/backend/playwright/runtime.py +441 -0
- nonebot_plugin_htmlrender/backend/playwright/telemetry.py +240 -0
- nonebot_plugin_htmlrender/backend/playwright/types.py +280 -0
- nonebot_plugin_htmlrender/browser.py +33 -206
- nonebot_plugin_htmlrender/config.py +41 -61
- nonebot_plugin_htmlrender/consts.py +109 -23
- nonebot_plugin_htmlrender/data_source.py +36 -312
- nonebot_plugin_htmlrender/py.typed +0 -0
- nonebot_plugin_htmlrender/render.py +712 -0
- nonebot_plugin_htmlrender/resources/__init__.py +34 -0
- nonebot_plugin_htmlrender/resources/config.py +66 -0
- nonebot_plugin_htmlrender/resources/filehost/__init__.py +162 -0
- nonebot_plugin_htmlrender/resources/filehost/cache.py +258 -0
- nonebot_plugin_htmlrender/resources/filehost/guard.py +159 -0
- nonebot_plugin_htmlrender/resources/filehost/warmup.py +251 -0
- nonebot_plugin_htmlrender/resources/resolve.py +338 -0
- nonebot_plugin_htmlrender/resources/template.py +313 -0
- nonebot_plugin_htmlrender/utils/__init__.py +48 -0
- nonebot_plugin_htmlrender/utils/install.py +172 -0
- nonebot_plugin_htmlrender/utils/process.py +292 -0
- nonebot_plugin_htmlrender/utils/signal.py +165 -0
- nonebot_plugin_htmlrender/utils/telemetry/__init__.py +91 -0
- nonebot_plugin_htmlrender/utils/telemetry/common.py +160 -0
- nonebot_plugin_htmlrender/utils/telemetry/prometheus.py +199 -0
- nonebot_plugin_htmlrender/utils/telemetry/sentry.py +228 -0
- nonebot_plugin_htmlrender-0.7.0.dist-info/METADATA +205 -0
- nonebot_plugin_htmlrender-0.7.0.dist-info/RECORD +52 -0
- {nonebot_plugin_htmlrender-0.6.7.dist-info → nonebot_plugin_htmlrender-0.7.0.dist-info}/WHEEL +1 -1
- nonebot_plugin_htmlrender/install.py +0 -239
- nonebot_plugin_htmlrender/process.py +0 -165
- nonebot_plugin_htmlrender/signal.py +0 -138
- nonebot_plugin_htmlrender/utils.py +0 -161
- nonebot_plugin_htmlrender-0.6.7.dist-info/METADATA +0 -220
- nonebot_plugin_htmlrender-0.6.7.dist-info/RECORD +0 -22
- /nonebot_plugin_htmlrender/templates/{github-markdown-light.css → markdown/github-markdown-light.css} +0 -0
- /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/katex.min.b64_fonts.css +0 -0
- /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/katex.min.js +0 -0
- /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/mathtex-script-type.min.js +0 -0
- /nonebot_plugin_htmlrender/templates/{katex → markdown/katex}/mhchem.min.js +0 -0
- /nonebot_plugin_htmlrender/templates/{markdown.html → markdown/markdown.html} +0 -0
- /nonebot_plugin_htmlrender/templates/{pygments-default.css → markdown/pygments-default.css} +0 -0
- /nonebot_plugin_htmlrender/templates/{text.css → text/text.css} +0 -0
- /nonebot_plugin_htmlrender/templates/{text.html → text/text.html} +0 -0
- {nonebot_plugin_htmlrender-0.6.7.dist-info → nonebot_plugin_htmlrender-0.7.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,55 +1,180 @@
|
|
|
1
|
+
from typing_extensions import Unpack
|
|
2
|
+
|
|
1
3
|
import nonebot
|
|
4
|
+
from nonebot import require
|
|
2
5
|
from nonebot.log import logger
|
|
3
6
|
from nonebot.plugin import PluginMetadata
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
from nonebot_plugin_htmlrender.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
from nonebot_plugin_htmlrender.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
require("nonebot_plugin_localstore")
|
|
9
|
+
|
|
10
|
+
from nonebot_plugin_htmlrender._bootstrap import (
|
|
11
|
+
_bootstrap_filehost_guard_on_import,
|
|
12
|
+
_bootstrap_optional_plugins_on_import,
|
|
13
|
+
)
|
|
14
|
+
from nonebot_plugin_htmlrender._bootstrap import (
|
|
15
|
+
_patch_filehost_request_headers_validator as _patch_filehost_request_headers_validator,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
_bootstrap_optional_plugins_on_import()
|
|
19
|
+
|
|
20
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
21
|
+
capture_element as capture_element,
|
|
22
|
+
)
|
|
23
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
24
|
+
get_new_page as get_new_page,
|
|
25
|
+
)
|
|
26
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
27
|
+
html_to_pic as html_to_pic,
|
|
28
|
+
)
|
|
29
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
30
|
+
md_to_pic as md_to_pic,
|
|
31
|
+
)
|
|
32
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
33
|
+
shutdown_htmlrender as shutdown_htmlrender,
|
|
34
|
+
)
|
|
35
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
36
|
+
startup_htmlrender as startup_htmlrender,
|
|
37
|
+
)
|
|
38
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
39
|
+
template_to_html as template_to_html,
|
|
40
|
+
)
|
|
41
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
42
|
+
template_to_pic as template_to_pic,
|
|
43
|
+
)
|
|
44
|
+
from nonebot_plugin_htmlrender._compat import (
|
|
45
|
+
text_to_pic as text_to_pic,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Wire the render context provider so that backend operations can obtain
|
|
49
|
+
# pages without importing the render module directly (avoids circular coupling).
|
|
50
|
+
from nonebot_plugin_htmlrender.backend.playwright._page import (
|
|
51
|
+
register_render_context_provider as _register_ctx_provider,
|
|
52
|
+
)
|
|
53
|
+
from nonebot_plugin_htmlrender.backend.playwright.runtime import (
|
|
54
|
+
clear_playwright_env_vars,
|
|
55
|
+
)
|
|
56
|
+
from nonebot_plugin_htmlrender.backend.playwright.types import BrowserSessionKwargs
|
|
57
|
+
from nonebot_plugin_htmlrender.config import Config, plugin_config
|
|
58
|
+
from nonebot_plugin_htmlrender.consts import RenderBackend, RenderStartupMode
|
|
59
|
+
from nonebot_plugin_htmlrender.render import (
|
|
60
|
+
available_render_backends,
|
|
61
|
+
capture_html_element,
|
|
62
|
+
get_default_render,
|
|
63
|
+
get_render,
|
|
64
|
+
get_render_backend_status,
|
|
65
|
+
get_render_context,
|
|
66
|
+
is_render_backend_available,
|
|
67
|
+
is_render_backend_registered,
|
|
68
|
+
list_render_backend_statuses,
|
|
69
|
+
probe_render,
|
|
70
|
+
registered_render_backends,
|
|
71
|
+
render_html,
|
|
72
|
+
render_markdown,
|
|
73
|
+
render_template,
|
|
74
|
+
render_template_html,
|
|
75
|
+
render_text,
|
|
76
|
+
shutdown_render,
|
|
77
|
+
startup_render,
|
|
78
|
+
unavailable_render_backends,
|
|
79
|
+
)
|
|
80
|
+
from nonebot_plugin_htmlrender.resources import (
|
|
81
|
+
ResourceResolveError,
|
|
82
|
+
resolve_template_vars,
|
|
83
|
+
to_resource_url,
|
|
84
|
+
)
|
|
85
|
+
from nonebot_plugin_htmlrender.resources.filehost import ensure_filehost_runtime_ready
|
|
86
|
+
|
|
87
|
+
_register_ctx_provider(get_render_context)
|
|
88
|
+
del _register_ctx_provider
|
|
17
89
|
|
|
18
90
|
__plugin_meta__ = PluginMetadata(
|
|
19
91
|
name="nonebot-plugin-htmlrender",
|
|
20
92
|
description="通过浏览器渲染图片",
|
|
21
|
-
usage=
|
|
93
|
+
usage=(
|
|
94
|
+
"提供 HTML/Markdown/模板渲染为图片的能力,作为库插件供其他插件调用。\n"
|
|
95
|
+
"主要接口:render_html, render_text, render_markdown, render_template 等。"
|
|
96
|
+
),
|
|
22
97
|
type="library",
|
|
23
98
|
config=Config,
|
|
24
99
|
homepage="https://github.com/kexue-z/nonebot-plugin-htmlrender",
|
|
25
|
-
|
|
100
|
+
supported_adapters=None,
|
|
26
101
|
)
|
|
27
102
|
|
|
28
103
|
driver = nonebot.get_driver()
|
|
29
104
|
|
|
30
105
|
|
|
106
|
+
_bootstrap_filehost_guard_on_import()
|
|
107
|
+
|
|
108
|
+
|
|
31
109
|
@driver.on_startup
|
|
32
|
-
async def init(**kwargs):
|
|
110
|
+
async def init(**kwargs: Unpack[BrowserSessionKwargs]) -> None:
|
|
111
|
+
"""插件启动时初始化渲染后端。"""
|
|
33
112
|
logger.info("HTMLRender Starting...")
|
|
34
|
-
|
|
35
|
-
|
|
113
|
+
if plugin_config.render_backend is None:
|
|
114
|
+
logger.info("No render backend selected; startup skipped.")
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
if plugin_config.render_backend == RenderBackend.PLAYWRIGHT:
|
|
118
|
+
await ensure_filehost_runtime_ready(reason="plugin_startup")
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
startup_mode = plugin_config.render_startup_mode
|
|
122
|
+
if startup_mode == RenderStartupMode.OFF:
|
|
123
|
+
logger.info("Render startup skipped by configuration.")
|
|
124
|
+
return
|
|
125
|
+
if startup_mode == RenderStartupMode.WARMUP:
|
|
126
|
+
await startup_render(**kwargs)
|
|
127
|
+
else:
|
|
128
|
+
await startup_render(**kwargs)
|
|
129
|
+
await probe_render()
|
|
130
|
+
except Exception as e:
|
|
131
|
+
logger.exception("Failed to start render runtime.")
|
|
132
|
+
raise RuntimeError("Render runtime startup failed.") from e
|
|
133
|
+
|
|
134
|
+
logger.opt(colors=True).info(
|
|
135
|
+
f"HTMLRender Started with backend <cyan>{plugin_config.render_backend}</cyan>."
|
|
136
|
+
)
|
|
36
137
|
|
|
37
138
|
|
|
38
139
|
@driver.on_shutdown
|
|
39
|
-
async def shutdown():
|
|
140
|
+
async def shutdown() -> None:
|
|
141
|
+
"""插件关闭时清理渲染资源。"""
|
|
40
142
|
logger.info("HTMLRender Shutting down...")
|
|
41
|
-
await
|
|
143
|
+
await shutdown_render()
|
|
144
|
+
clear_playwright_env_vars()
|
|
42
145
|
logger.info("HTMLRender Shut down.")
|
|
43
146
|
|
|
44
147
|
|
|
45
148
|
__all__ = [
|
|
149
|
+
"ResourceResolveError",
|
|
150
|
+
"available_render_backends",
|
|
46
151
|
"capture_element",
|
|
152
|
+
"capture_html_element",
|
|
153
|
+
"get_default_render",
|
|
47
154
|
"get_new_page",
|
|
155
|
+
"get_render",
|
|
156
|
+
"get_render_backend_status",
|
|
157
|
+
"get_render_context",
|
|
48
158
|
"html_to_pic",
|
|
159
|
+
"is_render_backend_available",
|
|
160
|
+
"is_render_backend_registered",
|
|
161
|
+
"list_render_backend_statuses",
|
|
49
162
|
"md_to_pic",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
163
|
+
"probe_render",
|
|
164
|
+
"registered_render_backends",
|
|
165
|
+
"render_html",
|
|
166
|
+
"render_markdown",
|
|
167
|
+
"render_template",
|
|
168
|
+
"render_template_html",
|
|
169
|
+
"render_text",
|
|
170
|
+
"resolve_template_vars",
|
|
171
|
+
"shutdown_htmlrender",
|
|
172
|
+
"shutdown_render",
|
|
173
|
+
"startup_htmlrender",
|
|
174
|
+
"startup_render",
|
|
52
175
|
"template_to_html",
|
|
53
176
|
"template_to_pic",
|
|
54
177
|
"text_to_pic",
|
|
178
|
+
"to_resource_url",
|
|
179
|
+
"unavailable_render_backends",
|
|
55
180
|
]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Bootstrap helpers executed at plugin import time."""
|
|
2
|
+
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
from importlib.util import find_spec
|
|
5
|
+
|
|
6
|
+
from nonebot import require
|
|
7
|
+
from nonebot.log import logger
|
|
8
|
+
|
|
9
|
+
from nonebot_plugin_htmlrender.config import plugin_config
|
|
10
|
+
from nonebot_plugin_htmlrender.consts import RenderBackend
|
|
11
|
+
from nonebot_plugin_htmlrender.resources.filehost import (
|
|
12
|
+
ensure_filehost_request_guard_installed,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
_OPTIONAL_PLUGIN_IDS = (
|
|
16
|
+
"nonebot_plugin_filehost",
|
|
17
|
+
"nonebot_plugin_sentry",
|
|
18
|
+
"nonebot_plugin_prometheus",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _patch_filehost_request_headers_validator() -> None:
|
|
23
|
+
"""修补 filehost 请求头验证器以兼容 pydantic。"""
|
|
24
|
+
try:
|
|
25
|
+
filehost_models = import_module("nonebot_plugin_filehost.models")
|
|
26
|
+
request_headers = getattr(filehost_models, "RequestHeaders", None)
|
|
27
|
+
request_scope_info = getattr(filehost_models, "RequestScopeInfo", None)
|
|
28
|
+
if request_headers is None or request_scope_info is None:
|
|
29
|
+
return
|
|
30
|
+
if bool(getattr(request_headers, "__htmlrender_validator_patched__", False)):
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
raw_validate = request_headers.__dict__.get("validate")
|
|
34
|
+
if not isinstance(raw_validate, classmethod):
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
validate_func = raw_validate.__func__
|
|
38
|
+
|
|
39
|
+
def _compat_validate(cls, value, *args, **kwargs): # type: ignore[no-untyped-def]
|
|
40
|
+
"""兼容性验证包装器。"""
|
|
41
|
+
del args, kwargs
|
|
42
|
+
return validate_func(cls, value)
|
|
43
|
+
|
|
44
|
+
request_headers.validate = classmethod(_compat_validate)
|
|
45
|
+
request_headers.__htmlrender_validator_patched__ = True
|
|
46
|
+
model_rebuild = getattr(request_scope_info, "model_rebuild", None)
|
|
47
|
+
if callable(model_rebuild):
|
|
48
|
+
model_rebuild(force=True)
|
|
49
|
+
logger.opt(colors=True).info(
|
|
50
|
+
"Patched <c>nonebot_plugin_filehost</c> websocket scope validator for pydantic compatibility."
|
|
51
|
+
)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
logger.opt(colors=True).warning(
|
|
54
|
+
"Failed to patch <c>nonebot_plugin_filehost</c> validator compatibility: <r>{e}</r>",
|
|
55
|
+
e=e,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _bootstrap_optional_plugins_on_import() -> None:
|
|
60
|
+
"""在导入时引导可选插件。"""
|
|
61
|
+
for plugin_name in _OPTIONAL_PLUGIN_IDS:
|
|
62
|
+
if find_spec(plugin_name) is None:
|
|
63
|
+
logger.opt(colors=True).info(
|
|
64
|
+
"Optional plugin <d>{plugin_name}</d> not installed, skip bootstrap.",
|
|
65
|
+
plugin_name=plugin_name,
|
|
66
|
+
)
|
|
67
|
+
continue
|
|
68
|
+
require(plugin_name)
|
|
69
|
+
if plugin_name == "nonebot_plugin_filehost":
|
|
70
|
+
_patch_filehost_request_headers_validator()
|
|
71
|
+
logger.opt(colors=True).info(
|
|
72
|
+
"Optional plugin <c>{plugin_name}</c> bootstrapped on import.",
|
|
73
|
+
plugin_name=plugin_name,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _bootstrap_filehost_guard_on_import() -> None:
|
|
78
|
+
"""在导入时安装 filehost 请求守卫。"""
|
|
79
|
+
if plugin_config.render_backend != RenderBackend.PLAYWRIGHT:
|
|
80
|
+
return
|
|
81
|
+
ensure_filehost_request_guard_installed(reason="plugin_import")
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# ruff: noqa: A002, FBT001, FBT002, PTH109
|
|
2
|
+
"""Backward-compatible deprecated API surface.
|
|
3
|
+
|
|
4
|
+
All deprecated top-level functions are defined here. Other modules
|
|
5
|
+
(``data_source``, ``browser``, ``__init__``) re-export from this
|
|
6
|
+
module so that old import paths keep working.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from collections.abc import AsyncIterator
|
|
10
|
+
from contextlib import asynccontextmanager
|
|
11
|
+
from os import getcwd
|
|
12
|
+
from typing import Any, Literal
|
|
13
|
+
from typing_extensions import Unpack, deprecated
|
|
14
|
+
|
|
15
|
+
from playwright.async_api import Browser
|
|
16
|
+
|
|
17
|
+
from nonebot_plugin_htmlrender.backend.playwright.operations import (
|
|
18
|
+
read_file as read_file,
|
|
19
|
+
)
|
|
20
|
+
from nonebot_plugin_htmlrender.backend.playwright.operations import (
|
|
21
|
+
read_tpl as read_tpl,
|
|
22
|
+
)
|
|
23
|
+
from nonebot_plugin_htmlrender.backend.playwright.runtime import (
|
|
24
|
+
clean_playwright_cache as _clean_playwright_cache,
|
|
25
|
+
)
|
|
26
|
+
from nonebot_plugin_htmlrender.backend.playwright.runtime import (
|
|
27
|
+
reconcile_legacy_playwright_cache as _reconcile_legacy_playwright_cache,
|
|
28
|
+
)
|
|
29
|
+
from nonebot_plugin_htmlrender.backend.playwright.types import (
|
|
30
|
+
BrowserSessionKwargs,
|
|
31
|
+
GotoKwargs,
|
|
32
|
+
HtmlPageKwargs,
|
|
33
|
+
LocatorScreenshotKwargs,
|
|
34
|
+
PageContextKwargs,
|
|
35
|
+
TemplatePageKwargs,
|
|
36
|
+
)
|
|
37
|
+
from nonebot_plugin_htmlrender.render import (
|
|
38
|
+
capture_html_element,
|
|
39
|
+
get_render,
|
|
40
|
+
get_render_context,
|
|
41
|
+
render_html,
|
|
42
|
+
render_markdown,
|
|
43
|
+
render_template,
|
|
44
|
+
render_template_html,
|
|
45
|
+
render_text,
|
|
46
|
+
shutdown_render,
|
|
47
|
+
startup_render,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _require_browser(session: object) -> Browser:
|
|
52
|
+
"""从渲染会话中提取 Browser 实例。
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
session: 渲染会话对象,需包含 ``handle`` 属性。
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
会话中的 :class:`Browser` 实例。
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
RuntimeError: 当前渲染目标不是 Browser 实例时抛出。
|
|
62
|
+
"""
|
|
63
|
+
browser = getattr(session, "handle", None)
|
|
64
|
+
if isinstance(browser, Browser):
|
|
65
|
+
return browser
|
|
66
|
+
raise RuntimeError("Current render target is not a Browser instance.")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@deprecated("`text_to_pic` is deprecated. Use `render_text` instead.")
|
|
70
|
+
async def text_to_pic(
|
|
71
|
+
text: str,
|
|
72
|
+
css_path: str = "",
|
|
73
|
+
width: int = 500,
|
|
74
|
+
type: Literal["jpeg", "png"] = "png",
|
|
75
|
+
quality: int | None = None,
|
|
76
|
+
device_scale_factor: float = 2,
|
|
77
|
+
screenshot_timeout: float | None = 30_000,
|
|
78
|
+
) -> bytes:
|
|
79
|
+
"""已弃用:将文本渲染为图片,请使用 ``render_text``。"""
|
|
80
|
+
return await render_text(
|
|
81
|
+
text,
|
|
82
|
+
css_path=css_path,
|
|
83
|
+
width=width,
|
|
84
|
+
image_type=type,
|
|
85
|
+
quality=quality,
|
|
86
|
+
device_scale_factor=device_scale_factor,
|
|
87
|
+
screenshot_timeout=screenshot_timeout,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@deprecated("`md_to_pic` is deprecated. Use `render_markdown` instead.")
|
|
92
|
+
async def md_to_pic(
|
|
93
|
+
md: str = "",
|
|
94
|
+
md_path: str = "",
|
|
95
|
+
css_path: str = "",
|
|
96
|
+
width: int = 500,
|
|
97
|
+
type: Literal["jpeg", "png"] = "png",
|
|
98
|
+
quality: int | None = None,
|
|
99
|
+
device_scale_factor: float = 2,
|
|
100
|
+
screenshot_timeout: float | None = 30_000,
|
|
101
|
+
) -> bytes:
|
|
102
|
+
"""已弃用:将 Markdown 渲染为图片,请使用 ``render_markdown``。"""
|
|
103
|
+
return await render_markdown(
|
|
104
|
+
md,
|
|
105
|
+
md_path=md_path,
|
|
106
|
+
css_path=css_path,
|
|
107
|
+
width=width,
|
|
108
|
+
image_type=type,
|
|
109
|
+
quality=quality,
|
|
110
|
+
device_scale_factor=device_scale_factor,
|
|
111
|
+
screenshot_timeout=screenshot_timeout,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@deprecated("`template_to_html` is deprecated. Use `render_template_html` instead.")
|
|
116
|
+
async def template_to_html(
|
|
117
|
+
template_path: str,
|
|
118
|
+
template_name: str,
|
|
119
|
+
filters: dict[str, Any] | None = None,
|
|
120
|
+
**kwargs: Any,
|
|
121
|
+
) -> str:
|
|
122
|
+
"""已弃用:将模板渲染为 HTML,请使用 ``render_template_html``。"""
|
|
123
|
+
return await render_template_html(
|
|
124
|
+
template_path,
|
|
125
|
+
template_name=template_name,
|
|
126
|
+
filters=filters,
|
|
127
|
+
**kwargs,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@deprecated("`html_to_pic` is deprecated. Use `render_html` instead.")
|
|
132
|
+
async def html_to_pic(
|
|
133
|
+
html: str,
|
|
134
|
+
wait: int = 0,
|
|
135
|
+
template_path: str | None = None,
|
|
136
|
+
type: Literal["jpeg", "png"] = "png",
|
|
137
|
+
quality: int | None = None,
|
|
138
|
+
device_scale_factor: float = 2,
|
|
139
|
+
screenshot_timeout: float | None = 30_000,
|
|
140
|
+
full_page: bool = True,
|
|
141
|
+
**kwargs: Unpack[HtmlPageKwargs],
|
|
142
|
+
) -> bytes:
|
|
143
|
+
"""已弃用:将 HTML 渲染为图片,请使用 ``render_html``。"""
|
|
144
|
+
return await render_html(
|
|
145
|
+
html,
|
|
146
|
+
wait=wait,
|
|
147
|
+
template_path=template_path,
|
|
148
|
+
image_type=type,
|
|
149
|
+
quality=quality,
|
|
150
|
+
device_scale_factor=device_scale_factor,
|
|
151
|
+
screenshot_timeout=screenshot_timeout,
|
|
152
|
+
full_page=full_page,
|
|
153
|
+
**kwargs,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@deprecated("`template_to_pic` is deprecated. Use `render_template` instead.")
|
|
158
|
+
async def template_to_pic(
|
|
159
|
+
template_path: str,
|
|
160
|
+
template_name: str,
|
|
161
|
+
templates: dict[str, Any],
|
|
162
|
+
filters: dict[str, Any] | None = None,
|
|
163
|
+
pages: TemplatePageKwargs | None = None,
|
|
164
|
+
wait: int = 0,
|
|
165
|
+
type: Literal["jpeg", "png"] = "png",
|
|
166
|
+
quality: int | None = None,
|
|
167
|
+
device_scale_factor: float = 2,
|
|
168
|
+
screenshot_timeout: float | None = 30_000,
|
|
169
|
+
) -> bytes:
|
|
170
|
+
"""已弃用:将模板渲染为图片,请使用 ``render_template``。"""
|
|
171
|
+
default_pages: TemplatePageKwargs = {
|
|
172
|
+
"viewport": {"width": 500, "height": 10},
|
|
173
|
+
"base_url": f"file://{getcwd()}",
|
|
174
|
+
}
|
|
175
|
+
return await render_template(
|
|
176
|
+
template_path,
|
|
177
|
+
template_name=template_name,
|
|
178
|
+
templates=templates,
|
|
179
|
+
filters=filters,
|
|
180
|
+
pages=pages or default_pages,
|
|
181
|
+
wait=wait,
|
|
182
|
+
image_type=type,
|
|
183
|
+
quality=quality,
|
|
184
|
+
device_scale_factor=device_scale_factor,
|
|
185
|
+
screenshot_timeout=screenshot_timeout,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@deprecated("`capture_element` is deprecated. Use `capture_html_element` instead.")
|
|
190
|
+
async def capture_element(
|
|
191
|
+
url: str,
|
|
192
|
+
element: str,
|
|
193
|
+
page_kwargs: PageContextKwargs | None = None,
|
|
194
|
+
goto_kwargs: GotoKwargs | None = None,
|
|
195
|
+
screenshot_kwargs: LocatorScreenshotKwargs | None = None,
|
|
196
|
+
) -> bytes:
|
|
197
|
+
"""已弃用:捕获页面元素截图,请使用 ``capture_html_element``。"""
|
|
198
|
+
return await capture_html_element(
|
|
199
|
+
url,
|
|
200
|
+
element,
|
|
201
|
+
page_kwargs=page_kwargs,
|
|
202
|
+
goto_kwargs=goto_kwargs,
|
|
203
|
+
screenshot_kwargs=screenshot_kwargs,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@deprecated("`get_new_page` is deprecated. Use `get_render_context` instead.")
|
|
208
|
+
@asynccontextmanager
|
|
209
|
+
async def get_new_page(
|
|
210
|
+
device_scale_factor: float = 2,
|
|
211
|
+
**kwargs: Unpack[HtmlPageKwargs],
|
|
212
|
+
) -> AsyncIterator[object]:
|
|
213
|
+
"""已弃用:获取新的浏览器页面,请使用 ``get_render_context``。"""
|
|
214
|
+
async with get_render_context(
|
|
215
|
+
device_scale_factor=device_scale_factor,
|
|
216
|
+
**kwargs,
|
|
217
|
+
) as page:
|
|
218
|
+
yield page
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@deprecated("`get_browser` is deprecated. Use `get_render` instead.")
|
|
222
|
+
async def get_browser(**kwargs: Unpack[BrowserSessionKwargs]) -> Browser:
|
|
223
|
+
"""已弃用:获取浏览器实例,请使用 ``get_render``。"""
|
|
224
|
+
session = await get_render(**kwargs)
|
|
225
|
+
return _require_browser(session)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@deprecated("`startup_htmlrender` is deprecated. Use `startup_render` instead.")
|
|
229
|
+
async def startup_htmlrender(**kwargs: Unpack[BrowserSessionKwargs]) -> Browser:
|
|
230
|
+
"""已弃用:启动 HTML 渲染引擎,请使用 ``startup_render``。"""
|
|
231
|
+
session = await startup_render(**kwargs)
|
|
232
|
+
return _require_browser(session)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@deprecated("`shutdown_htmlrender` is deprecated. Use `shutdown_render` instead.")
|
|
236
|
+
async def shutdown_htmlrender() -> None:
|
|
237
|
+
"""已弃用:关闭 HTML 渲染引擎,请使用 ``shutdown_render``。"""
|
|
238
|
+
await shutdown_render()
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
@deprecated("`_launch` is deprecated. Use `startup_render` instead.")
|
|
242
|
+
async def _launch(
|
|
243
|
+
browser_type: str,
|
|
244
|
+
**kwargs: Unpack[BrowserSessionKwargs],
|
|
245
|
+
) -> Browser:
|
|
246
|
+
"""已弃用:启动浏览器,请使用 ``startup_render``。"""
|
|
247
|
+
_ = browser_type
|
|
248
|
+
return await startup_htmlrender(**kwargs)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@deprecated(
|
|
252
|
+
"`clean_playwright_cache` from `nonebot_plugin_htmlrender.browser` is deprecated. "
|
|
253
|
+
"Use `nonebot_plugin_htmlrender.backend.playwright.runtime.reconcile_legacy_playwright_cache` instead."
|
|
254
|
+
)
|
|
255
|
+
def clean_playwright_cache(*, cleanup: bool) -> None:
|
|
256
|
+
"""已弃用:清理 Playwright 缓存。"""
|
|
257
|
+
_clean_playwright_cache(cleanup=cleanup)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
@deprecated(
|
|
261
|
+
"`reconcile_legacy_playwright_cache` from `nonebot_plugin_htmlrender.browser` "
|
|
262
|
+
"is deprecated. Use "
|
|
263
|
+
"`nonebot_plugin_htmlrender.backend.playwright.runtime.reconcile_legacy_playwright_cache` instead."
|
|
264
|
+
)
|
|
265
|
+
def reconcile_legacy_playwright_cache(*, cleanup: bool) -> None:
|
|
266
|
+
"""已弃用:协调旧版 Playwright 缓存目录。"""
|
|
267
|
+
_reconcile_legacy_playwright_cache(cleanup=cleanup)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
__all__ = [
|
|
271
|
+
"_launch",
|
|
272
|
+
"capture_element",
|
|
273
|
+
"clean_playwright_cache",
|
|
274
|
+
"get_browser",
|
|
275
|
+
"get_new_page",
|
|
276
|
+
"html_to_pic",
|
|
277
|
+
"md_to_pic",
|
|
278
|
+
"read_file",
|
|
279
|
+
"read_tpl",
|
|
280
|
+
"reconcile_legacy_playwright_cache",
|
|
281
|
+
"shutdown_htmlrender",
|
|
282
|
+
"startup_htmlrender",
|
|
283
|
+
"template_to_html",
|
|
284
|
+
"template_to_pic",
|
|
285
|
+
"text_to_pic",
|
|
286
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from .base import (
|
|
2
|
+
Backend,
|
|
3
|
+
BackendCapability,
|
|
4
|
+
RenderRuntime,
|
|
5
|
+
RenderSession,
|
|
6
|
+
SupportsHtmlRenderBackend,
|
|
7
|
+
)
|
|
8
|
+
from .factory import (
|
|
9
|
+
BackendAvailability,
|
|
10
|
+
BackendStatus,
|
|
11
|
+
available_backends,
|
|
12
|
+
backend_statuses,
|
|
13
|
+
build_backend,
|
|
14
|
+
get_backend_status,
|
|
15
|
+
is_backend_available,
|
|
16
|
+
is_backend_registered,
|
|
17
|
+
register_backend,
|
|
18
|
+
registered_backends,
|
|
19
|
+
unavailable_backends,
|
|
20
|
+
)
|
|
21
|
+
from .playwright import PlaywrightBackend, PlaywrightMode
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"Backend",
|
|
25
|
+
"BackendAvailability",
|
|
26
|
+
"BackendCapability",
|
|
27
|
+
"BackendStatus",
|
|
28
|
+
"PlaywrightBackend",
|
|
29
|
+
"PlaywrightMode",
|
|
30
|
+
"RenderRuntime",
|
|
31
|
+
"RenderSession",
|
|
32
|
+
"SupportsHtmlRenderBackend",
|
|
33
|
+
"available_backends",
|
|
34
|
+
"backend_statuses",
|
|
35
|
+
"build_backend",
|
|
36
|
+
"get_backend_status",
|
|
37
|
+
"is_backend_available",
|
|
38
|
+
"is_backend_registered",
|
|
39
|
+
"register_backend",
|
|
40
|
+
"registered_backends",
|
|
41
|
+
"unavailable_backends",
|
|
42
|
+
]
|