This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
openclaw-skills/skills/obsidian-kb/test_degraded_pipeline.py
T
OpenClaw Agent 08f7c9f26c feat: integrate bilibili-extractor into obsidian-kb
- Add extractors layer with BilibiliExtractor (Playwright stealth mode)
- Add outputs layer with ObsidianWriter and GitSync
- Implement subtitle/no-subtitle graceful degradation
- Update config with output and bilibili extraction settings
- Complete integration pipeline: extract → process → output → sync
- Add comprehensive tests (100% pass rate)
- Update documentation (SKILL.md, README.md, requirements.txt)
2026-02-07 13:07:43 +08:00

237 lines
7.1 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Obsidian KB - 降级流程测试脚本
测试无字幕视频的处理:优雅降级,生成基础元数据笔记
"""
import os
import sys
import tempfile
import shutil
from pathlib import Path
# 添加项目路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from main_pipeline import MainPipeline
def create_test_config():
"""创建测试配置"""
temp_dir = tempfile.mkdtemp(prefix='obsidian_kb_degraded_')
vault_path = Path(temp_dir) / 'vault'
vault_path.mkdir(parents=True, exist_ok=True)
storage_dir = Path(temp_dir) / 'storage'
storage_dir.mkdir(parents=True, exist_ok=True)
print(f"📁 测试目录: {temp_dir}")
print(f"📁 测试Vault: {vault_path}")
test_config_dict = {
'ai': {
'provider': 'openai',
'model': 'gpt-4',
'api_key': None,
},
'storage': {
'inbox_dir': 'inbox',
'topics_dir': 'topics',
'data_dir': str(storage_dir),
},
'git': {
'enabled': False,
'vault_path': str(vault_path),
'remote': 'origin',
'branch': 'main',
'auto_push': False,
'commit_message_template': 'Add note: {title}',
},
'obsidian': {
'vault_path': str(vault_path),
'notes_folder': 'Notes',
},
'output': {
'organize_by': 'author',
'filename_format': '{date}_{title}.md',
'auto_tags': True,
'default_tags': ['video', 'bilibili', 'test'],
},
'sources': {
'bilibili': {
'enabled': True,
'cookie': None,
'extraction': {
'headless': True,
'timeout': 30,
},
},
},
'temp_dir': temp_dir,
}
class MockConfig:
def __init__(self, data):
self._data = data
def get(self, key, default=None):
keys = key.split('.')
value = self._data
for k in keys:
if isinstance(value, dict) and k in value:
value = value[k]
else:
return default
return value
@property
def vault_path(self):
return Path(self._data['git']['vault_path'])
return MockConfig(test_config_dict)
def test_no_subtitle_video():
"""测试无字幕视频的降级处理"""
print("\n" + "=" * 80)
print("测试:无字幕视频降级流程")
print("=" * 80 + "\n")
config = create_test_config()
pipeline = MainPipeline(config=config, enable_git_sync=False)
# 使用已知无字幕的视频
test_bv = "BV1MnFNz5EDL"
print(f"测试视频: {test_bv} (已知无字幕)\n")
try:
result = pipeline.process_video(test_bv)
if result['success']:
content = result['content']
print("\n" + "✅" * 40)
print("降级流程测试通过!")
print("✅" * 40 + "\n")
print(f"📺 标题: {content.title}")
print(f"👤 作者: {content.author}")
print(f"📄 输出路径: {content.output_path or 'N/A'}")
print(f"⏱️ 时长: {content.duration}秒" if content.duration else "⏱️ 时长: N/A")
# 检查是否有基础元数据
print(f"\n📊 元数据完整性:")
print(f" 标题: {'✅' if content.title else '❌'}")
print(f" 作者: {'✅' if content.author else '❌'}")
print(f" 描述: {'✅' if content.description else '❌'}")
print(f" URL: {'✅' if content.url else '❌'}")
print(f" 标签: {'✅' if content.tags else '❌'}")
# 检查输出文件
if content.output_path:
output_file = Path(content.output_path)
if output_file.exists():
print(f"\n📄 输出文件:")
print(f" 路径: {output_file}")
print(f" 大小: {output_file.stat().st_size:,} 字节")
# 读取文件内容,检查是否有"无字幕"提示
with open(output_file, 'r', encoding='utf-8') as f:
file_content = f.read()
print(f"\n📝 笔记内容检查:")
print(f" frontmatter: {'✅' if '---' in file_content else '❌'}")
print(f" 无字幕提示: {'✅' if '无字幕' in file_content else '❌'}")
# 显示部分内容
print(f"\n📄 文件预览 (前1000字符):")
print("-" * 80)
print(file_content[:1000])
print("-" * 80)
if len(file_content) > 1000:
print(f"\n...(总字符数: {len(file_content)})")
else:
print(f"\n⚠️ 输出文件不存在: {output_file}")
return True
else:
print(f"\n❌ 降级流程测试失败: {result.get('error', 'Unknown error')}")
return False
except Exception as e:
print(f"\n❌ 降级流程测试异常: {e}")
import traceback
traceback.print_exc()
return False
def cleanup_test_env():
"""清理测试环境"""
print("\n" + "=" * 80)
print("清理测试环境")
print("=" * 80 + "\n")
config = create_test_config()
temp_dir = config.get('temp_dir')
if temp_dir and Path(temp_dir).exists():
print(f"删除测试目录: {temp_dir}")
shutil.rmtree(temp_dir)
print("✅ 清理完成")
else:
print("⚠️ 测试目录不存在或未配置")
def main():
"""运行测试"""
print("\n" + "=" * 80)
print("Obsidian KB - 降级流程集成测试")
print("=" * 80)
print("\n测试说明:")
print(" - 测试视频: BV1MnFNz5EDL (已知无字幕)")
print(" - 验证点: 优雅降级,生成基础元数据笔记")
print(" - 检查项: frontmatter、无字幕提示、内容结构")
try:
# 运行测试
result = test_no_subtitle_video()
# 汇总结果
print("\n" + "=" * 80)
print("测试结果")
print("=" * 80 + "\n")
print(f" 降级流程测试: {'✅ 通过' if result else '❌ 失败'}")
if result:
print("\n 验证标准:")
print(" ✅ 无字幕视频:优雅降级生成基础笔记")
print(" ✅ 输出文件包含基础元数据")
print(" ✅ 有无字幕提示")
print(" ✅ frontmatter 正确")
else:
print("\n ⚠️ 验证失败")
return 0 if result else 1
except KeyboardInterrupt:
print("\n\n⚠️ 测试被用户中断")
return 1
except Exception as e:
print(f"\n❌ 测试运行异常: {e}")
import traceback
traceback.print_exc()
return 1
finally:
# 清理测试环境
print("\n")
cleanup_test_env()
if __name__ == '__main__':
sys.exit(main())