mirror of
https://github.com/SirHumza/orbisRPC.git
synced 2026-10-10 13:00:54 +02:00
84 lines
3.3 KiB
Python
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()
|