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
268 lines
8.2 KiB
Python
268 lines
8.2 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, Tuple, Optional
|
|
|
|
if sys.platform == "win32":
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
|
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
|
|
|
|
|
|
class InstitutionQualityAnalyzer:
|
|
def __init__(self, archives_dir: Path):
|
|
self.archives_dir = archives_dir
|
|
self.quality_report: List[Dict] = []
|
|
|
|
def analyze_institution(self, file_path: Path) -> Dict:
|
|
try:
|
|
content = file_path.read_text(encoding="utf-8")
|
|
filename = file_path.name
|
|
|
|
analysis = {
|
|
"filename": filename,
|
|
"score": 0,
|
|
"max_score": 10,
|
|
"issues": [],
|
|
"strengths": [],
|
|
"missing_fields": [],
|
|
}
|
|
|
|
fm_match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
|
|
if fm_match:
|
|
fm_text = fm_match.group(1)
|
|
if "categories:" in fm_text:
|
|
analysis["score"] += 1
|
|
analysis["strengths"].append("有frontmatter categories")
|
|
if "tags:" in fm_text:
|
|
analysis["score"] += 1
|
|
if "type: institution" in fm_text:
|
|
analysis["score"] += 1
|
|
|
|
if "官网" in content or "官方网站" in content or "http" in content:
|
|
analysis["score"] += 1
|
|
analysis["strengths"].append("有官网信息")
|
|
else:
|
|
analysis["missing_fields"].append("官网链接")
|
|
|
|
if any(
|
|
x in content for x in ["研究重点", "研究方向", "核心研究", "重点领域"]
|
|
):
|
|
analysis["score"] += 1
|
|
analysis["strengths"].append("有研究方向")
|
|
else:
|
|
analysis["missing_fields"].append("研究重点")
|
|
|
|
if any(
|
|
x in content for x in ["主要成果", "研究成果", "核心产品", "旗舰项目"]
|
|
):
|
|
analysis["score"] += 1
|
|
analysis["strengths"].append("有主要成果")
|
|
else:
|
|
analysis["missing_fields"].append("主要成果")
|
|
|
|
if (
|
|
"联系方式" in content
|
|
or "联系信息" in content
|
|
or "contact" in content.lower()
|
|
):
|
|
analysis["score"] += 1
|
|
|
|
if len(content) > 1500:
|
|
analysis["score"] += 1
|
|
|
|
section_count = content.count("## ")
|
|
if section_count >= 4:
|
|
analysis["score"] += 1
|
|
analysis["strengths"].append(f"结构完整({section_count}章节)")
|
|
|
|
if content.count("来源") >= 2 or content.count("参考") >= 2:
|
|
analysis["score"] += 1
|
|
analysis["strengths"].append("有信息来源标注")
|
|
|
|
if "评级" in content or "质量" in content or "可信度" in content:
|
|
analysis["score"] += 1
|
|
analysis["strengths"].append("有质量评级")
|
|
|
|
quality_percentage = (analysis["score"] / analysis["max_score"]) * 100
|
|
analysis["quality_percentage"] = quality_percentage
|
|
|
|
if quality_percentage >= 90:
|
|
analysis["grade"] = "A"
|
|
elif quality_percentage >= 80:
|
|
analysis["grade"] = "B"
|
|
elif quality_percentage >= 70:
|
|
analysis["grade"] = "C"
|
|
else:
|
|
analysis["grade"] = "D"
|
|
|
|
return analysis
|
|
|
|
except Exception as e:
|
|
return {
|
|
"filename": file_path.name,
|
|
"score": 0,
|
|
"max_score": 10,
|
|
"error": str(e),
|
|
"grade": "F",
|
|
}
|
|
|
|
def analyze_all(self) -> List[Dict]:
|
|
archive_files = [
|
|
f for f in self.archives_dir.glob("*.md") if "框架" not in f.name
|
|
]
|
|
|
|
print(f"分析 {len(archive_files)} 个机构档案...")
|
|
|
|
results = []
|
|
for archive_file in archive_files:
|
|
result = self.analyze_institution(archive_file)
|
|
results.append(result)
|
|
|
|
results.sort(key=lambda x: x.get("quality_percentage", 0))
|
|
|
|
return results
|
|
|
|
def generate_quality_report(self) -> str:
|
|
results = self.analyze_all()
|
|
|
|
avg_score = (
|
|
sum(r.get("quality_percentage", 0) for r in results) / len(results)
|
|
if results
|
|
else 0
|
|
)
|
|
grade_a = sum(1 for r in results if r.get("grade") == "A")
|
|
grade_b = sum(1 for r in results if r.get("grade") == "B")
|
|
grade_c = sum(1 for r in results if r.get("grade") == "C")
|
|
grade_d = sum(1 for r in results if r.get("grade") == "D")
|
|
|
|
report = f"""# 机构档案质量分析报告
|
|
|
|
## 总体统计
|
|
|
|
| 指标 | 值 |
|
|
|------|-----|
|
|
| 总档案数 | {len(results)} |
|
|
| 平均质量分 | {avg_score:.1f}% |
|
|
| A级档案 | {grade_a} 个 |
|
|
| B级档案 | {grade_b} 个 |
|
|
| C级档案 | {grade_c} 个 |
|
|
| D级档案 | {grade_d} 个 |
|
|
|
|
## 按质量分级
|
|
|
|
### A级档案 (≥90%)
|
|
|
|
"""
|
|
|
|
for r in results:
|
|
if r.get("grade") == "A":
|
|
report += (
|
|
f"- **{r['filename']}**: {r.get('quality_percentage', 0):.0f}%\n"
|
|
)
|
|
|
|
report += f"""
|
|
### B级档案 (80-90%)
|
|
|
|
"""
|
|
|
|
for r in results:
|
|
if r.get("grade") == "B":
|
|
report += (
|
|
f"- **{r['filename']}**: {r.get('quality_percentage', 0):.0f}%\n"
|
|
)
|
|
|
|
report += f"""
|
|
### C级档案 (70-80%)
|
|
|
|
"""
|
|
|
|
for r in results:
|
|
if r.get("grade") == "C":
|
|
report += f"- **{r['filename']}**: {r.get('quality_percentage', 0):.0f}% - 缺失: {', '.join(r.get('missing_fields', []))}\n"
|
|
|
|
report += f"""
|
|
### D级档案 (<70%)
|
|
|
|
"""
|
|
|
|
for r in results:
|
|
if r.get("grade") == "D":
|
|
report += f"- **{r['filename']}**: {r.get('quality_percentage', 0):.0f}% - 缺失: {', '.join(r.get('missing_fields', []))}\n"
|
|
|
|
report += f"""
|
|
|
|
## 改进建议
|
|
|
|
### 需要优先修复的档案 (C级和D级)
|
|
|
|
"""
|
|
|
|
for r in results:
|
|
if r.get("grade") in ["C", "D"]:
|
|
missing = r.get("missing_fields", [])
|
|
if missing:
|
|
report += f"**{r['filename']}**: 补充 {', '.join(missing)}\n"
|
|
|
|
report += f"""
|
|
|
|
### 通用改进建议
|
|
|
|
1. **官网信息**: 确保每个机构都有官方网站链接
|
|
2. **研究重点**: 添加明确的研究方向/重点领域描述
|
|
3. **主要成果**: 列出代表性研究成果或产品
|
|
4. **联系方式**: 添加联系信息(可选)
|
|
5. **信息来源**: 确保每条数据有明确来源标注
|
|
6. **结构完整性**: 建议至少4个章节
|
|
|
|
---
|
|
|
|
*报告生成时间: {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}*
|
|
"""
|
|
|
|
return report
|
|
|
|
def save_report(self, output_path: Path):
|
|
report = self.generate_quality_report()
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(output_path, "w", encoding="utf-8") as f:
|
|
f.write(report)
|
|
print(f"✅ 质量报告已保存: {output_path}")
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("机构档案质量分析工具")
|
|
print("=" * 60)
|
|
|
|
archives_dir = Path(__file__).parent.parent / "机构档案"
|
|
output_path = (
|
|
Path(__file__).parent.parent
|
|
/ "outputs"
|
|
/ f"institution_quality_analysis_{datetime.date.today()}.md"
|
|
)
|
|
|
|
analyzer = InstitutionQualityAnalyzer(archives_dir)
|
|
analyzer.save_report(output_path)
|
|
|
|
results = analyzer.analyze_all()
|
|
avg = sum(r.get("quality_percentage", 0) for r in results) / len(results)
|
|
|
|
print()
|
|
print("=" * 60)
|
|
print("分析完成")
|
|
print("=" * 60)
|
|
print(f"平均质量分: {avg:.1f}%")
|
|
print(f"A级: {sum(1 for r in results if r.get('grade') == 'A')}个")
|
|
print(f"B级: {sum(1 for r in results if r.get('grade') == 'B')}个")
|
|
print(f"C级: {sum(1 for r in results if r.get('grade') == 'C')}个")
|
|
print(f"D级: {sum(1 for r in results if r.get('grade') == 'D')}个")
|
|
print("=" * 60)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|