nonebot-plugin-kuwo 0.2.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.
Files changed (31) hide show
  1. nonebot_plugin_kuwo-0.2.0/.env.example +9 -0
  2. nonebot_plugin_kuwo-0.2.0/.github/workflows/ci.yml +49 -0
  3. nonebot_plugin_kuwo-0.2.0/.github/workflows/release.yml +115 -0
  4. nonebot_plugin_kuwo-0.2.0/.gitignore +26 -0
  5. nonebot_plugin_kuwo-0.2.0/CHANGELOG.md +52 -0
  6. nonebot_plugin_kuwo-0.2.0/Cargo.lock +179 -0
  7. nonebot_plugin_kuwo-0.2.0/Cargo.toml +14 -0
  8. nonebot_plugin_kuwo-0.2.0/LICENSE +661 -0
  9. nonebot_plugin_kuwo-0.2.0/PKG-INFO +313 -0
  10. nonebot_plugin_kuwo-0.2.0/README.md +293 -0
  11. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/__init__.py +402 -0
  12. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/_qmc_rs.pyi +14 -0
  13. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/config.py +168 -0
  14. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/data_source.py +352 -0
  15. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/models.py +140 -0
  16. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/py.typed +1 -0
  17. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/qmc.py +74 -0
  18. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/render.py +313 -0
  19. nonebot_plugin_kuwo-0.2.0/nonebot_plugin_kuwo/utils.py +132 -0
  20. nonebot_plugin_kuwo-0.2.0/pyproject.toml +57 -0
  21. nonebot_plugin_kuwo-0.2.0/pytest.ini +2 -0
  22. nonebot_plugin_kuwo-0.2.0/src/lib.rs +60 -0
  23. nonebot_plugin_kuwo-0.2.0/src/qmc.rs +685 -0
  24. nonebot_plugin_kuwo-0.2.0/tests/AIM0000WoYYr0hishZ3b6ff42855ecade7711348a59f29bca0.mflac +0 -0
  25. nonebot_plugin_kuwo-0.2.0/tests/conftest.py +31 -0
  26. nonebot_plugin_kuwo-0.2.0/tests/test_command.py +845 -0
  27. nonebot_plugin_kuwo-0.2.0/tests/test_config.py +127 -0
  28. nonebot_plugin_kuwo-0.2.0/tests/test_data_source.py +249 -0
  29. nonebot_plugin_kuwo-0.2.0/tests/test_qmc.py +79 -0
  30. nonebot_plugin_kuwo-0.2.0/tests/test_utils.py +52 -0
  31. nonebot_plugin_kuwo-0.2.0/uv.lock +1752 -0
