bilinote-cli 0.1.2__tar.gz → 0.1.3__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.
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/.gitignore +1 -0
- bilinote_cli-0.1.3/CHANGELOG.md +15 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/PKG-INFO +8 -5
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/README.md +7 -4
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/pyproject.toml +1 -1
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/cli.py +98 -57
- bilinote_cli-0.1.2/CHANGELOG.md +0 -8
- bilinote_cli-0.1.2/CHANGELOG.md.tmp +0 -0
- bilinote_cli-0.1.2/publish.command +0 -72
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/.github/ISSUE_TEMPLATE//346/226/260/345/242/236/345/212/237/350/203/275/345/273/272/350/256/256.md" +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/.github/workflows/docker-build.yml +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/.github/workflows/main.yml +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/BiliNote.shortcut +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/CLAUDE.md +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/LICENSE +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/README.en.md +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/dev-docs//345/216/206/345/217/262/350/256/260/345/275/225/345/222/214/351/207/215/350/257/225/346/234/215/345/212/241/350/256/276/350/256/241.md" +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/dev-docs//345/217/221/345/270/203/345/210/260 githubTODO.md" +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/dev-docs//345/221/275/345/220/215/346/226/271/345/274/217.md" +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/config_manager.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/decorators/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/decorators/timeit.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/base.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/bilibili_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/common.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/douyin_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/douyin_helper/abogus.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/kuaishou_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/kuaishou_helper/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/kuaishou_helper/kuaishou.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/local_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/xiaoyuzhoufm_download.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/youtube_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/downloaders/youtube_subtitle.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/enmus/exception.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/enmus/note_enums.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/enmus/task_status_enums.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/exceptions/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/exceptions/biz_exception.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/exceptions/note.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/exceptions/provider.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/base.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/gpt_factory.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/prompt.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/prompt_builder.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/provider/OpenAI_compatible_provider.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/request_chunker.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/universal_gpt.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/utils.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/audio_model.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/gpt_model.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/model_config.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/notes_model.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/pipeline_model.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/process_config.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/provide_model.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/transcriber_model.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/models/video_record.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/secret_manager.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/batch_processor.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/cache/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/cache/task_cache.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/constant.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/note.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/pipeline/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/pipeline/ai_processor.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/pipeline/preparer.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/postprocessing.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/searcher.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/services/serial_executor.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/transcriber/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/transcriber/base.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/transcriber/bcut.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/transcriber/groq.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/transcriber/kuaishou.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/transcriber/transcriber_provider.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/transcriber/whisper_cpp.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/cookie_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/env_checker.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/file_cleanup.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/logger.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/note_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/path_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/screenshot_marker.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/status_code.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/url_parser.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/video_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/utils/video_reader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/validators/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/validators/video_url_validator.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/config/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/config/config.yaml.example +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/config/dev_config.json +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/config/model_config_manager.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/config/models.json +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/config/transcriber.json +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/ffmpeg_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/__init__.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/conftest.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/integration/test_transcriber_integration.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/downloaders/test_bilibili_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/downloaders/test_cookie_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/downloaders/test_douyin_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/downloaders/test_kuaishou_downloader.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/gpt/test_request_chunker.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/gpt/test_universal_gpt_checkpoint.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/services/test_searcher.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/services/test_task_serial_executor.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/transcriber/test_transcriber_fallback.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/utils/test_note_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/utils/test_path_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/utils/test_screenshot_marker.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/utils/test_url_parser.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/utils/test_video_helper.py +0 -0
- {bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/utils/test_video_reader_dedupe.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## [0.1.3] - 2026-05-19
|
|
5
|
+
### Changed
|
|
6
|
+
- search 指令改为输出 json 文件,由 process 指令对 json 文件中的视频链接进行批量处理。
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## [0.1.2] - 2026-05-17
|
|
10
|
+
### Changed
|
|
11
|
+
- search 指令后的批量记笔记功能,支持并行处理
|
|
12
|
+
|
|
13
|
+
## [0.1.1] - 2026-05-15
|
|
14
|
+
### Added
|
|
15
|
+
- 首次发布至 PyPI
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bilinote-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: AI 视频笔记生成 CLI 工具
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -87,10 +87,11 @@ bilinote process "<url>" --screenshot --link --style 学术风
|
|
|
87
87
|
bilinote process "<url>" --video-understanding --model gpt-4o
|
|
88
88
|
|
|
89
89
|
# 自定义输出目录
|
|
90
|
-
bilinote process "<url>" --output-dir
|
|
90
|
+
bilinote process "<url>" --output-dir <dir>
|
|
91
91
|
|
|
92
|
-
#
|
|
93
|
-
bilinote search "Python 教程" --platform bilibili
|
|
92
|
+
# 搜索视频(结果保存为 json)
|
|
93
|
+
bilinote search "Python 教程" --platform bilibili --output-dir <dir>
|
|
94
|
+
bilinote process --json "<search_result.json>" --index 2 3 8
|
|
94
95
|
|
|
95
96
|
# 其他命令
|
|
96
97
|
bilinote model-list # 列出可用模型
|
|
@@ -117,7 +118,7 @@ bilinote install-shortcut # 安装 macOS 快捷指令(推荐)
|
|
|
117
118
|
| 命令 | 说明 |
|
|
118
119
|
|------|------|
|
|
119
120
|
| `process <url>` | 处理视频生成笔记 |
|
|
120
|
-
| `search <keyword>` |
|
|
121
|
+
| `search <keyword>` | 并保存结果为 JSON |
|
|
121
122
|
| `model-list` | 列出可用模型 |
|
|
122
123
|
| `model-set-default <model>` | 设置默认模型 |
|
|
123
124
|
| `config set <key> <value>` | 设置密钥 |
|
|
@@ -136,6 +137,8 @@ bilinote install-shortcut # 安装 macOS 快捷指令(推荐)
|
|
|
136
137
|
| `--style` | 笔记风格:学术风、口语风等 |
|
|
137
138
|
| `--video-understanding` | 启用多模态理解 |
|
|
138
139
|
| `--output-dir` | 输出目录路径 |
|
|
140
|
+
| `--json` | 处理 json 文件的路径 |
|
|
141
|
+
| `--index` | 处理 json 文件中的链接序号 |
|
|
139
142
|
|
|
140
143
|
## 【指南】提取 Safari Cookie
|
|
141
144
|
|
|
@@ -66,10 +66,11 @@ bilinote process "<url>" --screenshot --link --style 学术风
|
|
|
66
66
|
bilinote process "<url>" --video-understanding --model gpt-4o
|
|
67
67
|
|
|
68
68
|
# 自定义输出目录
|
|
69
|
-
bilinote process "<url>" --output-dir
|
|
69
|
+
bilinote process "<url>" --output-dir <dir>
|
|
70
70
|
|
|
71
|
-
#
|
|
72
|
-
bilinote search "Python 教程" --platform bilibili
|
|
71
|
+
# 搜索视频(结果保存为 json)
|
|
72
|
+
bilinote search "Python 教程" --platform bilibili --output-dir <dir>
|
|
73
|
+
bilinote process --json "<search_result.json>" --index 2 3 8
|
|
73
74
|
|
|
74
75
|
# 其他命令
|
|
75
76
|
bilinote model-list # 列出可用模型
|
|
@@ -96,7 +97,7 @@ bilinote install-shortcut # 安装 macOS 快捷指令(推荐)
|
|
|
96
97
|
| 命令 | 说明 |
|
|
97
98
|
|------|------|
|
|
98
99
|
| `process <url>` | 处理视频生成笔记 |
|
|
99
|
-
| `search <keyword>` |
|
|
100
|
+
| `search <keyword>` | 并保存结果为 JSON |
|
|
100
101
|
| `model-list` | 列出可用模型 |
|
|
101
102
|
| `model-set-default <model>` | 设置默认模型 |
|
|
102
103
|
| `config set <key> <value>` | 设置密钥 |
|
|
@@ -115,6 +116,8 @@ bilinote install-shortcut # 安装 macOS 快捷指令(推荐)
|
|
|
115
116
|
| `--style` | 笔记风格:学术风、口语风等 |
|
|
116
117
|
| `--video-understanding` | 启用多模态理解 |
|
|
117
118
|
| `--output-dir` | 输出目录路径 |
|
|
119
|
+
| `--json` | 处理 json 文件的路径 |
|
|
120
|
+
| `--index` | 处理 json 文件中的链接序号 |
|
|
118
121
|
|
|
119
122
|
## 【指南】提取 Safari Cookie
|
|
120
123
|
|
|
@@ -5,6 +5,7 @@ import argparse
|
|
|
5
5
|
import sys
|
|
6
6
|
import os
|
|
7
7
|
import json
|
|
8
|
+
import re
|
|
8
9
|
import subprocess
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
|
|
@@ -109,9 +110,15 @@ def main():
|
|
|
109
110
|
# 处理本地视频
|
|
110
111
|
python cli.py process ./video.mp4
|
|
111
112
|
|
|
112
|
-
#
|
|
113
|
+
# 搜索视频并保存结果
|
|
113
114
|
python cli.py search "关键词" --platform bilibili
|
|
114
115
|
|
|
116
|
+
# 从搜索结果处理全部视频
|
|
117
|
+
python cli.py process --json ~/.bilinote/output/search_result/xxx.json
|
|
118
|
+
|
|
119
|
+
# 从搜索结果选择指定序号处理
|
|
120
|
+
python cli.py process --json ~/.bilinote/output/search_result/xxx.json --index 1 2 3
|
|
121
|
+
|
|
115
122
|
# 查看任务状态
|
|
116
123
|
python cli.py status <task_id>
|
|
117
124
|
|
|
@@ -140,9 +147,14 @@ def main():
|
|
|
140
147
|
subparsers = parser.add_subparsers(dest='command', help='可用命令')
|
|
141
148
|
|
|
142
149
|
# process 子命令 - 处理视频生成笔记
|
|
143
|
-
process_parser = subparsers.add_parser('process', help='处理视频生成笔记(支持批量 URL)',
|
|
150
|
+
process_parser = subparsers.add_parser('process', help='处理视频生成笔记(支持批量 URL 或 JSON)',
|
|
144
151
|
parents=[_SHARED_ARGS_PARSER])
|
|
145
|
-
process_parser.add_argument('video_urls', nargs='
|
|
152
|
+
process_parser.add_argument('video_urls', nargs='*', default=[],
|
|
153
|
+
help='视频链接或本地文件路径(可多个,与 --json 二选一)')
|
|
154
|
+
process_parser.add_argument('--json', dest='json_path', default=None,
|
|
155
|
+
help='从 search 结果 JSON 文件读取链接')
|
|
156
|
+
process_parser.add_argument('--index', nargs='+', type=int, default=None,
|
|
157
|
+
help='指定 JSON 中要处理的视频序号(如 --index 1 2 3)')
|
|
146
158
|
process_parser.add_argument('--platform',
|
|
147
159
|
choices=['bilibili', 'youtube', 'douyin', 'kuaishou', 'local'],
|
|
148
160
|
help='视频平台(可选,默认自动识别)')
|
|
@@ -150,14 +162,13 @@ def main():
|
|
|
150
162
|
process_parser.add_argument('--output-dir', default=None, help='批量输出目录(多任务时自动创建批次目录)')
|
|
151
163
|
|
|
152
164
|
# search 子命令 - 搜索视频
|
|
153
|
-
search_parser = subparsers.add_parser('search', help='
|
|
154
|
-
parents=[_SHARED_ARGS_PARSER])
|
|
165
|
+
search_parser = subparsers.add_parser('search', help='搜索视频并保存结果为 JSON')
|
|
155
166
|
search_parser.add_argument('keyword', help='搜索关键词')
|
|
156
167
|
search_parser.add_argument('--platform', default='bilibili',
|
|
157
168
|
choices=['bilibili', 'youtube'],
|
|
158
169
|
help='搜索平台(默认 bilibili)')
|
|
159
|
-
search_parser.add_argument('--
|
|
160
|
-
|
|
170
|
+
search_parser.add_argument('--output-dir', default=None,
|
|
171
|
+
help='搜索结果保存目录(默认 ~/.bilinote/output/search_result)')
|
|
161
172
|
|
|
162
173
|
# status 子命令 - 查询任务状态
|
|
163
174
|
status_parser = subparsers.add_parser('status', help='查询任务状态')
|
|
@@ -264,25 +275,33 @@ def main():
|
|
|
264
275
|
|
|
265
276
|
|
|
266
277
|
def process_video_cli(args):
|
|
267
|
-
"""
|
|
278
|
+
"""处理视频生成笔记(支持批量 URL 或 JSON)"""
|
|
268
279
|
video_urls = args.video_urls
|
|
269
|
-
|
|
270
|
-
|
|
280
|
+
json_path = args.json_path
|
|
281
|
+
|
|
282
|
+
if not video_urls and not json_path:
|
|
283
|
+
print('错误: 请提供视频链接或使用 --json 指定搜索结果文件')
|
|
284
|
+
sys.exit(1)
|
|
285
|
+
|
|
286
|
+
if json_path and video_urls:
|
|
287
|
+
print('错误: 视频链接和 --json 不可同时使用')
|
|
288
|
+
sys.exit(1)
|
|
289
|
+
|
|
290
|
+
if json_path:
|
|
291
|
+
video_urls = _load_urls_from_json(json_path, args.index)
|
|
292
|
+
|
|
271
293
|
model_name = args.model
|
|
272
294
|
if not model_name:
|
|
273
295
|
model_name = get_default_model()
|
|
274
296
|
if not model_name:
|
|
275
297
|
print('错误: 未配置默认模型,请使用 --model 指定模型或 model-set-default 设置默认模型')
|
|
276
298
|
sys.exit(1)
|
|
277
|
-
|
|
278
|
-
# 静态预检:API Key 是否存在
|
|
299
|
+
|
|
279
300
|
if not _check_model_api_key(model_name):
|
|
280
301
|
sys.exit(1)
|
|
281
|
-
|
|
282
|
-
# 一键从 argparse namespace 生成 ProcessConfig(quality、format 等自动处理)
|
|
302
|
+
|
|
283
303
|
cfg = ProcessConfig(**vars(args))
|
|
284
|
-
|
|
285
|
-
# 构建任务列表
|
|
304
|
+
|
|
286
305
|
items = []
|
|
287
306
|
for url in video_urls:
|
|
288
307
|
platform = args.platform or detect_platform(url)
|
|
@@ -291,11 +310,45 @@ def process_video_cli(args):
|
|
|
291
310
|
continue
|
|
292
311
|
task_id = extract_video_id(url, platform)
|
|
293
312
|
items.append((url, platform, task_id, task_id))
|
|
294
|
-
|
|
313
|
+
|
|
295
314
|
_process_tasks(items, cfg, model_name, args.output_dir)
|
|
296
315
|
_show_shortcut_process_prompt()
|
|
297
316
|
|
|
298
317
|
|
|
318
|
+
def _load_urls_from_json(json_path: str, indices: list[int] | None = None) -> list[str]:
|
|
319
|
+
"""从 search 结果 JSON 中读取链接列表"""
|
|
320
|
+
if not os.path.exists(json_path):
|
|
321
|
+
print(f"错误: 文件不存在: {json_path}")
|
|
322
|
+
sys.exit(1)
|
|
323
|
+
|
|
324
|
+
try:
|
|
325
|
+
with open(json_path, 'r', encoding='utf-8') as f:
|
|
326
|
+
data = json.load(f)
|
|
327
|
+
except json.JSONDecodeError as e:
|
|
328
|
+
print(f"错误: JSON 解析失败: {e}")
|
|
329
|
+
sys.exit(1)
|
|
330
|
+
|
|
331
|
+
results = data.get("results", [])
|
|
332
|
+
if not results:
|
|
333
|
+
print("错误: JSON 中无搜索结果")
|
|
334
|
+
sys.exit(1)
|
|
335
|
+
|
|
336
|
+
if indices:
|
|
337
|
+
index_set = set(indices)
|
|
338
|
+
selected = [r for r in results if r.get("index") in index_set]
|
|
339
|
+
not_found = index_set - {r.get("index") for r in results}
|
|
340
|
+
if not_found:
|
|
341
|
+
print(f"警告: 序号 {sorted(not_found)} 不在搜索结果中")
|
|
342
|
+
if not selected:
|
|
343
|
+
print("错误: 指定的序号无匹配结果")
|
|
344
|
+
sys.exit(1)
|
|
345
|
+
print(f"从 JSON 选择了 {len(selected)} 个视频(共 {len(results)} 条结果)")
|
|
346
|
+
return [r["link"] for r in selected]
|
|
347
|
+
|
|
348
|
+
print(f"从 JSON 加载全部 {len(results)} 个视频链接")
|
|
349
|
+
return [r["link"] for r in results]
|
|
350
|
+
|
|
351
|
+
|
|
299
352
|
def _process_tasks(items: list, cfg: ProcessConfig, model_name: str, output_dir: str | None = None, batch_name: str | None = None):
|
|
300
353
|
"""统一任务处理入口
|
|
301
354
|
|
|
@@ -426,8 +479,9 @@ def _format_duration(seconds):
|
|
|
426
479
|
|
|
427
480
|
|
|
428
481
|
def search_videos_cli(args):
|
|
429
|
-
"""
|
|
482
|
+
"""搜索视频并保存结果为 JSON"""
|
|
430
483
|
from app.services.searcher import search as searcher
|
|
484
|
+
from datetime import datetime
|
|
431
485
|
|
|
432
486
|
platform = args.platform or "bilibili"
|
|
433
487
|
keyword = args.keyword
|
|
@@ -435,13 +489,11 @@ def search_videos_cli(args):
|
|
|
435
489
|
print(f"搜索: {keyword} 平台: {platform}")
|
|
436
490
|
print("-" * 60)
|
|
437
491
|
|
|
438
|
-
# 1. 搜索
|
|
439
492
|
items = searcher(keyword, platform=platform)
|
|
440
493
|
if not items:
|
|
441
494
|
print("未找到相关视频")
|
|
442
495
|
return
|
|
443
496
|
|
|
444
|
-
# 2. 展示结果
|
|
445
497
|
print(f"搜索到 {len(items)} 条结果:\n")
|
|
446
498
|
for i, item in enumerate(items, 1):
|
|
447
499
|
parts = [f"{i}. {item['title']}"]
|
|
@@ -458,46 +510,35 @@ def search_videos_cli(args):
|
|
|
458
510
|
parts.append(" ".join(stats))
|
|
459
511
|
print(" ".join(parts))
|
|
460
512
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
return
|
|
513
|
+
search_result = {
|
|
514
|
+
"meta": {
|
|
515
|
+
"keyword": keyword,
|
|
516
|
+
"platform": platform,
|
|
517
|
+
"searched_at": datetime.now().isoformat(timespec="seconds"),
|
|
518
|
+
},
|
|
519
|
+
"results": [
|
|
520
|
+
{"index": i + 1, **item}
|
|
521
|
+
for i, item in enumerate(items)
|
|
522
|
+
],
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
output_dir = args.output_dir or os.path.join(
|
|
526
|
+
os.path.expanduser("~"), ".bilinote", "output", "search_result"
|
|
527
|
+
)
|
|
528
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
478
529
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
return
|
|
530
|
+
timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
|
|
531
|
+
safe_keyword = re.sub(r'[^\w\s\u4e00-\u9fff]', '', keyword).strip().replace(' ', '_')[:30]
|
|
532
|
+
filename = f"{timestamp}_{safe_keyword}.json"
|
|
533
|
+
json_path = os.path.join(output_dir, filename)
|
|
484
534
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
return
|
|
535
|
+
with open(json_path, 'w', encoding='utf-8') as f:
|
|
536
|
+
json.dump(search_result, f, ensure_ascii=False, indent=2)
|
|
488
537
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
for item in selected:
|
|
494
|
-
url = item['link']
|
|
495
|
-
detected_platform = detect_platform(url) or platform
|
|
496
|
-
task_id = extract_video_id(url, detected_platform)
|
|
497
|
-
title = item.get('title', task_id)
|
|
498
|
-
task_items.append((url, detected_platform, task_id, title))
|
|
499
|
-
|
|
500
|
-
_process_tasks(task_items, cfg, model_name, args.output_dir, batch_name=keyword)
|
|
538
|
+
print(f"\n搜索结果已保存至: {json_path}")
|
|
539
|
+
print(f"\n使用 process 命令处理搜索结果:")
|
|
540
|
+
print(f" bilinote process --json \"{json_path}\"")
|
|
541
|
+
print(f" bilinote process --json \"{json_path}\" --index 1 2 3")
|
|
501
542
|
|
|
502
543
|
|
|
503
544
|
def list_models():
|
bilinote_cli-0.1.2/CHANGELOG.md
DELETED
|
File without changes
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
set -e
|
|
2
|
-
|
|
3
|
-
# ---------- 用户配置 ----------
|
|
4
|
-
VERSION="0.1.2"
|
|
5
|
-
|
|
6
|
-
# CHANGELOG 分类包括:Added Changed Removed Fixed Security
|
|
7
|
-
|
|
8
|
-
CHANGELOG="### Changed
|
|
9
|
-
- search 指令后的批量记笔记功能,支持并行处理
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
cd "$(dirname "$0")"
|
|
13
|
-
|
|
14
|
-
# 检查 CHANGELOG 和版本是否已存在
|
|
15
|
-
if [ -f CHANGELOG.md ]; then
|
|
16
|
-
if grep -q "^## \[${VERSION}\]" CHANGELOG.md; then
|
|
17
|
-
echo "版本已存在,跳过"
|
|
18
|
-
exit 0
|
|
19
|
-
fi
|
|
20
|
-
else
|
|
21
|
-
echo "# Changelog" > CHANGELOG.md
|
|
22
|
-
fi
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# ---------- 自动修改 pyproject.toml ----------
|
|
26
|
-
if [ ! -f pyproject.toml ]; then
|
|
27
|
-
echo "错误:当前目录没有 pyproject.toml"
|
|
28
|
-
exit 1
|
|
29
|
-
fi
|
|
30
|
-
|
|
31
|
-
# 替换 version 字段
|
|
32
|
-
grep -q "^version" pyproject.toml || { echo "Error: 'version' line not found in pyproject.toml" >&2; exit 1; }
|
|
33
|
-
sed -i.bak -E "s/^version.*/version = \"${VERSION}\"/" pyproject.toml
|
|
34
|
-
|
|
35
|
-
rm -f pyproject.toml.bak # 删除备份文件
|
|
36
|
-
|
|
37
|
-
echo "✓ pyproject.toml 版本号已更新为 ${VERSION}"
|
|
38
|
-
|
|
39
|
-
# ---------- 自动更新 CHANGELOG.md ----------
|
|
40
|
-
DATE=$(date +%Y-%m-%d)
|
|
41
|
-
NEW_ENTRY="## [${VERSION}] - ${DATE}"$'\n'"${CHANGELOG}"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# 使用 awk 在第一个 "## [数字" 行之前插入新条目(前后空行)
|
|
45
|
-
awk -v new_entry="$NEW_ENTRY" '
|
|
46
|
-
BEGIN { inserted = 0 }
|
|
47
|
-
/^## \[[0-9]/ && !inserted {
|
|
48
|
-
# 在匹配行之前先打印新条目(前后加空行)
|
|
49
|
-
print ""
|
|
50
|
-
print new_entry
|
|
51
|
-
print ""
|
|
52
|
-
inserted = 1
|
|
53
|
-
}
|
|
54
|
-
{ print }
|
|
55
|
-
END {
|
|
56
|
-
# 如果没有匹配到任何版本标题,则在末尾追加新条目
|
|
57
|
-
if (!inserted) {
|
|
58
|
-
print ""
|
|
59
|
-
print new_entry
|
|
60
|
-
print ""
|
|
61
|
-
}
|
|
62
|
-
}' CHANGELOG.md > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
echo "✓ CHANGELOG.md 已添加 ${VERSION} 版本的更新记录"
|
|
66
|
-
|
|
67
|
-
# ---------- 原有发布流程 ----------
|
|
68
|
-
rm -rf dist/
|
|
69
|
-
uv build
|
|
70
|
-
ls dist/
|
|
71
|
-
export UV_PUBLISH_TOKEN="pypi-AgEIcHlwaS5vcmcCJGM1M2U5NThjLWQ4NTctNDBlNy04NDFhLTUzMTM4NTk0OTU2NwACFFsxLFsiYmlsaW5vdGUtY2xpIl1dAAIsWzIsWyJmN2Y4MzczOC1lMzlkLTQyOTgtODMyMS1mMTkxM2JhMDQxZDYiXV0AAAYg4oFE7cnbCFM5fV6HOB10sNzaBk84MYhbnZ6MWaT7Cu8"
|
|
72
|
-
uv publish
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/src/app/gpt/provider/OpenAI_compatible_provider.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/downloaders/test_bilibili_downloader.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/downloaders/test_kuaishou_downloader.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bilinote_cli-0.1.2 → bilinote_cli-0.1.3}/tests/unit/transcriber/test_transcriber_fallback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|