(TEMPORARY) stop DDOSING apis on search

This commit is contained in:
Eduard Prigoana 2026-02-04 23:12:58 +02:00
parent 2bde639ca6
commit 015003225c
3 changed files with 45 additions and 57 deletions

View file

@ -304,10 +304,10 @@ export class LosslessAPI {
const data = await response.json(); const data = await response.json();
const normalized = this.normalizeSearchResponse(data, 'tracks'); const normalized = this.normalizeSearchResponse(data, 'tracks');
const preparedTracks = normalized.items.map((t) => this.prepareTrack(t)); const preparedTracks = normalized.items.map((t) => this.prepareTrack(t));
const enrichedTracks = await this.enrichTracksWithAlbumDates(preparedTracks); // Note: Skipping enrichTracksWithAlbumDates for search results to avoid excessive album API calls
const result = { const result = {
...normalized, ...normalized,
items: enrichedTracks, items: preparedTracks,
}; };
await this.cache.set('search_tracks', query, result); await this.cache.set('search_tracks', query, result);

View file

@ -215,33 +215,26 @@ export const apiSettings = {
const targetUrls = instancesObj[type] || instancesObj.api || []; const targetUrls = instancesObj[type] || instancesObj.api || [];
if (targetUrls.length === 0) return []; if (targetUrls.length === 0) return [];
// Use cached speed results to sort if available, but DON'T run new speed tests
// Speed tests should only run explicitly via refreshSpeedTests() to avoid
// mass /track API calls when playing a song
const speedCache = this.getCachedSpeedTests(); const speedCache = this.getCachedSpeedTests();
// Construct cache key based on type
const getCacheKey = (u) => (type === 'streaming' ? `${u}#streaming` : u); const getCacheKey = (u) => (type === 'streaming' ? `${u}#streaming` : u);
const urlsToTest = targetUrls.filter((url) => !speedCache.speeds[getCacheKey(url)]); // Sort by cached speeds if we have any cached data
const hasCachedData = targetUrls.some((url) => speedCache.speeds[getCacheKey(url)]);
if (urlsToTest.length > 0) { if (hasCachedData) {
const results = await this.testSpecificUrls(urlsToTest, type); const sortedList = [...targetUrls].sort((a, b) => {
this.updateSpeedCache(results);
Object.assign(speedCache, this.getCachedSpeedTests());
}
const sortList = (list) => {
return [...list].sort((a, b) => {
const speedA = speedCache.speeds[getCacheKey(a)]?.speed ?? Infinity; const speedA = speedCache.speeds[getCacheKey(a)]?.speed ?? Infinity;
const speedB = speedCache.speeds[getCacheKey(b)]?.speed ?? Infinity; const speedB = speedCache.speeds[getCacheKey(b)]?.speed ?? Infinity;
return speedA - speedB; return speedA - speedB;
}); });
}; return sortedList;
}
const sortedList = sortList(targetUrls); // No cached data - return in default order without testing
return targetUrls;
// Persist the sorted order
instancesObj[type] = sortedList;
this.saveInstances(instancesObj);
return sortedList;
}, },
async refreshSpeedTests() { async refreshSpeedTests() {

View file

@ -1510,44 +1510,39 @@ export class UIRenderer {
const signal = this.searchAbortController.signal; const signal = this.searchAbortController.signal;
try { try {
const [tracksResult, artistsResult, albumsResult, playlistsResult] = await Promise.all([ // Optimize: Only make 2 API calls (tracks and playlists), extract artists/albums from tracks
const [tracksResult, playlistsResult] = await Promise.all([
this.api.searchTracks(query, { signal }), this.api.searchTracks(query, { signal }),
this.api.searchArtists(query, { signal }),
this.api.searchAlbums(query, { signal }),
this.api.searchPlaylists(query, { signal }), this.api.searchPlaylists(query, { signal }),
]); ]);
let finalTracks = tracksResult.items; let finalTracks = tracksResult.items;
let finalArtists = artistsResult.items;
let finalAlbums = albumsResult.items;
let finalPlaylists = playlistsResult.items; let finalPlaylists = playlistsResult.items;
if (finalArtists.length === 0 && finalTracks.length > 0) { // Extract artists from tracks
const artistMap = new Map(); const artistMap = new Map();
finalTracks.forEach((track) => { finalTracks.forEach((track) => {
if (track.artist && !artistMap.has(track.artist.id)) { if (track.artist && !artistMap.has(track.artist.id)) {
artistMap.set(track.artist.id, track.artist); artistMap.set(track.artist.id, track.artist);
} }
if (track.artists) { if (track.artists) {
track.artists.forEach((artist) => { track.artists.forEach((artist) => {
if (!artistMap.has(artist.id)) { if (!artistMap.has(artist.id)) {
artistMap.set(artist.id, artist); artistMap.set(artist.id, artist);
} }
}); });
} }
}); });
finalArtists = Array.from(artistMap.values()); let finalArtists = Array.from(artistMap.values());
}
if (finalAlbums.length === 0 && finalTracks.length > 0) { // Extract albums from tracks
const albumMap = new Map(); const albumMap = new Map();
finalTracks.forEach((track) => { finalTracks.forEach((track) => {
if (track.album && !albumMap.has(track.album.id)) { if (track.album && !albumMap.has(track.album.id)) {
albumMap.set(track.album.id, track.album); albumMap.set(track.album.id, track.album);
} }
}); });
finalAlbums = Array.from(albumMap.values()); let finalAlbums = Array.from(albumMap.values());
}
if (finalTracks.length) { if (finalTracks.length) {
this.renderListWithTracks(tracksContainer, finalTracks, true); this.renderListWithTracks(tracksContainer, finalTracks, true);
@ -1658,10 +1653,10 @@ export class UIRenderer {
dateDisplay = dateDisplay =
window.innerWidth > 768 window.innerWidth > 768
? releaseDate.toLocaleDateString('en-US', { ? releaseDate.toLocaleDateString('en-US', {
year: 'numeric', year: 'numeric',
month: 'long', month: 'long',
day: 'numeric', day: 'numeric',
}) })
: year; : year;
} }
} }
@ -2395,9 +2390,9 @@ export class UIRenderer {
<span>${artist.popularity}% popularity</span> <span>${artist.popularity}% popularity</span>
<div class="artist-tags"> <div class="artist-tags">
${(artist.artistRoles || []) ${(artist.artistRoles || [])
.filter((role) => role.category) .filter((role) => role.category)
.map((role) => `<span class="artist-tag">${role.category}</span>`) .map((role) => `<span class="artist-tag">${role.category}</span>`)
.join('')} .join('')}
</div> </div>
`; `;