Randoloot/tools/audio/fetch_freighter_sources.py
2026-10-18 15:11:06 +02:00

52 lines
2.3 KiB
Python

"""Download the CC0 source recordings used by build_freighter_audio.py."""
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
import urllib.request
import zipfile
import subprocess
ROOT = Path(__file__).resolve().parents[2]
DEST = ROOT / "tmp" / "freighter_audio_sources"
SOURCES = {
"shop.zip": "https://opengameart.org/sites/default/files/legit_audio_-_the_shop_free_sfx_wav.zip",
"workshop.7z": "https://opengameart.org/sites/default/files/workshop.7z",
"steam.zip": "https://opengameart.org/sites/default/files/steam_hisses.zip",
"scifi.zip": "https://opengameart.org/sites/default/files/sci-fi_sounds.zip",
}
def fetch(entry):
name, url = entry
target = DEST / name
if not target.exists():
request = urllib.request.Request(url, headers={"User-Agent": "Randoloot audio asset preparation"})
with urllib.request.urlopen(request, timeout=90) as response:
target.write_bytes(response.read())
if name.endswith(".zip"):
with zipfile.ZipFile(target) as archive:
names = archive.namelist()
for member in archive.infolist():
output = (DEST / name.removesuffix(".zip") / member.filename).resolve()
if not output.is_relative_to(DEST.resolve()):
raise ValueError("Unsafe archive path")
if not member.is_dir():
output.parent.mkdir(parents=True, exist_ok=True)
output.write_bytes(archive.read(member))
else:
names = subprocess.check_output(["tar", "-tf", str(target)], text=True).splitlines()
folder = DEST / "workshop"
folder.mkdir(exist_ok=True)
for name_in_archive in names:
output = (folder / name_in_archive).resolve()
if not output.is_relative_to(folder.resolve()):
raise ValueError("Unsafe archive path")
subprocess.run(["tar", "-xf", str(target), "-C", str(folder)], check=True)
return name, [name for name in names if name.lower().endswith((".wav", ".ogg", ".txt"))]
if __name__ == "__main__":
DEST.mkdir(parents=True, exist_ok=True)
(DEST / ".gdignore").write_text("")
with ThreadPoolExecutor(max_workers=4) as pool:
for name, files in pool.map(fetch, SOURCES.items()):
print(name)
print("\n".join(files))