#!/usr/bin/env python3 """Update meta.json and topics/index.json after adding questions. Usage: python3 update_meta.py - Reads the question file at topics/{group}/{subtopic}/{type}.json - Updates/creates topics/{group}/{subtopic}/meta.json - Updates/creates topics/index.json with subtopic stats meta.json format: { "slug": "gc-jvm", "name": "...", "description": "...", "tags": [...], "difficulty_range": [1, 5], "schema_version": "1.0.0", "question_files": ["fill_blank", "single_choice"], "stats": { "total": 20, "by_type": { "fill_blank": 10, "single_choice": 10 } } } index.json format: { "version": "1.0.0", "updated": "...", "topics": [ { "slug": "qunar-ai-fullstack", "name": "...", "subtopics": [ { "slug": "gc-jvm", "path": "topics/qunar-ai-fullstack/gc-jvm", "stats": {...} } ] } ] } Exit codes: 0 = success, 1 = error, 2 = usage error. """ import json import sys from pathlib import Path from datetime import date def load_json(path: Path) -> dict: if path.exists() and path.stat().st_size > 0: with open(path, encoding="utf-8") as f: return json.load(f) return {} def save_json(path: Path, data: dict): path.parent.mkdir(parents=True, exist_ok=True) with open(path, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) f.write("\n") def main(): if len(sys.argv) != 5: print(f"Usage: {sys.argv[0]} ", file=sys.stderr) sys.exit(2) topics_dir = Path(sys.argv[1]) group = sys.argv[2] subtopic = sys.argv[3] q_type = sys.argv[4] subtopic_dir = topics_dir / group / subtopic question_file = subtopic_dir / f"{q_type}.json" meta_file = subtopic_dir / "meta.json" index_file = topics_dir / "index.json" if not question_file.exists(): print(f"❌ Question file not found: {question_file}", file=sys.stderr) sys.exit(1) # Load question file q_data = load_json(question_file) questions = q_data.get("questions", []) count = len(questions) # Compute difficulty stats difficulties = [q.get("difficulty", 3) for q in questions] diff_range = [min(difficulties), max(difficulties)] if difficulties else [1, 5] # Compute tag union all_tags = sorted(set( tag for q in questions for tag in q.get("tags", []) )) # --- Update meta.json --- meta = load_json(meta_file) meta["slug"] = meta.get("slug", subtopic) meta["name"] = meta.get("name", subtopic.replace("-", " ").title()) meta.setdefault("description", "") meta["tags"] = all_tags meta["difficulty_range"] = diff_range meta["schema_version"] = "1.0.0" meta["updated"] = date.today().isoformat() # question_files is an array of type names if "question_files" not in meta: meta["question_files"] = [] if q_type not in meta["question_files"]: meta["question_files"].append(q_type) # stats has total and by_type if "stats" not in meta: meta["stats"] = {"total": 0, "by_type": {}} meta["stats"]["by_type"][q_type] = count meta["stats"]["total"] = sum(meta["stats"]["by_type"].values()) save_json(meta_file, meta) # --- Update index.json --- index = load_json(index_file) index.setdefault("version", "1.0.0") index["updated"] = date.today().isoformat() index.setdefault("topics", []) # Find or create the group topic entry group_entry = None for t in index["topics"]: if t.get("slug") == group: group_entry = t break if group_entry is None: group_entry = { "slug": group, "name": meta.get("name", group.replace("-", " ").title()), "description": meta.get("description", ""), "subtopics": [], } index["topics"].append(group_entry) group_entry.setdefault("subtopics", []) # Find or create the subtopic entry sub_entry = None for s in group_entry["subtopics"]: if s.get("slug") == subtopic: sub_entry = s break if sub_entry is None: sub_entry = { "slug": subtopic, "name": meta.get("name", subtopic.replace("-", " ").title()), "description": meta.get("description", ""), "path": f"topics/{group}/{subtopic}", "stats": {"total": 0, "by_type": {}}, } group_entry["subtopics"].append(sub_entry) sub_entry["stats"]["by_type"][q_type] = count sub_entry["stats"]["total"] = sum(sub_entry["stats"]["by_type"].values()) save_json(index_file, index) # Output summary result = { "subtopic": subtopic, "question_type": q_type, "count": count, "total": meta["stats"]["total"], "meta_file": str(meta_file), "index_file": str(index_file), } print(json.dumps(result, ensure_ascii=False)) sys.exit(0) if __name__ == "__main__": main()