mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-04-13 12:22:33 -05:00
161 lines
4.9 KiB
Python
161 lines
4.9 KiB
Python
"""Exporter for RomM known_bios_files.json format.
|
|
|
|
Produces JSON matching the exact format of
|
|
rommapp/romm/backend/models/fixtures/known_bios_files.json:
|
|
- Keys are "igdb_slug:filename"
|
|
- Values contain size, crc, md5, sha1 (all optional but at least one hash)
|
|
- Hashes are lowercase hex strings
|
|
- Size is an integer
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from collections import OrderedDict
|
|
from pathlib import Path
|
|
|
|
from .base_exporter import BaseExporter
|
|
|
|
# retrobios slug -> IGDB slug (reverse of scraper SLUG_MAP)
|
|
_REVERSE_SLUG: dict[str, str] = {
|
|
"3do": "3do",
|
|
"nintendo-64dd": "64dd",
|
|
"amstrad-cpc": "acpc",
|
|
"commodore-amiga": "amiga",
|
|
"arcade": "arcade",
|
|
"atari-st": "atari-st",
|
|
"atari-5200": "atari5200",
|
|
"atari-7800": "atari7800",
|
|
"atari-400-800": "atari8bit",
|
|
"coleco-colecovision": "colecovision",
|
|
"sega-dreamcast": "dc",
|
|
"doom": "doom",
|
|
"enterprise-64-128": "enterprise",
|
|
"fairchild-channel-f": "fairchild-channel-f",
|
|
"nintendo-fds": "fds",
|
|
"sega-game-gear": "gamegear",
|
|
"nintendo-gb": "gb",
|
|
"nintendo-gba": "gba",
|
|
"nintendo-gbc": "gbc",
|
|
"sega-mega-drive": "genesis",
|
|
"mattel-intellivision": "intellivision",
|
|
"j2me": "j2me",
|
|
"atari-lynx": "lynx",
|
|
"apple-macintosh-ii": "mac",
|
|
"microsoft-msx": "msx",
|
|
"nintendo-ds": "nds",
|
|
"snk-neogeo-cd": "neo-geo-cd",
|
|
"nintendo-nes": "nes",
|
|
"nintendo-gamecube": "ngc",
|
|
"magnavox-odyssey2": "odyssey-2-slash-videopac-g7000",
|
|
"nec-pc-98": "pc-9800-series",
|
|
"nec-pc-fx": "pc-fx",
|
|
"nintendo-pokemon-mini": "pokemon-mini",
|
|
"sony-playstation-2": "ps2",
|
|
"sony-psp": "psp",
|
|
"sony-playstation": "psx",
|
|
"nintendo-satellaview": "satellaview",
|
|
"sega-saturn": "saturn",
|
|
"scummvm": "scummvm",
|
|
"sega-mega-cd": "segacd",
|
|
"sharp-x68000": "sharp-x68000",
|
|
"sega-master-system": "sms",
|
|
"nintendo-snes": "snes",
|
|
"nintendo-sufami-turbo": "sufami-turbo",
|
|
"nintendo-sgb": "super-gb",
|
|
"nec-pc-engine": "tg16",
|
|
"videoton-tvc": "tvc",
|
|
"philips-videopac": "videopac-g7400",
|
|
"wolfenstein-3d": "wolfenstein",
|
|
"sharp-x1": "x1",
|
|
"microsoft-xbox": "xbox",
|
|
"sinclair-zx-spectrum": "zxs",
|
|
}
|
|
|
|
|
|
class Exporter(BaseExporter):
|
|
"""Export truth data to RomM known_bios_files.json format."""
|
|
|
|
@staticmethod
|
|
def platform_name() -> str:
|
|
return "romm"
|
|
|
|
def export(
|
|
self,
|
|
truth_data: dict,
|
|
output_path: str,
|
|
scraped_data: dict | None = None,
|
|
) -> None:
|
|
native_map: dict[str, str] = {}
|
|
if scraped_data:
|
|
for sys_id, sys_data in scraped_data.get("systems", {}).items():
|
|
nid = sys_data.get("native_id")
|
|
if nid:
|
|
native_map[sys_id] = nid
|
|
|
|
output: OrderedDict[str, dict] = OrderedDict()
|
|
|
|
systems = truth_data.get("systems", {})
|
|
for sys_id in sorted(systems):
|
|
sys_data = systems[sys_id]
|
|
files = sys_data.get("files", [])
|
|
if not files:
|
|
continue
|
|
|
|
igdb_slug = native_map.get(sys_id, _REVERSE_SLUG.get(sys_id, sys_id))
|
|
|
|
for fe in files:
|
|
name = fe.get("name", "")
|
|
if name.startswith("_") or self._is_pattern(name):
|
|
continue
|
|
|
|
key = f"{igdb_slug}:{name}"
|
|
|
|
entry: OrderedDict[str, object] = OrderedDict()
|
|
|
|
size = fe.get("size")
|
|
if size is not None:
|
|
entry["size"] = int(size)
|
|
|
|
crc = fe.get("crc32", "")
|
|
if crc:
|
|
entry["crc"] = str(crc).strip().lower()
|
|
|
|
md5 = fe.get("md5", "")
|
|
if isinstance(md5, list):
|
|
md5 = md5[0] if md5 else ""
|
|
if md5:
|
|
entry["md5"] = str(md5).strip().lower()
|
|
|
|
sha1 = fe.get("sha1", "")
|
|
if isinstance(sha1, list):
|
|
sha1 = sha1[0] if sha1 else ""
|
|
if sha1:
|
|
entry["sha1"] = str(sha1).strip().lower()
|
|
|
|
output[key] = entry
|
|
|
|
Path(output_path).write_text(
|
|
json.dumps(output, indent=2, ensure_ascii=False) + "\n",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
def validate(self, truth_data: dict, output_path: str) -> list[str]:
|
|
data = json.loads(Path(output_path).read_text(encoding="utf-8"))
|
|
|
|
exported_names: set[str] = set()
|
|
for key in data:
|
|
if ":" in key:
|
|
_, filename = key.split(":", 1)
|
|
exported_names.add(filename)
|
|
|
|
issues: list[str] = []
|
|
for sys_data in truth_data.get("systems", {}).values():
|
|
for fe in sys_data.get("files", []):
|
|
name = fe.get("name", "")
|
|
if name.startswith("_") or self._is_pattern(name):
|
|
continue
|
|
if name not in exported_names:
|
|
issues.append(f"missing: {name}")
|
|
return issues
|