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-subscribe` | 订阅内容源 | `/kb-subscribe <source>:<type>:<id>` |
|
||||||
| `/kb-inbox` | 查看收件箱 | `/kb-inbox [--limit N]` |
|
| `/kb-inbox` | 查看收件箱 | `/kb-inbox [--limit N]` |
|
||||||
| `/kb-process` | 处理内容 | `/kb-process [content_id]` |
|
| `/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
|
### /kb-subscribe
|
||||||
|
|
||||||
订阅一个内容源,支持自动获取更新。
|
订阅一个内容源,支持自动获取更新。
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ try:
|
|||||||
from src.storage import Storage
|
from src.storage import Storage
|
||||||
from src.pipeline import ProcessingPipeline
|
from src.pipeline import ProcessingPipeline
|
||||||
from src.models import ContentStatus
|
from src.models import ContentStatus
|
||||||
|
from src.sources.bilibili import BilibiliAdapter
|
||||||
CONFIG_AVAILABLE = True
|
CONFIG_AVAILABLE = True
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print(f"Import warning: {e}", file=sys.stderr)
|
print(f"Import warning: {e}", file=sys.stderr)
|
||||||
@@ -102,6 +103,110 @@ def cmd_subscribe(args: argparse.Namespace):
|
|||||||
return 0
|
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):
|
def cmd_inbox(args: argparse.Namespace):
|
||||||
"""Handle inbox command - display pending items."""
|
"""Handle inbox command - display pending items."""
|
||||||
print_header("Inbox Contents")
|
print_header("Inbox Contents")
|
||||||
@@ -427,6 +532,9 @@ def main():
|
|||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
epilog="""
|
epilog="""
|
||||||
Examples:
|
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 subscribe bilibili fav 12345 --name="Tech Favorites"
|
||||||
%(prog)s inbox --limit 10 --sort date
|
%(prog)s inbox --limit 10 --sort date
|
||||||
%(prog)s process all --yes
|
%(prog)s process all --yes
|
||||||
@@ -439,6 +547,28 @@ Examples:
|
|||||||
|
|
||||||
subparsers = parser.add_subparsers(dest='command', help='Available commands')
|
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 子命令
|
||||||
subscribe_parser = subparsers.add_parser(
|
subscribe_parser = subparsers.add_parser(
|
||||||
'subscribe',
|
'subscribe',
|
||||||
|
|||||||
Reference in New Issue
Block a user