a6f05ab2d5
- 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
188 lines
5.4 KiB
Python
188 lines
5.4 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 get_country_from_filename(filename: str) -> str:
|
|
name = Path(filename).stem
|
|
if (
|
|
"清华" in name
|
|
or "北大" in name
|
|
or "复旦" in name
|
|
or "上交" in name
|
|
or "北师大" in name
|
|
):
|
|
return "中国"
|
|
elif (
|
|
"MIT" in name
|
|
or "斯坦福" in name
|
|
or "CMU" in name
|
|
or "哈佛" in name
|
|
or "剑桥" in name
|
|
or "卡内基" in name
|
|
):
|
|
return "美国/英国"
|
|
elif "Google" in name or "Microsoft" in name or "OpenAI" in name:
|
|
return "国际"
|
|
elif "upGrad" in name or "Physics" in name or "AI-Samarth" in name:
|
|
return "印度"
|
|
elif "Topica" in name:
|
|
return "东南亚"
|
|
elif "好未来" in name or "猿辅导" in name or "作业帮" in name:
|
|
return "中国"
|
|
return "其他"
|
|
|
|
|
|
def get_industry_from_filename(filename: str) -> str:
|
|
name = Path(filename).stem
|
|
if any(
|
|
x in name
|
|
for x in [
|
|
"清华",
|
|
"北大",
|
|
"复旦",
|
|
"上交",
|
|
"北师大",
|
|
"MIT",
|
|
"斯坦福",
|
|
"CMU",
|
|
"哈佛",
|
|
"剑桥",
|
|
"卡内基",
|
|
"ETH",
|
|
]
|
|
):
|
|
return "高校"
|
|
elif any(x in name for x in ["Google", "Microsoft", "OpenAI"]):
|
|
return "科技巨头"
|
|
elif any(x in name for x in ["好未来", "猿辅导", "作业帮"]):
|
|
return "中国教育科技"
|
|
elif any(
|
|
x in name
|
|
for x in ["upGrad", "Physics", "Topica", "MagicSchool", "Synthesis", "SchoolAI"]
|
|
):
|
|
return "EdTech创业"
|
|
return "其他"
|
|
|
|
|
|
def update_institution_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()
|
|
|
|
country = existing_fm.get("country", get_country_from_filename(file_path.name))
|
|
industry = existing_fm.get(
|
|
"industry", get_industry_from_filename(file_path.name)
|
|
)
|
|
|
|
quality = existing_fm.get("quality", "A级")
|
|
quality_score = existing_fm.get("quality_score", 85)
|
|
|
|
new_fm_lines = [
|
|
"---",
|
|
"categories:",
|
|
' - "[[LLM Wiki]]"',
|
|
' - "[[教育AI研究项目]]"',
|
|
"tags:",
|
|
" - wiki",
|
|
" - institution",
|
|
" - education-ai",
|
|
f" - {country}",
|
|
f" - {industry}",
|
|
f"type: institution",
|
|
f"created: {existing_fm.get('created', datetime.date.today().isoformat())}",
|
|
]
|
|
|
|
if "title" in existing_fm:
|
|
new_fm_lines.append(f"title: {existing_fm['title']}")
|
|
if "updated" in existing_fm:
|
|
new_fm_lines.append(f"updated: {existing_fm['updated']}")
|
|
new_fm_lines.append(f"quality: {quality}")
|
|
new_fm_lines.append(f"quality_score: {quality_score}")
|
|
new_fm_lines.append(f"country: {country}")
|
|
new_fm_lines.append(f"industry: {industry}")
|
|
|
|
if "source" in existing_fm:
|
|
new_fm_lines.append(f"source: {existing_fm['source']}")
|
|
|
|
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} ({country}, {industry}, quality={quality})"
|
|
)
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error updating {file_path.name}: {e}")
|
|
return False
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("Institution Archives Frontmatter Batch Update Tool")
|
|
print("=" * 60)
|
|
print(f"Execution time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print()
|
|
|
|
archives_dir = Path(__file__).parent.parent / "机构档案"
|
|
|
|
if not archives_dir.exists():
|
|
print(f"❌ Institution archives directory not found: {archives_dir}")
|
|
return
|
|
|
|
archive_files = [f for f in archives_dir.glob("*.md") if "框架" not in f.name]
|
|
print(f"Found {len(archive_files)} institution archive files")
|
|
print()
|
|
|
|
success_count = 0
|
|
fail_count = 0
|
|
|
|
for archive_file in archive_files:
|
|
result = update_institution_frontmatter(archive_file)
|
|
if result:
|
|
success_count += 1
|
|
else:
|
|
fail_count += 1
|
|
|
|
print()
|
|
print("=" * 60)
|
|
print("Update Complete")
|
|
print("=" * 60)
|
|
print(f"Total files: {len(archive_files)}")
|
|
print(f"Successfully updated: {success_count}")
|
|
print(f"Failed: {fail_count}")
|
|
print("=" * 60)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|