Skip to content

Commit 8478cbe

Browse files
committed
document utilities
Signed-off-by: Adam Ratzman <adam@adamratzman.com>
1 parent d98d06e commit 8478cbe

File tree

10 files changed

+241
-32
lines changed

10 files changed

+241
-32
lines changed

src/main/kotlin/com/adamratzman/spotify/endpoints/client/ClientPlayerAPI.kt

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import java.util.function.Supplier
2929
* for more information on how this works. This is in beta and is available for **premium users only**. Endpoints are **not** guaranteed to work
3030
*/
3131
class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
32+
/**
33+
* Get information about a user’s available devices.
34+
*/
3235
fun getDevices(): SpotifyRestAction<List<Device>> {
3336
return toAction(Supplier {
3437
get(EndpointBuilder("/me/player/devices").toString()).toInnerObject<List<Device>>(
@@ -37,6 +40,9 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
3740
})
3841
}
3942

43+
/**
44+
* Get information about the user’s current playback state, including track, track progress, and active device.
45+
*/
4046
fun getCurrentContext(): SpotifyRestAction<CurrentlyPlayingContext?> {
4147
return toAction(Supplier {
4248
val obj = catch {
@@ -47,6 +53,9 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
4753
})
4854
}
4955

56+
/**
57+
* Get tracks from the current user’s recently played tracks.
58+
*/
5059
fun getRecentlyPlayed(): SpotifyRestActionPaging<PlayHistory, CursorBasedPagingObject<PlayHistory>> {
5160
return toActionPaging(Supplier {
5261
get(EndpointBuilder("/me/player/recently-played").toString()).toCursorBasedPagingObject<PlayHistory>(
@@ -55,6 +64,9 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
5564
})
5665
}
5766

67+
/**
68+
* Get the object currently being played on the user’s Spotify account.
69+
*/
5870
fun getCurrentlyPlaying(): SpotifyRestAction<CurrentlyPlayingObject?> {
5971
return toAction(Supplier {
6072
val obj =
@@ -66,14 +78,26 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
6678
})
6779
}
6880

69-
fun pausePlayback(deviceId: String? = null): SpotifyRestAction<Unit> {
81+
/**
82+
* Pause playback on the user’s account.
83+
*
84+
* @param deviceId the device to play on
85+
*/
86+
fun pause(deviceId: String? = null): SpotifyRestAction<Unit> {
7087
return toAction(Supplier {
7188
put(EndpointBuilder("/me/player/pause").with("device_id", deviceId).toString())
7289
Unit
7390
})
7491
}
7592

76-
fun seekPosition(positionMs: Long, deviceId: String? = null): SpotifyRestAction<Unit> {
93+
/**
94+
* Seeks to the given position in the user’s currently playing track.
95+
*
96+
* @param positionMs The position in milliseconds to seek to. Must be a positive number. Passing in a position
97+
* that is greater than the length of the track will cause the player to start playing the next song.
98+
* @param deviceId the device to play on
99+
*/
100+
fun seek(positionMs: Long, deviceId: String? = null): SpotifyRestAction<Unit> {
77101
return toAction(Supplier {
78102
if (positionMs < 0) throw IllegalArgumentException("Position must not be negative!")
79103
put(
@@ -86,6 +110,12 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
86110
})
87111
}
88112

113+
/**
114+
* Set the repeat mode for the user’s playback. Options are repeat-track, repeat-context, and off.
115+
*
116+
* @param state mode to describe how to repeat in the current context
117+
* @param deviceId the device to play on
118+
*/
89119
fun setRepeatMode(state: PlayerRepeatState, deviceId: String? = null): SpotifyRestAction<Unit> {
90120
return toAction(Supplier {
91121
put(
@@ -98,6 +128,12 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
98128
})
99129
}
100130

131+
/**
132+
* Set the volume for the user’s current playback device.
133+
*
134+
* @param volume The volume to set. Must be a value from 0 to 100 inclusive.
135+
* @param deviceId the device to play on
136+
*/
101137
fun setVolume(volume: Int, deviceId: String? = null): SpotifyRestAction<Unit> {
102138
if (volume !in 0..100) throw IllegalArgumentException("Volume must be within 0 to 100 inclusive. Provided: $volume")
103139
return toAction(Supplier {
@@ -111,14 +147,24 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
111147
})
112148
}
113149

114-
fun skipToNextTrack(deviceId: String? = null): SpotifyRestAction<Unit> {
150+
/**
151+
* Skips to next track in the user’s queue.
152+
*
153+
* @param deviceId the device to play on
154+
*/
155+
fun skipForward(deviceId: String? = null): SpotifyRestAction<Unit> {
115156
return toAction(Supplier {
116157
post(EndpointBuilder("/me/player/next").with("device_id", deviceId).toString())
117158
Unit
118159
})
119160
}
120161

121-
fun rewindToLastTrack(deviceId: String? = null): SpotifyRestAction<Unit> {
162+
/**
163+
* Skips to previous track in the user’s queue.
164+
*
165+
* @param deviceId the device to play on
166+
*/
167+
fun skipBehind(deviceId: String? = null): SpotifyRestAction<Unit> {
122168
return toAction(Supplier {
123169
post(EndpointBuilder("/me/player/previous").with("device_id", deviceId).toString())
124170
Unit
@@ -178,15 +224,26 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
178224
*
179225
* @param deviceId the device to play on
180226
*/
181-
fun resumePlayback(deviceId: String? = null) = startPlayback(deviceId = deviceId)
227+
fun resume(deviceId: String? = null) = startPlayback(deviceId = deviceId)
182228

183-
fun shufflePlayback(shuffle: Boolean = true, deviceId: String? = null): SpotifyRestAction<Unit> {
229+
/**
230+
* Toggle shuffle on or off for user’s playback.
231+
*
232+
* @param deviceId the device to play on
233+
*/
234+
fun toggleShuffle(shuffle: Boolean = true, deviceId: String? = null): SpotifyRestAction<Unit> {
184235
return toAction(Supplier {
185236
put(EndpointBuilder("/me/player/shuffle").with("state", shuffle).with("device_id", deviceId).toString())
186237
Unit
187238
})
188239
}
189240

241+
/**
242+
* Transfer playback to a new device and determine if it should start playing.
243+
*
244+
* @param deviceId the device to play on
245+
* @param play whether to immediately start playback on the transferred device
246+
*/
190247
fun transferPlayback(vararg deviceId: String, play: Boolean = true): SpotifyRestAction<Unit> {
191248
if (deviceId.size > 1) throw IllegalArgumentException("Although an array is accepted, only a single device_id is currently supported. Supplying more than one will 400 Bad Request")
192249
return toAction(Supplier {
@@ -198,5 +255,21 @@ class ClientPlayerAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
198255
})
199256
}
200257

201-
enum class PlayerRepeatState { TRACK, CONTEXT, OFF }
258+
/**
259+
* What state the player can repeat in.
260+
*/
261+
enum class PlayerRepeatState {
262+
/**
263+
* Repeat the current track
264+
*/
265+
TRACK,
266+
/**
267+
* Repeat the current context
268+
*/
269+
CONTEXT,
270+
/**
271+
* Will turn repeat off
272+
*/
273+
OFF
274+
}
202275
}

src/main/kotlin/com/adamratzman/spotify/endpoints/client/ClientPlaylistAPI.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.adamratzman.spotify.utils.UserURI
1818
import com.adamratzman.spotify.utils.encode
1919
import com.adamratzman.spotify.utils.toObject
2020
import com.adamratzman.spotify.utils.toPagingObject
21+
import com.beust.klaxon.Json
2122
import com.beust.klaxon.JsonArray
2223
import com.beust.klaxon.JsonObject
2324
import java.awt.image.BufferedImage
@@ -370,7 +371,17 @@ class ClientPlaylistAPI(api: SpotifyAPI) : PlaylistsAPI(api) {
370371
return DatatypeConverter.printBase64Binary(bos.toByteArray())
371372
}
372373

373-
data class Snapshot(val snapshot_id: String)
374+
/**
375+
* Contains the snapshot id, returned from API responses
376+
*
377+
* @param snapshotId playlist state identifier
378+
*/
379+
data class Snapshot(@Json(name = "snapshot_id") val snapshotId: String)
374380
}
375381

382+
/**
383+
* Represents the positions inside a playlist's items list of where to locate the track
384+
*
385+
* @param positions positions (zero-based)
386+
*/
376387
class SpotifyTrackPositions(vararg val positions: Int) : ArrayList<Int>(positions.toList())

src/main/kotlin/com/adamratzman/spotify/endpoints/public/ArtistsAPI.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class ArtistsAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
6969
limit: Int? = null,
7070
offset: Int? = null,
7171
market: Market? = null,
72-
include: List<AlbumInclusionStrategy> = listOf()
72+
vararg include: AlbumInclusionStrategy
7373
): SpotifyRestAction<LinkedResult<SimpleAlbum>> {
7474
return toAction(Supplier {
7575
get(
@@ -82,6 +82,11 @@ class ArtistsAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
8282
})
8383
}
8484

85+
/**
86+
* Describes object types to include when finding albums
87+
*
88+
* @param keyword the spotify id of the strategy
89+
*/
8590
enum class AlbumInclusionStrategy(val keyword: String) {
8691
ALBUM("album"), SINGLE("single"), APPEARS_ON("appears_on"), COMPILATION("compilation")
8792
}

src/main/kotlin/com/adamratzman/spotify/endpoints/public/BrowseAPI.kt

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,20 +254,97 @@ class BrowseAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
254254
}
255255
}
256256

257-
enum class TuneableTrackAttribute(val attribute: String) {
257+
/**
258+
* Describes a track attribute
259+
*
260+
* @param attribute the spotify id for the track attribute
261+
*/
262+
enum class TuneableTrackAttribute(private val attribute: String) {
263+
/**
264+
* A confidence measure from 0.0 to 1.0 of whether the track is acoustic.
265+
* 1.0 represents high confidence the track is acoustic.
266+
*/
258267
ACOUSTICNESS("acousticness"),
268+
/**
269+
* Danceability describes how suitable a track is for dancing based on a combination of musical
270+
* elements including tempo, rhythm stability, beat strength, and overall regularity. A value of 0.0 is
271+
* least danceable and 1.0 is most danceable.
272+
*/
259273
DANCEABILITY("danceability"),
274+
/**
275+
* The duration of the track in milliseconds.
276+
*/
260277
DURATION_IN_MILLISECONDS("duration_ms"),
278+
/**
279+
* Energy is a measure from 0.0 to 1.0 and represents a perceptual measure of intensity and activity.
280+
* Typically, energetic tracks feel fast, loud, and noisy. For example, death metal has high energy,
281+
* while a Bach prelude scores low on the scale. Perceptual features contributing to this attribute
282+
* include dynamic range, perceived loudness, timbre, onset rate, and general entropy.
283+
*/
261284
ENERGY("energy"),
285+
/**
286+
* Predicts whether a track contains no vocals. “Ooh” and “aah” sounds are treated as
287+
* instrumental in this context. Rap or spoken word tracks are clearly “vocal”. The
288+
* closer the instrumentalness value is to 1.0, the greater likelihood the track contains
289+
* no vocal content. Values above 0.5 are intended to represent instrumental tracks, but
290+
* confidence is higher as the value approaches 1.0.
291+
*/
262292
INSTRUMENTALNESS("instrumentalness"),
293+
/**
294+
* The key the track is in. Integers map to pitches using standard Pitch Class notation.
295+
* E.g. 0 = C, 1 = C♯/D♭, 2 = D, and so on.
296+
*/
263297
KEY("key"),
298+
/**
299+
* Detects the presence of an audience in the recording. Higher liveness values represent an increased
300+
* probability that the track was performed live. A value above 0.8 provides strong likelihood
301+
* that the track is live.
302+
*/
264303
LIVENESS("liveness"),
304+
/**
305+
* The overall loudness of a track in decibels (dB). Loudness values are averaged across the
306+
* entire track and are useful for comparing relative loudness of tracks. Loudness is the
307+
* quality of a sound that is the primary psychological correlate of physical strength (amplitude).
308+
* Values typical range between -60 and 0 db.
309+
*/
265310
LOUDNESS("loudness"),
311+
/**
312+
* Mode indicates the modality (major or minor) of a track, the type of scale from which its
313+
* melodic content is derived. Major is represented by 1 and minor is 0.
314+
*/
266315
MODE("mode"),
316+
/**
317+
* The popularity of the track. The value will be between 0 and 100, with 100 being the most popular.
318+
* The popularity is calculated by algorithm and is based, in the most part, on the total number of
319+
* plays the track has had and how recent those plays are. Note: When applying track relinking via
320+
* the market parameter, it is expected to find relinked tracks with popularities that do not match
321+
* min_*, max_*and target_* popularities. These relinked tracks are accurate replacements for unplayable tracks with the expected popularity scores. Original, non-relinked tracks are available via the linked_from attribute of the relinked track response.
322+
*/
267323
POPULARITY("popularity"),
324+
/**
325+
* Speechiness detects the presence of spoken words in a track. The more exclusively speech-like the
326+
* recording (e.g. talk show, audio book, poetry), the closer to 1.0 the attribute value. Values above
327+
* 0.66 describe tracks that are probably made entirely of spoken words. Values between 0.33 and 0.66
328+
* describe tracks that may contain both music and speech, either in sections or layered, including
329+
* such cases as rap music. Values below 0.33 most likely represent music and other non-speech-like
330+
* tracks.
331+
*/
268332
SPEECHINESS("speechiness"),
333+
/**
334+
* The overall estimated tempo of a track in beats per minute (BPM). In musical terminology, tempo is the
335+
* speed or pace of a given piece and derives directly from the average beat duration.
336+
*/
269337
TEMPO("tempo"),
338+
/**
339+
* An estimated overall time signature of a track. The time signature (meter)
340+
* is a notational convention to specify how many beats are in each bar (or measure).
341+
*/
270342
TIME_SIGNATURE("time_signature"),
343+
/**
344+
* A measure from 0.0 to 1.0 describing the musical positiveness conveyed by a track. Tracks with high
345+
* valence sound more positive (e.g. happy, cheerful, euphoric), while tracks with low valence
346+
* sound more negative (e.g. sad, depressed, angry).
347+
*/
271348
VALENCE("valence");
272349

273350
override fun toString() = attribute

src/main/kotlin/com/adamratzman/spotify/endpoints/public/SearchAPI.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ import java.util.function.Supplier
2222
* Get Spotify catalog information about artists, albums, tracks or playlists that match a keyword string.
2323
*/
2424
class SearchAPI(api: SpotifyAPI) : SpotifyEndpoint(api) {
25-
enum class SearchType(val id: String) {
25+
/**
26+
* Describes which object to search for
27+
*
28+
* @param id internal spotify id
29+
*/
30+
enum class SearchType(internal val id: String) {
2631
ALBUM("album"), TRACK("track"), ARTIST("artist"), PLAYLIST("playlist")
2732
}
2833

src/main/kotlin/com/adamratzman/spotify/utils/AuthObjects.kt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
package com.adamratzman.spotify.utils
33

44
import com.adamratzman.spotify.main.SpotifyScope
5+
import com.beust.klaxon.Json
56

7+
/**
8+
* Represents a Spotify Token, retrieved through instantiating a new [SpotifyAPI]
9+
*/
610
data class Token(
7-
val access_token: String,
8-
val token_type: String,
9-
val expires_in: Int,
10-
val refresh_token: String? = null,
11-
val scope: String?
11+
@Json(name = "access_token") val accessToken: String,
12+
@Json(name = "token_type") val tokenType: String,
13+
@Json(name = "expires_in")val expiresIn: Int,
14+
@Json(name = "refresh_token") val refreshToken: String? = null,
15+
@Json(ignored = false) private val scopeString: String? = null
1216
) {
13-
fun getScopes(): List<SpotifyScope> {
14-
val scopes = mutableListOf<SpotifyScope>()
15-
scope?.split(" ")?.forEach { split ->
16-
SpotifyScope.values().forEach { if (split == it.uri) scopes.add(it) }
17-
}
18-
return scopes
17+
@Json(ignored = true) val scopes: List<SpotifyScope>? = scopeString?.let { str ->
18+
str.split(" ").mapNotNull { scope -> SpotifyScope.values().find { it.uri == scope } }
1919
}
2020
}
2121

src/main/kotlin/com/adamratzman/spotify/utils/HttpConnection.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ package com.adamratzman.spotify.utils
44
import java.net.HttpURLConnection
55
import java.net.URL
66

7-
enum class HttpRequestMethod { GET, POST, PUT, DELETE }
8-
data class HttpHeader(val key: String, val value: String)
7+
internal enum class HttpRequestMethod { GET, POST, PUT, DELETE }
8+
internal data class HttpHeader(val key: String, val value: String)
99

10-
class HttpConnection(
10+
internal class HttpConnection(
1111
private val url: String,
1212
private val method: HttpRequestMethod,
1313
private val body: String?,
@@ -50,4 +50,4 @@ class HttpConnection(
5050
}
5151
}
5252

53-
data class HttpResponse(val responseCode: Int, val body: String, val headers: List<HttpHeader>)
53+
internal data class HttpResponse(val responseCode: Int, val body: String, val headers: List<HttpHeader>)

0 commit comments

Comments
 (0)