tidal: chunk playlist adding, fix next-paging handling
This commit is contained in:
@ -121,8 +121,13 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
|
||||
try {
|
||||
let albumUrl: URL;
|
||||
if (nextLink) {
|
||||
this.logger.debug('getAlbumItems nextPage', nextLink);
|
||||
albumUrl = new URL(nextLink);
|
||||
} else {
|
||||
this.logger.debug(
|
||||
'getAlbumItems albumUrl',
|
||||
`${this.apiBase}/albums/${albumId}/relationships/items`
|
||||
);
|
||||
albumUrl = new URL(`${this.apiBase}/albums/${albumId}/relationships/items`);
|
||||
albumUrl.searchParams.append('countryCode', 'DE');
|
||||
}
|
||||
@ -144,7 +149,12 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
|
||||
return { id: x.id, type: x.type };
|
||||
});
|
||||
if (respData.links?.next) {
|
||||
const nextPage = await this.getAlbumItems(albumId, remaning, respData.links.next);
|
||||
this.logger.debug('getAlbumItems requesting next page', respData.links.next);
|
||||
const nextPage = await this.getAlbumItems(
|
||||
albumId,
|
||||
remaning,
|
||||
this.apiBase + respData.links.next
|
||||
);
|
||||
tracks = tracks.concat(nextPage);
|
||||
}
|
||||
return tracks;
|
||||
@ -243,8 +253,23 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
|
||||
this.logger.error('Could not check for tidal dupes', dbe);
|
||||
}
|
||||
|
||||
// This would be API v2, but that's still in beta and only allows adding an item *before* another one
|
||||
const options: RequestInit = {
|
||||
// Tidal can only handle max. 20 items to be added at once
|
||||
// This isn't documented, but the API helpfully provides a useful error message
|
||||
let chunkSize = 20;
|
||||
const chunkedTracks: { id: string; type: string }[][] = [];
|
||||
let chunkIndex = 0;
|
||||
while (chunkIndex < tracks.length) {
|
||||
chunkedTracks.push(tracks.slice(chunkIndex, chunkIndex + chunkSize));
|
||||
chunkIndex += chunkSize;
|
||||
}
|
||||
|
||||
const apiUrl = new URL(`${this.apiBase}/playlists/${TIDAL_PLAYLIST_ID}/relationships/items`);
|
||||
let options: RequestInit;
|
||||
let request: Request;
|
||||
let resp: Response | null = null;
|
||||
let respTxt: string | null = null;
|
||||
for (let chunk of chunkedTracks) {
|
||||
options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `${token.token_type} ${token.access_token}`,
|
||||
@ -252,17 +277,14 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
|
||||
Accept: 'application/vnd.api+json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: tracks,
|
||||
data: chunk,
|
||||
meta: {
|
||||
positionBefore: 'ffb6286e-237a-4dfc-bbf1-2fb0eb004ed5' // Hardcoded last element of list
|
||||
}
|
||||
})
|
||||
};
|
||||
const apiUrl = new URL(`${this.apiBase}/playlists/${TIDAL_PLAYLIST_ID}/relationships/items`);
|
||||
const request = new Request(apiUrl, options);
|
||||
|
||||
let resp: Response | null = null;
|
||||
let respTxt: string | null = null;
|
||||
request = new Request(apiUrl, options);
|
||||
try {
|
||||
resp = await fetch(request);
|
||||
this.processTidalHeaders(resp.headers);
|
||||
@ -281,7 +303,7 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
|
||||
if (token == null) {
|
||||
return;
|
||||
}
|
||||
this.addToPlaylistRetry(song, remaning--);
|
||||
await this.addToPlaylistRetry(song, remaning--);
|
||||
}
|
||||
} else if (respObj === null) {
|
||||
switch (resp.status) {
|
||||
@ -314,9 +336,8 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
|
||||
'sec'
|
||||
);
|
||||
// Try again secondsToWait sec later, just to be safe one additional second
|
||||
setTimeout(() => {
|
||||
this.addToPlaylistRetry(song, remaning--);
|
||||
}, secondsToWait * 1000);
|
||||
await sleep(secondsToWait * 1000);
|
||||
await this.addToPlaylistRetry(song, remaning--);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -335,6 +356,7 @@ export class TidalPlaylistAdder extends OauthPlaylistAdder implements PlaylistAd
|
||||
this.logger.error('Add to playlist request failed', resp?.status, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
public async addToPlaylist(song: SongInfo) {
|
||||
await this.addToPlaylistRetry(song);
|
||||
}
|
||||
|
Reference in New Issue
Block a user