Skip to content

Commit 63c5504

Browse files
committed
add getNullable method for 204-available methods, update dependencies
1 parent e741279 commit 63c5504

File tree

9 files changed

+79
-69
lines changed

9 files changed

+79
-69
lines changed

build.gradle.kts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackOutput.Target
55

66
plugins {
77
id("lt.petuska.npm.publish") version "1.1.2"
8-
kotlin("multiplatform") version "1.5.31"
8+
kotlin("multiplatform")
99
`maven-publish`
1010
signing
1111
id("io.codearte.nexus-staging") version "0.30.0"
1212
id("com.android.library")
13-
kotlin("plugin.serialization") version "1.5.31"
14-
id("com.diffplug.spotless") version "5.14.2"
13+
kotlin("plugin.serialization")
14+
id("com.diffplug.spotless") version "6.3.0"
1515
id("com.moowork.node") version "1.3.1"
16-
id("org.jetbrains.dokka") version "1.5.0"
16+
id("org.jetbrains.dokka")
1717
}
1818

1919
repositories {
@@ -27,8 +27,8 @@ buildscript {
2727
mavenCentral()
2828
}
2929
dependencies {
30-
classpath("com.android.tools.build:gradle:4.1.3")
31-
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31")
30+
classpath("com.android.tools.build:gradle:")
31+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:")
3232
}
3333
}
3434

@@ -68,8 +68,9 @@ android {
6868
testOptions {
6969
this.unitTests.isReturnDefaultValues = true
7070
}
71-
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
72-
71+
//sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
72+
sourceSets["main"].setRoot("src/androidMain")
73+
sourceSets["test"].setRoot("src/androidTest")
7374
/*sourceSets {
7475
getByName("main") {
7576
manifest.srcFile("src/androidMain/AndroidManifest.xml")
@@ -95,7 +96,7 @@ kotlin {
9596

9697
android {
9798
compilations.all {
98-
kotlinOptions.jvmTarget = "1.8"
99+
kotlinOptions.jvmTarget = "8"
99100
}
100101

101102
mavenPublication {
@@ -109,7 +110,7 @@ kotlin {
109110

110111
jvm {
111112
compilations.all {
112-
kotlinOptions.jvmTarget = "1.8"
113+
kotlinOptions.jvmTarget = "8"
113114
}
114115
testRuns["test"].executionTask.configure {
115116
useJUnit()
@@ -121,8 +122,7 @@ kotlin {
121122

122123
}
123124

124-
val irOnlyJs = project.hasProperty("irOnly")
125-
js(if (irOnlyJs) KotlinJsCompilerType.IR else KotlinJsCompilerType.BOTH) {
125+
js(KotlinJsCompilerType.IR) {
126126

127127
mavenPublication {
128128
setupPom(artifactId)
@@ -151,7 +151,7 @@ kotlin {
151151
}
152152
}*/
153153

154-
if (irOnlyJs) binaries.executable()
154+
binaries.executable()
155155
}
156156