@@ -0,0 +1,9 @@
1
+ # NoneBot command prefix example
2
+ COMMAND_START=["/"]
3
+ LOG_LEVEL=INFO
4
+
5
+ # Kuwo plugin settings
6
+ KUWO_SEARCH_LIMIT=5
7
+ KUWO_LIST_RENDER_MODE=text
8
+ KUWO_TRACK_RENDER_MODE=text # support: text | card | record | file
9
+ KUWO_DEFAULT_QUALITY=standard
@@ -0,0 +1,49 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ${{ matrix.os }}
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ os:
14
+ - ubuntu-latest
15
+ - ubuntu-24.04-arm
16
+ - windows-latest
17
+ - windows-11-arm
18
+ - macos-latest
19
+ - macos-26-intel
20
+
21
+ steps:
22
+ - name: Checkout
23
+ uses: actions/checkout@v6
24
+
25
+ - name: Setup Python
26
+ uses: actions/setup-python@v6
27
+ with:
28
+ python-version: "3.13"
29
+
30
+ - name: Setup uv
31
+ uses: astral-sh/setup-uv@v7
32
+
33
+ - name: Setup Rust
34
+ uses: dtolnay/rust-toolchain@stable
35
+
36
+ - name: Sync dependencies
37
+ run: uv sync --dev
38
+
39
+ - name: Rust fmt
40
+ run: cargo fmt --all --check
41
+
42
+ - name: Build Rust extension
43
+ run: uv run maturin develop --release --locked
44
+
45
+ - name: Ruff
46
+ run: uv run ruff check .
47
+
48
+ - name: Pytest
49
+ run: uv run pytest tests/ -q -p no:cacheprovider
@@ -0,0 +1,115 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - "v*"
8
+
9
+ permissions:
10
+ contents: read
11
+ id-token: write
12
+
13
+ jobs:
14
+ build-wheels:
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ include:
19
+ - os: ubuntu-latest
20
+ target: x86_64-unknown-linux-gnu
21
+ manylinux: "2014"
22
+ - os: ubuntu-24.04-arm
23
+ target: aarch64-unknown-linux-gnu
24
+ manylinux: "2014"
25
+ - os: windows-latest
26
+ target: x86_64-pc-windows-msvc
27
+ manylinux: "off"
28
+ - os: windows-11-arm
29
+ target: aarch64-pc-windows-msvc
30
+ manylinux: "off"
31
+ - os: macos-26-intel
32
+ target: x86_64-apple-darwin
33
+ manylinux: "off"
34
+ - os: macos-latest
35
+ target: aarch64-apple-darwin
36
+ manylinux: "off"
37
+
38
+ runs-on: ${{ matrix.os }}
39
+
40
+ steps:
41
+ - name: Checkout
42
+ uses: actions/checkout@v6
43
+
44
+ - name: Setup Python
45
+ uses: actions/setup-python@v6
46
+ with:
47
+ python-version: "3.13"
48
+
49
+ - name: Build wheels
50
+ uses: PyO3/maturin-action@v1
51
+ with:
52
+ maturin-version: "1.13.1"
53
+ command: build
54
+ target: ${{ matrix.target }}
55
+ manylinux: ${{ matrix.manylinux }}
56
+ args: --release --out dist --compatibility pypi --locked
57
+
58
+ - name: Upload wheel artifacts
59
+ uses: actions/upload-artifact@v4
60
+ with:
61
+ name: wheels-${{ matrix.os }}-${{ matrix.target }}
62
+ path: dist
63
+
64
+ build-sdist:
65
+ runs-on: ubuntu-latest
66
+
67
+ steps:
68
+ - name: Checkout
69
+ uses: actions/checkout@v6
70
+
71
+ - name: Setup Python
72
+ uses: actions/setup-python@v6
73
+ with:
74
+ python-version: "3.13"
75
+
76
+ - name: Setup uv
77
+ uses: astral-sh/setup-uv@v7
78
+
79
+ - name: Setup Rust
80
+ uses: dtolnay/rust-toolchain@stable
81
+
82
+ - name: Sync dependencies
83
+ run: uv sync --dev
84
+
85
+ - name: Build sdist
86
+ run: uv run maturin sdist --out dist
87
+
88
+ - name: Upload sdist artifact
89
+ uses: actions/upload-artifact@v4
90
+ with:
91
+ name: sdist
92
+ path: dist
93
+
94
+ publish:
95
+ needs:
96
+ - build-wheels
97
+ - build-sdist
98
+ runs-on: ubuntu-latest
99
+ environment:
100
+ name: pypi
101
+
102
+ steps:
103
+ - name: Download artifacts
104
+ uses: actions/download-artifact@v4
105
+ with:
106
+ path: dist-artifacts
107
+
108
+ - name: Prepare dist directory
109
+ shell: bash
110
+ run: |
111
+ mkdir -p dist
112
+ find dist-artifacts -type f \( -name "*.whl" -o -name "*.tar.gz" \) -exec cp {} dist/ \;
113
+
114
+ - name: Publish to PyPI
115
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,26 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ target/
8
+ *.egg-info
9
+
10
+ # Virtual environments
11
+ .venv
12
+
13
+ # Vibe Coding files
14
+ .serena/
15
+ AGENTS.md
16
+ ARCHITECTURE.md
17
+ SPEC.md
18
+
19
+ # Test temp files
20
+ tests/.tmp/
21
+ tests/.tmp-config*/
22
+ pytest-cache-files-*
23
+ .ruff_cache/
24
+ nonebot_plugin_kuwo/_qmc_rs*.pyd
25
+ nonebot_plugin_kuwo/_qmc_rs*.so
26
+ nonebot_plugin_kuwo/_qmc_rs*.dylib
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 - 2026-04-20
4
+
5
+ - 为 Rust 原生扩展补充 `_qmc_rs.pyi` 与 `py.typed`,修复 Pylance 对 `_qmc_rs` 的未知导入符号提示
6
+ - 强化 CI / Release 工作流,补齐 Rust 格式检查与锁文件约束
7
+ - Release 工作流显式固定 Linux `manylinux2014`,并使用 `--compatibility pypi`
8
+ - 补充 Rust 原生 `derive_qmc_key` 与 `decrypt_qmc_bytes` 的直接样本测试
9
+ - 将 `nonebot_plugin_kuwo/qmc.py` 的核心算法整体迁移为 Rust 扩展
10
+ - 使用 `PyO3 + maturin` 暴露原生扩展模块 `nonebot_plugin_kuwo._qmc_rs`
11
+ - 保留 Python 包装层 `nonebot_plugin_kuwo/qmc.py`,维持原有 Python API 形状
12
+ - `decrypt_mflac_file` 现在由 Rust 原生代码执行,并在原生层释放 GIL
13
+ - `pyproject.toml` 切换为 `maturin` build backend,并增加开发依赖 `maturin`
14
+ - 更新 `.gitignore`,忽略 Rust 构建产物与本地扩展文件
15
+ - 新增 GitHub Actions 工作流,用于 CI 和跨平台 PyPI 发布
16
+
17
+ ## 0.1.3 - 2026-04-19
18
+
19
+ - 为 `/kw` 和 `/kwid` 增加 `-q/--quality` 选项
20
+ - `text` / `card` 输出模式接入音质参数
21
+ - 新增 `record` 输出模式
22
+ - `record` 模式强制使用 `standard` 音质
23
+ - 补充 `record` 模式相关命令测试和配置测试
24
+
25
+ ## 0.1.2 - 2026-04-19
26
+
27
+ - 为 `/kw` 和 `/kwid` 增加 OneBot V11 自定义音乐卡片输出
28
+ - 自定义音乐卡片使用音乐直链作为 `url` 与 `audio`
29
+ - 新增 `KUWO_TRACK_RENDER_MODE=text|card`
30
+ - 搜索列表渲染配置重命名为 `KUWO_LIST_RENDER_MODE=text|image`
31
+ - 增加 `KUWO_TRACK_RENDER_MODE=card` 时的 `kwsearch -> image` 默认联动
32
+
33
+ ## 0.1.1 - 2026-04-09
34
+
35
+ - 为 `kwsearch` 增加基于 `nonebot-plugin-htmlrender` 的图片列表渲染
36
+ - 搜索结果模型新增 `web_albumpic_short` 并支持直接拼接封面 URL
37
+ - 图片列表改为直接复用搜索接口封面信息
38
+ - 图片渲染失败时自动回退为文本模式
39
+ - 为 `kwsearch` 图片链路补充 `debug` / `info` 日志
40
+
41
+ ## 0.1.0 - 2026-04-08
42
+
43
+ - 使用 `uv` 初始化项目并补齐基础依赖
44
+ - 新增 `nonebot_plugin_kuwo` 插件骨架
45
+ - 实现 `kwsearch` / `kw搜索` 搜索命令
46
+ - 实现 `kw <关键词>` 首条歌曲直链命令
47
+ - 实现 `kwid <rid>` 详情与直链命令
48
+ - 新增搜索响应模型、异步数据源和文本渲染逻辑
49
+ - 新增音质到 `br` 的映射与运行时配置读取
50
+ - 增加并发获取封面与单曲信息的链路
51
+ - 按 NoneBot 官方发布规范补齐 `require("nonebot_plugin_alconna")` 与适配器继承元数据
52
+ - 增加基础单元测试和 nonebug 命令测试
@@ -0,0 +1,179 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
10
+
11
+ [[package]]
12
+ name = "base64"
13
+ version = "0.22.1"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
16
+
17
+ [[package]]
18
+ name = "heck"
19
+ version = "0.5.0"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
22
+
23
+ [[package]]
24
+ name = "indoc"
25
+ version = "2.0.7"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
28
+ dependencies = [
29
+ "rustversion",
30
+ ]
31
+
32
+ [[package]]
33
+ name = "libc"
34
+ version = "0.2.185"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
37
+
38
+ [[package]]
39
+ name = "memoffset"
40
+ version = "0.9.1"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
43
+ dependencies = [
44
+ "autocfg",
45
+ ]
46
+
47
+ [[package]]
48
+ name = "nonebot-plugin-kuwo-rust"
49
+ version = "0.2.0"
50
+ dependencies = [
51
+ "base64",
52
+ "pyo3",
53
+ ]
54
+
55
+ [[package]]
56
+ name = "once_cell"
57
+ version = "1.21.4"
58
+ source = "registry+https://github.com/rust-lang/crates.io-index"
59
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
60
+
61
+ [[package]]
62
+ name = "portable-atomic"
63
+ version = "1.13.1"
64
+ source = "registry+https://github.com/rust-lang/crates.io-index"
65
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
66
+
67
+ [[package]]
68
+ name = "proc-macro2"
69
+ version = "1.0.106"
70
+ source = "registry+https://github.com/rust-lang/crates.io-index"
71
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
72
+ dependencies = [
73
+ "unicode-ident",
74
+ ]
75
+
76
+ [[package]]
77
+ name = "pyo3"
78
+ version = "0.27.2"
79
+ source = "registry+https://github.com/rust-lang/crates.io-index"
80
+ checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d"
81
+ dependencies = [
82
+ "indoc",
83
+ "libc",
84
+ "memoffset",
85
+ "once_cell",
86
+ "portable-atomic",
87
+ "pyo3-build-config",
88
+ "pyo3-ffi",
89
+ "pyo3-macros",
90
+ "unindent",
91
+ ]
92
+
93
+ [[package]]
94
+ name = "pyo3-build-config"
95
+ version = "0.27.2"
96
+ source = "registry+https://github.com/rust-lang/crates.io-index"
97
+ checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6"
98
+ dependencies = [
99
+ "target-lexicon",
100
+ ]
101
+
102
+ [[package]]
103
+ name = "pyo3-ffi"
104
+ version = "0.27.2"
105
+ source = "registry+https://github.com/rust-lang/crates.io-index"
106
+ checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089"
107
+ dependencies = [
108
+ "libc",
109
+ "pyo3-build-config",
110
+ ]
111
+
112
+ [[package]]
113
+ name = "pyo3-macros"
114
+ version = "0.27.2"
115
+ source = "registry+https://github.com/rust-lang/crates.io-index"
116
+ checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02"
117
+ dependencies = [
118
+ "proc-macro2",
119
+ "pyo3-macros-backend",
120
+ "quote",
121
+ "syn",
122
+ ]
123
+
124
+ [[package]]
125
+ name = "pyo3-macros-backend"
126
+ version = "0.27.2"
127
+ source = "registry+https://github.com/rust-lang/crates.io-index"
128
+ checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9"
129
+ dependencies = [
130
+ "heck",
131
+ "proc-macro2",
132
+ "pyo3-build-config",
133
+ "quote",
134
+ "syn",
135
+ ]
136
+
137
+ [[package]]
138
+ name = "quote"
139
+ version = "1.0.45"
140
+ source = "registry+https://github.com/rust-lang/crates.io-index"
141
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
142
+ dependencies = [
143
+ "proc-macro2",
144
+ ]
145
+
146
+ [[package]]
147
+ name = "rustversion"
148
+ version = "1.0.22"
149
+ source = "registry+https://github.com/rust-lang/crates.io-index"
150
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
151
+
152
+ [[package]]
153
+ name = "syn"
154
+ version = "2.0.117"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
157
+ dependencies = [
158
+ "proc-macro2",
159
+ "quote",
160
+ "unicode-ident",
161
+ ]
162
+
163
+ [[package]]
164
+ name = "target-lexicon"
165
+ version = "0.13.5"
166
+ source = "registry+https://github.com/rust-lang/crates.io-index"
167
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
168
+
169
+ [[package]]
170
+ name = "unicode-ident"
171
+ version = "1.0.24"
172
+ source = "registry+https://github.com/rust-lang/crates.io-index"
173
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
174
+
175
+ [[package]]
176
+ name = "unindent"
177
+ version = "0.2.4"
178
+ source = "registry+https://github.com/rust-lang/crates.io-index"
179
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,14 @@
1
+ [package]
2
+ name = "nonebot-plugin-kuwo-rust"
3
+ version = "0.2.0"
4
+ edition = "2021"
5
+ publish = false
6
+ readme = "README.md"
7
+
8
+ [lib]
9
+ name = "_qmc_rs"
10
+ crate-type = ["cdylib"]
11
+
12
+ [dependencies]
13
+ base64 = "0.22.1"
14
+ pyo3 = { version = "0.27.1", features = ["extension-module", "abi3-py310"] }