(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 normalized = this.normalizeSearchResponse(data, 'tracks');
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 = {
...normalized,
items: enrichedTracks,
items: preparedTracks,
};
await this.cache.set('search_tracks', query, result);

View file

@ -215,33 +215,26 @@ export const apiSettings = {
const targetUrls = instancesObj[type] || instancesObj.api || [];
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();
// Construct cache key based on type
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) {
const results = await this.testSpecificUrls(urlsToTest, type);
this.updateSpeedCache(results);
Object.assign(speedCache, this.getCachedSpeedTests());
}
const sortList = (list) => {
return [...list].sort((a, b) => {
if (hasCachedData) {
const sortedList = [...targetUrls].sort((a, b) => {
const speedA = speedCache.speeds[getCacheKey(a)]?.speed ?? Infinity;
const speedB = speedCache.speeds[getCacheKey(b)]?.speed ?? Infinity;
return speedA - speedB;
});
};
return sortedList;
}
const sortedList = sortList(targetUrls);
// Persist the sorted order
instancesObj[type] = sortedList;
this.saveInstances(instancesObj);
return sortedList;
// No cached data - return in default order without testing
return targetUrls;
},
async refreshSpeedTests() {

View file

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