Files
llm_wiki/raw/教育AI研究/tools/fix_knowledge_cards_frontmatter.py
hehaiguang1123 a6f05ab2d5 Phase 0-2: Schema cleanup, typed relations, event-driven automation
- Phase 0: AGENTS.md cleanup (dedup quotes, renumber sections, merge qmd)
- Phase 1: typed relations (manage-relations.py, graph-search.py, check-staleness.py, detect-conflicts.py)
- Phase 2: frontmatter validator, weekly lint, knowledge promotion, git hooks
- Fix .gitignore to track tools/ and .githooks/
- Fix git remote URL (remove plaintext token)
- New wiki pages: 504 pages, 34 raw sources
2026-07-01 08:05:43 +08:00

187 lines
5.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import io
import re
import datetime
from pathlib import Path
from typing import Dict, List, Optional, Tuple
if sys.platform == "win32":
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
def extract_existing_frontmatter(file_path: Path) -> Dict[str, any]:
try:
content = file_path.read_text(encoding="utf-8")
match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
if match:
fm_text = match.group(1)
fm = {}
for line in fm_text.split("\n"):
if ":" in line:
key, value = line.split(":", 1)
key = key.strip()
value = value.strip()
if value.startswith("[") or value.startswith("{"):
continue
elif value.startswith('"') and value.endswith('"'):
fm[key] = value.strip('"')
elif value:
fm[key] = value
return fm
except Exception as e:
print(f"Error reading {file_path.name}: {e}")
return {}
def get_card_type_from_filename(filename: str) -> Tuple[str, str]:
name = Path(filename).stem
if "AI教育" in name or "全球图景" in name or "九校" in name:
return "concept", "概念"
elif any(
x in name
for x in [
"CMU",
"MIT",
"斯坦福",
"牛津",
"哈佛",
"AIEOU",
"RAISE",
"Accelerator",
]
):
return "entity", "机构"
elif any(
x in name for x in ["Victor", "Emma", "Ken", "Rose", "Neil", "Ryan", "Kestin"]
):
return "entity", "人物"
elif "知识卡片" in name:
return "concept", "概念"
return "concept", "概念"
def update_frontmatter(file_path: Path) -> bool:
try:
content = file_path.read_text(encoding="utf-8")
if not content.startswith("---"):
print(f"⚠️ No frontmatter in {file_path.name}")
return False
fm_match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
if not fm_match:
print(f"⚠️ Cannot parse frontmatter in {file_path.name}")
return False
fm_text = fm_match.group(1)
body = content[fm_match.end() :]
existing_fm = {}
for line in fm_text.split("\n"):
if ":" in line:
key, value = line.split(":", 1)
existing_fm[key.strip()] = value.strip()
card_type, card_category = get_card_type_from_filename(file_path.name)
new_fm_lines = [
"---",
"categories:",
' - "[[LLM Wiki]]"',
' - "[[知识卡片]]"',
"tags:",
]
existing_tags = existing_fm.get("tags", "")
if existing_tags:
if existing_tags.startswith("["):
tag_match = re.findall(r"'([^']+)'", existing_tags)
for tag in tag_match:
new_fm_lines.append(f" - {tag}")
else:
for tag in existing_tags.split(","):
tag = tag.strip()
if tag:
new_fm_lines.append(f" - {tag}")
else:
new_fm_lines.append(" - AI教育")
new_fm_lines.append(" - 知识卡片")
new_fm_lines.extend(
[
f"type: {card_type}",
f"created: {existing_fm.get('created', datetime.date.today().isoformat())}",
]
)
if "updated" in existing_fm:
new_fm_lines.append(f"updated: {existing_fm['updated']}")
if "source" in existing_fm:
new_fm_lines.append(f"source: {existing_fm['source']}")
if "title" in existing_fm:
new_fm_lines.append(f"title: {existing_fm['title']}")
if "review-date" in existing_fm:
new_fm_lines.append(f"review-date: {existing_fm['review-date']}")
if "review-status" in existing_fm:
new_fm_lines.append(f"review-status: {existing_fm['review-status']}")
new_fm_lines.append("---")
new_content = "\n".join(new_fm_lines) + body
file_path.write_text(new_content, encoding="utf-8")
print(
f"✅ Updated: {file_path.name} (type={card_type}, category={card_category})"
)
return True
except Exception as e:
print(f"❌ Error updating {file_path.name}: {e}")
return False
def main():
print("=" * 60)
print("Knowledge Cards Frontmatter Batch Update Tool")
print("=" * 60)
print(f"Execution time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
cards_dir = Path(__file__).parent.parent / "知识卡片"
if not cards_dir.exists():
print(f"❌ Knowledge cards directory not found: {cards_dir}")
return
card_files = list(cards_dir.glob("*.md"))
print(f"Found {len(card_files)} knowledge card files")
print()
success_count = 0
fail_count = 0
for card_file in card_files:
result = update_frontmatter(card_file)
if result:
success_count += 1
else:
fail_count += 1
print()
print("=" * 60)
print("Update Complete")
print("=" * 60)
print(f"Total files: {len(card_files)}")
print(f"Successfully updated: {success_count}")
print(f"Failed: {fail_count}")
print("=" * 60)
if __name__ == "__main__":
main()