diff --git a/scripts/common.py b/scripts/common.py index 8c65dee1..bb2dc2b2 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -808,6 +808,35 @@ def unique_emulator_profiles(profiles: dict[str, dict]) -> dict[str, dict]: } +GAME_DATA_TOPS = ("RPG Maker", "ScummVM") + + +def compute_composition(db: dict) -> dict: + """File and byte counts by tree area. + + Three buckets, each re-derivable from paths alone: arcade ROM sets + (Arcade/), game and engine data (the RPG Maker/ and ScummVM/ trees), + and console or computer system files (everything else). + """ + buckets = { + "systems": {"files": 0, "size_bytes": 0}, + "arcade": {"files": 0, "size_bytes": 0}, + "game_data": {"files": 0, "size_bytes": 0}, + } + for entry in db.get("files", {}).values(): + parts = entry.get("path", "").split("/") + top = parts[1] if len(parts) > 1 else "" + if top == "Arcade": + bucket = buckets["arcade"] + elif top in GAME_DATA_TOPS: + bucket = buckets["game_data"] + else: + bucket = buckets["systems"] + bucket["files"] += 1 + bucket["size_bytes"] += entry.get("size", 0) + return buckets + + def group_identical_platforms( platforms: list[str], platforms_dir: str, diff --git a/scripts/generate_readme.py b/scripts/generate_readme.py index d8c6d414..f3c5dfee 100644 --- a/scripts/generate_readme.py +++ b/scripts/generate_readme.py @@ -18,6 +18,7 @@ from datetime import datetime, timezone sys.path.insert(0, os.path.dirname(__file__)) from common import ( + compute_composition, list_registered_platforms, load_database, load_emulator_profiles, @@ -143,6 +144,7 @@ def generate_readme(db: dict, platforms_dir: str) -> str: load_emulator_profiles("emulators", skip_aliases=False) ) emulator_count = len(profiles) + comp = compute_composition(db) system_ids: set[str] = set() for p in profiles.values(): @@ -231,7 +233,10 @@ def generate_readme(db: dict, platforms_dir: str) -> str: f"- **{len(coverages)} platforms** supported with platform-specific verification", f"- **{emulator_count} emulators** profiled from source (RetroArch cores + standalone)", f"- **{len(system_ids)} systems** covered (NES, SNES, PlayStation, Saturn, Dreamcast, ...)", - f"- **{total_files:,} files** verified with MD5, SHA1, CRC32 checksums", + f"- **{total_files:,} files** verified with MD5, SHA1, CRC32 checksums:" + f" {comp['systems']['files']:,} system files," + f" {comp['arcade']['files']:,} arcade ROM sets," + f" {comp['game_data']['files']:,} game and engine data files", *_catalog_matched_line(db), f"- **{size_mb:.0f} MB** total collection size", "", diff --git a/scripts/generate_site.py b/scripts/generate_site.py index 5964063e..329659f9 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -21,6 +21,7 @@ from pathlib import Path sys.path.insert(0, os.path.dirname(__file__)) from common import ( + compute_composition, list_registered_platforms, load_database, load_emulator_profiles, @@ -294,6 +295,8 @@ def generate_home( "", "", "", + composition_sentence(db), + "", ] # Platforms FIRST (main action) @@ -417,11 +420,24 @@ def compute_stats(db: dict, coverages: dict, profiles: dict) -> dict: "platforms": len(coverages), "emulators": len(unique), "systems": len(systems), + "catalog_matched": sum( + 1 for f in db.get("files", {}).values() if f.get("provenance") + ), "source": REPO_URL, "downloads": RELEASE_URL, } +def composition_sentence(db: dict) -> str: + comp = compute_composition(db) + return ( + f"Of these files, {comp['systems']['files']:,} are console and " + f"computer system files, {comp['arcade']['files']:,} arcade ROM sets " + f"(`Arcade/`), and {comp['game_data']['files']:,} game and engine " + "data (the `RPG Maker/` and `ScummVM/` trees)." + ) + + def generate_stats(stats: dict) -> str: return json.dumps(stats, indent=2) + "\n" @@ -2568,6 +2584,7 @@ def main(): ) stats = compute_stats(db, coverages, profiles) + stats["composition"] = compute_composition(db) write_if_changed(str(docs / "stats.json"), generate_stats(stats)) # Build system_id -> manufacturer page map (needed by all generators)