diff --git a/scripts/igir-dorename.sh b/scripts/igir-dorename.sh new file mode 100644 index 0000000..73fc226 --- /dev/null +++ b/scripts/igir-dorename.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# scripts/igir-dorename.sh (runs ON valhalla) +# +# igir 'move' to canonical No-Intro/Redump names, in place, for one platform. +# Records a before/after filename manifest under /storage1/igir/manifests for +# reversibility. Unmatched files are left untouched; --dir-game-subdir never +# keeps the folder flat (EmuDeck expects flat per-platform dirs). +# +# Only run on platforms that scored healthy in igir-dryrun.sh (>=~80% identified) +# AND have no co-located saves keyed to ROM basenames (renaming would orphan +# them) AND are NOT disc systems with .m3u multi-disc playlists (renaming the +# images breaks the playlists). Carts are the safe case. +# +# ssh ginnoir@valhalla 'bash -s -- gb "no-intro/Nintendo - Game Boy.dat"' < scripts/igir-dorename.sh +# # or, already deployed on the host: +# ssh ginnoir@valhalla 'bash /storage1/igir/dorename.sh nes "no-intro/Nintendo - Nintendo Entertainment System.dat"' +# +# Undo: the before-manifest lists original names; igir is deterministic, so +# re-running against the same DAT is idempotent. +set -uo pipefail +plat="$1"; shift +dargs=(); for d in "$@"; do dargs+=(-d "/dats/$d"); done +mkdir -p /storage1/igir/manifests +before="/storage1/igir/manifests/${plat}-before.txt" +after="/storage1/igir/manifests/${plat}-after.txt" +ls -1 "/storage1/Emulation/roms/$plat" > "$before" +docker run --rm \ + -v /storage1/Emulation/roms:/input \ + -v /storage1/igir/dats/libretro-database/metadat:/dats:ro \ + -v /storage1/igir/reports:/output \ + node:lts npx -y igir@latest move "${dargs[@]}" \ + --dir-game-subdir never \ + -i "/input/$plat" -o "/input/$plat" 2>&1 \ + | grep -vE "npm notice|npm warn" || true +ls -1 "/storage1/Emulation/roms/$plat" > "$after" +echo "RENAME $plat: before_files=$(wc -l < "$before") after_files=$(wc -l < "$after")" diff --git a/scripts/igir-dryrun.sh b/scripts/igir-dryrun.sh new file mode 100644 index 0000000..8f042f9 --- /dev/null +++ b/scripts/igir-dryrun.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# scripts/igir-dryrun.sh (runs ON valhalla) +# +# Read-only igir REPORT for one platform folder against the given DAT(s), then a +# checksum-status summary + a sample of unmatched files. Used to score a platform +# ("identified%") before deciding whether to canonicalize it with igir-dorename.sh. +# +# DAT paths are relative to libretro-database/metadat (so "no-intro/..." or +# "redump/...") — the cache populated by scripts/igir-report.ps1. +# +# ssh ginnoir@valhalla 'bash -s -- gb "no-intro/Nintendo - Game Boy.dat"' < scripts/igir-dryrun.sh +# # or, already deployed on the host: +# ssh ginnoir@valhalla 'bash /storage1/igir/dryrun.sh nes "no-intro/Nintendo - Nintendo Entertainment System.dat"' +set -uo pipefail +plat="$1"; shift +dargs=(); for d in "$@"; do dargs+=(-d "/dats/$d"); done +out="_dry_${plat}.csv" +docker run --rm \ + -v /storage1/Emulation/roms:/input:ro \ + -v /storage1/igir/dats/libretro-database/metadat:/dats:ro \ + -v /storage1/igir/reports:/output \ + node:lts npx -y igir@latest report "${dargs[@]}" \ + -i "/input/$plat" --report-output "/output/$out" 2>&1 \ + | grep -E "files found|games," || true +python3 - "/storage1/igir/reports/$out" <<'PY' +import csv,sys +name=sys.argv[1].split('/')[-1] +found=unused=dup=missing=0; samp=[] +with open(sys.argv[1],newline='',encoding='utf-8',errors='replace') as fh: + for r in csv.DictReader(fh): + s=r.get('Status','') + if s=='FOUND': found+=1 + elif s=='UNUSED': + unused+=1 + if len(samp)<10: samp.append(r.get('ROM Files') or r.get('Game Name','')) + elif s=='DUPLICATE': dup+=1 + elif s=='MISSING': missing+=1 +den=found+dup+unused +pct=100.0*(found+dup)/den if den else 0 +print(f"SUMMARY {name}: identified={pct:.1f}% matched={found+dup}/{den} FOUND={found} DUP={dup} UNUSED={unused} MISSING={missing}") +for x in samp: print(" UNUSED:",x) +PY