Skip to content

Commit de53e59

Browse files
committed
chunk playlist addition
1 parent c47cefa commit de53e59

File tree

1 file changed

+72
-70
lines changed

1 file changed

+72
-70
lines changed

src/commonMain/kotlin/com.adamratzman.spotify/endpoints/client/ClientPlaylistApi.kt

Lines changed: 72 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
6464
* @return The created [Playlist] object with no tracks
6565
*/
6666
fun createClientPlaylist(
67-
name: String,
68-
description: String? = null,
69-
public: Boolean? = null,
70-
collaborative: Boolean? = null,
71-
user: String = (api as SpotifyClientApi).userId
67+
name: String,
68+
description: String? = null,
69+
public: Boolean? = null,
70+
collaborative: Boolean? = null,
71+
user: String = (api as SpotifyClientApi).userId
7272
): SpotifyRestAction<Playlist> {
7373
if (name.isEmpty()) throw BadRequestException(ErrorObject(400, "Name cannot be empty"))
7474
return toAction {
@@ -78,8 +78,8 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
7878
if (public != null) body += json { "public" to public }
7979
if (collaborative != null) body += json { "collaborative" to collaborative }
8080
post(
81-
EndpointBuilder("/users/${UserUri(user).id.encodeUrl()}/playlists").toString(),
82-
body.toJson()
81+
EndpointBuilder("/users/${UserUri(user).id.encodeUrl()}/playlists").toString(),
82+
body.toJson()
8383
).toObject(Playlist.serializer(), api, json)
8484
}
8585
}
@@ -102,7 +102,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
102102
*/
103103

104104
fun addTrackToClientPlaylist(playlist: String, track: String, position: Int? = null) =
105-
addTracksToClientPlaylist(playlist, track, position = position)
105+
addTracksToClientPlaylist(playlist, track, position = position)
106106

