Skip to content

Commit da889dc

Browse files
authored
Merge pull request #180 from adamint/dev
Update documentation, add samples, add PagingObject#getWithNext
2 parents 77e9b62 + f9ad4bf commit da889dc

File tree

99 files changed

+3865
-1190
lines changed

Some content is hidden

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

99 files changed

+3865
-1190
lines changed

README.md

Lines changed: 137 additions & 111 deletions
Large diffs are not rendered by default.

TESTING.md

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,52 @@
11
# Testing
22

3-
We use [Spek](https://github.com/spekframework/spek) to run unit tests.
3+
We use [Spek](https://github.com/spekframework/spek) to run unit tests. You must add Maven Central to the gradle repositories
4+
in order to pull Spek.
45

5-
To run any test, you must have two environment variables, `SPOTIFY_CLIENT_ID` and `SPOTIFY_CLIENT_SECRET` set to a Spotify application in your current shell.
6+
You must create a Spotify application [here](https://developer.spotify.com/dashboard/applications) to get credentials.
67

7-
`export SPOTIFY_CLIENT_ID=your_client_id`
8+
To run **only** public endpoint tests, run
89

9-
`export SPOTIFY_CLIENT_SECRET=your_client_secret`
10+
`gradle check`
1011

11-
To run **only** public endpoint and utility tests, run `gradle check`
12+
Note: You must have `SPOTIFY_CLIENT_ID` and `SPOTIFY_CLIENT_SECRET` as environment variables.
1213

13-
To run **all** tests, you need a valid Spotify redirect uri, and token (string). These are `SPOTIFY_REDIRECT_URI` and `SPOTIFY_TOKEN_STRING` respectively.
14+
To run **all** tests, you need a valid Spotify application, redirect uri, and token string. use:
1415

15-
Then: `gradle check`
16+
`gradle check`
17+
18+
Note: In addition to `SPOTIFY_CLIENT_ID` and `SPOTIFY_CLIENT_SECRET`, you also must have the following environment
19+
variables set up: `SPOTIFY_REDIRECT_URI` and `SPOTIFY_TOKEN_STRING`
1620

1721
Some tests may fail if you do not allow access to all required scopes. To mitigate this, you can individually grant
1822
each scope or use the following code snippet to print out the Spotify token string (given a generated authorization code)
1923

2024
**How to generate an authorization URL**
2125
```kotlin
22-
import com.adamratzman.spotify.SpotifyScope
23-
import com.adamratzman.spotify.spotifyClientApi
24-
25-
spotifyClientApi {
26-
credentials {
27-
clientId = "YOUR_CLIENT_ID"
28-
clientSecret = "YOUR_CLIENT_SECRET"
29-
redirectUri = "YOUR_REDIRECT_URI"
26+
import com.adamratzman.spotify.main.SpotifyScope
27+
import com.adamratzman.spotify.SpotifyApi.Companion.spotifyClientApi
28+
29+
val api = spotifyClientApi(
30+
"SPOTIFY_CLIENT_ID",
31+
"SPOTIFY_CLIENT_SECRET",
32+
"SPOTIFY_REDIRECT_URI") {
33+
authorization {
34+
tokenString = "SPOTIFY_TOKEN_STRING"
3035
}
3136
}.getAuthorizationUrl(*SpotifyScope.values())
3237

3338
```
3439

3540
**How to get a Spotify token**
3641
```kotlin
37-
import com.adamratzman.spotify.spotifyClientApi
42+
import com.adamratzman.spotify.SpotifyApi.Companion.spotifyClientApi
3843

39-
spotifyClientApi {
40-
credentials {
41-
clientId = "YOUR_CLIENT_ID"
42-
clientSecret = "YOUR_CLIENT_SECRET"
43-
redirectUri = "YOUR_REDIRECT_URI"
44-
}
44+
val api = spotifyClientApi(
45+
"SPOTIFY_CLIENT_ID",
46+
"SPOTIFY_CLIENT_SECRET",
47+
"SPOTIFY_REDIRECT_URI") {
4548
authorization {
46-
authorizationCode = "SPOTIFY_AUTHORIZATION_CODE"
49+
tokenString = "SPOTIFY_TOKEN_STRING"
4750
}
4851
}.build().token.accessToken.let { println(it) }
4952
```

build.gradle.kts

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import org.jetbrains.dokka.gradle.DokkaTask
22
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
3+
import java.net.URI
34

45
plugins {
56
`maven-publish`
@@ -21,6 +22,12 @@ java {
2122
withJavadocJar()
2223
}
2324

25+
tasks.withType<Test> {
26+
this.testLogging {
27+
this.showStandardStreams = true
28+
}
29+
}
30+
2431
repositories {
2532
mavenCentral()
2633
jcenter()
@@ -95,6 +102,9 @@ kotlin {
95102
}
96103
}
97104

105+
all {
106+
languageSettings.useExperimentalAnnotation("kotlin.Experimental")
107+
}
98108
}
99109
}
100110
}
@@ -113,7 +123,7 @@ tasks.named<Test>("jvmTest") {
113123
spotless {
114124
kotlin {
115125
target("**/*.kt")
116-
licenseHeader("/* Spotify Web API - Kotlin Wrapper; MIT License, 2019; Original author: Adam Ratzman */")
126+
licenseHeader("/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2020; Original author: Adam Ratzman */")
117127
ktlint()
118128
}
119129
}
@@ -123,6 +133,10 @@ nexusStaging {
123133
}
124134

125135

136+
tasks.withType<GenerateModuleMetadata> {
137+
enabled = false
138+
}
139+
126140
publishing {
127141
publications {
128142
val jvm by getting(MavenPublication::class) {
@@ -165,17 +179,30 @@ publishing {
165179
}
166180
}
167181
repositories {
168-
maven {
169-
name = "nexus"
170-
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
171-
val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
172-
url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
173-
174-
credentials {
175-
val nexusUsername: String? by project.extra
176-
val nexusPassword: String? by project.extra
177-
username = nexusUsername
178-
password = nexusPassword
182+
if (project.hasProperty("publishToCentral")) {
183+
maven {
184+
name = "nexus"
185+
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
186+
val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
187+
url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
188+
189+
credentials {
190+
val nexusUsername: String? by project.extra
191+
val nexusPassword: String? by project.extra
192+
username = nexusUsername
193+
password = nexusPassword
194+
}
195+
}
196+
} else {
197+
if (project.extra.has("spaceUser") && project.extra.has("spacePassword")) {
198+
maven {
199+
credentials {
200+
username = project.extra["spaceUser"]?.toString()
201+
password = project.extra["spacePassword"]?.toString()
202+
}
203+
204+
url = URI.create("https://maven.jetbrains.space/adam/ratzman")
205+
}
179206
}
180207
}
181208
}

samples/build.gradle

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
plugins {
2+
id 'org.jetbrains.kotlin.jvm' version '1.3.61'
3+
}
4+
5+
group 'com.adamratzman'
6+
version '3.0.0'
7+
8+
repositories {
9+
mavenLocal()
10+
mavenCentral()
11+
}
12+
13+
dependencies {
14+
compile "com.adamratzman:spotify-api-kotlin:3.0.0"
15+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
16+
}
17+
18+
compileKotlin {
19+
kotlinOptions.jvmTarget = "1.8"
20+
}
21+
compileTestKotlin {
22+
kotlinOptions.jvmTarget = "1.8"
23+
}

samples/settings.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
enableFeaturePreview('GRADLE_METADATA')
2+
3+
rootProject.name = 'samples'
4+
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2020; Original author: Adam Ratzman */
2+
package private
3+
4+
import com.adamratzman.spotify.SpotifyApi.Companion.spotifyClientApi
5+
import com.adamratzman.spotify.annotations.SpotifyExperimentalHttpApi
6+
7+
@SpotifyExperimentalHttpApi
8+
fun main() {
9+
// instantiate api
10+
val api = spotifyClientApi(
11+
System.getenv("SPOTIFY_CLIENT_ID"),
12+
System.getenv("SPOTIFY_CLIENT_SECRET"),
13+
System.getenv("SPOTIFY_REDIRECT_URI")) {
14+
authorization {
15+
tokenString = System.getenv("SPOTIFY_TOKEN_STRING")
16+
}
17+
}.build()
18+
19+
// see if you're following playlist "I'm Good Radio"
20+
println(api.following.isFollowingPlaylist("spotify:playlist:37i9dQZF1E8L0j2hm3kP31").complete())
21+
22+
// see if you're following users adamratzman1 and adamratzman
23+
println(api.following.isFollowingUsers("adamratzman1", "adamratzman").complete())
24+
25+
// see if you're following artist Louane
26+
println(api.following.isFollowingArtist("spotify:artist:7wjeXCtRND2ZdKfMJFu6JC").complete())
27+
28+
// get all followed artists, limiting 1 each request
29+
println(api.following.getFollowedArtists(limit = 1).getAllItems().complete())
30+
31+
// follow and unfollow, if you weren't previously following, the artist Louane
32+
33+
val isFollowingLouane = api.following.isFollowingArtist("spotify:artist:7wjeXCtRND2ZdKfMJFu6JC").complete()
34+
35+
if (isFollowingLouane) api.following.unfollowArtist("spotify:artist:7wjeXCtRND2ZdKfMJFu6JC").complete()
36+
api.following.followArtist("spotify:artist:7wjeXCtRND2ZdKfMJFu6JC").complete()
37+
38+
if (!isFollowingLouane) api.following.unfollowArtist("spotify:artist:7wjeXCtRND2ZdKfMJFu6JC").complete()
39+
40+
// follow and unfollow, if you weren't previously following, the user adamratzman1
41+
42+
val isFollowingAdam = api.following.isFollowingUser("adamratzman").complete()
43+
44+
if (isFollowingAdam) api.following.unfollowUser("adamratzman").complete()
45+
api.following.followUser("adamratzman").complete()
46+
47+
if (!isFollowingAdam) api.following.unfollowUser("adamratzman").complete()
48+
49+
// follow and unfollow, if you weren't previously following, the playlist Today's Top Hits
50+
51+
val isFollowingTodaysTopHits = api.following.isFollowingPlaylist("spotify:playlist:37i9dQZF1DXcBWIGoYBM5M").complete()
52+
53+
if (isFollowingTodaysTopHits) api.following.unfollowPlaylist("spotify:playlist:37i9dQZF1DXcBWIGoYBM5M").complete()
54+
api.following.followPlaylist("spotify:playlist:37i9dQZF1DXcBWIGoYBM5M").complete()
55+
56+
if (!isFollowingTodaysTopHits) api.following.unfollowPlaylist("spotify:playlist:37i9dQZF1DXcBWIGoYBM5M").complete()
57+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2020; Original author: Adam Ratzman */
2+
package private
3+
4+
import com.adamratzman.spotify.SpotifyApi.Companion.spotifyClientApi
5+
import com.adamratzman.spotify.endpoints.client.LibraryType.TRACK
6+
7+
fun main() {
8+
// instantiate api
9+
val api = spotifyClientApi(
10+
System.getenv("SPOTIFY_CLIENT_ID"),
11+
System.getenv("SPOTIFY_CLIENT_SECRET"),
12+
System.getenv("SPOTIFY_REDIRECT_URI")) {
13+
authorization {
14+
tokenString = System.getenv("SPOTIFY_TOKEN_STRING")
15+
}
16+
}.build()
17+
18+
// get all your saved tracks
19+
println(api.library.getSavedTracks(limit = 50).getAllItems().complete().map { it.track.name })
20+
21+
// get your 11-20th saved albums
22+
println(api.library.getSavedAlbums(limit = 10, offset = 10).complete().map { it.album.name })
23+
24+
// check if your library contains the track "I'm Good" by the Mowgli's
25+
println(api.library.contains(TRACK, api.search.searchTrack("I'm Good the Mowgli's").complete()[0].id).complete())
26+
27+
// add and remove track "Up" by Nav
28+
api.library.add(TRACK, "spotify:track:5qbcsZMwL0x46sX7VO37Ye").complete()
29+
api.library.remove(TRACK, "spotify:track:5qbcsZMwL0x46sX7VO37Ye").complete()
30+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2020; Original author: Adam Ratzman */
2+
package private
3+
4+
import com.adamratzman.spotify.SpotifyApi.Companion.spotifyClientApi
5+
import com.adamratzman.spotify.endpoints.client.ClientPersonalizationApi.TimeRange.LONG_TERM
6+
import com.adamratzman.spotify.endpoints.client.ClientPersonalizationApi.TimeRange.SHORT_TERM
7+
8+
fun main() {
9+
// instantiate api
10+
val api = spotifyClientApi(
11+
System.getenv("SPOTIFY_CLIENT_ID"),
12+
System.getenv("SPOTIFY_CLIENT_SECRET"),
13+
System.getenv("SPOTIFY_REDIRECT_URI")) {
14+
authorization {
15+
tokenString = System.getenv("SPOTIFY_TOKEN_STRING")
16+
}
17+
}.build()
18+
19+
// print your top 30 artists over the last few years
20+
println(api.personalization.getTopArtists(30, timeRange = LONG_TERM).complete().items.map { it.name })
21+
22+
// print your top 20 tracks in the last 4 weeks
23+
println(api.personalization.getTopTracks(timeRange = SHORT_TERM).complete().items.map { track -> "${track.name} by ${track.artists.joinToString(", ") { it.name }}" })
24+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2020; Original author: Adam Ratzman */
2+
package private
3+
4+
import com.adamratzman.spotify.SpotifyApi.Companion.spotifyClientApi
5+
import com.adamratzman.spotify.annotations.SpotifyExperimentalFunctionApi
6+
import com.adamratzman.spotify.endpoints.client.ClientPlayerApi.PlayerRepeatState.TRACK
7+
8+
@SpotifyExperimentalFunctionApi
9+
fun main() {
10+
// instantiate api
11+
val api = spotifyClientApi(
12+
System.getenv("SPOTIFY_CLIENT_ID"),
13+
System.getenv("SPOTIFY_CLIENT_SECRET"),
14+
System.getenv("SPOTIFY_REDIRECT_URI")) {
15+
authorization {
16+
tokenString = System.getenv("SPOTIFY_TOKEN_STRING")
17+
}
18+
}.build()
19+
20+
// print all devices connected to this Spotify account
21+
println(api.player.getDevices().complete())
22+
23+
// get the current context track position
24+
println(api.player.getCurrentContext().complete()?.progressMs)
25+
26+
// get the 20 most recently played (there is a small lag) tracks
27+
println(api.player.getRecentlyPlayed().complete().map { it.track.name })
28+
29+
// get the currenty played PlaybackActions
30+
println(api.player.getCurrentlyPlaying().complete()?.actions)
31+
32+
// play song "I'm Good" by the Mowgli's
33+
api.player.startPlayback(tracksToPlay = listOf(api.search.searchTrack("I'm Good the Mowgli's").complete()[0].uri.uri)).complete()
34+
35+
// pause playback on the current device.
36+
api.player.pause().complete()
37+
38+
// seek the beginning of the track currently playing
39+
api.player.seek(0).complete()
40+
41+
// resume playback
42+
api.player.resume().complete()
43+
44+
// set repeat the current track
45+
api.player.setRepeatMode(TRACK).complete()
46+
47+
// set volume to 50%
48+
api.player.setVolume(50).complete()
49+
50+
// skip to the next track
51+
api.player.skipForward().complete()
52+
53+
// skip back to the last track that was in the user queue
54+
api.player.skipBehind().complete()
55+
56+
// toggle shuffling
57+
api.player.toggleShuffle(shuffle = true).complete()
58+
59+
// transfer playback
60+
api.player.transferPlayback(api.player.getDevices().complete().first().id!!).complete()
61+
}

0 commit comments

Comments
 (0)