Skip to content

Commit f9f485e

Browse files
authored
Merge branch 'dev' into serialization
2 parents a8d3711 + ced8d66 commit f9f485e

File tree

19 files changed

+132
-113
lines changed

19 files changed

+132
-113
lines changed

build.gradle.kts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
21
import org.jetbrains.dokka.gradle.DokkaTask
32
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
43

54
plugins {
65
`maven-publish`
76
signing
87
`java-library`
9-
id("io.codearte.nexus-staging") version "0.21.1"
8+
id("io.codearte.nexus-staging") version "0.21.2"
109
kotlin("multiplatform") version "1.3.61"
1110
kotlin("plugin.serialization") version "1.3.61"
12-
id("com.diffplug.gradle.spotless") version "3.26.0"
11+
id("com.diffplug.gradle.spotless") version "3.26.1"
1312
id("com.moowork.node") version "1.3.1"
1413
id("org.jetbrains.dokka") version "0.10.0"
1514
}
1615

1716
group = "com.adamratzman"
18-
version = "3.0.0-rc.5"
17+
version = "3.0.0"
1918

2019
java {
2120
withSourcesJar()
@@ -34,10 +33,10 @@ kotlin {
3433

3534
targets {
3635
sourceSets {
37-
val coroutineVersion = "1.3.2"
36+
val coroutineVersion = "1.3.3"
3837
val serializationVersion = "0.14.0"
39-
val spekVersion = "2.0.8"
40-
val ktorVersion = "1.2.6"
38+
val spekVersion = "2.0.9"
39+
val ktorVersion = "1.3.0-rc2"
4140

4241
val commonMain by getting {
4342
dependencies {
@@ -62,7 +61,6 @@ kotlin {
6261
}
6362

6463
dependencies {
65-
implementation("com.neovisionaries:nv-i18n:1.26")
6664
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion")
6765
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion")
6866
implementation("io.ktor:ktor-client-apache:$ktorVersion")
@@ -74,7 +72,7 @@ kotlin {
7472
dependencies {
7573
implementation(kotlin("test"))
7674
implementation(kotlin("test-junit"))
77-
implementation("org.junit.jupiter:junit-jupiter:5.5.2")
75+
implementation("org.junit.jupiter:junit-jupiter:5.6.0-M1")
7876
implementation("org.spekframework.spek2:spek-dsl-jvm:$spekVersion")
7977
runtimeOnly("org.spekframework.spek2:spek-runner-junit5:$spekVersion")
8078
runtimeOnly(kotlin("reflect"))
@@ -83,7 +81,7 @@ kotlin {
8381

8482
val jsMain by getting {
8583
dependencies {
86-
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.3.2")
84+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutineVersion")
8785
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion")
8886
implementation("io.ktor:ktor-client-js:$ktorVersion")
8987
compileOnly(kotlin("stdlib-js"))

src/commonMain/kotlin/com.adamratzman.spotify/SpotifyApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ class SpotifyClientApi internal constructor(
413413
val userId: String
414414

415415
init {
416-
userId = users.getUserProfile().complete().id
416+
userId = users.getClientProfile().complete().id
417417
}
418418

419419
/**

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

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
5959
*
6060
* @return The created [Playlist] object with no tracks
6161
*/
62-
fun createPlaylist(
62+
fun createClientPlaylist(
6363
name: String,
6464
description: String? = null,
6565
public: Boolean? = null,
@@ -95,8 +95,8 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
9595
* @throws BadRequestException if any invalid track ids is provided or the playlist is not found
9696
*/
9797

98-
fun addTrackToPlaylist(playlist: String, track: String, position: Int? = null) =
99-
addTracksToPlaylist(playlist, track, position = position)
98+
fun addTrackToClientPlaylist(playlist: String, track: String, position: Int? = null) =
99+
addTracksToClientPlaylist(playlist, track, position = position)
100100

101101
/**
102102
* Add one or more tracks to a user’s playlist.
@@ -112,7 +112,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
112112
*
113113
* @throws BadRequestException if any invalid track ids is provided or the playlist is not found
114114
*/
115-
fun addTracksToPlaylist(playlist: String, vararg tracks: String, position: Int? = null): SpotifyRestAction<Unit> {
115+
fun addTracksToClientPlaylist(playlist: String, vararg tracks: String, position: Int? = null): SpotifyRestAction<Unit> {
116116
val body = jsonMap()
117117
body += json { "uris" to JsonArray(tracks.map { TrackUri(TrackUri(it).id.encodeUrl()).uri }.map(::JsonPrimitive)) }
118118
if (position != null) body += json { "position" to position }
@@ -139,7 +139,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
139139
*
140140
* @throws BadRequestException if the playlist is not found or parameters exceed the max length
141141
*/
142-
fun changePlaylistDetails(
142+
fun changeClientPlaylistDetails(
143143
playlist: String,
144144
name: String? = null,
145145
public: Boolean? = null,
@@ -172,7 +172,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
172172
*
173173
* @throws BadRequestException if the filters provided are illegal
174174
*/
175-
fun getPlaylists(
175+
fun getClientPlaylists(
176176
limit: Int? = null,
177177
offset: Int? = null
178178
): SpotifyRestActionPaging<SimplePlaylist, PagingObject<SimplePlaylist>> {
@@ -185,7 +185,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
185185
}
186186

187187
/**
188-
* Find a client playlist by its id. If you want to find multiple playlists, consider using [getPlaylists]
188+
* Find a client playlist by its id. If you want to find multiple playlists, consider using [getClientPlaylists]
189189
*
190190
* **Note that** private playlists are only retrievable for the current user and require the [SpotifyScope.PLAYLIST_READ_PRIVATE] scope
191191
* to have been authorized by the user. Note that this scope alone will not return a collaborative playlist, even
@@ -197,9 +197,9 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
197197
*
198198
* @return A possibly-null [SimplePlaylist] if the playlist doesn't exist
199199
*/
200-
fun getPlaylist(id: String): SpotifyRestAction<SimplePlaylist?> {
200+
fun getClientPlaylist(id: String): SpotifyRestAction<SimplePlaylist?> {
201201
return toAction {
202-
val playlists = getPlaylists().complete()
202+
val playlists = getClientPlaylists().complete()
203203
playlists.items.find { it.id == id } ?: playlists.getAllItems().complete().find { it.id == id }
204204
}
205205
}
@@ -211,7 +211,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
211211
*
212212
* @param playlist playlist id
213213
*/
214-
fun deletePlaylist(playlist: String): SpotifyRestAction<Unit> {
214+
fun deleteClientPlaylist(playlist: String): SpotifyRestAction<Unit> {
215215
return (api as SpotifyClientApi).following.unfollowPlaylist(PlaylistUri(playlist).id)
216216
}
217217

@@ -235,7 +235,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
235235
*
236236
* @throws BadRequestException if the playlist is not found or illegal filters are applied
237237
*/
238-
fun reorderPlaylistTracks(
238+
fun reorderClientPlaylistTracks(
239239
playlist: String,
240240
reorderRangeStart: Int,
241241
reorderRangeLength: Int? = null,
@@ -267,7 +267,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
267267
*
268268
* @throws BadRequestException if playlist is not found or illegal tracks are provided
269269
*/
270-
fun setPlaylistTracks(playlist: String, vararg tracks: String): SpotifyRestAction<Unit> {
270+
fun setClientPlaylistTracks(playlist: String, vararg tracks: String): SpotifyRestAction<Unit> {
271271
return toAction {
272272
val body = jsonMap()
273273
body += json { "uris" to JsonArray(tracks.map { TrackUri(TrackUri(it).id.encodeUrl()).uri }.map(::JsonPrimitive)) }
@@ -291,14 +291,14 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
291291
*
292292
* @throws BadRequestException if playlist is not found or illegal tracks are provided
293293
*/
294-
fun replacePlaylistTracks(playlist: String, vararg tracks: String) = setPlaylistTracks(playlist, *tracks)
294+
fun replaceClientPlaylistTracks(playlist: String, vararg tracks: String) = setClientPlaylistTracks(playlist, *tracks)
295295

296296
/**
297297
* Remove all the tracks in a playlist
298298
* @param playlist the spotify id or uri for the playlist.
299299
*/
300-
fun removeAllPlaylistTracks(playlist: String): SpotifyRestAction<Unit> {
301-
return setPlaylistTracks(playlist)
300+
fun removeAllClientPlaylistTracks(playlist: String): SpotifyRestAction<Unit> {
301+
return setClientPlaylistTracks(playlist)
302302
}
303303

304304
/**
@@ -322,7 +322,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
322322
* @throws IIOException if the image is not found
323323
* @throws BadRequestException if invalid data is provided
324324
*/
325-
fun uploadPlaylistCover(
325+
fun uploadClientPlaylistCover(
326326
playlist: String,
327327
imagePath: String? = null,
328328
imageFile: File? = null,
@@ -357,12 +357,12 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
357357
* @param positions The positions at which the track is located in the playlist
358358
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
359359
*/
360-
fun removeTrackFromPlaylist(
360+
fun removeTrackFromClientPlaylist(
361361
playlist: String,
362362
track: String,
363363
positions: SpotifyTrackPositions,
364364
snapshotId: String? = null
365-
) = removeTracksFromPlaylist(playlist, track to positions, snapshotId = snapshotId)
365+
) = removeTracksFromClientPlaylist(playlist, track to positions, snapshotId = snapshotId)
366366

367367
/**
368368
* Remove all occurrences of a track from the specified playlist.
@@ -374,11 +374,11 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
374374
* @param track The track id
375375
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
376376
*/
377-
fun removeTrackFromPlaylist(
377+
fun removeTrackFromClientPlaylist(
378378
playlist: String,
379379
track: String,
380380
snapshotId: String? = null
381-
) = removeTracksFromPlaylist(playlist, track, snapshotId = snapshotId)
381+
) = removeTracksFromClientPlaylist(playlist, track, snapshotId = snapshotId)
382382

383383
/**
384384
* Remove all occurrences of the specified tracks from the given playlist.
@@ -390,7 +390,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
390390
* @param tracks An array of track ids
391391
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
392392
*/
393-
fun removeTracksFromPlaylist(
393+
fun removeTracksFromClientPlaylist(
394394
playlist: String,
395395
vararg tracks: String,
396396
snapshotId: String? = null
@@ -406,7 +406,7 @@ class ClientPlaylistApi(api: SpotifyApi<*, *>) : PlaylistApi(api) {
406406
* @param tracks An array of [Pair]s of track ids *and* track positions (zero-based)
407407
* @param snapshotId The playlist snapshot against which to apply this action. **recommended to have**
408408
*/
409-
fun removeTracksFromPlaylist(
409+
fun removeTracksFromClientPlaylist(
410410
playlist: String,
411411
vararg tracks: Pair<String, SpotifyTrackPositions>,
412412
snapshotId: String? = null

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ class ClientProfileApi(api: SpotifyApi<*, *>) : UserApi(api) {
2626
*
2727
* @return Never-null [SpotifyUserInformation] object with possibly-null country, email, subscription and birthday fields
2828
*/
29-
fun getUserProfile(): SpotifyRestAction<SpotifyUserInformation> {
29+
fun getClientProfile(): SpotifyRestAction<SpotifyUserInformation> {
3030
return toAction {
3131
get(EndpointBuilder("/me").toString()).toObject(SpotifyUserInformation.serializer(), api, json)
3232
}
3333
}
34+
35+
@Deprecated("Renamed to use `client` instead of `user`", ReplaceWith("getClientProfile"))
36+
fun getUserProfile() = getClientProfile()
3437
}

src/commonMain/kotlin/com.adamratzman.spotify/http/HttpConnection.kt

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ import io.ktor.client.HttpClient
99
import io.ktor.client.features.ResponseException
1010
import io.ktor.client.request.HttpRequestBuilder
1111
import io.ktor.client.request.header
12+
import io.ktor.client.request.request
1213
import io.ktor.client.request.url
13-
import io.ktor.client.response.readText
14+
import io.ktor.client.statement.readText
1415
import io.ktor.client.utils.EmptyContent
1516
import io.ktor.http.ContentType
1617
import io.ktor.http.HttpMethod
1718
import io.ktor.http.content.ByteArrayContent
1819
import io.ktor.http.content.TextContent
20+
import io.ktor.utils.io.core.toByteArray
1921
import kotlinx.coroutines.CancellationException
2022
import kotlinx.coroutines.delay
21-
import kotlinx.io.core.toByteArray
22-
import kotlinx.io.core.use
2323

2424
enum class HttpRequestMethod(internal val externalMethod: HttpMethod) {
2525
GET(HttpMethod.Get),
@@ -88,39 +88,38 @@ internal class HttpConnection constructor(
8888
val httpRequest = buildRequest(additionalHeaders)
8989

9090
try {
91-
return client.execute(httpRequest).use {
92-
val resp = it.response
93-
val respCode = resp.status.value
91+
return client.request<io.ktor.client.statement.HttpResponse>(httpRequest).let { response ->
92+
val respCode = response.status.value
9493

9594
if (respCode == 502 && retryIf502) {
9695
api?.logger?.logError(
97-
false,
98-
"Received 502 (Invalid response) for URL $url and $this\nRetrying..",
99-
null
96+
false,
97+
"Received 502 (Invalid response) for URL $url and $this\nRetrying..",
98+
null
10099
)
101-
return@use execute(additionalHeaders, retryIf502 = false)
100+
return@let execute(additionalHeaders, retryIf502 = false)
102101
} else if (respCode == 502 && !retryIf502) {
103102
api?.logger?.logWarning("Recieved 502 (Invalid response) for URL $url and $this\nNot retrying")
104103
}
105104

106105
if (respCode == 429) {
107-
val ratelimit = resp.headers["Retry-After"]!!.toLong() + 1L
106+
val ratelimit = response.headers["Retry-After"]!!.toLong() + 1L
108107
if (api?.retryWhenRateLimited == true) {
109108
api.logger.logError(
110-
false,
111-
"The request ($url) was ratelimited for $ratelimit seconds at ${getCurrentTimeMs()}",
112-
null
109+
false,
110+
"The request ($url) was ratelimited for $ratelimit seconds at ${getCurrentTimeMs()}",
111+
null
113112
)
114113

115114
delay(ratelimit * 1000)
116-
return@use execute(additionalHeaders, retryIf502 = retryIf502)
115+
return@let execute(additionalHeaders, retryIf502 = retryIf502)
117116
} else throw SpotifyRatelimitedException(ratelimit)
118117
}
119118

120-
val body = resp.readText()
119+
val body = response.readText()
121120

122121
if (respCode == 401 && body.contains("access token") &&
123-
api != null && api.automaticRefresh
122+
api != null && api.automaticRefresh
124123
) {
125124
api.suspendRefreshToken()
126125
val newAdditionalHeaders = additionalHeaders?.toMutableList() ?: mutableListOf()
@@ -129,14 +128,14 @@ internal class HttpConnection constructor(
129128
}
130129

131130
return HttpResponse(
132-
responseCode = respCode,
133-
body = body,
134-
headers = resp.headers.entries().map { (key, value) ->
135-
HttpHeader(
136-
key,
137-
value.getOrNull(0) ?: "null"
138-
)
139-
}
131+
responseCode = respCode,
132+
body = body,
133+
headers = response.headers.entries().map { (key, value) ->
134+
HttpHeader(
135+
key,
136+
value.getOrNull(0) ?: "null"
137+
)
138+
}
140139
)
141140
}
142141
} catch (e: CancellationException) {

src/commonMain/kotlin/com.adamratzman.spotify/models/Browse.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ data class SpotifyCategory(
3535
*/
3636
@Serializable
3737
data class RecommendationSeed(
38-
@SerialName("href") override val href: String?,
38+
@SerialName("href") override val href: String? = null,
3939
@SerialName("id") override val id: String,
4040

4141
val initialPoolSize: Int,
4242
val afterFilteringSize: Int,
43-
val afterRelinkingSize: Int?,
43+
val afterRelinkingSize: Int? = null,
4444
val type: String
4545
) : Identifiable()
4646

src/commonMain/kotlin/com.adamratzman.spotify/models/PagingObjects.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ class PagingObject<T : Any>(
6262
override val href: String,
6363
override val items: List<T>,
6464
override val limit: Int,
65-
override val next: String?,
65+
override val next: String? = null,
6666
override val offset: Int,
67-
override val previous: String?,
67+
override val previous: String? = null,
6868
override val total: Int = 0
6969
) : AbstractPagingObject<T>(href, items, limit, next, offset, previous, total) {
7070
@Suppress("UNCHECKED_CAST")
@@ -135,7 +135,7 @@ class CursorBasedPagingObject<T : Any>(
135135
override val href: String,
136136
override val items: List<T>,
137137
override val limit: Int,
138-
override val next: String?,
138+
override val next: String? = null,
139139
@SerialName("cursors") val cursor: Cursor,
140140
override val total: Int = 0
141141
) : AbstractPagingObject<T>(href, items, limit, next, 0, null, total) {

0 commit comments

Comments
 (0)