mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-10-08 11:46:43 +00:00
Compare commits
1 Commits
master
...
publish/is
Author | SHA1 | Date | |
---|---|---|---|
|
fd2c66e0fd |
2
.github/actions/setup-python/action.yml
vendored
2
.github/actions/setup-python/action.yml
vendored
@@ -14,7 +14,7 @@ inputs:
|
|||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- uses: astral-sh/setup-uv@v7
|
- uses: astral-sh/setup-uv@v6
|
||||||
with:
|
with:
|
||||||
python-version: ${{ inputs.python-version }}
|
python-version: ${{ inputs.python-version }}
|
||||||
cache-suffix: ${{ inputs.env-group }}
|
cache-suffix: ${{ inputs.env-group }}
|
||||||
|
@@ -7,7 +7,7 @@ ci:
|
|||||||
autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks"
|
autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks"
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.13.3
|
rev: v0.12.11
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff-check
|
- id: ruff-check
|
||||||
args: [--fix]
|
args: [--fix]
|
||||||
|
@@ -9750,7 +9750,7 @@
|
|||||||
"color": "#199579"
|
"color": "#199579"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_official": true
|
"is_official": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"module_name": "nonebot_plugin_mhcodes",
|
"module_name": "nonebot_plugin_mhcodes",
|
||||||
@@ -9764,4 +9764,16 @@
|
|||||||
],
|
],
|
||||||
"is_official": false
|
"is_official": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"module_name": "nonebot_plugin_arkguesser",
|
||||||
|
"project_link": "nonebot-plugin-arkguesser",
|
||||||
|
"author_id": 225500959,
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"label": "Arknights",
|
||||||
|
"color": "#655cf9"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_official": false
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
@@ -8,13 +8,11 @@ FrontMatter:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from itertools import chain
|
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import Optional, Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
from nonebot.log import logger
|
|
||||||
from nonebot.utils import path_to_module_name
|
from nonebot.utils import path_to_module_name
|
||||||
|
|
||||||
from . import _managers, _module_name_to_plugin_id, get_plugin
|
from . import _managers, _module_name_to_plugin_id, get_plugin
|
||||||
@@ -110,19 +108,6 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> set[Plugin]:
|
|||||||
encoding: 指定 toml 文件编码
|
encoding: 指定 toml 文件编码
|
||||||
|
|
||||||
用法:
|
用法:
|
||||||
新格式:
|
|
||||||
|
|
||||||
```toml title=pyproject.toml
|
|
||||||
[tool.nonebot]
|
|
||||||
plugin_dirs = ["some_dir"]
|
|
||||||
|
|
||||||
[tool.nonebot.plugins]
|
|
||||||
some-store-plugin = ["some_store_plugin"]
|
|
||||||
"@local" = ["some_local_plugin"]
|
|
||||||
```
|
|
||||||
|
|
||||||
旧格式:
|
|
||||||
|
|
||||||
```toml title=pyproject.toml
|
```toml title=pyproject.toml
|
||||||
[tool.nonebot]
|
[tool.nonebot]
|
||||||
plugins = ["some_plugin"]
|
plugins = ["some_plugin"]
|
||||||
@@ -141,22 +126,11 @@ def load_from_toml(file_path: str, encoding: str = "utf-8") -> set[Plugin]:
|
|||||||
raise ValueError("Cannot find '[tool.nonebot]' in given toml file!")
|
raise ValueError("Cannot find '[tool.nonebot]' in given toml file!")
|
||||||
if not isinstance(nonebot_data, dict):
|
if not isinstance(nonebot_data, dict):
|
||||||
raise TypeError("'[tool.nonebot]' must be a Table!")
|
raise TypeError("'[tool.nonebot]' must be a Table!")
|
||||||
plugins = nonebot_data.get("plugins", {})
|
plugins = nonebot_data.get("plugins", [])
|
||||||
plugin_dirs = nonebot_data.get("plugin_dirs", [])
|
plugin_dirs = nonebot_data.get("plugin_dirs", [])
|
||||||
assert isinstance(plugins, (list, dict)), (
|
assert isinstance(plugins, list), "plugins must be a list of plugin name"
|
||||||
"plugins must be a list or a dict of plugin name"
|
|
||||||
)
|
|
||||||
assert isinstance(plugin_dirs, list), "plugin_dirs must be a list of directories"
|
assert isinstance(plugin_dirs, list), "plugin_dirs must be a list of directories"
|
||||||
if isinstance(plugins, list):
|
return load_all_plugins(plugins, plugin_dirs)
|
||||||
logger.warning("Legacy project format found! Upgrade with `nb upgrade-format`.")
|
|
||||||
return load_all_plugins(
|
|
||||||
set(
|
|
||||||
chain.from_iterable(plugins.values())
|
|
||||||
if isinstance(plugins, dict)
|
|
||||||
else plugins
|
|
||||||
),
|
|
||||||
plugin_dirs,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def load_builtin_plugin(name: str) -> Optional[Plugin]:
|
def load_builtin_plugin(name: str) -> Optional[Plugin]:
|
||||||
|
@@ -89,7 +89,7 @@ def origin_is_annotated(origin: t.Optional[type[t.Any]]) -> bool:
|
|||||||
return origin is t_ext.Annotated
|
return origin is t_ext.Annotated
|
||||||
|
|
||||||
|
|
||||||
NONE_TYPES = {None, type(None), t.Literal[None], t_ext.Literal[None]} # noqa: PYI061
|
NONE_TYPES = {None, type(None), t.Literal[None], t_ext.Literal[None]}
|
||||||
if sys.version_info >= (3, 10):
|
if sys.version_info >= (3, 10):
|
||||||
NONE_TYPES.add(types.NoneType)
|
NONE_TYPES.add(types.NoneType)
|
||||||
|
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
[tool.nonebot]
|
|
||||||
plugins = []
|
|
||||||
plugin_dirs = []
|
|
@@ -1,5 +1,3 @@
|
|||||||
[tool.nonebot]
|
[tool.nonebot]
|
||||||
|
plugins = []
|
||||||
plugin_dirs = []
|
plugin_dirs = []
|
||||||
|
|
||||||
[tool.nonebot.plugins]
|
|
||||||
"@local" = []
|
|
||||||
|
@@ -93,8 +93,6 @@ def test_load_json():
|
|||||||
|
|
||||||
@_recover
|
@_recover
|
||||||
def test_load_toml():
|
def test_load_toml():
|
||||||
nonebot.load_from_toml("./plugins.legacy.toml")
|
|
||||||
|
|
||||||
nonebot.load_from_toml("./plugins.toml")
|
nonebot.load_from_toml("./plugins.toml")
|
||||||
|
|
||||||
with pytest.raises(ValueError, match="Cannot find"):
|
with pytest.raises(ValueError, match="Cannot find"):
|
||||||
|
@@ -1,229 +0,0 @@
|
|||||||
---
|
|
||||||
sidebar_position: 8
|
|
||||||
description: 轻量化 HTML 绘图
|
|
||||||
---
|
|
||||||
|
|
||||||
# 轻量化 HTML 绘图
|
|
||||||
|
|
||||||
图片是机器人交互中不可或缺的一部分,对于信息展示的直观性、美观性有很大的作用。
|
|
||||||
基于 PIL 直接绘制图片具有良好的性能和存储开销,但是难以调试、维护过程式的绘图代码。
|
|
||||||
使用浏览器渲染类插件可以方便地绘制网页,且能够直接通过 JS 对网页效果进行编程,但是它占用的存储和内存空间相对可观。
|
|
||||||
|
|
||||||
NoneBot 提供的 `nonebot-plugin-htmlkit` 提供了另一种基于 HTML 和 CSS 语法的轻量化绘图选择:它基于 `litehtml` 解析库,无须安装额外的依赖即可使用,没有进程间通信带来的额外开销,且在支持 `webp` `avif` 等丰富图片格式的前提下,安装用的 wheel 文件大小仅有约 10 MB。
|
|
||||||
|
|
||||||
作为粗略的性能参考,在一台 Ryzen 7 9700X 的 Windows 电脑上,渲染 [PEP 7](https://peps.python.org/pep-0007/) 的 HTML 页面(分辨率为 800x5788,大小约 1.4MB,从本地文件系统读取 CSS)大约需要 100ms,每个渲染任务内存最高占用约为 40MB.
|
|
||||||
|
|
||||||
## 安装插件
|
|
||||||
|
|
||||||
在使用前请先安装 `nonebot-plugin-htmlkit` 插件至项目环境中,可参考[获取商店插件](../tutorial/store.mdx#安装插件)来了解并选择安装插件的方式。如:
|
|
||||||
|
|
||||||
在**项目目录**下执行以下命令:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nb plugin install nonebot-plugin-htmlkit
|
|
||||||
```
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 插件目前兼容以下系统架构:
|
|
||||||
|
|
||||||
- Windows x64
|
|
||||||
- macOS arm64(M-系列芯片)
|
|
||||||
- Linux x64 (非 Alpine 等 musl 系发行版)
|
|
||||||
- Linux arm64 (非 Alpine 等 musl 系发行版)
|
|
||||||
|
|
||||||
:::caution 访问网络内容
|
|
||||||
|
|
||||||
如果需要访问网络资源(如 http(s) 网页内容),NoneBot 需要客户端型驱动器(Forward)。内置的驱动器有 `~httpx` 与 `~aiohttp`。
|
|
||||||
|
|
||||||
详见[选择驱动器](../advanced/driver.md)。
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## 使用插件
|
|
||||||
|
|
||||||
### 加载插件
|
|
||||||
|
|
||||||
在使用本插件前同样需要使用 `require` 方法进行**加载**并**导入**需要使用的方法,可参考 [跨插件访问](../advanced/requiring.md) 一节进行了解,如:
|
|
||||||
|
|
||||||
```python
|
|
||||||
from nonebot import require
|
|
||||||
|
|
||||||
require("nonebot_plugin_htmlkit")
|
|
||||||
|
|
||||||
from nonebot_plugin_htmlkit import html_to_pic, md_to_pic, template_to_pic, text_to_pic
|
|
||||||
```
|
|
||||||
|
|
||||||
插件会自动使用[配置中的参数](#配置-fontconfig)初始化 `fontconfig` 以提供字体查找功能。
|
|
||||||
|
|
||||||
### 渲染 API
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 主要提供以下**异步**渲染函数:
|
|
||||||
|
|
||||||
#### html_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def html_to_pic(
|
|
||||||
html: str,
|
|
||||||
*,
|
|
||||||
base_url: str = "",
|
|
||||||
dpi: float = 144.0,
|
|
||||||
max_width: float = 800.0,
|
|
||||||
device_height: float = 600.0,
|
|
||||||
default_font_size: float = 12.0,
|
|
||||||
font_name: str = "sans-serif",
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
lang: str = "zh",
|
|
||||||
culture: str = "CN",
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
urljoin_fn: Callable[[str, str], str] = urllib3.parse.urljoin,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
最核心的渲染函数。
|
|
||||||
|
|
||||||
`base_url` 和 `urljoin_fn` 控制着传入 `image_fetch_fn` 和 `css_fetch_fn` 回调的 url 内容。
|
|
||||||
|
|
||||||
`allow_refit` 如果为真,渲染时会自动缩小产出图片的宽度到最适合的宽度,否则必定产出 `max_width` 宽度的图片。
|
|
||||||
|
|
||||||
`max_width` 与 `device_height` 会在 `@media` 判断中被使用。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
以下为辅助的封装函数,关键字参数若未特殊说明均与 `html_to_pic` 含义相同。
|
|
||||||
|
|
||||||
#### text_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def text_to_pic(
|
|
||||||
text: str,
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染多行文本。
|
|
||||||
|
|
||||||
`text` 会被放置于 `<div id="main" class="main-box"> <div class="text">` 中,可据此编写 CSS 来改变文本表现。
|
|
||||||
|
|
||||||
#### md_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def md_to_pic(
|
|
||||||
md: str = "",
|
|
||||||
md_path: str = "",
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染 Markdown 文本。默认为 GitHub Markdown Light 风格,支持基于 `pygments` 的代码高亮。
|
|
||||||
|
|
||||||
`md` 和 `md_path` 二选一,前者设置时应为 Markdown 的文本,后者设置时应为指向 Markdown 文本文件的路径。
|
|
||||||
|
|
||||||
#### template_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def template_to_pic(
|
|
||||||
template_path: str | PathLike[str] | Sequence[str | PathLike[str]],
|
|
||||||
template_name: str,
|
|
||||||
templates: Mapping[Any, Any],
|
|
||||||
filters: None | Mapping[str, Any] = None,
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
device_height: int = 600,
|
|
||||||
base_url: str | None = None,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
渲染 jinja2 模板。
|
|
||||||
|
|
||||||
`template_path` 为 jinja2 环境的路径,`template_name` 是环境中要加载模板的名字,`templates` 为传入模板的参数,`filters` 为过滤器名 -> 自定义过滤器的映射。
|
|
||||||
|
|
||||||
### 控制外部资源获取
|
|
||||||
|
|
||||||
通过传入 `img_fetch_fn` 与 `css_fetch_fn`,我们可以在实际访问资源前进行审查,修改资源的来源,或是对 IO 操作进行缓存。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
如果你想要禁用外部资源加载/只从文件系统加载/只从网络加载,可以使用 `none_fetcher` `filesystem_***_fetcher` `network_***_fetcher`。
|
|
||||||
|
|
||||||
默认的 fetcher 行为(对于 `file://` 从文件系统加载,其余从网络加载)位于 `combined_***_fetcher`,可以通过对其封装实现缓存等操作。
|
|
||||||
|
|
||||||
## 配置项
|
|
||||||
|
|
||||||
### 配置 fontconfig
|
|
||||||
|
|
||||||
`htmlkit` 使用 `fontconfig` 查找字体,请参阅 [`fontconfig 用户手册`](https://fontconfig.pages.freedesktop.org/fontconfig/fontconfig-user) 了解环境变量的具体含义、如何通过编写配置文件修改字体配置等。
|
|
||||||
|
|
||||||
#### fontconfig_file
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置文件路径。
|
|
||||||
|
|
||||||
#### fontconfig_path
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置目录。
|
|
||||||
|
|
||||||
#### fontconfig_sysroot
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的 sysroot。
|
|
||||||
|
|
||||||
#### fc_debug
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置 Fontconfig 的 debug 级别。
|
|
||||||
|
|
||||||
#### fc_dbg_match_filter
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
当 `FC_DEBUG` 设置为 `MATCH2` 时,过滤 debug 输出。
|
|
||||||
|
|
||||||
#### fc_lang
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置默认语言,否则从 `LOCALE` 环境变量获取。
|
|
||||||
|
|
||||||
#### fontconfig_use_mmap
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
是否使用 `mmap(2)` 读取字体缓存。
|
|
@@ -7,61 +7,6 @@ description: 配置编辑器以获得最佳体验
|
|||||||
|
|
||||||
框架基于 [PEP484](https://www.python.org/dev/peps/pep-0484/)、[PEP 561](https://www.python.org/dev/peps/pep-0561/)、[PEP8](https://www.python.org/dev/peps/pep-0008/) 等规范进行开发并且**拥有完整类型注解**。框架使用 Pyright(Pylance)工具进行类型检查,确保代码可以被编辑器正确解析。
|
框架基于 [PEP484](https://www.python.org/dev/peps/pep-0484/)、[PEP 561](https://www.python.org/dev/peps/pep-0561/)、[PEP8](https://www.python.org/dev/peps/pep-0008/) 等规范进行开发并且**拥有完整类型注解**。框架使用 Pyright(Pylance)工具进行类型检查,确保代码可以被编辑器正确解析。
|
||||||
|
|
||||||
## CLI 脚手架提供的编辑器工具支持
|
|
||||||
|
|
||||||
在使用 NB-CLI [创建项目](./quick-start.mdx#创建项目)时,如果选择了用于插件开发的 `simple` 模板,其会根据选择的开发工具,**自动配置项目根目录下的 `.vscode/extensions.json` 文件**,以推荐最匹配的 VS Code 插件,同时自动将相应的预设配置项写入 `pyproject.toml` 作为“开箱即用”配置,从而提升开发体验。
|
|
||||||
|
|
||||||
```bash
|
|
||||||
[?] 选择一个要使用的模板: simple (插件开发者)
|
|
||||||
...
|
|
||||||
[?] 要使用哪些开发工具?
|
|
||||||
```
|
|
||||||
|
|
||||||
### 支持的开发工具
|
|
||||||
|
|
||||||
1. Pyright (Pylance)
|
|
||||||
|
|
||||||
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) | [项目](https://github.com/microsoft/pyright) | [文档](https://microsoft.github.io/pyright/)
|
|
||||||
|
|
||||||
由微软开发的 Python 静态类型检查器和语言服务器,提供智能感知、跳转定义、查找引用、实时错误检查等强大功能。
|
|
||||||
|
|
||||||
作为 VS Code 官方推荐的 Python 语言服务器,与 Pylance 扩展配合使用,能提供最流畅、最准确的代码补全和类型推断体验,是绝大多数开发者的首选。
|
|
||||||
|
|
||||||
2. Ruff
|
|
||||||
|
|
||||||
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff) | [项目](https://github.com/astral-sh/ruff) | [文档](https://docs.astral.sh/ruff/)
|
|
||||||
|
|
||||||
一个用 Rust 编写的超快 Python 代码格式化和 lint 工具,完全兼容 `black`、`isort`、`flake8` 等主流工具的规则。
|
|
||||||
|
|
||||||
速度极快(比 `black` 和 `flake8` 快 100 倍以上),配置简单,能自动格式化代码并检测潜在错误、代码风格问题(尤其是误用同步网络请求库),是提升代码质量和开发效率的必备利器。
|
|
||||||
|
|
||||||
3. MyPy
|
|
||||||
|
|
||||||
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=matangover.mypy) | [项目](https://github.com/python/mypy) | [文档](https://mypy.readthedocs.io/en/stable/index.html)
|
|
||||||
|
|
||||||
一个官方实现的 Python 静态类型检查器,通过分析代码中的类型注解来发现类型错误。
|
|
||||||
|
|
||||||
4. BasedPyright
|
|
||||||
|
|
||||||
[VS Code 插件](https://marketplace.visualstudio.com/items?itemName=detachhead.basedpyright) | [项目](https://github.com/DetachHead/basedpyright) | [文档](https://docs.basedpyright.com/)
|
|
||||||
|
|
||||||
一个基于 Pyright 的、由社区维护的替代性 Python 语言服务器,旨在提供更优的类型检查支持与接近 Pylance 的更好的使用体验。
|
|
||||||
|
|
||||||
相较于 Pylance,BasedPyright 允许配合 VS Code 之外的其他编辑器使用,同时也复刻了部分 Pylance 限定的功能。
|
|
||||||
|
|
||||||
如果您是高级用户,希望尝试 Pylance 的替代方案,或遇到 Pylance 在特定环境下的兼容性问题,可以考虑使用 BasedPyright。
|
|
||||||
|
|
||||||
:::caution 提示
|
|
||||||
为避免 `Pylance` 和 `BasedPyright` 相互冲突导致配置混乱甚至异常,脚手架默认不允许在创建项目时同时配置这两者。
|
|
||||||
|
|
||||||
如果确实需要同时使用,请在创建项目时选择 Pylance/Pyright 并根据[相关文档](https://docs.basedpyright.com/latest/installation/ides/#vscode-vscodium)进行手动配置。
|
|
||||||
:::
|
|
||||||
|
|
||||||
### 配置效果
|
|
||||||
|
|
||||||
选择上述工具后,NB-CLI 会在您的项目根目录下生成一个 `.vscode/extensions.json` 文件并在 `pyproject.toml` 文件中写入相应的配置项。当您在 VS Code 中打开此项目时,IDE
|
|
||||||
会自动弹出提示,建议您安装这些推荐的扩展,一键即可完成开发环境的初始化,让您可以立即开始编写代码,无需手动搜索和安装插件。
|
|
||||||
|
|
||||||
## 编辑器推荐配置
|
## 编辑器推荐配置
|
||||||
|
|
||||||
### Visual Studio Code
|
### Visual Studio Code
|
||||||
|
@@ -81,9 +81,8 @@ nb create
|
|||||||
请注意,多选项使用**空格**选中或取消,**回车**确认。
|
请注意,多选项使用**空格**选中或取消,**回车**确认。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
[?] 要使用哪些适配器? Console (基于终端的交互式适配器)
|
|
||||||
[?] 要使用哪些驱动器? FastAPI (FastAPI 驱动器)
|
[?] 要使用哪些驱动器? FastAPI (FastAPI 驱动器)
|
||||||
[?] 要使用什么本地存储策略? 用户全局 (默认,适用于单用户下单实例)
|
[?] 要使用哪些适配器? Console (基于终端的交互式适配器)
|
||||||
[?] 立即安装依赖? (Y/n) Yes
|
[?] 立即安装依赖? (Y/n) Yes
|
||||||
[?] 创建虚拟环境? (Y/n) Yes
|
[?] 创建虚拟环境? (Y/n) Yes
|
||||||
```
|
```
|
||||||
|
@@ -189,16 +189,12 @@ nonebot.load_from_json("plugin_config.json", encoding="utf-8")
|
|||||||
|
|
||||||
### `load_from_toml`
|
### `load_from_toml`
|
||||||
|
|
||||||
通过 TOML 文件加载插件,是 [`load_all_plugins`](#load_all_plugins) 的 TOML 变种。通过读取 TOML 文件中的 `[tool.nonebot]` Table 中的 `plugin_dirs` Array 与
|
通过 TOML 文件加载插件,是 [`load_all_plugins`](#load_all_plugins) 的 TOML 变种。通过读取 TOML 文件中的 `[tool.nonebot]` Table 中的 `plugins` 和 `plugin_dirs` Array 进行加载。例如:
|
||||||
`[tool.nonebot.plugins]` Table 中的多个 Array 进行加载。例如:
|
|
||||||
|
|
||||||
```toml title=plugin_config.toml
|
```toml title=plugin_config.toml
|
||||||
[tool.nonebot]
|
[tool.nonebot]
|
||||||
|
plugins = ["path.to.your.plugin"]
|
||||||
plugin_dirs = ["path/to/your/plugins"]
|
plugin_dirs = ["path/to/your/plugins"]
|
||||||
|
|
||||||
[tool.nonebot.plugins]
|
|
||||||
"@local" = ["path.to.your.plugin"] # 本地插件等非插件商店来源的插件
|
|
||||||
"nonebot-plugin-someplugin" = ["nonebot_plugin_someplugin"] # 插件商店来源的插件
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@@ -24,9 +24,6 @@ NoneBot 提供了一个[商店](/store/plugins),商店内容均由社区开发
|
|||||||
|
|
||||||
商店中每个内容的卡片都包含了其名称和简介等信息,点击**卡片右上角**链接图标即可跳转到其主页。
|
商店中每个内容的卡片都包含了其名称和简介等信息,点击**卡片右上角**链接图标即可跳转到其主页。
|
||||||
|
|
||||||
与此同时,NB-CLI 也提供了一个 TUI 版本的商店界面,可通过 `nb adapter store`、`nb plugin store`、`nb driver store` 命令或 CLI
|
|
||||||
交互式界面进入。其提供了接近网页商店的体验,同时允许快捷安装到当前项目。
|
|
||||||
|
|
||||||
## 安装插件
|
## 安装插件
|
||||||
|
|
||||||
<Asciinema
|
<Asciinema
|
||||||
|
@@ -7,14 +7,8 @@ toc_max_heading_level: 2
|
|||||||
|
|
||||||
## 最近更新
|
## 最近更新
|
||||||
|
|
||||||
### 🚀 新功能
|
|
||||||
|
|
||||||
- Feature: 更新 NB-CLI 新版插件加载格式与文档 [@NCBM](https://github.com/NCBM) ([#3614](https://github.com/nonebot/nonebot2/pull/3614))
|
|
||||||
|
|
||||||
### 📝 文档
|
### 📝 文档
|
||||||
|
|
||||||
- Feature: 更新 NB-CLI 新版插件加载格式与文档 [@NCBM](https://github.com/NCBM) ([#3614](https://github.com/nonebot/nonebot2/pull/3614))
|
|
||||||
- Docs: 添加 htmlkit 文档至最佳实践 [@BlueGlassBlock](https://github.com/BlueGlassBlock) ([#3682](https://github.com/nonebot/nonebot2/pull/3682))
|
|
||||||
- Docs: 修复 userinfo 插件链接 [@XieXiLin2](https://github.com/XieXiLin2) ([#3660](https://github.com/nonebot/nonebot2/pull/3660))
|
- Docs: 修复 userinfo 插件链接 [@XieXiLin2](https://github.com/XieXiLin2) ([#3660](https://github.com/nonebot/nonebot2/pull/3660))
|
||||||
- Docs: 升级 docusaurus 3.8.1 [@StarHeartHunt](https://github.com/StarHeartHunt) ([#3649](https://github.com/nonebot/nonebot2/pull/3649))
|
- Docs: 升级 docusaurus 3.8.1 [@StarHeartHunt](https://github.com/StarHeartHunt) ([#3649](https://github.com/nonebot/nonebot2/pull/3649))
|
||||||
- Docs: 更新文档《手动创建项目》 [@Chen-Luan](https://github.com/Chen-Luan) ([#3623](https://github.com/nonebot/nonebot2/pull/3623))
|
- Docs: 更新文档《手动创建项目》 [@Chen-Luan](https://github.com/Chen-Luan) ([#3623](https://github.com/nonebot/nonebot2/pull/3623))
|
||||||
@@ -28,7 +22,6 @@ toc_max_heading_level: 2
|
|||||||
|
|
||||||
### 🍻 插件发布
|
### 🍻 插件发布
|
||||||
|
|
||||||
- Plugin: 怪物猎人集会码插件 [@noneflow](https://github.com/noneflow) ([#3684](https://github.com/nonebot/nonebot2/pull/3684))
|
|
||||||
- Plugin: nonebot-plugin-htmlkit [@noneflow](https://github.com/noneflow) ([#3695](https://github.com/nonebot/nonebot2/pull/3695))
|
- Plugin: nonebot-plugin-htmlkit [@noneflow](https://github.com/noneflow) ([#3695](https://github.com/nonebot/nonebot2/pull/3695))
|
||||||
- Plugin: 言令 [@noneflow](https://github.com/noneflow) ([#3675](https://github.com/nonebot/nonebot2/pull/3675))
|
- Plugin: 言令 [@noneflow](https://github.com/noneflow) ([#3675](https://github.com/nonebot/nonebot2/pull/3675))
|
||||||
- Plugin: 算法比赛助手 [@noneflow](https://github.com/noneflow) ([#3672](https://github.com/nonebot/nonebot2/pull/3672))
|
- Plugin: 算法比赛助手 [@noneflow](https://github.com/noneflow) ([#3672](https://github.com/nonebot/nonebot2/pull/3672))
|
||||||
|
@@ -1,229 +0,0 @@
|
|||||||
---
|
|
||||||
sidebar_position: 8
|
|
||||||
description: 轻量化 HTML 绘图
|
|
||||||
---
|
|
||||||
|
|
||||||
# 轻量化 HTML 绘图
|
|
||||||
|
|
||||||
图片是机器人交互中不可或缺的一部分,对于信息展示的直观性、美观性有很大的作用。
|
|
||||||
基于 PIL 直接绘制图片具有良好的性能和存储开销,但是难以调试、维护过程式的绘图代码。
|
|
||||||
使用浏览器渲染类插件可以方便地绘制网页,且能够直接通过 JS 对网页效果进行编程,但是它占用的存储和内存空间相对可观。
|
|
||||||
|
|
||||||
NoneBot 提供的 `nonebot-plugin-htmlkit` 提供了另一种基于 HTML 和 CSS 语法的轻量化绘图选择:它基于 `litehtml` 解析库,无须安装额外的依赖即可使用,没有进程间通信带来的额外开销,且在支持 `webp` `avif` 等丰富图片格式的前提下,安装用的 wheel 文件大小仅有约 10 MB。
|
|
||||||
|
|
||||||
作为粗略的性能参考,在一台 Ryzen 7 9700X 的 Windows 电脑上,渲染 [PEP 7](https://peps.python.org/pep-0007/) 的 HTML 页面(分辨率为 800x5788,大小约 1.4MB,从本地文件系统读取 CSS)大约需要 100ms,每个渲染任务内存最高占用约为 40MB.
|
|
||||||
|
|
||||||
## 安装插件
|
|
||||||
|
|
||||||
在使用前请先安装 `nonebot-plugin-htmlkit` 插件至项目环境中,可参考[获取商店插件](../tutorial/store.mdx#安装插件)来了解并选择安装插件的方式。如:
|
|
||||||
|
|
||||||
在**项目目录**下执行以下命令:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nb plugin install nonebot-plugin-htmlkit
|
|
||||||
```
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 插件目前兼容以下系统架构:
|
|
||||||
|
|
||||||
- Windows x64
|
|
||||||
- macOS arm64(M-系列芯片)
|
|
||||||
- Linux x64 (非 Alpine 等 musl 系发行版)
|
|
||||||
- Linux arm64 (非 Alpine 等 musl 系发行版)
|
|
||||||
|
|
||||||
:::caution 访问网络内容
|
|
||||||
|
|
||||||
如果需要访问网络资源(如 http(s) 网页内容),NoneBot 需要客户端型驱动器(Forward)。内置的驱动器有 `~httpx` 与 `~aiohttp`。
|
|
||||||
|
|
||||||
详见[选择驱动器](../advanced/driver.md)。
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## 使用插件
|
|
||||||
|
|
||||||
### 加载插件
|
|
||||||
|
|
||||||
在使用本插件前同样需要使用 `require` 方法进行**加载**并**导入**需要使用的方法,可参考 [跨插件访问](../advanced/requiring.md) 一节进行了解,如:
|
|
||||||
|
|
||||||
```python
|
|
||||||
from nonebot import require
|
|
||||||
|
|
||||||
require("nonebot_plugin_htmlkit")
|
|
||||||
|
|
||||||
from nonebot_plugin_htmlkit import html_to_pic, md_to_pic, template_to_pic, text_to_pic
|
|
||||||
```
|
|
||||||
|
|
||||||
插件会自动使用[配置中的参数](#配置-fontconfig)初始化 `fontconfig` 以提供字体查找功能。
|
|
||||||
|
|
||||||
### 渲染 API
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 主要提供以下**异步**渲染函数:
|
|
||||||
|
|
||||||
#### html_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def html_to_pic(
|
|
||||||
html: str,
|
|
||||||
*,
|
|
||||||
base_url: str = "",
|
|
||||||
dpi: float = 144.0,
|
|
||||||
max_width: float = 800.0,
|
|
||||||
device_height: float = 600.0,
|
|
||||||
default_font_size: float = 12.0,
|
|
||||||
font_name: str = "sans-serif",
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
lang: str = "zh",
|
|
||||||
culture: str = "CN",
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
urljoin_fn: Callable[[str, str], str] = urllib3.parse.urljoin,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
最核心的渲染函数。
|
|
||||||
|
|
||||||
`base_url` 和 `urljoin_fn` 控制着传入 `image_fetch_fn` 和 `css_fetch_fn` 回调的 url 内容。
|
|
||||||
|
|
||||||
`allow_refit` 如果为真,渲染时会自动缩小产出图片的宽度到最适合的宽度,否则必定产出 `max_width` 宽度的图片。
|
|
||||||
|
|
||||||
`max_width` 与 `device_height` 会在 `@media` 判断中被使用。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
以下为辅助的封装函数,关键字参数若未特殊说明均与 `html_to_pic` 含义相同。
|
|
||||||
|
|
||||||
#### text_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def text_to_pic(
|
|
||||||
text: str,
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染多行文本。
|
|
||||||
|
|
||||||
`text` 会被放置于 `<div id="main" class="main-box"> <div class="text">` 中,可据此编写 CSS 来改变文本表现。
|
|
||||||
|
|
||||||
#### md_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def md_to_pic(
|
|
||||||
md: str = "",
|
|
||||||
md_path: str = "",
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染 Markdown 文本。默认为 GitHub Markdown Light 风格,支持基于 `pygments` 的代码高亮。
|
|
||||||
|
|
||||||
`md` 和 `md_path` 二选一,前者设置时应为 Markdown 的文本,后者设置时应为指向 Markdown 文本文件的路径。
|
|
||||||
|
|
||||||
#### template_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def template_to_pic(
|
|
||||||
template_path: str | PathLike[str] | Sequence[str | PathLike[str]],
|
|
||||||
template_name: str,
|
|
||||||
templates: Mapping[Any, Any],
|
|
||||||
filters: None | Mapping[str, Any] = None,
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
device_height: int = 600,
|
|
||||||
base_url: str | None = None,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
渲染 jinja2 模板。
|
|
||||||
|
|
||||||
`template_path` 为 jinja2 环境的路径,`template_name` 是环境中要加载模板的名字,`templates` 为传入模板的参数,`filters` 为过滤器名 -> 自定义过滤器的映射。
|
|
||||||
|
|
||||||
### 控制外部资源获取
|
|
||||||
|
|
||||||
通过传入 `img_fetch_fn` 与 `css_fetch_fn`,我们可以在实际访问资源前进行审查,修改资源的来源,或是对 IO 操作进行缓存。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
如果你想要禁用外部资源加载/只从文件系统加载/只从网络加载,可以使用 `none_fetcher` `filesystem_***_fetcher` `network_***_fetcher`。
|
|
||||||
|
|
||||||
默认的 fetcher 行为(对于 `file://` 从文件系统加载,其余从网络加载)位于 `combined_***_fetcher`,可以通过对其封装实现缓存等操作。
|
|
||||||
|
|
||||||
## 配置项
|
|
||||||
|
|
||||||
### 配置 fontconfig
|
|
||||||
|
|
||||||
`htmlkit` 使用 `fontconfig` 查找字体,请参阅 [`fontconfig 用户手册`](https://fontconfig.pages.freedesktop.org/fontconfig/fontconfig-user) 了解环境变量的具体含义、如何通过编写配置文件修改字体配置等。
|
|
||||||
|
|
||||||
#### fontconfig_file
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置文件路径。
|
|
||||||
|
|
||||||
#### fontconfig_path
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置目录。
|
|
||||||
|
|
||||||
#### fontconfig_sysroot
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的 sysroot。
|
|
||||||
|
|
||||||
#### fc_debug
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置 Fontconfig 的 debug 级别。
|
|
||||||
|
|
||||||
#### fc_dbg_match_filter
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
当 `FC_DEBUG` 设置为 `MATCH2` 时,过滤 debug 输出。
|
|
||||||
|
|
||||||
#### fc_lang
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置默认语言,否则从 `LOCALE` 环境变量获取。
|
|
||||||
|
|
||||||
#### fontconfig_use_mmap
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
是否使用 `mmap(2)` 读取字体缓存。
|
|
@@ -1,229 +0,0 @@
|
|||||||
---
|
|
||||||
sidebar_position: 8
|
|
||||||
description: 轻量化 HTML 绘图
|
|
||||||
---
|
|
||||||
|
|
||||||
# 轻量化 HTML 绘图
|
|
||||||
|
|
||||||
图片是机器人交互中不可或缺的一部分,对于信息展示的直观性、美观性有很大的作用。
|
|
||||||
基于 PIL 直接绘制图片具有良好的性能和存储开销,但是难以调试、维护过程式的绘图代码。
|
|
||||||
使用浏览器渲染类插件可以方便地绘制网页,且能够直接通过 JS 对网页效果进行编程,但是它占用的存储和内存空间相对可观。
|
|
||||||
|
|
||||||
NoneBot 提供的 `nonebot-plugin-htmlkit` 提供了另一种基于 HTML 和 CSS 语法的轻量化绘图选择:它基于 `litehtml` 解析库,无须安装额外的依赖即可使用,没有进程间通信带来的额外开销,且在支持 `webp` `avif` 等丰富图片格式的前提下,安装用的 wheel 文件大小仅有约 10 MB。
|
|
||||||
|
|
||||||
作为粗略的性能参考,在一台 Ryzen 7 9700X 的 Windows 电脑上,渲染 [PEP 7](https://peps.python.org/pep-0007/) 的 HTML 页面(分辨率为 800x5788,大小约 1.4MB,从本地文件系统读取 CSS)大约需要 100ms,每个渲染任务内存最高占用约为 40MB.
|
|
||||||
|
|
||||||
## 安装插件
|
|
||||||
|
|
||||||
在使用前请先安装 `nonebot-plugin-htmlkit` 插件至项目环境中,可参考[获取商店插件](../tutorial/store.mdx#安装插件)来了解并选择安装插件的方式。如:
|
|
||||||
|
|
||||||
在**项目目录**下执行以下命令:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nb plugin install nonebot-plugin-htmlkit
|
|
||||||
```
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 插件目前兼容以下系统架构:
|
|
||||||
|
|
||||||
- Windows x64
|
|
||||||
- macOS arm64(M-系列芯片)
|
|
||||||
- Linux x64 (非 Alpine 等 musl 系发行版)
|
|
||||||
- Linux arm64 (非 Alpine 等 musl 系发行版)
|
|
||||||
|
|
||||||
:::caution 访问网络内容
|
|
||||||
|
|
||||||
如果需要访问网络资源(如 http(s) 网页内容),NoneBot 需要客户端型驱动器(Forward)。内置的驱动器有 `~httpx` 与 `~aiohttp`。
|
|
||||||
|
|
||||||
详见[选择驱动器](../advanced/driver.md)。
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## 使用插件
|
|
||||||
|
|
||||||
### 加载插件
|
|
||||||
|
|
||||||
在使用本插件前同样需要使用 `require` 方法进行**加载**并**导入**需要使用的方法,可参考 [跨插件访问](../advanced/requiring.md) 一节进行了解,如:
|
|
||||||
|
|
||||||
```python
|
|
||||||
from nonebot import require
|
|
||||||
|
|
||||||
require("nonebot_plugin_htmlkit")
|
|
||||||
|
|
||||||
from nonebot_plugin_htmlkit import html_to_pic, md_to_pic, template_to_pic, text_to_pic
|
|
||||||
```
|
|
||||||
|
|
||||||
插件会自动使用[配置中的参数](#配置-fontconfig)初始化 `fontconfig` 以提供字体查找功能。
|
|
||||||
|
|
||||||
### 渲染 API
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 主要提供以下**异步**渲染函数:
|
|
||||||
|
|
||||||
#### html_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def html_to_pic(
|
|
||||||
html: str,
|
|
||||||
*,
|
|
||||||
base_url: str = "",
|
|
||||||
dpi: float = 144.0,
|
|
||||||
max_width: float = 800.0,
|
|
||||||
device_height: float = 600.0,
|
|
||||||
default_font_size: float = 12.0,
|
|
||||||
font_name: str = "sans-serif",
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
lang: str = "zh",
|
|
||||||
culture: str = "CN",
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
urljoin_fn: Callable[[str, str], str] = urllib3.parse.urljoin,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
最核心的渲染函数。
|
|
||||||
|
|
||||||
`base_url` 和 `urljoin_fn` 控制着传入 `image_fetch_fn` 和 `css_fetch_fn` 回调的 url 内容。
|
|
||||||
|
|
||||||
`allow_refit` 如果为真,渲染时会自动缩小产出图片的宽度到最适合的宽度,否则必定产出 `max_width` 宽度的图片。
|
|
||||||
|
|
||||||
`max_width` 与 `device_height` 会在 `@media` 判断中被使用。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
以下为辅助的封装函数,关键字参数若未特殊说明均与 `html_to_pic` 含义相同。
|
|
||||||
|
|
||||||
#### text_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def text_to_pic(
|
|
||||||
text: str,
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染多行文本。
|
|
||||||
|
|
||||||
`text` 会被放置于 `<div id="main" class="main-box"> <div class="text">` 中,可据此编写 CSS 来改变文本表现。
|
|
||||||
|
|
||||||
#### md_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def md_to_pic(
|
|
||||||
md: str = "",
|
|
||||||
md_path: str = "",
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染 Markdown 文本。默认为 GitHub Markdown Light 风格,支持基于 `pygments` 的代码高亮。
|
|
||||||
|
|
||||||
`md` 和 `md_path` 二选一,前者设置时应为 Markdown 的文本,后者设置时应为指向 Markdown 文本文件的路径。
|
|
||||||
|
|
||||||
#### template_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def template_to_pic(
|
|
||||||
template_path: str | PathLike[str] | Sequence[str | PathLike[str]],
|
|
||||||
template_name: str,
|
|
||||||
templates: Mapping[Any, Any],
|
|
||||||
filters: None | Mapping[str, Any] = None,
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
device_height: int = 600,
|
|
||||||
base_url: str | None = None,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
渲染 jinja2 模板。
|
|
||||||
|
|
||||||
`template_path` 为 jinja2 环境的路径,`template_name` 是环境中要加载模板的名字,`templates` 为传入模板的参数,`filters` 为过滤器名 -> 自定义过滤器的映射。
|
|
||||||
|
|
||||||
### 控制外部资源获取
|
|
||||||
|
|
||||||
通过传入 `img_fetch_fn` 与 `css_fetch_fn`,我们可以在实际访问资源前进行审查,修改资源的来源,或是对 IO 操作进行缓存。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
如果你想要禁用外部资源加载/只从文件系统加载/只从网络加载,可以使用 `none_fetcher` `filesystem_***_fetcher` `network_***_fetcher`。
|
|
||||||
|
|
||||||
默认的 fetcher 行为(对于 `file://` 从文件系统加载,其余从网络加载)位于 `combined_***_fetcher`,可以通过对其封装实现缓存等操作。
|
|
||||||
|
|
||||||
## 配置项
|
|
||||||
|
|
||||||
### 配置 fontconfig
|
|
||||||
|
|
||||||
`htmlkit` 使用 `fontconfig` 查找字体,请参阅 [`fontconfig 用户手册`](https://fontconfig.pages.freedesktop.org/fontconfig/fontconfig-user) 了解环境变量的具体含义、如何通过编写配置文件修改字体配置等。
|
|
||||||
|
|
||||||
#### fontconfig_file
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置文件路径。
|
|
||||||
|
|
||||||
#### fontconfig_path
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置目录。
|
|
||||||
|
|
||||||
#### fontconfig_sysroot
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的 sysroot。
|
|
||||||
|
|
||||||
#### fc_debug
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置 Fontconfig 的 debug 级别。
|
|
||||||
|
|
||||||
#### fc_dbg_match_filter
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
当 `FC_DEBUG` 设置为 `MATCH2` 时,过滤 debug 输出。
|
|
||||||
|
|
||||||
#### fc_lang
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置默认语言,否则从 `LOCALE` 环境变量获取。
|
|
||||||
|
|
||||||
#### fontconfig_use_mmap
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
是否使用 `mmap(2)` 读取字体缓存。
|
|
@@ -1,229 +0,0 @@
|
|||||||
---
|
|
||||||
sidebar_position: 8
|
|
||||||
description: 轻量化 HTML 绘图
|
|
||||||
---
|
|
||||||
|
|
||||||
# 轻量化 HTML 绘图
|
|
||||||
|
|
||||||
图片是机器人交互中不可或缺的一部分,对于信息展示的直观性、美观性有很大的作用。
|
|
||||||
基于 PIL 直接绘制图片具有良好的性能和存储开销,但是难以调试、维护过程式的绘图代码。
|
|
||||||
使用浏览器渲染类插件可以方便地绘制网页,且能够直接通过 JS 对网页效果进行编程,但是它占用的存储和内存空间相对可观。
|
|
||||||
|
|
||||||
NoneBot 提供的 `nonebot-plugin-htmlkit` 提供了另一种基于 HTML 和 CSS 语法的轻量化绘图选择:它基于 `litehtml` 解析库,无须安装额外的依赖即可使用,没有进程间通信带来的额外开销,且在支持 `webp` `avif` 等丰富图片格式的前提下,安装用的 wheel 文件大小仅有约 10 MB。
|
|
||||||
|
|
||||||
作为粗略的性能参考,在一台 Ryzen 7 9700X 的 Windows 电脑上,渲染 [PEP 7](https://peps.python.org/pep-0007/) 的 HTML 页面(分辨率为 800x5788,大小约 1.4MB,从本地文件系统读取 CSS)大约需要 100ms,每个渲染任务内存最高占用约为 40MB.
|
|
||||||
|
|
||||||
## 安装插件
|
|
||||||
|
|
||||||
在使用前请先安装 `nonebot-plugin-htmlkit` 插件至项目环境中,可参考[获取商店插件](../tutorial/store.mdx#安装插件)来了解并选择安装插件的方式。如:
|
|
||||||
|
|
||||||
在**项目目录**下执行以下命令:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nb plugin install nonebot-plugin-htmlkit
|
|
||||||
```
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 插件目前兼容以下系统架构:
|
|
||||||
|
|
||||||
- Windows x64
|
|
||||||
- macOS arm64(M-系列芯片)
|
|
||||||
- Linux x64 (非 Alpine 等 musl 系发行版)
|
|
||||||
- Linux arm64 (非 Alpine 等 musl 系发行版)
|
|
||||||
|
|
||||||
:::caution 访问网络内容
|
|
||||||
|
|
||||||
如果需要访问网络资源(如 http(s) 网页内容),NoneBot 需要客户端型驱动器(Forward)。内置的驱动器有 `~httpx` 与 `~aiohttp`。
|
|
||||||
|
|
||||||
详见[选择驱动器](../advanced/driver.md)。
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## 使用插件
|
|
||||||
|
|
||||||
### 加载插件
|
|
||||||
|
|
||||||
在使用本插件前同样需要使用 `require` 方法进行**加载**并**导入**需要使用的方法,可参考 [跨插件访问](../advanced/requiring.md) 一节进行了解,如:
|
|
||||||
|
|
||||||
```python
|
|
||||||
from nonebot import require
|
|
||||||
|
|
||||||
require("nonebot_plugin_htmlkit")
|
|
||||||
|
|
||||||
from nonebot_plugin_htmlkit import html_to_pic, md_to_pic, template_to_pic, text_to_pic
|
|
||||||
```
|
|
||||||
|
|
||||||
插件会自动使用[配置中的参数](#配置-fontconfig)初始化 `fontconfig` 以提供字体查找功能。
|
|
||||||
|
|
||||||
### 渲染 API
|
|
||||||
|
|
||||||
`nonebot-plugin-htmlkit` 主要提供以下**异步**渲染函数:
|
|
||||||
|
|
||||||
#### html_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def html_to_pic(
|
|
||||||
html: str,
|
|
||||||
*,
|
|
||||||
base_url: str = "",
|
|
||||||
dpi: float = 144.0,
|
|
||||||
max_width: float = 800.0,
|
|
||||||
device_height: float = 600.0,
|
|
||||||
default_font_size: float = 12.0,
|
|
||||||
font_name: str = "sans-serif",
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
lang: str = "zh",
|
|
||||||
culture: str = "CN",
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
urljoin_fn: Callable[[str, str], str] = urllib3.parse.urljoin,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
最核心的渲染函数。
|
|
||||||
|
|
||||||
`base_url` 和 `urljoin_fn` 控制着传入 `image_fetch_fn` 和 `css_fetch_fn` 回调的 url 内容。
|
|
||||||
|
|
||||||
`allow_refit` 如果为真,渲染时会自动缩小产出图片的宽度到最适合的宽度,否则必定产出 `max_width` 宽度的图片。
|
|
||||||
|
|
||||||
`max_width` 与 `device_height` 会在 `@media` 判断中被使用。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
以下为辅助的封装函数,关键字参数若未特殊说明均与 `html_to_pic` 含义相同。
|
|
||||||
|
|
||||||
#### text_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def text_to_pic(
|
|
||||||
text: str,
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染多行文本。
|
|
||||||
|
|
||||||
`text` 会被放置于 `<div id="main" class="main-box"> <div class="text">` 中,可据此编写 CSS 来改变文本表现。
|
|
||||||
|
|
||||||
#### md_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def md_to_pic(
|
|
||||||
md: str = "",
|
|
||||||
md_path: str = "",
|
|
||||||
css_path: str = "",
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
可用于渲染 Markdown 文本。默认为 GitHub Markdown Light 风格,支持基于 `pygments` 的代码高亮。
|
|
||||||
|
|
||||||
`md` 和 `md_path` 二选一,前者设置时应为 Markdown 的文本,后者设置时应为指向 Markdown 文本文件的路径。
|
|
||||||
|
|
||||||
#### template_to_pic
|
|
||||||
|
|
||||||
```python
|
|
||||||
async def template_to_pic(
|
|
||||||
template_path: str | PathLike[str] | Sequence[str | PathLike[str]],
|
|
||||||
template_name: str,
|
|
||||||
templates: Mapping[Any, Any],
|
|
||||||
filters: None | Mapping[str, Any] = None,
|
|
||||||
*,
|
|
||||||
max_width: int = 500,
|
|
||||||
device_height: int = 600,
|
|
||||||
base_url: str | None = None,
|
|
||||||
img_fetch_fn: ImgFetchFn = combined_img_fetcher,
|
|
||||||
css_fetch_fn: CSSFetchFn = combined_css_fetcher,
|
|
||||||
allow_refit: bool = True,
|
|
||||||
image_format: Literal["png", "jpeg"] = "png",
|
|
||||||
jpeg_quality: int = 100,
|
|
||||||
) -> bytes:
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
渲染 jinja2 模板。
|
|
||||||
|
|
||||||
`template_path` 为 jinja2 环境的路径,`template_name` 是环境中要加载模板的名字,`templates` 为传入模板的参数,`filters` 为过滤器名 -> 自定义过滤器的映射。
|
|
||||||
|
|
||||||
### 控制外部资源获取
|
|
||||||
|
|
||||||
通过传入 `img_fetch_fn` 与 `css_fetch_fn`,我们可以在实际访问资源前进行审查,修改资源的来源,或是对 IO 操作进行缓存。
|
|
||||||
|
|
||||||
`img_fetch_fn` 预期为一个异步可调用对象(函数),接收图片 url 并返回对应 url 的 jpeg 或 png 二进制数据(`bytes`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
`css_fetch_fn` 预期为一个异步可调用对象(函数),接收目标 CSS url 并返回对应 url 的 CSS 文本(`str`),可在拒绝加载时返回 `None`.
|
|
||||||
|
|
||||||
如果你想要禁用外部资源加载/只从文件系统加载/只从网络加载,可以使用 `none_fetcher` `filesystem_***_fetcher` `network_***_fetcher`。
|
|
||||||
|
|
||||||
默认的 fetcher 行为(对于 `file://` 从文件系统加载,其余从网络加载)位于 `combined_***_fetcher`,可以通过对其封装实现缓存等操作。
|
|
||||||
|
|
||||||
## 配置项
|
|
||||||
|
|
||||||
### 配置 fontconfig
|
|
||||||
|
|
||||||
`htmlkit` 使用 `fontconfig` 查找字体,请参阅 [`fontconfig 用户手册`](https://fontconfig.pages.freedesktop.org/fontconfig/fontconfig-user) 了解环境变量的具体含义、如何通过编写配置文件修改字体配置等。
|
|
||||||
|
|
||||||
#### fontconfig_file
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置文件路径。
|
|
||||||
|
|
||||||
#### fontconfig_path
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的配置目录。
|
|
||||||
|
|
||||||
#### fontconfig_sysroot
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
覆盖默认的 sysroot。
|
|
||||||
|
|
||||||
#### fc_debug
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置 Fontconfig 的 debug 级别。
|
|
||||||
|
|
||||||
#### fc_dbg_match_filter
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
当 `FC_DEBUG` 设置为 `MATCH2` 时,过滤 debug 输出。
|
|
||||||
|
|
||||||
#### fc_lang
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
设置默认语言,否则从 `LOCALE` 环境变量获取。
|
|
||||||
|
|
||||||
#### fontconfig_use_mmap
|
|
||||||
|
|
||||||
- **类型**: `str | None`
|
|
||||||
- **默认值**: `None`
|
|
||||||
|
|
||||||
是否使用 `mmap(2)` 读取字体缓存。
|
|
Reference in New Issue
Block a user