Files
SirHumza--orbisRPC/scripts/build_art_table.py
T

84 lines
3.3 KiB
Python

#!/usr/bin/env python3
"""build_art_table.py - resolve Sony CDN artwork for a title list via TMDB.
Runs on the BUILD host (console network blocks TMDB port 80) and emits
orbisrpc/art_table.h: {titleId, name, icon_url} for every resolvable title.
Also downloads each icon into icons/ for the art_base_url pack.
Usage: python3 scripts/build_art_table.py titles.txt [--icons icons/]
Title list: one TITLEID per line (CUSAxxxxx etc.); unknown IDs are skipped.
"""
import hashlib
import hmac
import json
import os
import sys
import urllib.request
KEY = bytes([
0xF5, 0xDE, 0x66, 0xD2, 0x68, 0x0E, 0x25, 0x5B, 0x2D, 0xF7, 0x9E, 0x74,
0xF8, 0x90, 0xEB, 0xF3, 0x49, 0x26, 0x2F, 0x61, 0x8B, 0xCA, 0xE2, 0xA9,
0xAC, 0xCD, 0xEE, 0x51, 0x56, 0xCE, 0x8D, 0xF2, 0xCD, 0xF2, 0xD4, 0x8C,
0x71, 0x17, 0x3C, 0xDC, 0x25, 0x94, 0x46, 0x5B, 0x87, 0x40, 0x5D, 0x19,
0x7C, 0xF1, 0xAE, 0xD3, 0xB7, 0xE9, 0x67, 0x1E, 0xEB, 0x56, 0xCA, 0x67,
0x53, 0xC2, 0xE6, 0xB0,
])
TMDB = "http://tmdb.np.dl.playstation.net"
def c_escape(s):
return s.replace("\\", "\\\\").replace('"', '\\"')
def resolve(tid):
mac = hmac.new(KEY, (tid + "_00\x00").encode("latin1")[:12],
hashlib.sha1).hexdigest().upper()
url = f"{TMDB}/tmdb2/{tid}_00_{mac}/{tid}_00.json"
req = urllib.request.Request(url, headers={"User-Agent": "orbisRPC-arttbl"})
d = json.loads(urllib.request.urlopen(req, timeout=20).read())
name = d["names"][0]["name"]
icon = d["icons"][0]["icon"].replace("http://", "https://")
return name, icon
def main():
titles = [l.strip() for l in open(sys.argv[1]) if l.strip()]
icons = sys.argv[3] if len(sys.argv) > 3 and sys.argv[2] == "--icons" else None
if icons:
os.makedirs(icons, exist_ok=True)
rows = []
for tid in titles:
try:
name, icon = resolve(tid)
except Exception as e:
print(f"MISS {tid}: {str(e)[:60]}", flush=True)
continue
print(f"OK {tid} :: {name}", flush=True)
rows.append((tid, name, icon))
if icons:
try:
img = urllib.request.urlopen(icon, timeout=25).read()
open(os.path.join(icons, tid.lower() + ".png"), "wb").write(img)
except Exception as e:
print(f" icon fetch failed: {str(e)[:60]}", flush=True)
with open("orbisrpc/art_table.h", "w") as f:
f.write("/* art_table.h - GENERATED by scripts/build_art_table.py.\n")
f.write(" * Do not edit: Sony CDN artwork baked at build time so the\n")
f.write(" * console needs no TMDB network access for art.\n")
f.write(f" * Titles: {len(rows)}. */\n")
f.write("#ifndef ORBISRPC_ART_TABLE_H\n#define ORBISRPC_ART_TABLE_H\n")
f.write("#include <stddef.h>\n")
f.write("typedef struct { const char *id; const char *name;"
" const char *icon; } art_entry_t;\n")
f.write("static const art_entry_t ORBISRPC_ART_TABLE[] = {\n")
for tid, name, icon in rows:
f.write(f' {{ "{tid}", "{c_escape(name)}", "{icon}" }},\n')
f.write("};\n#define ORBISRPC_ART_TABLE_N "
f"(sizeof ORBISRPC_ART_TABLE / sizeof ORBISRPC_ART_TABLE[0])\n")
f.write("#endif\n")
print(f"wrote art_table.h with {len(rows)} entries")
if __name__ == "__main__":
main()