157157
// val hostOs = System.getProperty("os.name")
@@ -217,13 +217,13 @@ kotlin {
217217
val kotlinxDatetimeVersion = "0.3.1"
218218

219219
sourceSets {
220-
val serializationVersion = "1.3.0"
221-
val ktorVersion = "1.6.3"
220+
val serializationVersion = "1.3.2"
221+
val ktorVersion = "2.0.0-beta-1"
222222
val korlibsVersion = "2.2.0"
223223
val sparkVersion = "2.9.3"
224-
val androidSpotifyAuthVersion = "1.2.3"
224+
val androidSpotifyAuthVersion = "1.2.5"
225225
val androidCryptoVersion = "1.0.0"
226-
val coroutineMTVersion = "1.5.2-native-mt"
226+
val coroutineMTVersion = "1.6.0-native-mt"
227227

228228
val commonMain by getting {
229229
dependencies {
@@ -298,7 +298,7 @@ kotlin {
298298
implementation("com.pnikosis:materialish-progress:1.7")
299299
implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
300300
implementation("androidx.security:security-crypto:$androidCryptoVersion")
301-
implementation("androidx.appcompat:appcompat:1.3.1")
301+
implementation("androidx.appcompat:appcompat:1.4.1")
302302
}
303303
}
304304

gradle.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ org.gradle.jvmargs=-Xmx8000m
1818
kotlin.native.enableDependencyPropagation=false
1919
android.useAndroidX=true
2020
android.enableJetifier=true
21-
kotlin.mpp.enableGranularSourceSetsMetadata=true
21+
kotlin.mpp.enableGranularSourceSetsMetadata=true
22+
kotlinVersion=1.5.31
23+
androidBuildToolsVersion=7.0.0
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

settings.gradle.kts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
pluginManagement {
2-
val mainKotlinVersion = "1.5.0"
2+
val kotlinVersion: String by settings
3+
val androidBuildToolsVersion: String by settings
4+
5+
plugins {
6+
id("org.jetbrains.kotlin.multiplatform").version(kotlinVersion)
7+
id("org.jetbrains.kotlin.plugin.serialization").version(kotlinVersion)
8+
id("org.jetbrains.dokka").version(kotlinVersion)
9+
}
310

411
resolutionStrategy {
512
eachPlugin {
613
if (requested.id.id == "kotlin-multiplatform") {
7-
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$mainKotlinVersion")
14+
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
815
}
916
if (requested.id.id == "org.jetbrains.kotlin.jvm") {
10-
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$mainKotlinVersion")
17+
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
1118
}
1219
if (requested.id.id == "kotlinx-serialization") {
13-
useModule("org.jetbrains.kotlin:kotlin-serialization:$mainKotlinVersion")
14-
} else if (requested.id.namespace == "com.android") {
15-
useModule("com.android.tools.build:gradle:3.5.4")
20+
useModule("org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion")
21+
} else if (requested.id.id == "com.android.library") {
22+
useModule("com.android.tools.build:gradle:$androidBuildToolsVersion")
1623
} else if (requested.id.id == "kotlin-android-extensions") {
17-
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$mainKotlinVersion")
24+
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
1825
}
1926
}
2027
}
@@ -27,7 +34,4 @@ pluginManagement {
2734
}
2835
}
2936

30-
rootProject.name = "spotify-web-api-kotlin"
31-
include("java-interop-basic-sample")
32-
findProject(":java-interop-basic-sample")?.name = "java-interop-basic"
33-
include("java-interop-sample")
37+
rootProject.name = "spotify-web-api-kotlin"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import com.adamratzman.spotify.models.serialization.nonstrictJson
99
import com.adamratzman.spotify.models.serialization.toObject
1010
import com.adamratzman.spotify.utils.urlEncodeBase64String
1111
import com.soywiz.krypto.SHA256
12-
import io.ktor.client.features.ServerResponseException
12+
import io.ktor.client.plugins.ServerResponseException
1313
import io.ktor.utils.io.core.toByteArray
1414
import kotlinx.coroutines.CancellationException
1515
import kotlinx.serialization.json.Json

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.adamratzman.spotify
33

44
import com.adamratzman.spotify.models.AuthenticationError
55
import com.adamratzman.spotify.models.ErrorObject
6-
import io.ktor.client.features.ResponseException
6+
import io.ktor.client.plugins.ResponseException
77

88
public sealed class SpotifyException(message: String, cause: Throwable? = null) : Exception(message, cause) {
99
public abstract class UnNullableException(message: String) : SpotifyException(message)

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,12 @@ public class ClientPlayerApi(api: GenericSpotifyApi) : SpotifyEndpoint(api) {
9393
requireScopes(SpotifyScope.USER_READ_PLAYBACK_STATE)
9494

9595
val obj = catch {
96-
get(
96+
getNullable(
9797
endpointBuilder("/me/player")
9898
.with("additional_types", additionalTypes.joinToString(",") { it.identifier })
9999
.with("market", market?.name)
100100
.toString()
101-
)
102-
.toObject(CurrentlyPlayingContext.serializer(), api, json)
101+
)?.toObject(CurrentlyPlayingContext.serializer(), api, json)
103102
}
104103
return if (obj?.timestamp == null) null else obj
105104
}

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

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.adamratzman.spotify.models.ErrorResponse
1111
import com.adamratzman.spotify.models.serialization.toObject
1212
import com.adamratzman.spotify.utils.ConcurrentHashMap
1313
import com.adamratzman.spotify.utils.getCurrentTimeMs
14+
import io.ktor.http.HttpStatusCode
1415
import kotlin.math.ceil
1516
import kotlinx.coroutines.CancellationException
1617
import kotlinx.coroutines.async
@@ -76,26 +77,30 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
7677

7778

7879
internal suspend fun get(url: String): String {
79-
return execute(url)
80+
return execute<String>(url)
81+
}
82+
83+
internal suspend fun getNullable(url: String): String? {
84+
return execute<String?>(url)
8085
}
8186

8287
internal suspend fun post(url: String, body: String? = null, contentType: String? = null): String {
83-
return execute(url, body, HttpRequestMethod.POST, contentType = contentType)
88+
return execute<String>(url, body, HttpRequestMethod.POST, contentType = contentType)
8489
}
8590

8691
internal suspend fun put(url: String, body: String? = null, contentType: String? = null): String {
87-
return execute(url, body, HttpRequestMethod.PUT, contentType = contentType)
92+
return execute<String>(url, body, HttpRequestMethod.PUT, contentType = contentType)
8893
}
8994

9095
internal suspend fun delete(
9196
url: String,
9297
body: String? = null,
9398
contentType: String? = null
9499
): String {
95-
return execute(url, body, HttpRequestMethod.DELETE, contentType = contentType)
100+
return execute<String>(url, body, HttpRequestMethod.DELETE, contentType = contentType)
96101
}
97102

98-
private suspend fun execute(
103+
private suspend fun <T: String?> execute(
99104
url: String,
100105
body: String? = null,
101106
method: HttpRequestMethod = HttpRequestMethod.GET,
@@ -117,7 +122,7 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
117122
}
118123

119124
try {
120-
return withTimeout(api.spotifyApiOptions.requestTimeoutMillis ?: 100 * 1000L) {
125+
return withTimeout(api.spotifyApiOptions.requestTimeoutMillis ?: (100 * 1000L)) {
121126
try {
122127
val document = createConnection(url, body, method, contentType).execute(
123128
additionalHeaders = cacheState?.eTag?.let {
@@ -126,7 +131,7 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
126131
retryIfInternalServerErrorLeft = api.spotifyApiOptions.retryOnInternalServerErrorTimes
127132
)
128133

129-
handleResponse(document, cacheState, spotifyRequest, retry202) ?: execute(
134+
handleResponse(document, cacheState, spotifyRequest, retry202) ?: execute<T>(
130135
url,
131136
body,
132137
method,
@@ -137,7 +142,7 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
137142
if (e.statusCode == 401 && !attemptedRefresh) {
138143
api.refreshToken()
139144

140-
execute(
145+
execute<T>(
141146
url,
142147
body,
143148
method,
@@ -165,10 +170,13 @@ public abstract class SpotifyEndpoint(public val api: GenericSpotifyApi) {
165170
): String? {
166171
val statusCode = document.responseCode
167172

168-
if (statusCode == HttpConnectionStatus.HTTP_NOT_MODIFIED.code) {
173+
if (statusCode == HttpStatusCode.NotModified.value) {
169174
requireNotNull(cacheState?.eTag) { "304 status only allowed on Etag-able endpoints" }
170175
return cacheState?.data
171176
}
177+
else if (statusCode == HttpStatusCode.NoContent.value) {
178+
return null
179+
}
172180

173181
val responseBody = document.body
174182

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

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ import com.adamratzman.spotify.models.SpotifyRatelimitedException
1212
import com.adamratzman.spotify.models.serialization.nonstrictJson
1313
import com.adamratzman.spotify.models.serialization.toObject
1414
import io.ktor.client.HttpClient
15-
import io.ktor.client.features.ResponseException
15+
import io.ktor.client.plugins.ResponseException
1616
import io.ktor.client.request.HttpRequestBuilder
1717
import io.ktor.client.request.header
1818
import io.ktor.client.request.request
19+
import io.ktor.client.request.setBody
1920
import io.ktor.client.request.url
20-
import io.ktor.client.statement.readText
21+
import io.ktor.client.statement.bodyAsText
2122
import io.ktor.http.ContentType
2223
import io.ktor.http.HttpMethod
2324
import io.ktor.http.content.ByteArrayContent
@@ -61,19 +62,21 @@ public class HttpConnection constructor(
6162
url(this@HttpConnection.url)
6263
method = this@HttpConnection.method.externalMethod
6364

64-
body = when (this@HttpConnection.method) {
65-
HttpRequestMethod.DELETE -> {
66-
bodyString.toByteArrayContent() ?: body
67-
}
68-
HttpRequestMethod.PUT, HttpRequestMethod.POST -> {
69-
val contentString = if (contentType == ContentType.Application.FormUrlEncoded) {
70-
bodyMap?.map { "${it.key}=${it.value}" }?.joinToString("&") ?: bodyString
71-
} else bodyString
65+
setBody(
66+
when (this@HttpConnection.method) {
67+
HttpRequestMethod.DELETE -> {
68+
bodyString.toByteArrayContent() ?: body
69+
}
70+
HttpRequestMethod.PUT, HttpRequestMethod.POST -> {
71+
val contentString = if (contentType == ContentType.Application.FormUrlEncoded) {
72+
bodyMap?.map { "${it.key}=${it.value}" }?.joinToString("&") ?: bodyString
73+
} else bodyString
7274

73-
contentString.toByteArrayContent() ?: ByteArrayContent("".toByteArray(), contentType)
75+
contentString.toByteArrayContent() ?: ByteArrayContent("".toByteArray(), contentType)
76+
}
77+
else -> body
7478
}
75-
else -> body
76-
}
79+
)
7780

7881
// let additionalHeaders overwrite headers
7982
val allHeaders = if (additionalHeaders == null) this@HttpConnection.headers
@@ -91,7 +94,7 @@ public class HttpConnection constructor(
9194
val httpRequest = buildRequest(additionalHeaders)
9295
if (api?.spotifyApiOptions?.enableDebugMode == true) println("DEBUG MODE: Request: $this")
9396
try {
94-
return httpClient.request<io.ktor.client.statement.HttpResponse>(httpRequest).let { response ->
97+
return httpClient.request(httpRequest).let { response ->
9598
val respCode = response.status.value
9699

97100
if (respCode in 500..599 && (retryIfInternalServerErrorLeft == null || retryIfInternalServerErrorLeft == -1 || retryIfInternalServerErrorLeft > 0)) {
@@ -115,12 +118,10 @@ public class HttpConnection constructor(
115118
} else throw SpotifyRatelimitedException(ratelimit)
116119
}
117120

118-
val body = response.readText()
121+
val body: String = response.bodyAsText()
119122
if (api?.spotifyApiOptions?.enableDebugMode == true) println("DEBUG MODE: $body")
120123

121-
if (respCode == 401 && body.contains("access token") &&
122-
api != null && api.spotifyApiOptions.automaticRefresh
123-
) {
124+
if (respCode == 401 && body.contains("access token") && api?.spotifyApiOptions?.automaticRefresh == true) {
124125
api.refreshToken()
125126
val newAdditionalHeaders =
126127
additionalHeaders?.toMutableList()?.filter { it.key != "Authorization" }?.toMutableList()
@@ -146,7 +147,7 @@ public class HttpConnection constructor(
146147
} catch (e: CancellationException) {
147148
throw e
148149
} catch (e: ResponseException) {
149-
val errorBody = e.response.readText()
150+
val errorBody = e.response.bodyAsText()
150151
if (api?.spotifyApiOptions?.enableDebugMode == true) println("DEBUG MODE: $errorBody")
151152
try {
152153
val respCode = e.response.status.value
@@ -222,8 +223,4 @@ public class HttpConnection constructor(
222223
expectSuccess = false
223224
}
224225
}
225-
}
226-
227-
public enum class HttpConnectionStatus(public val code: Int) {
228-
HTTP_NOT_MODIFIED(304);
229-
}
226+
}

0 commit comments

Comments
 (0)