feat: 支持嵌套格式元数据(kb-bilibili-metadata 输出)
This commit is contained in:
@@ -8,41 +8,44 @@
|
||||
- Template-based output
|
||||
- Quality scoring
|
||||
- Automatic tagging
|
||||
- **多格式元数据支持**: 支持扁平结构 `{"title":"xxx"}` 和嵌套结构 `{"data":{"metadata":{...}}}`
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Analyze content
|
||||
# 分析内容
|
||||
python deep_analyzer.py --metadata meta.json --content content.json --output analysis.md
|
||||
|
||||
# Specify type
|
||||
# 指定类型
|
||||
python deep_analyzer.py --metadata meta.json --content content.json --type tutorial --output tutorial.md
|
||||
|
||||
# 指定 AI 提供商
|
||||
python deep_analyzer.py -m meta.json -c content.json -o out.md --provider zhipu --model glm-4
|
||||
```
|
||||
|
||||
## Output
|
||||
## Metadata Format
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: "分析标题"
|
||||
source: "bilibili"
|
||||
quality_score: 95
|
||||
tags:
|
||||
- python
|
||||
- tutorial
|
||||
---
|
||||
支持两种元数据格式:
|
||||
|
||||
## 一句话总结
|
||||
```json
|
||||
// 格式1: 扁平结构
|
||||
{
|
||||
"title": "视频标题",
|
||||
"author": "作者名",
|
||||
"duration": 619,
|
||||
"bvid": "BVxxx"
|
||||
}
|
||||
|
||||
内容摘要...
|
||||
|
||||
## 核心要点
|
||||
|
||||
1. 要点1
|
||||
2. 要点2
|
||||
// 格式2: 嵌套结构(kb-bilibili-metadata 输出)
|
||||
{
|
||||
"data": {
|
||||
"metadata": {
|
||||
"title": "视频标题",
|
||||
"author": "作者名",
|
||||
"duration": "10:19"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
cp -r kb-deep-analyzer/ ~/skills/
|
||||
```
|
||||
会自动转换为扁平格式进行分析。
|
||||
|
||||
@@ -751,6 +751,70 @@ def load_json(file_path: str) -> Dict:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def normalize_metadata(metadata: Dict) -> Dict:
|
||||
"""
|
||||
标准化元数据格式,支持嵌套和平面两种结构
|
||||
|
||||
支持以下输入格式:
|
||||
1. 扁平结构: {"title": "xxx", "author": "yyy", "duration": 619}
|
||||
2. 嵌套结构: {"data": {"metadata": {"title": "xxx", "author": "yyy", "duration": "10:19"}}}
|
||||
|
||||
输出: 扁平结构,duration 转换为秒数
|
||||
"""
|
||||
if not metadata:
|
||||
return {}
|
||||
|
||||
# 如果已经包含 title 字段,认为是扁平结构
|
||||
if 'title' in metadata:
|
||||
# 处理 duration 格式(可能是 "10:19" 字符串或数字)
|
||||
duration = metadata.get('duration', 0)
|
||||
if isinstance(duration, str) and ':' in duration:
|
||||
parts = duration.split(':')
|
||||
try:
|
||||
seconds = int(parts[0]) * 60 + int(parts[1])
|
||||
metadata['duration'] = seconds
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
return metadata
|
||||
|
||||
# 如果是嵌套结构,提取 data.metadata
|
||||
data = metadata.get('data', {})
|
||||
meta = data.get('metadata', {})
|
||||
|
||||
# 提取扁平化字段
|
||||
normalized = {
|
||||
'title': meta.get('title', metadata.get('title', '未知')),
|
||||
'author': meta.get('author', metadata.get('author', '')),
|
||||
'bvid': meta.get('bvid', metadata.get('bvid', '')),
|
||||
'aid': meta.get('aid', metadata.get('aid', 0)),
|
||||
'pubtime': meta.get('pubtime', metadata.get('pubtime', '')),
|
||||
'platform': meta.get('platform', 'unknown'),
|
||||
'url': meta.get('url', ''),
|
||||
}
|
||||
|
||||
# 处理 duration
|
||||
duration = meta.get('duration', 0)
|
||||
if isinstance(duration, str):
|
||||
if ':' in duration:
|
||||
# "10:19" 格式
|
||||
parts = duration.split(':')
|
||||
try:
|
||||
normalized['duration'] = int(parts[0]) * 60 + int(parts[1])
|
||||
except (ValueError, IndexError):
|
||||
normalized['duration'] = 0
|
||||
else:
|
||||
try:
|
||||
normalized['duration'] = int(duration)
|
||||
except ValueError:
|
||||
normalized['duration'] = 0
|
||||
elif isinstance(duration, (int, float)):
|
||||
normalized['duration'] = int(duration)
|
||||
else:
|
||||
normalized['duration'] = 0
|
||||
|
||||
return normalized
|
||||
|
||||
|
||||
def format_duration(seconds: int) -> str:
|
||||
"""格式化时长"""
|
||||
h = seconds // 3600
|
||||
@@ -827,7 +891,8 @@ def main():
|
||||
|
||||
# 加载数据
|
||||
print(f"[Main] 加载元数据: {args.metadata}")
|
||||
metadata = load_json(args.metadata)
|
||||
raw_metadata = load_json(args.metadata)
|
||||
metadata = normalize_metadata(raw_metadata)
|
||||
|
||||
print(f"[Main] 加载内容: {args.content}")
|
||||
content = load_json(args.content)
|
||||
|
||||
Reference in New Issue
Block a user