7a1ad6088a
- 更新 SKILL.md:添加 frontmatter 元数据和自动触发规则说明 - 创建 handler.py:实现链接检测和预览生成 - 支持多种 URL 模式:B站(完整/BV号/短链接)、YouTube、知乎 - 智能去重避免重复显示 - 短链接显示友好提示 - 支持批量检测多个链接 - 添加 AUTO_TRIGGER.md 实现文档 - 更新任务文件:标记任务1已完成 测试通过: ✅ B站完整 URL、BV号、短链接 ✅ YouTube 视频 ✅ 知乎文章 ✅ 批量检测和去重
112 lines
3.1 KiB
Python
112 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""手动添加B站视频到obsidian-kb收件箱"""
|
|
|
|
import sys
|
|
import os
|
|
import urllib.request
|
|
from urllib.request import Request, urlopen
|
|
|
|
# 添加路径以便导入模块
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'src'))
|
|
|
|
from sources.bilibili import BilibiliAdapter
|
|
from models import Content, ContentStatus
|
|
from storage import Storage
|
|
|
|
def resolve_short_url(url: str) -> str:
|
|
"""
|
|
解析短链接(如 b23.tv)到完整URL,或接受BV号
|
|
|
|
Args:
|
|
url: 可能是短链接的URL、完整URL或BV号
|
|
|
|
Returns:
|
|
str: 完整URL或BV号
|
|
"""
|
|
# 如果已经是完整URL,直接返回
|
|
if 'bilibili.com/video/' in url:
|
|
return url
|
|
|
|
# 如果是BV号,直接返回(bilibili.py 的 extract_content 会处理)
|
|
if url.upper().startswith('BV'):
|
|
return url
|
|
|
|
# 如果是短链接,尝试解析
|
|
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 None
|
|
|
|
# 默认返回原URL
|
|
return url
|
|
|
|
def add_video_to_inbox(url: str) -> str:
|
|
"""
|
|
添加B站视频到收件箱
|
|
|
|
Args:
|
|
url: B站视频URL
|
|
|
|
Returns:
|
|
str: Content ID
|
|
"""
|
|
print(f"📥 正在处理视频: {url}")
|
|
|
|
# 解析短链接
|
|
resolved_url = resolve_short_url(url)
|
|
if resolved_url is None:
|
|
return None
|
|
|
|
# 创建适配器
|
|
adapter = BilibiliAdapter()
|
|
|
|
# 提取视频元数据
|
|
print(" → 获取视频信息...")
|
|
content = adapter.extract_content(resolved_url)
|
|
if not content:
|
|
print(" ❌ 无法提取视频信息")
|
|
return None
|
|
|
|
print(f" → 标题: {content.title}")
|
|
print(f" → UP主: {content.author}")
|
|
print(f" → 时长: {content.duration}秒")
|
|
|
|
# 获取字幕
|
|
print(" → 获取字幕...")
|
|
transcript = adapter.get_transcript(content)
|
|
if transcript:
|
|
content.transcript = transcript
|
|
print(f" ✓ 字幕已获取 ({len(transcript)} 字符)")
|
|
else:
|
|
print(" ⚠️ 无法获取字幕")
|
|
|
|
# 设置状态为已确认(准备处理)
|
|
content.status = ContentStatus.CONFIRMED
|
|
|
|
# 保存到收件箱
|
|
print(" → 保存到收件箱...")
|
|
storage = Storage()
|
|
storage.save_content(content)
|
|
|
|
print(f"\n✅ 视频已添加到收件箱!")
|
|
print(f" Content ID: {content.id}")
|
|
print(f"\n💡 使用以下命令处理:")
|
|
print(f" python3 src/cli.py process {content.id}")
|
|
print(f" 或者:")
|
|
print(f" python3 src/cli.py process all")
|
|
|
|
return content.id
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) < 2:
|
|
print("用法: python3 add_video.py <B站视频URL>")
|
|
print("示例: python3 add_video.py https://b23.tv/oLBZZfK")
|
|
sys.exit(1)
|
|
|
|
url = sys.argv[1]
|
|
add_video_to_inbox(url)
|