Files
pokemon/scripts/pc-import-staging.py
ginnoir 0537ceba5d Sync catalog with vault: engine facet, Jaizu Emerald set, and PC placements.
Add engine annotation + MOC/wiki export support, a PC import staging helper, and refresh catalog.json after placing gated fan-games and new hack notes.
2026-06-23 00:35:16 -05:00

102 lines
3.8 KiB
Python

#!/usr/bin/env python3
"""Repack staged PC downloads from /tmp/pc-import into roms/windows/."""
import os
import subprocess
import tempfile
import zipfile
import shutil
DEST = "/storage1/Emulation/roms/windows"
STAGE = "/tmp/pc-import"
def repack_rar_to_zip(rar_path, dest_zip):
tmp = tempfile.mkdtemp(prefix="pcrepack_")
try:
r = subprocess.run(["bsdtar", "-xf", rar_path, "-C", tmp], capture_output=True, text=True)
if r.returncode != 0:
return False, "bsdtar: " + (r.stderr or r.stdout)[:200]
tmp_zip = dest_zip + ".part"
with zipfile.ZipFile(tmp_zip, "w", zipfile.ZIP_DEFLATED) as z:
for root, _, files in os.walk(tmp):
for fn in files:
fp = os.path.join(root, fn)
z.write(fp, os.path.relpath(fp, tmp))
os.replace(tmp_zip, dest_zip)
has_exe = any(fn.lower() == "game.exe" for fn in os.listdir(tmp))
return True, f"{os.path.getsize(dest_zip):,} bytes, Game.exe={has_exe}"
finally:
shutil.rmtree(tmp, ignore_errors=True)
def merge_zip_overlay(base_zip, overlay_zip, dest_zip):
tmp = tempfile.mkdtemp(prefix="pcmerge_")
try:
with zipfile.ZipFile(base_zip) as z:
z.extractall(tmp)
with zipfile.ZipFile(overlay_zip) as z:
z.extractall(tmp)
tmp_zip = dest_zip + ".part"
with zipfile.ZipFile(tmp_zip, "w", zipfile.ZIP_DEFLATED) as z:
for root, _, files in os.walk(tmp):
for fn in files:
fp = os.path.join(root, fn)
z.write(fp, os.path.relpath(fp, tmp))
os.replace(tmp_zip, dest_zip)
has_exe = os.path.exists(os.path.join(tmp, "Game.exe"))
return True, f"{os.path.getsize(dest_zip):,} bytes, Game.exe={has_exe}"
finally:
shutil.rmtree(tmp, ignore_errors=True)
def apply_deserted():
base_rar = update_rar = None
for fn in os.listdir(STAGE):
if "Deserted" not in fn:
continue
if "1.4" in fn:
update_rar = os.path.join(STAGE, fn)
else:
base_rar = os.path.join(STAGE, fn)
if not base_rar:
return False, "base rar missing"
tmp = tempfile.mkdtemp(prefix="pcdeserted_")
try:
r = subprocess.run(["bsdtar", "-xf", base_rar, "-C", tmp], capture_output=True, text=True)
if r.returncode != 0:
return False, "base extract: " + (r.stderr or "")[:120]
if update_rar:
r = subprocess.run(["bsdtar", "-xf", update_rar, "-C", tmp], capture_output=True, text=True)
if r.returncode != 0:
return False, "update extract: " + (r.stderr or "")[:120]
dest_zip = os.path.join(DEST, "Pokemon - Deserted (Hack).zip")
tmp_zip = dest_zip + ".part"
with zipfile.ZipFile(tmp_zip, "w", zipfile.ZIP_DEFLATED) as z:
for root, _, files in os.walk(tmp):
for fn in files:
fp = os.path.join(root, fn)
z.write(fp, os.path.relpath(fp, tmp))
os.replace(tmp_zip, dest_zip)
has_exe = os.path.exists(os.path.join(tmp, "Game.exe"))
return True, f"{os.path.getsize(dest_zip):,} bytes, Game.exe={has_exe}, update={bool(update_rar)}"
finally:
shutil.rmtree(tmp, ignore_errors=True)
def main():
os.makedirs(DEST, exist_ok=True)
for label, fn in [
("bushido", lambda: repack_rar_to_zip(
f"{STAGE}/bushido.rar", f"{DEST}/Pokemon - bushido (Hack).zip")),
("rejuvenation", lambda: merge_zip_overlay(
f"{STAGE}/rejuvenation.zip", f"{STAGE}/rejuvenation-patch.zip",
f"{DEST}/Pokemon - Rejuvenation (Hack).zip")),
("deserted", apply_deserted),
]:
ok, msg = fn()
print(f"{label}: {ok} {msg}")
if __name__ == "__main__":
main()