feat: skip a verified placeholder file in The Only Doe 0.05 instead of failing the media conversion
gui/journal_icon.png in that build is a text note ("PLACEHOLDER: Download a journal icon...") with an
.svg next to it, so Ren'Py cannot load it either. A build can now list placeholder files by path and
SHA-256; only an exact match is skipped and the report carries a non-blocking warning. The full
conversion of the game (2898 files, 2.77 GB) now finishes without failed media.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b3f435f416
commit
25bd39dd43
3 files changed
+32
-2
No files matched your search
@@ -86,7 +86,7 @@ def convert_archive(archive: Path, filename: str, work: Path, progress: Progress
|
||||
return profile.convert(detection.root, work, progress)
|
||||
game_dir = find_game_dir(src_root)
|
||||
|
||||
from app.games.renpy_builds import identify, prepare_source, skipped_files, waive_known
|
||||
from app.games.renpy_builds import identify, placeholder_files, prepare_source, skipped_files, waive_known
|
||||
build = identify(game_dir) # before the archives are unpacked and scripts decompiled
|
||||
rpas = sorted(game_dir.rglob("*.rpa"))
|
||||
for i, rpa in enumerate(rpas, 1):
|
||||
@@ -125,8 +125,11 @@ def convert_archive(archive: Path, filename: str, work: Path, progress: Progress
|
||||
|
||||
files: dict[str, dict[str, Any]] = {}
|
||||
aliases: dict[str, str] = {}
|
||||
placeholders = placeholder_files(build, game_dir)
|
||||
for p in sorted(placeholders):
|
||||
data.warn("Файл-заглушка оригинала не конвертируется", p.relative_to(game_dir).as_posix(), blocking=False)
|
||||
media = [p for p in game_dir.rglob("*")
|
||||
if p.is_file() and assets.kind_of(p) and not _is_engine_file(game_dir, p)]
|
||||
if p.is_file() and assets.kind_of(p) and not _is_engine_file(game_dir, p) and p not in placeholders]
|
||||
counts = {"image": 0, "audio": 0, "video": 0, "font": 0}
|
||||
failed: list[str] = []
|
||||
done = 0
|
||||
|
||||
@@ -92,6 +92,8 @@ BUILDS: dict[str, dict] = {
|
||||
},
|
||||
"bb19a33af00324fa027a629c052aee885e72f1b7bee7074403a5b9e20c69e2d8": {
|
||||
"id": "renpy/the-only-doe-0.05",
|
||||
# The author left a text note instead of a picture; Ren'Py cannot load it either (there is an .svg next to it)
|
||||
"placeholders": {"gui/journal_icon.png": "4b45bd642d6e43c85dabb5e8b0df3e52e628cde7640519af1a64751750f6b711"},
|
||||
# One menu branch tests `... before_sleeping=2` (assignment), which Ren'Py cannot compile either:
|
||||
# sleep.rpyc holds the same text. The port corrects the operator; the digest pins the exact line.
|
||||
"lines": {
|
||||
@@ -134,6 +136,19 @@ def skipped_files(build_id: str | None) -> set[str]:
|
||||
return {name.lower() for name in build.get("skip", ())} if build else set()
|
||||
|
||||
|
||||
def placeholder_files(build_id: str | None, game_dir: Path) -> set[Path]:
|
||||
"""Files of the build that carry text instead of media; only an exact SHA-256 match is skipped."""
|
||||
build = next((b for b in BUILDS.values() if b["id"] == build_id), {})
|
||||
found = set()
|
||||
for relative, digest in build.get("placeholders", {}).items():
|
||||
path = game_dir / relative
|
||||
if path.is_file():
|
||||
with path.open("rb") as stream:
|
||||
if hashlib.file_digest(stream, "sha256").hexdigest() == digest:
|
||||
found.add(path)
|
||||
return found
|
||||
|
||||
|
||||
def identify(game_dir: Path) -> str | None:
|
||||
"""The id of a known build, or None."""
|
||||
build = BUILDS.get(fingerprint(game_dir))
|
||||
|
||||
@@ -71,3 +71,15 @@ def test_known_build_line_patch_requires_the_exact_line():
|
||||
assert renpy_builds.prepare_source("renpy/the-only-doe-0.05", "other.rpy", source) == source
|
||||
edited = source.replace("spitroast", "other")
|
||||
assert renpy_builds.prepare_source("renpy/the-only-doe-0.05", "sleep.rpy", edited) == edited
|
||||
|
||||
|
||||
def test_placeholder_media_is_skipped_only_on_an_exact_match(tmp_path):
|
||||
from app.games import renpy_builds
|
||||
|
||||
icon = tmp_path / "gui" / "journal_icon.png"
|
||||
icon.parent.mkdir()
|
||||
icon.write_text("PLACEHOLDER: Download a journal icon from a free resource and save as journal_icon.png in gui folder.")
|
||||
assert renpy_builds.placeholder_files("renpy/the-only-doe-0.05", tmp_path) == {icon}
|
||||
assert renpy_builds.placeholder_files(None, tmp_path) == set()
|
||||
icon.write_text("a real file now")
|
||||
assert renpy_builds.placeholder_files("renpy/the-only-doe-0.05", tmp_path) == set()
|
||||
Reference in new issue
Block a user