diff --git a/scripts/check_platform_folder.py b/scripts/check_platform_folder.py index b803c6f9..f57e86cd 100644 --- a/scripts/check_platform_folder.py +++ b/scripts/check_platform_folder.py @@ -14,23 +14,29 @@ from pathlib import Path API = "https://abdess.github.io/retrobios/api/v1/platforms/" +# The digest each check mode compares. A mode missing here (existence) only +# asks that the file be present. +DIGESTS = {"md5": "md5", "sha1": "sha1"} + + def accepts(entry: dict, path: Path, mode: str) -> bool: """Whether the platform's own check passes the file at path.""" + digest = DIGESTS.get(mode) raw = entry.get(mode) or "" values = raw if isinstance(raw, list) else str(raw).split(",") declared = [value.strip().lower() for value in values if value.strip()] - if mode == "existence" or not declared: + if digest is None or not declared: return path.is_file() # nothing to compare: the platform checks presence try: if entry.get("zipped_file"): # the hash of one member, its name casefolded with zipfile.ZipFile(path) as archive: names = {name.casefold(): name for name in archive.namelist()} member = names.get(entry["zipped_file"].casefold()) - return bool(member) and hashlib.new(mode, archive.read(member)).hexdigest() in declared - actual = hashlib.new(mode, path.read_bytes()).hexdigest() + return bool(member) and hashlib.new(digest, archive.read(member)).hexdigest() in declared + actual = hashlib.new(digest, path.read_bytes()).hexdigest() if entry.get("zip_digest") != "composite" and any(actual.startswith(d) for d in declared): return True # a truncated md5 (Batocera) compares by its prefix - if mode == "md5" and path.suffix.lower() == ".zip": # Recalbox: members in name order + if digest == DIGESTS["md5"] and path.suffix.lower() == ".zip": # Recalbox: members in name order with zipfile.ZipFile(path) as archive: names = sorted(name for name in archive.namelist() if not name.endswith("/")) return hashlib.md5(b"".join(map(archive.read, names))).hexdigest() in declared diff --git a/scripts/generate_site.py b/scripts/generate_site.py index a2220819..c2e33910 100644 --- a/scripts/generate_site.py +++ b/scripts/generate_site.py @@ -6100,7 +6100,6 @@ def _directory_copies(entry: dict, consumers: FileConsumers) -> list[str]: f"([browse]({tree}))"] -ROMSET_FAQ = "../wiki/technical-faq.md#which-mame-version-do-the-arcade-bios-sets-match" _MAME_RELEASE = re.compile(r"^0\.\d") @@ -8473,7 +8472,7 @@ def generate_which_pack() -> str: *setup_picker(registry, display), "## Folders and ZIP files { #manual-download }", "", - "- A big ZIP comes in parts. Download every part.", + "- A big ZIP comes in parts, like `Pack.part1of2.zip`. Download every part.", "- Unzip them into your BIOS folder. Put the files straight in it, " "not in a new folder.", "- Leave the ZIPs inside, like `neogeo.zip`, as they are.", diff --git a/tests/test_site_r2_nav.py b/tests/test_site_r2_nav.py index 50c1a40f..0510ced7 100644 --- a/tests/test_site_r2_nav.py +++ b/tests/test_site_r2_nav.py @@ -291,7 +291,7 @@ class PlatformShareCards(unittest.TestCase): def test_other_pages_keep_their_section_card(self): self.assertEqual(sitestarlight.og_image("platforms/index.md", "setup"), f"{sitestarlight.SITE_URL}assets/og/setup.png") - # A manufacturer page has its own card since round 3 (6.6); one + # A manufacturer page has its own card since round 3 (6.6). One # without a rendered card keeps its section's. self.assertEqual(sitestarlight.og_image("systems/sony.md", "explore"), f"{sitestarlight.SITE_URL}assets/og/systems/sony.png") diff --git a/wiki/faq.md b/wiki/faq.md index 3ae3cd47..f9109a35 100644 --- a/wiki/faq.md +++ b/wiki/faq.md @@ -15,7 +15,7 @@ order: 50 ## How do I know which BIOS I need? -Run the command with `--dry-run`. It lists the files and changes nothing. +Run the command with `--dry-run`. It lists the files, changing nothing. ```sh @@ -34,8 +34,8 @@ Flycast's **Language** option. ## Zip or unzip? { #zip-or-unzip } -Unzip the ZIP you downloaded into the folder your setup's page names. Leave -the ZIPs inside as they are, like `neogeo.zip`. +Unzip the ZIP you downloaded into the folder your setup's page names. Keep +the ZIPs inside zipped, like `neogeo.zip`. ## Does a BIOS work on every setup? @@ -60,9 +60,10 @@ Sometimes. Some emulators carry a stand-in, and some games then fail. ## Is the command safe? { #is-piping-the-installer-into-a-shell-safe } -- It checks the installer's fingerprint, then each file before saving it. +- It stops if the installer does not match its expected fingerprint, then + checks each file before saving it. - It writes in your BIOS folder, and for some emulators in your save folder. -- It never changes or deletes a game or a save. +- It never touches a game or a save. - It keeps any file it replaces in `retrobios-backup`, next to your BIOS folder. `--restore` puts it back.