fix: iTunes functions fall back to direct Apple API when backend not configured
_iGet now tries backend proxy first (if backendUrl set), falls back to direct Apple API URL so iTunes search/lookup/charts work regardless of backend config. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
063bf64996
commit
55be924805
1 file changed
+36
-14
+36
-14
@@ -39,49 +39,71 @@ export async function ndAuth() {
|
|||||||
return S._ndToken;
|
return S._ndToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── ITUNES (proxied through backend to avoid Apple's browser origin block) ───
|
// ─── ITUNES ───
|
||||||
function _iBase() { return S.cfg.backendUrl || ''; }
|
// Try backend proxy first (avoids Apple's 403 browser-origin block).
|
||||||
|
// Fall back to direct Apple API if no backend is configured or proxy fails.
|
||||||
|
const ITUNES = 'https://itunes.apple.com';
|
||||||
|
const APPLE_RSS = 'https://rss.applemarketingtools.com';
|
||||||
|
|
||||||
async function _iGet(path) {
|
async function _fetch(url) {
|
||||||
try {
|
try {
|
||||||
const r = await fetch(_iBase() + path);
|
const r = await fetch(url);
|
||||||
if (!r.ok) return {};
|
const text = await r.text();
|
||||||
return await r.json();
|
if (!text) return {};
|
||||||
|
return JSON.parse(text);
|
||||||
} catch { return {}; }
|
} catch { return {}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function _iGet(proxyPath, directUrl) {
|
||||||
|
const base = S.cfg.backendUrl;
|
||||||
|
if (base) {
|
||||||
|
const d = await _fetch(base + proxyPath);
|
||||||
|
if (d && Object.keys(d).length) return d;
|
||||||
|
}
|
||||||
|
return directUrl ? _fetch(directUrl) : {};
|
||||||
|
}
|
||||||
|
|
||||||
export async function itunesSearch(query, entity='musicTrack', limit=25) {
|
export async function itunesSearch(query, entity='musicTrack', limit=25) {
|
||||||
const d = await _iGet(`/api/itunes/search?term=${encodeURIComponent(query)}&entity=${entity}&limit=${limit}`);
|
const qs = `term=${encodeURIComponent(query)}&media=music&entity=${entity}&limit=${limit}&country=us&explicit=Yes`;
|
||||||
|
const d = await _iGet(`/api/itunes/search?term=${encodeURIComponent(query)}&entity=${entity}&limit=${limit}`,
|
||||||
|
`${ITUNES}/search?${qs}`);
|
||||||
return d.results || [];
|
return d.results || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function itunesLookupAlbum(collectionId) {
|
export async function itunesLookupAlbum(collectionId) {
|
||||||
const d = await _iGet(`/api/itunes/lookup?id=${collectionId}&entity=song`);
|
const d = await _iGet(`/api/itunes/lookup?id=${collectionId}&entity=song`,
|
||||||
|
`${ITUNES}/lookup?id=${collectionId}&entity=song&explicit=Yes`);
|
||||||
return (d.results || []).filter(x => x.wrapperType === 'track');
|
return (d.results || []).filter(x => x.wrapperType === 'track');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function itunesLookupArtistSongs(artistId, limit=15) {
|
export async function itunesLookupArtistSongs(artistId, limit=15) {
|
||||||
const d = await _iGet(`/api/itunes/lookup?id=${artistId}&entity=song&limit=${limit}`);
|
const d = await _iGet(`/api/itunes/lookup?id=${artistId}&entity=song&limit=${limit}`,
|
||||||
|
`${ITUNES}/lookup?id=${artistId}&entity=song&limit=${limit}&country=us&explicit=Yes`);
|
||||||
return (d.results || []).filter(x => x.wrapperType === 'track');
|
return (d.results || []).filter(x => x.wrapperType === 'track');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function itunesLookupArtistAlbums(artistId, limit=200) {
|
export async function itunesLookupArtistAlbums(artistId, limit=200) {
|
||||||
const d = await _iGet(`/api/itunes/lookup?id=${artistId}&entity=album&limit=${limit}`);
|
const d = await _iGet(`/api/itunes/lookup?id=${artistId}&entity=album&limit=${limit}`,
|
||||||
|
`${ITUNES}/lookup?id=${artistId}&entity=album&limit=${limit}&country=us`);
|
||||||
return (d.results || []).filter(x => x.wrapperType === 'collection' && x.collectionType === 'Album');
|
return (d.results || []).filter(x => x.wrapperType === 'collection' && x.collectionType === 'Album');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function itunesTopCharts() {
|
export async function itunesTopCharts() {
|
||||||
for (const country of ['de', 'us']) {
|
for (const country of ['de', 'us']) {
|
||||||
const d = await _iGet(`/api/itunes/charts?type=albums&country=${country}`);
|
const d = await _iGet(`/api/itunes/charts?type=albums&country=${country}`,
|
||||||
if (d.results?.length) return d.results;
|
`${APPLE_RSS}/api/v2/${country}/music/most-played/50/albums.json`);
|
||||||
|
const results = d.results || d.feed?.results;
|
||||||
|
if (results?.length) return results;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function itunesTopSongs() {
|
export async function itunesTopSongs() {
|
||||||
for (const country of ['de', 'us']) {
|
for (const country of ['de', 'us']) {
|
||||||
const d = await _iGet(`/api/itunes/charts?type=songs&country=${country}`);
|
const d = await _iGet(`/api/itunes/charts?type=songs&country=${country}`,
|
||||||
if (d.results?.length) return d.results;
|
`${APPLE_RSS}/api/v2/${country}/music/most-played/50/songs.json`);
|
||||||
|
const results = d.results || d.feed?.results;
|
||||||
|
if (results?.length) return results;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user