mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-20 10:23:16 -05:00
fix: site systems match under every spelling
Platform pages matched emulators to systems by the exact id, so the RetroArch page listed none for sega-mega-drive (genesis_plus_gx says sega-megadrive), and listed every emulator of a system instead of those the platform runs. Emulator cards linked only ids a platform uses: 2,057 of 4,215 system lines had no link, now 327, the rest having no page. Ids are compared as _norm_system_id reads them, and a system only profiles name is placed by the files they file under it.
This commit is contained in:
1 parent
2e0d3d626a
commit
91403aa149
3 files changed
+119
-16
No files matched your search
+50
-14
@@ -146,6 +146,7 @@ def _build_system_page_map_from_data(
|
||||
manufacturers: dict,
|
||||
coverages: dict,
|
||||
db: dict,
|
||||
profiles: dict | None = None,
|
||||
) -> None:
|
||||
"""Build system_id -> (manufacturer_slug, console_name) mapping.
|
||||
|
||||
@@ -210,6 +211,26 @@ def _build_system_page_map_from_data(
|
||||
_system_page_map[sys_id] = console_norm[suffix]
|
||||
break
|
||||
|
||||
# Systems only emulator profiles name (sega-naomi, commodore-pet): placed
|
||||
# by the files the profile files under them, as a platform's are. A
|
||||
# profile of one system files all of its entries there.
|
||||
for profile in (profiles or {}).values():
|
||||
systems = [str(sid) for sid in profile.get("systems") or []]
|
||||
for sys_id in systems:
|
||||
if sys_id in _system_page_map:
|
||||
continue
|
||||
files = [
|
||||
entry for entry in profile.get("files") or []
|
||||
if isinstance(entry, dict)
|
||||
and (entry.get("system") == sys_id or len(systems) == 1)
|
||||
]
|
||||
place = _system_folder(files, db, name_consoles)
|
||||
if place is not None:
|
||||
mfr, console = place
|
||||
_system_page_map[sys_id] = (mfr.lower().replace(" ", "-"), console)
|
||||
elif sys_id in console_norm:
|
||||
_system_page_map[sys_id] = console_norm[sys_id]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1680,11 +1701,7 @@ def _render_platform_systems(
|
||||
ok_count = sum(1 for f in files if f["status"] == "ok")
|
||||
total = len(files)
|
||||
|
||||
sys_emus = []
|
||||
if emulator_files:
|
||||
for emu_name, emu_data in emulator_files.items():
|
||||
if sys_id in emu_data.get("systems", set()):
|
||||
sys_emus.append(emu_name)
|
||||
sys_emus = _system_emulators(sys_id, emulator_files)
|
||||
|
||||
sys_link = _system_link(sys_id, "../")
|
||||
|
||||
@@ -1914,11 +1931,7 @@ def generate_platform_page(
|
||||
f'<span class="rb-badge rb-badge-warning">'
|
||||
f'{non_ok} issue{"s" if non_ok > 1 else ""}</span>'
|
||||
)
|
||||
sys_emus = []
|
||||
if emulator_files:
|
||||
for emu_name, emu_data in emulator_files.items():
|
||||
if sys_id in emu_data.get("systems", set()):
|
||||
sys_emus.append(emu_name)
|
||||
sys_emus = _system_emulators(sys_id, emulator_files)
|
||||
emu_str = ", ".join(sys_emus[:3])
|
||||
if len(sys_emus) > 3:
|
||||
emu_str += f" +{len(sys_emus) - 3}"
|
||||
@@ -4108,14 +4121,33 @@ def _build_file_consumers(db: dict, coverages: dict, profiles: dict) -> FileCons
|
||||
|
||||
|
||||
def _build_emulator_file_index(profiles: dict) -> dict[str, dict]:
|
||||
"""Map emulator_name -> {systems: set}, for the platform pages."""
|
||||
"""Map emulator_name -> {systems, norm}, for the platform pages.
|
||||
|
||||
norm holds the systems as _norm_system_id reads them: a platform files
|
||||
the Mega Drive as sega-mega-drive and genesis_plus_gx as sega-megadrive,
|
||||
and an exact match left the RetroArch page with no emulator for it.
|
||||
"""
|
||||
from common import _norm_system_id
|
||||
|
||||
return {
|
||||
name: {"systems": set(profile.get("systems", []))}
|
||||
name: {
|
||||
"systems": set(profile.get("systems", [])),
|
||||
"norm": {_norm_system_id(str(s)) for s in profile.get("systems", [])},
|
||||
}
|
||||
for name, profile in profiles.items()
|
||||
if profile.get("type") != "alias"
|
||||
}
|
||||
|
||||
|
||||
def _system_emulators(sys_id: str, emulator_files: dict | None) -> list[str]:
|
||||
"""The emulators a platform runs for one of its systems."""
|
||||
from common import _norm_system_id
|
||||
|
||||
norm = _norm_system_id(sys_id)
|
||||
return [name for name, data in (emulator_files or {}).items()
|
||||
if sys_id in data["systems"] or norm in data["norm"]]
|
||||
|
||||
|
||||
def _mkdocs_config(docs: Path, text: str) -> tuple[Path, str]:
|
||||
"""Where the site's config goes, and its text for that place.
|
||||
|
||||
@@ -4533,7 +4565,7 @@ def _generate(args: argparse.Namespace) -> None:
|
||||
# Build system_id -> manufacturer page map (needed by all generators)
|
||||
print("Building system cross-reference map...")
|
||||
manufacturers = _group_by_manufacturer(db)
|
||||
_build_system_page_map_from_data(manufacturers, coverages, db)
|
||||
_build_system_page_map_from_data(manufacturers, coverages, db, profiles)
|
||||
print(f" {len(_system_page_map)} system IDs mapped to pages")
|
||||
|
||||
# Generate platform pages
|
||||
@@ -4543,9 +4575,13 @@ def _generate(args: argparse.Namespace) -> None:
|
||||
generate_platform_index(coverages, registry),
|
||||
)
|
||||
for name, cov in coverages.items():
|
||||
# The emulators this platform runs, not every one of the system.
|
||||
runs = resolve_platform_cores(cov["config"], profiles)
|
||||
write_if_changed(
|
||||
str(docs / "platforms" / f"{name}.md"),
|
||||
generate_platform_page(name, cov, registry, emulator_files),
|
||||
generate_platform_page(name, cov, registry, {
|
||||
emu: data for emu, data in emulator_files.items() if emu in runs
|
||||
}),
|
||||
)
|
||||
PAGE_DATA[f"platforms/{name}.md"] = platform_structured_data(name, cov)
|
||||
|
||||
|
||||
+29
-2
@@ -128,10 +128,37 @@ def _slugify_anchor(text: str) -> str:
|
||||
slug = slug.strip("-")
|
||||
return slug
|
||||
|
||||
_norm_page_cache: dict[str, tuple[str, str] | None] = {}
|
||||
_norm_page_size = -1
|
||||
|
||||
|
||||
def _page_by_norm(sys_id: str) -> tuple[str, str] | None:
|
||||
"""The page an id leads to under another spelling of the same system.
|
||||
|
||||
Emulator cards name sega-megadrive or sinclair-zxspectrum, the pages are
|
||||
keyed by the platforms' spellings: 2,431 of 4,195 cards had no link. A
|
||||
spelling two pages share leads nowhere rather than to either.
|
||||
"""
|
||||
global _norm_page_size
|
||||
from common import _norm_system_id
|
||||
|
||||
if _norm_page_size != len(_system_page_map):
|
||||
_norm_page_cache.clear()
|
||||
for known, page in _system_page_map.items():
|
||||
key = _norm_system_id(known)
|
||||
if _norm_page_cache.get(key, page) != page:
|
||||
_norm_page_cache[key] = None
|
||||
else:
|
||||
_norm_page_cache[key] = page
|
||||
_norm_page_size = len(_system_page_map)
|
||||
return _norm_page_cache.get(_norm_system_id(sys_id))
|
||||
|
||||
|
||||
def _system_link(sys_id: str, prefix: str = "") -> str:
|
||||
"""Generate a markdown link to a system page with anchor."""
|
||||
if sys_id in _system_page_map:
|
||||
slug, console = _system_page_map[sys_id]
|
||||
page = _system_page_map.get(sys_id) or _page_by_norm(sys_id)
|
||||
if page:
|
||||
slug, console = page
|
||||
anchor = _slugify_anchor(console)
|
||||
return f"[{sys_id}]({prefix}systems/{slug}.md#{anchor})"
|
||||
return sys_id
|
||||
|
||||
@@ -56,5 +56,45 @@ class LinksFollowContent(unittest.TestCase):
|
||||
self.assertEqual(place and place[1], console)
|
||||
|
||||
|
||||
class OtherSpellingsOfOneSystem(unittest.TestCase):
|
||||
"""Platforms and profiles spell systems their own way: the RetroArch page
|
||||
listed no emulator for sega-mega-drive although genesis_plus_gx declares
|
||||
sega-megadrive, and 2,057 of 4,215 emulator system lines had no link."""
|
||||
|
||||
def test_a_platform_system_finds_its_emulators(self):
|
||||
index = gs._build_emulator_file_index({
|
||||
"genesis_plus_gx": {"systems": ["sega-megadrive"]},
|
||||
"np2kai": {"systems": ["pc-98"]},
|
||||
})
|
||||
self.assertEqual(gs._system_emulators("sega-mega-drive", index), ["genesis_plus_gx"])
|
||||
self.assertEqual(gs._system_emulators("nintendo-snes", index), [])
|
||||
|
||||
def test_a_profile_spelling_links_to_the_platform_page(self):
|
||||
import siterender
|
||||
|
||||
saved = dict(siterender._system_page_map)
|
||||
self.addCleanup(lambda: (siterender._system_page_map.clear(),
|
||||
siterender._system_page_map.update(saved)))
|
||||
siterender._system_page_map.clear()
|
||||
siterender._system_page_map["sega-mega-drive"] = ("sega", "Mega Drive")
|
||||
self.assertIn("systems/sega.md#mega-drive", siterender._system_link("sega-megadrive"))
|
||||
siterender._system_page_map["megadrive"] = ("other", "Elsewhere")
|
||||
self.assertEqual(siterender._system_link("sega-megadrive"), "sega-megadrive")
|
||||
|
||||
def test_a_system_only_profiles_name_is_placed_by_their_files(self):
|
||||
import siterender
|
||||
|
||||
saved = dict(siterender._system_page_map)
|
||||
self.addCleanup(lambda: (siterender._system_page_map.clear(),
|
||||
siterender._system_page_map.update(saved)))
|
||||
siterender._system_page_map.clear()
|
||||
manufacturers = {"Commodore": {"PET": [{"name": "basic4.bin"}]}}
|
||||
profiles = {"vice_xpet": {"systems": ["commodore-pet"],
|
||||
"files": [{"name": "basic4.bin"}]}}
|
||||
gs._build_system_page_map_from_data(
|
||||
manufacturers, {}, {"files": {}, "indexes": {}}, profiles)
|
||||
self.assertEqual(siterender._system_page_map["commodore-pet"], ("commodore", "PET"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user