feat: Add /kb-add command for quick video addition
- Add cmd_add() function to support adding single videos to inbox - Support BV IDs, full URLs, and short links (with friendly warning) - Add --process flag to immediately process after adding - Add --yes flag to skip confirmation prompts - Update SKILL.md with /kb-add command documentation
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
| 命令 | 描述 | 用法 |
|
||||
|------|------|------|
|
||||
| `/kb-add` | 添加单个视频 | `/kb-add <URL> [--process] [--yes]` |
|
||||
| `/kb-subscribe` | 订阅内容源 | `/kb-subscribe <source>:<type>:<id>` |
|
||||
| `/kb-inbox` | 查看收件箱 | `/kb-inbox [--limit N]` |
|
||||
| `/kb-process` | 处理内容 | `/kb-process [content_id]` |
|
||||
@@ -20,6 +21,43 @@
|
||||
|
||||
## 命令详解
|
||||
|
||||
### /kb-add
|
||||
|
||||
快速添加单个视频到收件箱。
|
||||
|
||||
**用法:**
|
||||
```
|
||||
/kb-add BV1xx411c7mD
|
||||
/kb-add "https://www.bilibili.com/video/BV1xx411c7mD"
|
||||
/kb-add "https://www.bilibili.com/video/BV1xx411c7mD" --process
|
||||
/kb-add BV1xx411c7mD --yes
|
||||
```
|
||||
|
||||
**参数:**
|
||||
- `<URL>` - 视频URL或BV号
|
||||
- 完整URL: `https://www.bilibili.com/video/BVxxxxx`
|
||||
- BV号: `BVxxxxx`
|
||||
- 短链接: `https://b23.tv/xxxxx`(显示友好提示)
|
||||
- `--process` - 添加后立即处理
|
||||
- `--yes` - 跳过确认提示
|
||||
|
||||
**输出示例:**
|
||||
```
|
||||
📥 正在添加视频: BV1xx411c7mD
|
||||
→ 标题: Python编程入门教程
|
||||
→ UP主: CodeMaster
|
||||
→ 时长: 3600秒
|
||||
→ 获取字幕... ✅
|
||||
|
||||
✅ 视频已添加到收件箱!
|
||||
Content ID: abc123def456
|
||||
|
||||
💡 使用以下命令处理:
|
||||
python3 src/cli.py process abc123def456
|
||||
或:
|
||||
python3 src/cli.py process all
|
||||
```
|
||||
|
||||
### /kb-subscribe
|
||||
|
||||
订阅一个内容源,支持自动获取更新。
|
||||
|
||||
@@ -18,6 +18,7 @@ try:
|
||||
from src.storage import Storage
|
||||
from src.pipeline import ProcessingPipeline
|
||||
from src.models import ContentStatus
|
||||
from src.sources.bilibili import BilibiliAdapter
|
||||
CONFIG_AVAILABLE = True
|
||||
except ImportError as e:
|
||||
print(f"Import warning: {e}", file=sys.stderr)
|
||||
@@ -102,6 +103,110 @@ def cmd_subscribe(args: argparse.Namespace):
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_add(args: argparse.Namespace):
|
||||
"""Handle add command - add a single video to inbox."""
|
||||
print_header("Add Video to Inbox")
|
||||
|
||||
if not CONFIG_AVAILABLE:
|
||||
print("Error: Required modules not available. Please check installation.")
|
||||
return 1
|
||||
|
||||
# Import here to avoid issues if not available
|
||||
from src.models import ContentStatus
|
||||
|
||||
url = args.url
|
||||
|
||||
# Handle short links (b23.tv)
|
||||
if 'b23.tv' in url:
|
||||
print(f" ⚠️ 检测到短链接: {url}")
|
||||
print(f" 💡 B站对短链接有反爬虫保护,请提供:")
|
||||
print(f" 1. 完整URL: https://www.bilibili.com/video/BVxxxxx")
|
||||
print(f" 2. 或BV号: BVxxxxx")
|
||||
print(f"\n 提示: 可以在浏览器打开短链接,从地址栏复制完整URL")
|
||||
return 1
|
||||
|
||||
# Create adapter
|
||||
adapter = BilibiliAdapter()
|
||||
|
||||
# Extract video metadata
|
||||
print(f" → 正在获取视频信息: {url}")
|
||||
content = adapter.extract_content(url)
|
||||
if not content:
|
||||
print(" ❌ 无法提取视频信息")
|
||||
return 1
|
||||
|
||||
print(f" → 标题: {content.title}")
|
||||
print(f" → UP主: {content.author}")
|
||||
print(f" → 时长: {content.duration}秒")
|
||||
|
||||
# Get transcript
|
||||
print(" → 正在获取字幕...")
|
||||
transcript = adapter.get_transcript(content)
|
||||
if transcript:
|
||||
content.transcript = transcript
|
||||
print(f" ✓ 字幕已获取 ({len(transcript)} 字符)")
|
||||
else:
|
||||
print(" ⚠️ 无法获取字幕")
|
||||
|
||||
# Set status to CONFIRMED (ready to process)
|
||||
content.status = ContentStatus.CONFIRMED
|
||||
|
||||
# Confirm before saving (unless --yes)
|
||||
if not args.yes:
|
||||
print(f"\n📋 准备添加到收件箱:")
|
||||
print(f" 标题: {content.title}")
|
||||
print(f" UP主: {content.author}")
|
||||
print(f" 时长: {content.duration}秒")
|
||||
print(f" 字幕: {'有' if transcript else '无'}")
|
||||
|
||||
if args.process:
|
||||
print(f" 操作: 添加并立即处理")
|
||||
else:
|
||||
print(f" 操作: 仅添加到收件箱")
|
||||
|
||||
confirm = input("\n确认添加? [Y/n]: ").strip().lower()
|
||||
if confirm and confirm not in ('y', 'yes'):
|
||||
print("❌ 已取消")
|
||||
return 0
|
||||
|
||||
# Save to inbox
|
||||
print("\n → 保存到收件箱...")
|
||||
storage = Storage()
|
||||
storage.save_content(content)
|
||||
|
||||
print(f"\n✅ 视频已添加到收件箱!")
|
||||
print(f" Content ID: {content.id}")
|
||||
|
||||
# Process immediately if --process flag is set
|
||||
if args.process:
|
||||
print(f"\n🔄 开始处理内容...")
|
||||
try:
|
||||
from src.pipeline import ProcessingPipeline
|
||||
from src.models import ContentStatus
|
||||
|
||||
pipeline = ProcessingPipeline()
|
||||
content_text = content.transcript or content.summary or ""
|
||||
|
||||
result = pipeline.process_full(content, content_text)
|
||||
storage.save_content(result)
|
||||
|
||||
print(f" ✅ 处理完成")
|
||||
print(f" 📄 笔记: {result.output_path or 'N/A'}")
|
||||
print(f" 🏷️ 标签: {', '.join(result.tags)}")
|
||||
except Exception as e:
|
||||
print(f" ❌ 处理失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return 1
|
||||
else:
|
||||
print(f"\n💡 使用以下命令处理:")
|
||||
print(f" python3 src/cli.py process {content.id}")
|
||||
print(f" 或:")
|
||||
print(f" python3 src/cli.py process all")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_inbox(args: argparse.Namespace):
|
||||
"""Handle inbox command - display pending items."""
|
||||
print_header("Inbox Contents")
|
||||
@@ -427,6 +532,9 @@ def main():
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
%(prog)s add "BV1xx411c7mD"
|
||||
%(prog)s add "https://www.bilibili.com/video/BV1xx411c7mD" --process
|
||||
%(prog)s add "https://b23.tv/xxxxx" --yes
|
||||
%(prog)s subscribe bilibili fav 12345 --name="Tech Favorites"
|
||||
%(prog)s inbox --limit 10 --sort date
|
||||
%(prog)s process all --yes
|
||||
@@ -439,6 +547,28 @@ Examples:
|
||||
|
||||
subparsers = parser.add_subparsers(dest='command', help='Available commands')
|
||||
|
||||
# add 子命令
|
||||
add_parser = subparsers.add_parser(
|
||||
'add',
|
||||
aliases=['a'],
|
||||
help='Add a single video to inbox'
|
||||
)
|
||||
add_parser.add_argument(
|
||||
'url',
|
||||
help='Video URL or BV ID (supports: BVxxxxx, full URL)'
|
||||
)
|
||||
add_parser.add_argument(
|
||||
'--process',
|
||||
action='store_true',
|
||||
help='Process immediately after adding'
|
||||
)
|
||||
add_parser.add_argument(
|
||||
'--yes',
|
||||
action='store_true',
|
||||
help='Skip confirmation prompts'
|
||||
)
|
||||
add_parser.set_defaults(func=cmd_add)
|
||||
|
||||
# subscribe 子命令
|
||||
subscribe_parser = subparsers.add_parser(
|
||||
'subscribe',
|
||||
|
||||
Reference in New Issue
Block a user