nonebot-plugin-htmlrender 0.6.3__tar.gz → 0.6.5__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.
Files changed (55) hide show
  1. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/PKG-INFO +2 -2
  2. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/browser.py +23 -21
  3. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/config.py +22 -12
  4. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/utils.py +13 -0
  5. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/pyproject.toml +2 -2
  6. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/uv.lock +374 -348
  7. nonebot_plugin_htmlrender-0.6.3/nonebot_plugin_htmlrender/compat.py +0 -24
  8. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/.github/workflows/codecov.yml +0 -0
  9. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/.github/workflows/publish.yml +0 -0
  10. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/.gitignore +0 -0
  11. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/.pre-commit-config.yaml +0 -0
  12. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/.python-version +0 -0
  13. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/LICENSE +0 -0
  14. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/README.md +0 -0
  15. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/docs/example.md +0 -0
  16. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/docs/html2pic.png +0 -0
  17. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/docs/md2pic.png +0 -0
  18. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/docs/template2pic.png +0 -0
  19. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/docs/text2pic.png +0 -0
  20. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/.env.dev +0 -0
  21. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/bot.py +0 -0
  22. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/plugins/render/__init__.py +0 -0
  23. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/plugins/render/html2pic.html +0 -0
  24. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/plugins/render/templates/markdown.css +0 -0
  25. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/plugins/render/templates/mystyle.css +0 -0
  26. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/plugins/render/templates/progress.html.jinja2 +0 -0
  27. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/plugins/render/templates/text.html +0 -0
  28. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/example/plugins/render/utils.py +0 -0
  29. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/__init__.py +0 -0
  30. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/consts.py +0 -0
  31. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/data_source.py +0 -0
  32. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/install.py +0 -0
  33. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/process.py +0 -0
  34. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/signal.py +0 -0
  35. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/github-markdown-light.css +0 -0
  36. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/katex/katex.min.b64_fonts.css +0 -0
  37. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/katex/katex.min.js +0 -0
  38. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/katex/mathtex-script-type.min.js +0 -0
  39. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/katex/mhchem.min.js +0 -0
  40. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/markdown.html +0 -0
  41. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/pygments-default.css +0 -0
  42. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/text.css +0 -0
  43. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/nonebot_plugin_htmlrender/templates/text.html +0 -0
  44. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/__init__.py +0 -0
  45. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/conftest.py +0 -0
  46. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/resources/test_template_filter.png +0 -0
  47. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/templates/markdown.css +0 -0
  48. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/templates/mystyle.css +0 -0
  49. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/templates/progress.html.jinja2 +0 -0
  50. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/templates/text.html +0 -0
  51. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/test_browser.py +0 -0
  52. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/test_deprecated_decorator.py +0 -0
  53. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/test_htmlrender.py +0 -0
  54. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/test_install.py +0 -0
  55. {nonebot_plugin_htmlrender-0.6.3 → nonebot_plugin_htmlrender-0.6.5}/tests/test_process.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nonebot-plugin-htmlrender
3
- Version: 0.6.3
3
+ Version: 0.6.5
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
@@ -31,7 +31,7 @@ Requires-Python: <4.0,>=3.9
31
31
  Requires-Dist: aiofiles>=0.8.0
32
32
  Requires-Dist: jinja2>=3.0.3
33
33
  Requires-Dist: markdown>=3.3.6
34
- Requires-Dist: nonebot2>=2.2.0
34
+ Requires-Dist: nonebot2>=2.4.2
35
35
  Requires-Dist: playwright>=1.48.0
36
36
  Requires-Dist: pygments>=2.10.0
37
37
  Requires-Dist: pymdown-extensions>=9.1
