#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Patch popadmin.js music() UI to support background image upload/display.""" from __future__ import annotations from pathlib import Path p = Path(__file__).with_name("popadmin.js") c = p.read_text(encoding="utf-8") replacements = [ ( "· 封面/mp3 存 sparkr", "· 封面/背景图/mp3 存 sparkr", ), ( "封面ID曲名会员上架排序音频操作", "封面背景ID曲名会员上架排序音频操作", ), ( "${t.coverUrl ? `\"\"` : '—'}\n" " ${esc(t.id)}", "${t.coverUrl ? `\"\"` : '—'}\n" " ${t.backgroundUrl ? `\"\"` : '—'}\n" " ${esc(t.id)}", ), ( '\n' ' ', '\n' ' \n' ' ', ), ( ": '暂无曲目'", ": '暂无曲目'", ), ] for old, new in replacements: if old not in c: raise SystemExit(f"pattern not found:\n{old[:120]!r}") if old.count(old) != 1 and c.count(old) != 1: raise SystemExit(f"pattern not unique ({c.count(old)}):\n{old[:80]!r}") c = c.replace(old, new, 1) handler_old = """ $('content').querySelectorAll('[data-mcover]').forEach((inp) => { inp.onchange = async () => { if (!inp.files?.[0]) return; const fd = new FormData(); fd.append('file', inp.files[0]); await apiUpload('/spark/music/' + inp.dataset.mcover + '/cover', fd); pages.music(); }; }); $('content').querySelectorAll('[data-maudio]').forEach((inp) => {""" handler_new = """ $('content').querySelectorAll('[data-mcover]').forEach((inp) => { inp.onchange = async () => { if (!inp.files?.[0]) return; const fd = new FormData(); fd.append('file', inp.files[0]); await apiUpload('/spark/music/' + inp.dataset.mcover + '/cover', fd); pages.music(); }; }); $('content').querySelectorAll('[data-mbg]').forEach((inp) => { inp.onchange = async () => { if (!inp.files?.[0]) return; const fd = new FormData(); fd.append('file', inp.files[0]); await apiUpload('/spark/music/' + inp.dataset.mbg + '/background', fd); pages.music(); }; }); $('content').querySelectorAll('[data-maudio]').forEach((inp) => {""" if handler_old not in c: raise SystemExit("cover/audio handlers not found") if "data-mbg" in c and "/background" in c[c.find("async music()") : c.find("async novelCms()")]: print("already patched?") else: c = c.replace(handler_old, handler_new, 1) p.write_text(c, encoding="utf-8") music = c[c.find("async music()") : c.find("async novelCms()")] assert "backgroundUrl" in music assert "data-mbg" in music assert "/background" in music print("patched ok", p, "bytes", p.stat().st_size)