Skip to content

Commit 937a860

Browse files
authored
Merge pull request #228 from adamint/dev
3.3.0 release
2 parents 9a0ccec + 675e415 commit 937a860

File tree

68 files changed

+2201
-2724
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2201
-2724
lines changed

README.md

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ This is the [Kotlin](https://kotlinlang.org/) implementation of the [Spotify Web
2323
+ [Using the API](#using-the-api)
2424
* [Tips](#tips)
2525
+ [Building the API](#building-the-api)
26-
+ [What is the SpotifyRestAction class?](#what-is-the-spotifyrestaction-class)
27-
+ [SpotifyRestPagingAction](#spotifyrestpagingaction)
2826
* [Notes](#notes)
2927
+ [The benefits of LinkedResults, PagingObjects, and Cursor-based Paging Objects](#the-benefits-of-linkedresults-pagingobjects-and-cursor-based-paging-objects)
3028
+ [Generic Requests](#generic-request)
@@ -39,7 +37,7 @@ repositories {
3937
jcenter()
4038
}
4139
42-
implementation("com.adamratzman:spotify-api-kotlin-core:3.2.15")
40+
implementation("com.adamratzman:spotify-api-kotlin-core:3.3.0")
4341
```
4442

4543
Note that images and profiles are not supported on the Kotlin/JS target.
@@ -109,7 +107,7 @@ Example creation (default settings)
109107

110108
```kotlin
111109
val api = spotifyAppApi("clientId", "clientSecret").build() // create and build api
112-
println(api.browse.getNewReleases().complete()) // use it
110+
println(api.browse.getNewReleases()) // use it
113111
```
114112

115113
Example creation, using an existing Token and setting automatic token refresh to false
@@ -123,7 +121,7 @@ val api = spotifyAppApi(
123121
automaticRefresh = false
124122
)
125123
)
126-
println(api.browse.getNewReleases().complete()) // use it
124+
println(api.browse.getNewReleases()) // use it
127125
```
128126

129127
### SpotifyClientApi
@@ -205,7 +203,7 @@ val api = spotifyClientPkceApi(
205203
retryWhenRateLimited = false
206204
)
207205
).build()
208-
println(api.library.getSavedTracks().complete().take(10).filterNotNull().map { it.track.name })
206+
println(api.library.getSavedTracks().take(10).filterNotNull().map { it.track.name })
209207
```
210208

211209
#### Non-PKCE (backend applications, requires client secret)
@@ -238,7 +236,7 @@ val api = spotifyClientApi(
238236
"your-redirect-uri",
239237
authCode
240238
).build() // create and build api
241-
println(api.personalization.getTopTracks(limit = 5).complete().items.map { it.name }) // print user top tracks
239+
println(api.personalization.getTopTracks(limit = 5).items.map { it.name }) // print user top tracks
242240
```
243241

244242
##### Example: You've saved a user's token from previous authorization and need to create an api instance.
@@ -256,7 +254,7 @@ val api = spotifyClientApi(
256254
}
257255
)
258256
).build()
259-
println(api.personalization.getTopTracks(limit = 5).complete().items.map { it.name })
257+
println(api.personalization.getTopTracks(limit = 5).items.map { it.name })
260258
```
261259

262260

@@ -293,7 +291,7 @@ val api = spotifyImplicitGrantApi(
293291
null,
294292
token
295293
) // create api. there is no need to build it
296-
println(api.personalization.getTopArtists(limit = 1).complete()[0].name) // use it
294+
println(api.personalization.getTopArtists(limit = 1)[0].name) // use it
297295
```
298296

299297
### SpotifyApiBuilder Block & setting API options
@@ -356,45 +354,13 @@ APIs available only in `SpotifyClientApi` and `SpotifyImplicitGrantApi` instance
356354
## Tips
357355

358356
### Building the API
359-
The easiest way to build the API is synchronously using .build() after a builder
360-
361-
```kotlin
362-
spotifyAppApi(clientId, clientSecret).build()
363-
```
364-
365-
You can also build the API asynchronously using Kotlin coroutines.
357+
The easiest way to build the API is using .build() after a builder
366358
```kotlin
367359
runBlocking {
368-
spotifyAppApi(clientId, clientSecret).buildAsyncAt(this) { api ->
369-
// do things
370-
}
360+
val api = spotifyAppApi(clientId, clientSecret).build()
371361
}
372362
```
373363

374-
### What is the SpotifyRestAction class?
375-
Abstracting requests into a `SpotifyRestAction` class allows for a lot of flexibility in sending and receiving requests.
376-
This class includes options for asynchronous and blocking execution in all endpoints. However,
377-
due to this, you **must** call one of the provided methods in order for the call
378-
to execute! The `SpotifyRestAction` provides many methods and fields for use, including blocking and asynchronous ones. For example,
379-
- `hasRun()` tells you whether the rest action has been *started*
380-
- `hasCompleted()` tells you whether this rest action has been fully executed and *completed*
381-
- `complete()` blocks the current thread and returns the result
382-
- `suspendComplete(context: CoroutineContext = Dispatchers.Default)` switches to given context, invokes the supplier, and synchronously retrieves the result.
383-
- `suspendQueue()` suspends the coroutine, invokes the supplier asynchronously, and resumes with the result
384-
- `queue()` executes and immediately returns
385-
- `queue(consumer: (T) -> Unit)` executes the provided callback as soon as the request
386-
is asynchronously evaluated
387-
- `queueAfter(quantity: Int, timeUnit: TimeUnit, consumer: (T) -> Unit)` executes the
388-
provided callback after the provided time. As long as supplier execution is less than the provided
389-
time, this will likely be accurate within a few milliseconds.
390-
- `asFuture()` transforms the supplier into a `CompletableFuture` (only JVM)
391-
392-
### SpotifyRestPagingAction
393-
Separate from, but a superset of SpotifyRestAction, this specialized implementation of RestActions includes extensions
394-
for `AbstractPagingObject` (`PagingObject` and `CursorBasedPagingObject`). This class gives you the same functionality as SpotifyRestAction,
395-
but you also have the ability to retrieve *all* of its items or linked PagingObjects, or a *subset* of its items or linked PagingObjects with one call, with
396-
a single method call to `getAllItems()` or `getAllPagingObjects()`, or `getWithNext(total: Int, context: CoroutineContext = Dispatchers.Default)` or `getWithNextItems(total: Int, context: CoroutineContext = Dispatchers.Default)` respectively
397-
398364
## Notes
399365
### The benefits of LinkedResults, PagingObjects, and Cursor-based Paging Objects
400366
Spotify provides these three object models in order to simplify our lives as developers. So let's see what we
@@ -430,22 +396,17 @@ val api = spotifyAppApi(
430396
System.getenv("SPOTIFY_CLIENT_SECRET")
431397
).build()
432398

433-
// block and print out the names of the twenty most similar songs to the search
434-
println(api.search.searchTrack("Début de la Suite").complete().joinToString { it.name })
435-
436-
// now, let's do it asynchronously
437-
api.search.searchTrack("Début de la Suite").queue { tracks -> println(tracks.joinToString { track -> track.name }) }
399+
// print out the names of the twenty most similar songs to the search
400+
println(api.search.searchTrack("Début de la Suite").joinToString { it.name })
438401

439402
// simple, right? what about if we want to print out the featured playlists message from the "Overview" tab?
440-
println(api.browse.getFeaturedPlaylists().complete().message)
403+
println(api.browse.getFeaturedPlaylists().message)
441404

442405
// easy! let's try something a little harder
443406
// let's find out Bénabar's Spotify ID, find his top tracks, and print them out
444-
445-
val benabarId = api.search.searchArtist("Bénabar").complete()[0].id
446-
// this works; a redundant way would be: api.artists.getArtist("spotify:artist:6xoAWsIOZxJVPpo7Qvqaqv").complete().id
447-
448-
println(api.artists.getArtistTopTracks(benabarId).complete().joinToString { it.name })
407+
val benabarId = api.search.searchArtist("Bénabar")[0].id
408+
// this works; a redundant way would be: api.artists.getArtist("spotify:artist:6xoAWsIOZxJVPpo7Qvqaqv").id
409+
println(api.artists.getArtistTopTracks(benabarId).joinToString { it.name })
449410
```
450411

451412
### Track Relinking

build.gradle.kts

Lines changed: 30 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import org.jetbrains.dokka.gradle.DokkaTask
2+
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
23
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackOutput.Target
34

45
plugins {
56
`maven-publish`
67
signing
78
id("io.codearte.nexus-staging") version "0.22.0"
89
kotlin("multiplatform") version "1.4.21"
9-
kotlin("plugin.serialization") version "1.4.10"
10+
kotlin("plugin.serialization") version "1.4.21"
1011
id("com.diffplug.gradle.spotless") version "4.4.0"
1112
id("com.moowork.node") version "1.3.1"
1213
id("org.jetbrains.dokka") version "1.4.20"
@@ -35,7 +36,7 @@ dependencies {
3536
}
3637

3738
group = "com.adamratzman"
38-
version = "3.2.15"
39+
version = "3.3.0"
3940

4041
tasks.withType<Test> {
4142
this.testLogging {
@@ -68,7 +69,7 @@ android {
6869
testOptions {
6970
@Suppress("UNCHECKED_CAST")
7071
this.unitTests.all(closureOf<Test> {
71-
this.useJUnitPlatform()
72+
// this.useJUnitPlatform()
7273
} as groovy.lang.Closure<Test>)
7374
}
7475
sourceSets {
@@ -95,6 +96,10 @@ kotlin {
9596
explicitApiWarning()
9697

9798
android {
99+
compilations.all {
100+
kotlinOptions.jvmTarget = "1.8"
101+
}
102+
98103
mavenPublication {
99104
artifactId = "spotify-api-kotlin-android"
100105
setupPom(artifactId)
@@ -106,40 +111,52 @@ kotlin {
106111
}
107112

108113
jvm {
114+
compilations.all {
115+
kotlinOptions.jvmTarget = "1.8"
116+
}
117+
testRuns["test"].executionTask.configure {
118+
useJUnit()
119+
}
120+
109121
mavenPublication {
110122
artifactId = "spotify-api-kotlin"
111123
setupPom(artifactId)
112124
}
113125
}
114126

115-
js(BOTH) {
127+
js(KotlinJsCompilerType.LEGACY) {
116128
mavenPublication {
117129
artifactId = "spotify-api-kotlin-js"
118130
setupPom(artifactId)
119131
}
120132

121133
browser {
122-
dceTask {
123-
keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
124-
}
125-
126134
webpackTask {
127135
output.libraryTarget = Target.UMD
128136
}
129137

130138
testTask {
131-
enabled = false
139+
useKarma {
140+
useChromeHeadless()
141+
webpackConfig.cssSupport.enabled = true
142+
}
143+
// this.
132144
}
133145
}
134146

135-
nodejs()
147+
nodejs {
148+
testTask {
149+
useMocha {
150+
timeout = "5000"
151+
}
152+
}
153+
}
136154
}
137155

138156
targets {
139157
sourceSets {
140158
val coroutineVersion = "1.4.2"
141159
val serializationVersion = "1.0.1"
142-
val spekVersion = "2.0.15"
143160
val ktorVersion = "1.4.1"
144161

145162
val commonMain by getting {
@@ -153,7 +170,6 @@ kotlin {
153170
dependencies {
154171
implementation(kotlin("test-common"))
155172
implementation(kotlin("test-annotations-common"))
156-
implementation("org.spekframework.spek2:spek-dsl-metadata:$spekVersion")
157173
}
158174
}
159175

@@ -170,12 +186,8 @@ kotlin {
170186

171187
val jvmTest by getting {
172188
dependencies {
173-
implementation(kotlin("test"))
174189
implementation(kotlin("test-junit"))
175-
implementation("org.junit.jupiter:junit-jupiter:5.6.2")
176190
implementation("com.sparkjava:spark-core:2.9.3")
177-
implementation("org.spekframework.spek2:spek-dsl-jvm:$spekVersion")
178-
runtimeOnly("org.spekframework.spek2:spek-runner-junit5:$spekVersion")
179191
runtimeOnly(kotlin("reflect"))
180192
}
181193
}
@@ -186,13 +198,14 @@ kotlin {
186198
implementation("io.ktor:ktor-client-js:$ktorVersion")
187199
implementation(npm("abort-controller", "3.0.0"))
188200
implementation(npm("node-fetch", "2.6.0"))
201+
implementation(kotlin("stdlib-js"))
202+
189203
}
190204
}
191205

192206
val jsTest by getting {
193207
dependencies {
194208
implementation(kotlin("test-js"))
195-
implementation("org.spekframework.spek2:spek-dsl-js:$spekVersion")
196209
}
197210
}
198211

@@ -211,13 +224,9 @@ kotlin {
211224

212225
val androidTest by getting {
213226
dependencies {
214-
implementation(kotlin("test"))
215227
implementation(kotlin("test-junit"))
216-
implementation("org.junit.jupiter:junit-jupiter:5.6.2")
217228
implementation("com.sparkjava:spark-core:2.9.3")
218229
implementation("org.mockito:mockito-core:3.3.3")
219-
implementation("org.spekframework.spek2:spek-dsl-jvm:$spekVersion")
220-
runtimeOnly("org.spekframework.spek2:spek-runner-junit5:$spekVersion")
221230
runtimeOnly(kotlin("reflect"))
222231
}
223232
}
@@ -270,40 +279,6 @@ signing {
270279
tasks {
271280
val dokkaHtml by getting(DokkaTask::class) {
272281
outputDirectory.set(projectDir.resolve("docs"))
273-
274-
dokkaSourceSets {
275-
val js by creating {
276-
sourceLink {
277-
localDirectory.set(file("src"))
278-
remoteUrl.set(uri("https://github.com/adamint/spotify-web-api-kotlin/tree/master/").toURL())
279-
remoteLineSuffix.set("#L")
280-
}
281-
}
282-
val jvm by creating {
283-
sourceLink {
284-
localDirectory.set(file("src"))
285-
remoteUrl.set(uri("https://github.com/adamint/spotify-web-api-kotlin/tree/master/").toURL())
286-
remoteLineSuffix.set("#L")
287-
288-
}
289-
}
290-
291-
register("common") {
292-
sourceLink {
293-
localDirectory.set(file("src"))
294-
remoteUrl.set(uri("https://github.com/adamint/spotify-web-api-kotlin/tree/master/").toURL())
295-
remoteLineSuffix.set("#L")
296-
}
297-
}
298-
299-
register("global") {
300-
sourceLink {
301-
localDirectory.set(file("src"))
302-
remoteUrl.set(uri("https://github.com/adamint/spotify-web-api-kotlin/tree/master/").toURL())
303-
remoteLineSuffix.set("#L")
304-
}
305-
}
306-
}
307282
}
308283

309284
spotless {
@@ -319,10 +294,6 @@ tasks {
319294
}
320295

321296

322-
getByName<Test>("jvmTest") {
323-
useJUnitPlatform()
324-
}
325-
326297
val publishJvm by registering(Task::class) {
327298
dependsOn.add(check)
328299
dependsOn.add(dokkaHtml)

karma.config.d/karma.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
config.set({
2+
client: {
3+
mocha: {
4+
timeout: 5000
5+
}
6+
}
7+
})

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pluginManagement {
2-
val mainKotlinVersion = "1.4.0"
2+
val mainKotlinVersion = "1.4.21"
33

44
resolutionStrategy {
55
eachPlugin {

0 commit comments

Comments
 (0)