@@ -13,7 +13,7 @@ from playwright.async_api import (
13
13
 
14
14
  from nonebot_plugin_htmlrender.config import plugin_config
15
15
  from nonebot_plugin_htmlrender.install import install_browser
16
- from nonebot_plugin_htmlrender.utils import proxy_settings, suppress_and_log
16
+ from nonebot_plugin_htmlrender.utils import proxy_settings, suppress_and_log, with_lock
17
17
 
18
18
  _browser: Optional[Browser] = None
19
19
  _playwright: Optional[Playwright] = None
@@ -70,12 +70,11 @@ async def get_new_page(device_scale_factor: float = 2, **kwargs) -> AsyncIterato
70
70
  """
71
71
  ctx = await get_browser()
72
72
  page = await ctx.new_page(device_scale_factor=device_scale_factor, **kwargs)
73
- try:
73
+ async with page:
74
74
  yield page
75
- finally:
76
- await page.close()
77
75
 
78
76
 
77
+ @with_lock
79
78
  async def get_browser(**kwargs) -> Browser:
80
79
  """
81
80
  获取浏览器实例。
@@ -140,6 +139,7 @@ async def _connect(browser_type: str, **kwargs) -> Browser:
140
139
  raise RuntimeError("Playwright 未初始化")
141
140
 
142
141
 
142
+ @with_lock
143
143
  async def start_browser(**kwargs) -> Browser:
144
144
  """
145
145
  启动 Playwright 浏览器实例。
@@ -151,33 +151,35 @@ async def start_browser(**kwargs) -> Browser:
151
151
  Browser: 启动的浏览器实例。
152
152
  """
153
153
  global _browser, _playwright
154
+
155
+ await shutdown_browser()
154
156
  _playwright = await async_playwright().start()
155
157
 
156
158
  if (
157
159
  plugin_config.htmlrender_browser == "chromium"
158
160
  and plugin_config.htmlrender_connect_over_cdp
159
161
  ):
160
- return await _connect_via_cdp(**kwargs)
161
-
162
- if plugin_config.htmlrender_connect:
163
- return await _connect(plugin_config.htmlrender_browser, **kwargs)
162
+ _browser = await _connect_via_cdp(**kwargs)
163
+ elif plugin_config.htmlrender_connect:
164
+ _browser = await _connect(plugin_config.htmlrender_browser, **kwargs)
165
+ else:
166
+ if plugin_config.htmlrender_browser_channel:
167
+ kwargs["channel"] = plugin_config.htmlrender_browser_channel
164
168
 
165
- if plugin_config.htmlrender_browser_channel:
166
- kwargs["channel"] = plugin_config.htmlrender_browser_channel
169
+ if plugin_config.htmlrender_proxy_host:
170
+ kwargs["proxy"] = proxy_settings(plugin_config.htmlrender_proxy_host)
167
171
 
168
- if plugin_config.htmlrender_proxy_host:
169
- kwargs["proxy"] = proxy_settings(plugin_config.htmlrender_proxy_host)
172
+ if plugin_config.htmlrender_browser_executable_path:
173
+ kwargs["executable_path"] = plugin_config.htmlrender_browser_executable_path
174
+ else:
175
+ try:
176
+ await check_playwright_env()
177
+ except RuntimeError:
178
+ await install_browser()
179
+ await check_playwright_env()
170
180
 
171
- if plugin_config.htmlrender_browser_executable_path:
172
- kwargs["executable_path"] = plugin_config.htmlrender_browser_executable_path
173
- else:
174
- try:
175
- await check_playwright_env()
176
- except RuntimeError:
177
- await install_browser()
178
- await check_playwright_env()
181
+ _browser = await _launch(plugin_config.htmlrender_browser, **kwargs)
179
182
 
180
- _browser = await _launch(plugin_config.htmlrender_browser, **kwargs)
181
183
  return _browser
182
184
 
183
185
 
@@ -1,10 +1,9 @@
1
- from typing import Optional
2
- from typing_extensions import Self
1
+ from typing import Any, Optional
3
2
 
4
3
  from nonebot import get_driver, get_plugin_config
4
+ from nonebot.compat import model_validator
5
5
  from pydantic import BaseModel, Field
6
6
 
7
- from nonebot_plugin_htmlrender.compat import model_validator
8
7
  from nonebot_plugin_htmlrender.consts import BROWSER_CHANNEL_TYPES, BROWSER_ENGINE_TYPES
9
8
 
10
9
 
@@ -41,23 +40,34 @@ class Config(BaseModel):
41
40
  )
42
41
 
43
42
  @model_validator(mode="after")
44
- def check_browser_channel(self) -> Self:
45
- if (
46
- self.htmlrender_browser_channel is not None
47
- and self.htmlrender_browser_channel not in BROWSER_CHANNEL_TYPES
48
- ):
43
+ @classmethod
44
+ def check_browser_channel(cls, data: Any) -> Any:
45
+ browser_channel = (
46
+ data.get("htmlrender_browser_channel")
47
+ if isinstance(data, dict)
48
+ else getattr(data, "htmlrender_browser_channel", None)
49
+ )
50
+
51
+ if browser_channel is not None and browser_channel not in BROWSER_CHANNEL_TYPES:
49
52
  raise ValueError(
50
53
  f"Invalid browser channel type. Must be one of {BROWSER_CHANNEL_TYPES}"
51
54
  )
52
- return self
55
+ return data
53
56
 
54
57
  @model_validator(mode="after")
55
- def check_browser(self) -> Self:
56
- if self.htmlrender_browser not in BROWSER_ENGINE_TYPES:
58
+ @classmethod
59
+ def check_browser(cls, data: Any) -> Any:
60
+ browser = (
61
+ data.get("htmlrender_browser", "chromium")
62
+ if isinstance(data, dict)
63
+ else getattr(data, "htmlrender_browser", "chromium")
64
+ )
65
+
66
+ if browser not in BROWSER_ENGINE_TYPES:
57
67
  raise ValueError(
58
68
  f"Invalid browser type. Must be one of {BROWSER_ENGINE_TYPES}"
59
69
  )
60
- return self
70
+ return data
61
71
 
62
72
 
63
73
  global_config = get_driver().config
@@ -1,3 +1,5 @@
1
+ from asyncio import Lock
2
+ from collections.abc import Awaitable
1
3
  from contextlib import contextmanager
2
4
  from functools import wraps
3
5
  import re
@@ -146,3 +148,14 @@ def proxy_settings(proxy_host: Optional[str]) -> Optional[dict]:
146
148
  proxy["bypass"] = plugin_config.htmlrender_proxy_host_bypass
147
149
 
148
150
  return proxy
151
+
152
+
153
+ def with_lock(func: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[R]]:
154
+ lock = Lock()
155
+
156
+ @wraps(func)
157
+ async def wrapper(*args, **kwargs) -> R:
158
+ async with lock:
159
+ return await func(*args, **kwargs)
160
+
161
+ return wrapper
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nonebot-plugin-htmlrender"
3
- version = "0.6.3"
3
+ version = "0.6.5"
4
4
  description = "通过浏览器渲染图片"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "kexue", email = "x@kexue-cloud.cn" }]
@@ -10,7 +10,7 @@ dependencies = [
10
10
  "aiofiles>=0.8.0",
11
11
  "jinja2>=3.0.3",
12
12
  "markdown>=3.3.6",
13
- "nonebot2>=2.2.0",
13
+ "nonebot2>=2.4.2",
14
14
  "playwright>=1.48.0",
15
15
  "pygments>=2.10.0",
16
16
  "pymdown-extensions>=9.1",