107107
/**
108108
* Add one or more tracks to a user’s playlist.
@@ -113,24 +113,26 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
113113
* **[Api Reference](https://developer.spotify.com/documentation/web-api/reference/playlists/add-tracks-to-playlist/)**
114114
*
115115
* @param playlist The spotify id or uri for the playlist.
116-
* @param tracks Spotify track ids. A maximum of 100 tracks can be added in one request.
116+
* @param tracks Spotify track ids.
117117
* @param position The position to insert the tracks, a zero-based index. For example, to insert the tracks in the
118118
* first position: position=0; to insert the tracks in the third position: position=2. If omitted, the tracks will
119119
* be appended to the playlist. Tracks are added in the order they are listed in the query string or request body.
120120
*
121121
* @throws BadRequestException if any invalid track ids is provided or the playlist is not found
122122
*/
123-
fun addTracksToClientPlaylist(playlist: String, vararg tracks: String, position: Int? = null): SpotifyRestAction<Unit> {
124-
val body = jsonMap()
125-
body += json { "uris" to JsonArray(tracks.map { TrackUri(TrackUri(it).id.encodeUrl()).uri }.map(::JsonPrimitive)) }
126-
if (position != null) body += json { "position" to position }
123+
fun addTracksToClientPlaylist(playlist: String, vararg tracks: String, position: Int? = null): SpotifyRestAction<Unit> {
127124
return toAction {
128-
post(
129-
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/tracks").toString(),
130-
body.toJson()
131-
)
132-
Unit
125+
chunk(100, tracks.toList()) { chunk ->
126+
val body = jsonMap()
127+
body += json { "uris" to JsonArray(chunk.map { TrackUri(TrackUri(it).id.encodeUrl()).uri }.map(::JsonPrimitive)) }
128+
if (position != null) body += json { "position" to position }
129+
post(
130+
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/tracks").toString(),
131+
body.toJson()
132+
)
133+
}
133134
}
135+
134136
}
135137

136138
/**
@@ -150,11 +152,11 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
150152
* @throws BadRequestException if the playlist is not found or parameters exceed the max length
151153
*/
152154
fun changeClientPlaylistDetails(
153-
playlist: String,
154-
name: String? = null,
155-
public: Boolean? = null,
156-
collaborative: Boolean? = null,
157-
description: String? = null
155+
playlist: String,
156+
name: String? = null,
157+
public: Boolean? = null,
158+
collaborative: Boolean? = null,
159+
description: String? = null
158160
): SpotifyRestAction<Unit> {
159161
val body = jsonMap()
160162
if (name != null) body += json { "name" to name }
@@ -185,14 +187,14 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
185187
* @throws BadRequestException if the filters provided are illegal
186188
*/
187189
fun getClientPlaylists(
188-
limit: Int? = api.defaultLimit,
189-
offset: Int? = null
190+
limit: Int? = api.defaultLimit,
191+
offset: Int? = null
190192
): SpotifyRestActionPaging<SimplePlaylist, PagingObject<SimplePlaylist>> {
191193
require(!(limit != null && limit !in 1..50)) { "Limit must be between 1 and 50. Provided $limit" }
192194
require(!(offset != null && offset !in 0..100000)) { "Offset must be between 0 and 100,000. Provided $limit" }
193195
return toActionPaging {
194196
get(EndpointBuilder("/me/playlists").with("limit", limit).with("offset", offset).toString())
195-
.toPagingObject(SimplePlaylist.serializer(), endpoint = this, json = json)
197+
.toPagingObject(SimplePlaylist.serializer(), endpoint = this, json = json)
196198
}
197199
}
198200

@@ -252,11 +254,11 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
252254
* @throws BadRequestException if the playlist is not found or illegal filters are applied
253255
*/
254256
fun reorderClientPlaylistTracks(
255-
playlist: String,
256-
reorderRangeStart: Int,
257-
reorderRangeLength: Int? = null,
258-
insertionPoint: Int,
259-
snapshotId: String? = null
257+
playlist: String,
258+
reorderRangeStart: Int,
259+
reorderRangeLength: Int? = null,
260+
insertionPoint: Int,
261+
snapshotId: String? = null
260262
): SpotifyRestAction<PlaylistSnapshot> {
261263
return toAction {
262264
val body = jsonMap()
@@ -265,8 +267,8 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
265267
if (reorderRangeLength != null) body += json { "range_length" to reorderRangeLength }
266268
if (snapshotId != null) body += json { "snapshot_id" to snapshotId }
267269
put(
268-
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/tracks").toString(),
269-
body.toJson()
270+
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/tracks").toString(),
271+
body.toJson()
270272
).toObject(PlaylistSnapshot.serializer(), api, json)
271273
}
272274
}
@@ -290,8 +292,8 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
290292
val body = jsonMap()
291293
body += json { "uris" to JsonArray(tracks.map { TrackUri(TrackUri(it).id.encodeUrl()).uri }.map(::JsonPrimitive)) }
292294
put(
293-
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/tracks").toString(),
294-
body.toJson()
295+
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/tracks").toString(),
296+
body.toJson()
295297
)
296298
Unit
297299
}
@@ -347,12 +349,12 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
347349
* @throws BadRequestException if invalid data is provided
348350
*/
349351
fun uploadClientPlaylistCover(
350-
playlist: String,
351-
imagePath: String? = null,
352-
imageFile: File? = null,
353-
image: BufferedImage? = null,
354-
imageData: String? = null,
355-
imageUrl: String? = null
352+
playlist: String,
353+
imagePath: String? = null,
354+
imageFile: File? = null,
355+
image: BufferedImage? = null,
356+
imageData: String? = null,
357+
imageUrl: String? = null
356358
): SpotifyRestAction<Unit> {
357359
return toAction {
358360
val data = imageData ?: when {
@@ -363,8 +365,8 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
363365
else -> throw IllegalArgumentException("No cover image was specified")
364366
}
365367
put(
366-
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/images").toString(),
367-
data, contentType = "image/jpeg"
368+
EndpointBuilder("/playlists/${PlaylistUri(playlist).id.encodeUrl()}/images").toString(),
369+
data, contentType = "image/jpeg"
368370
)
369371
Unit
370372
}
@@ -384,10 +386,10 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
384386
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
385387
*/
386388
fun removeTrackFromClientPlaylist(
387-
playlist: String,
388-
track: String,
389-
positions: SpotifyTrackPositions,
390-
snapshotId: String? = null
389+
playlist: String,
390+
track: String,
391+
positions: SpotifyTrackPositions,
392+
snapshotId: String? = null
391393
) = removeTracksFromClientPlaylist(playlist, track to positions, snapshotId = snapshotId)
392394

393395
/**
@@ -403,9 +405,9 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
403405
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
404406
*/
405407
fun removeTrackFromClientPlaylist(
406-
playlist: String,
407-
track: String,
408-
snapshotId: String? = null
408+
playlist: String,
409+
track: String,
410+
snapshotId: String? = null
409411
) = removeTracksFromClientPlaylist(playlist, track, snapshotId = snapshotId)
410412

411413
/**
@@ -421,9 +423,9 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
421423
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
422424
*/
423425
fun removeTracksFromClientPlaylist(
424-
playlist: String,
425-
vararg tracks: String,
426-
snapshotId: String? = null
426+
playlist: String,
427+
vararg tracks: String,
428+
snapshotId: String? = null
427429
) = removePlaylistTracksImpl(playlist, tracks.map { it to null }.toTypedArray(), snapshotId)
428430

429431
/**
@@ -439,15 +441,15 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
439441
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
440442
*/
441443
fun removeTracksFromClientPlaylist(
442-
playlist: String,
443-
vararg tracks: Pair<String, SpotifyTrackPositions>,
444-
snapshotId: String? = null
444+
playlist: String,
445+
vararg tracks: Pair<String, SpotifyTrackPositions>,
446+
snapshotId: String? = null
445447
) = removePlaylistTracksImpl(playlist, tracks.toList().toTypedArray(), snapshotId)
446448

447449
private fun removePlaylistTracksImpl(
448-
playlist: String,
449-
tracks: Array<Pair<String, SpotifyTrackPositions?>>,
450-
snapshotId: String?
450+
playlist: String,
451+
tracks: Array<Pair<String, SpotifyTrackPositions?>>,
452+
snapshotId: String?
451453
): SpotifyRestAction<PlaylistSnapshot> {
452454
return toAction {
453455
require(tracks.isNotEmpty()) { "You need to provide at least one track to remove" }
@@ -456,19 +458,19 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
456458
if (snapshotId != null) body += json { "snapshot_id" to snapshotId }
457459
body += json {
458460
"tracks" to JsonArray(
459-
tracks.map { (track, positions) ->
460-
val json = jsonMap()
461-
json += json { "uri" to TrackUri(track).uri }
462-
if (positions?.positions?.isNotEmpty() == true) json += json {
463-
"positions" to JsonArray(
464-
positions.positions.map(::JsonPrimitive)
465-
)
466-
}
467-
JsonObject(json)
468-
})
461+
tracks.map { (track, positions) ->
462+
val json = jsonMap()
463+
json += json { "uri" to TrackUri(track).uri }
464+
if (positions?.positions?.isNotEmpty() == true) json += json {
465+
"positions" to JsonArray(
466+
positions.positions.map(::JsonPrimitive)
467+
)
468+
}
469+
JsonObject(json)
470+
})
469471
}
470472
delete(
471-
EndpointBuilder("/playlists/${PlaylistUri(playlist).id}/tracks").toString(), body = body.toJson()
473+
EndpointBuilder("/playlists/${PlaylistUri(playlist).id}/tracks").toString(), body = body.toJson()
472474
).toObject(PlaylistSnapshot.serializer(), api, json)
473475
}
474476
}

0 commit comments

Comments
 (0)