Main build: parse README, render single-page HTML via Jinja2 templates.
(repo_root: Path)
| 509 | |
| 510 | |
| 511 | def build(repo_root: Path) -> None: |
| 512 | """Main build: parse README, render single-page HTML via Jinja2 templates.""" |
| 513 | website = repo_root / "website" |
| 514 | readme_text = (repo_root / "README.md").read_text(encoding="utf-8") |
| 515 | |
| 516 | subtitle = "" |
| 517 | for line in readme_text.split("\n"): |
| 518 | stripped = line.strip() |
| 519 | if stripped and not stripped.startswith("#"): |
| 520 | subtitle = stripped |
| 521 | break |
| 522 | |
| 523 | parsed_groups = parse_readme(readme_text) |
| 524 | sponsors = parse_sponsors(readme_text) |
| 525 | |
| 526 | categories = [cat for g in parsed_groups for cat in g["categories"]] |
| 527 | cat_slugs = [cat["slug"] for cat in categories] |
| 528 | group_slugs = [g["slug"] for g in parsed_groups] |
| 529 | all_top_level_slugs = cat_slugs + group_slugs + [BUILTIN_SLUG] |
| 530 | duplicates = {s for s, n in Counter(all_top_level_slugs).items() if n > 1} |
| 531 | if duplicates: |
| 532 | raise ValueError(f"slug collision in /categories/ namespace: {sorted(duplicates)}. Rename a category or group so their slugs differ.") |
| 533 | total_entries = sum(c["entry_count"] for c in categories) |
| 534 | entries = extract_entries(categories, parsed_groups) |
| 535 | build_date = datetime.now(UTC) |
| 536 | |
| 537 | stars_data = load_stars(website / "data" / "github_stars.json") |
| 538 | |
| 539 | repo_self = stars_data.get("vinta/awesome-python", {}) |
| 540 | repo_stars = None |
| 541 | if "stars" in repo_self: |
| 542 | stars_val = repo_self["stars"] |
| 543 | repo_stars = f"{stars_val // 1000}k" if stars_val >= 1000 else str(stars_val) |
| 544 | |
| 545 | for entry in entries: |
| 546 | repo_key = extract_github_repo(entry["url"]) |
| 547 | if not repo_key and entry.get("source_type") == "Built-in": |
| 548 | repo_key = "python/cpython" |
| 549 | if repo_key and repo_key in stars_data: |
| 550 | sd = stars_data[repo_key] |
| 551 | entry["stars"] = sd["stars"] |
| 552 | entry["owner"] = sd["owner"] |
| 553 | entry["last_commit_at"] = sd.get("last_commit_at", "") |
| 554 | |
| 555 | entries = sort_entries(entries) |
| 556 | category_urls = {cat["name"]: category_path(cat) for cat in categories} |
| 557 | |
| 558 | filter_urls: dict[str, str] = dict(category_urls) |
| 559 | for group in parsed_groups: |
| 560 | filter_urls[group["name"]] = group_path(group["slug"]) |
| 561 | for entry in entries: |
| 562 | for sub in entry.get("subcategories", []): |
| 563 | filter_urls[sub["value"]] = sub["url"] |
| 564 | builtin_entries = [e for e in entries if e.get("source_type") == BUILTIN_FILTER] |
| 565 | if builtin_entries: |
| 566 | filter_urls[BUILTIN_FILTER] = BUILTIN_PATH |
| 567 | |
| 568 | env = Environment( |