Files
wehub-resource-sync 2114b14ee0
Sync main into demo / sync (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:26 +08:00

65 lines
1.8 KiB
JavaScript

/**
* Backfill cached high-resolution artwork pointers for existing Spotify seed data.
*
* This does not download files. It records the deterministic Apple artwork URL that
* can later be mirrored into mobilegym-data/spotify/images and rewritten to CDN paths.
*/
import { existsSync, readFileSync, writeFileSync } from 'fs';
import { dirname, resolve } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const DATA_DIR = resolve(__dirname, '../data');
const FILES = [
'defaults.json',
'playlistTracks.json',
'artistTracks.json',
'searchResults.json',
'albumTracks.json',
];
const APPLE_ARTWORK_SIZE_RE = /\/(\d+)x(\d+)(bb)?(?=\.[a-z0-9]+(?:\?|$))/i;
function inferLargeArtworkUrl(raw) {
if (typeof raw !== 'string' || !raw) return '';
const resized = raw.replace(APPLE_ARTWORK_SIZE_RE, '/1000x1000$3');
return resized === raw ? '' : resized;
}
function backfill(value) {
const walk = (node) => {
let changed = 0;
if (Array.isArray(node)) {
for (const item of node) {
changed += walk(item);
}
return changed;
}
if (!node || typeof node !== 'object') return 0;
if (typeof node.cover === 'string' && !node.coverLarge) {
const large = inferLargeArtworkUrl(node.cover);
if (large) {
node.coverLarge = large;
changed += 1;
}
}
for (const child of Object.values(node)) changed += walk(child);
return changed;
};
return walk(value);
}
for (const file of FILES) {
const path = resolve(DATA_DIR, file);
if (!existsSync(path)) continue;
const data = JSON.parse(readFileSync(path, 'utf8'));
const changed = backfill(data);
if (changed > 0) {
writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
}
console.log(`${file}: ${changed} coverLarge field(s) added`);
}