2
2
package com.adamratzman.spotify
3
3
4
4
import com.adamratzman.spotify.SpotifyApi.Companion.getCredentialedToken
5
- import com.adamratzman.spotify.SpotifyApi.Companion.spotifyAppApi
6
- import com.adamratzman.spotify.SpotifyApi.Companion.spotifyClientApi
7
5
import com.adamratzman.spotify.http.HttpConnection
8
6
import com.adamratzman.spotify.http.HttpRequestMethod
9
7
import com.adamratzman.spotify.models.Token
@@ -16,27 +14,217 @@ import kotlinx.coroutines.Job
16
14
import kotlinx.coroutines.launch
17
15
import kotlinx.serialization.json.Json
18
16
19
- // Kotlin DSL builders
17
+ // Kotlin DSL builders and top-level utilities
20
18
19
+ // ==============================================
20
+
21
+ // Get Spotify client authorization url
22
+ /* *
23
+ * Get the authorization url for the provided [clientId] and [redirectUri] application settings, when attempting to authorize with
24
+ * specified [scopes]
25
+ *
26
+ * @param scopes Spotify scopes the api instance should be able to access for the user
27
+ * @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
28
+ * @param redirectUri Spotify [redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/)
29
+ * @param isImplicitGrantFlow Whether the authorization url should be for the Implicit Grant flow, otherwise for Authorization Code flo
30
+ * @param shouldShowDialog If [isImplicitGrantFlow] is true, whether or not to force the user to approve the app again if they’ve already done so.
31
+ */
32
+ fun getSpotifyAuthorizationUrl (vararg scopes : SpotifyScope , clientId : String , redirectUri : String , isImplicitGrantFlow : Boolean = false, shouldShowDialog : Boolean = false): String {
33
+ return SpotifyApi .getAuthUrlFull(* scopes, clientId = clientId, redirectUri = redirectUri, isImplicitGrantFlow = isImplicitGrantFlow, shouldShowDialog = shouldShowDialog)
34
+ }
35
+
36
+
37
+ // ==============================================
38
+
39
+ // Implicit grant builder
40
+ /*
41
+ ____________________________
42
+ / This is Implicit Grant \
43
+ \ authorization /
44
+ ----------------------------
45
+ \ ^__^
46
+ \ (oo)\_______
47
+ (__)\ )\/\
48
+ ||----w |
49
+ || ||
50
+ */
51
+
52
+ /* *
53
+ * Instantiate a new [SpotifyImplicitGrantApi] using a Spotify [clientId], [redirectUri], and [token] retrieved from the implicit
54
+ * grant flow
55
+ *
56
+ * @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
57
+ * @param redirectUri Spotify [redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/)
58
+ * @param token Token created from the hash response in the implicit grant callback
59
+ * @param options Override default API options such as the cache limit
60
+ *
61
+ * @return [SpotifyImplicitGrantApi] that can immediately begin making calls
62
+ */
63
+ fun spotifyImplicitGrantApi (clientId : String , redirectUri : String , token : Token , options : SpotifyApiOptions = SpotifyApiOptionsBuilder ().build()) =
64
+ SpotifyImplicitGrantApi (
65
+ clientId,
66
+ null ,
67
+ redirectUri,
68
+ token,
69
+ options.useCache,
70
+ options.cacheLimit,
71
+ options.retryWhenRateLimited,
72
+ options.enableLogger,
73
+ options.testTokenValidity,
74
+ options.defaultLimit,
75
+ options.allowBulkRequests,
76
+ options.requestTimeoutMillis,
77
+ options.json
78
+ )
79
+
80
+
81
+ // App Api builders
82
+
83
+ /*
84
+ ____________________________
85
+ / This is Client Credentials \
86
+ \ authorization /
87
+ ----------------------------
88
+ \ ^__^
89
+ \ (oo)\_______
90
+ (__)\ )\/\
91
+ ||----w |
92
+ || ||
93
+ */
94
+
95
+ /* *
96
+ * Instantiate a new [SpotifyAppApiBuilder] using a Spotify [clientId] and [clientSecret]
97
+ *
98
+ * @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
99
+ * @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
100
+ *
101
+ * @return Configurable [SpotifyAppApiBuilder] that, when built, creates a new [SpotifyAppApi]
102
+ */
103
+ fun spotifyAppApi (clientId : String , clientSecret : String ) = spotifyAppApi(clientId, clientSecret) {}
104
+
105
+ /* *
106
+ * Instantiate a new [SpotifyAppApiBuilder] using a Spotify [clientId] and [clientSecret], with the ability to configure
107
+ * the api settings by providing a builder initialization [block]
108
+ *
109
+ * @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
110
+ * @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
111
+ * @param block Api settings block
112
+ *
113
+ * @return Configurable [SpotifyAppApiBuilder] that, when built, creates a new [SpotifyAppApi]
114
+ */
21
115
fun spotifyAppApi (clientId : String , clientSecret : String , block : SpotifyAppApiBuilder .() -> Unit = {}) =
22
- spotifyAppApi(clientId, clientSecret, block)
116
+ SpotifyAppApiBuilder ().apply (block).apply {
117
+ credentials {
118
+ this .clientId = clientId
119
+ this .clientSecret = clientSecret
120
+ }
121
+ }
23
122
24
- fun spotifyAppApi (block : SpotifyAppApiBuilder .() -> Unit ) =
25
- spotifyAppApi(block)
123
+ /* *
124
+ * Instantiate a new [SpotifyAppApiBuilder] by providing a builder initialization [block].
125
+ *
126
+ * **Note**: You **must** provide your app credentials in the [SpotifyAppApiBuilder.credentials] block
127
+ *
128
+ * @param block Api settings block
129
+ *
130
+ * @return Configurable [SpotifyAppApiBuilder] that, when built, creates a new [SpotifyAppApi]
131
+ */
132
+ fun spotifyAppApi (block : SpotifyAppApiBuilder .() -> Unit ) = SpotifyAppApiBuilder ().apply (block)
133
+
134
+
135
+ // Client Api Builders
136
+ /*
137
+ ____________________________
138
+ / This is Authorization Code \
139
+ \ authorization /
140
+ ----------------------------
141
+ \ ^__^
142
+ \ (oo)\_______
143
+ (__)\ )\/\
144
+ ||----w |
145
+ || ||
146
+ */
147
+
148
+ /* *
149
+ * Instantiate a new [SpotifyClientApiBuilder] using a Spotify [clientId], [clientSecret], and [redirectUri], with the ability to configure
150
+ * the api settings by providing a builder initialization [block]
151
+ *
152
+ * **Note**: If trying to build [SpotifyClientApi], you **must** provide client authorization in the [SpotifyClientApiBuilder.authorization]
153
+ * block
154
+ *
155
+ * @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
156
+ * @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
157
+ * @param redirectUri Spotify [redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/)
158
+ * @param block Api settings block
159
+ *
160
+ * @return Configurable [SpotifyClientApiBuilder] that, when built, creates a new [SpotifyClientApi]
161
+ */
162
+ fun spotifyClientApi (
163
+ clientId : String ,
164
+ clientSecret : String ,
165
+ redirectUri : String ,
166
+ block : SpotifyClientApiBuilder .() -> Unit
167
+ ) = SpotifyClientApiBuilder ().apply (block).apply {
168
+ credentials {
169
+ this .clientId = clientId
170
+ this .clientSecret = clientSecret
171
+ this .redirectUri = redirectUri
172
+ }
173
+ }
26
174
27
- fun spotifyAppApi (clientId : String , clientSecret : String , redirectUri : String , block : SpotifyClientApiBuilder .() -> Unit = {}) =
28
- spotifyClientApi(clientId, clientSecret, redirectUri, block)
175
+ /* *
176
+ * Instantiate a new [SpotifyClientApiBuilder] using a Spotify [clientId], [clientSecret], and [redirectUri],
177
+ * with an existing [SpotifyUserAuthorization] and with the ability to configure the api settings by providing a
178
+ * builder initialization [block]
179
+ *
180
+ * @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
181
+ * @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
182
+ * @param redirectUri Spotify [redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/)
183
+ * @param authorization A [SpotifyUserAuthorization] that must contain one of the following: authorization code (preferred),
184
+ * access token string (tokenString), [Token] object, **and** that may contain a refresh token (preferred)
185
+ * with which to refresh the access token
186
+ * @param options Override default API options such as the cache limit
187
+ * @param block Api settings block
188
+ *
189
+ * @return Configurable [SpotifyClientApiBuilder] that, when built, creates a new [SpotifyClientApi]
190
+ */
191
+ fun spotifyClientApi (
192
+ clientId : String ,
193
+ clientSecret : String ,
194
+ redirectUri : String ,
195
+ authorization : SpotifyUserAuthorization ,
196
+ options : SpotifyApiOptions ? = null,
197
+ block : SpotifyClientApiBuilder .() -> Unit = {}
198
+ ) = SpotifyClientApiBuilder ().apply (block).apply {
199
+ credentials {
200
+ this .clientId = clientId
201
+ this .clientSecret = clientSecret
202
+ this .redirectUri = redirectUri
203
+ }
204
+ options?.let { this .options = options }
205
+ this .authorization = authorization
206
+ }
207
+
208
+ /* *
209
+ * Instantiate a new [SpotifyClientApiBuilder] by providing a builder initialization [block]
210
+ *
211
+ * **Note**: If trying to build [SpotifyClientApi], you **must** provide client authorization in the [SpotifyClientApiBuilder.authorization]
212
+ * block
213
+ *
214
+ * @param block Api settings block
215
+ *
216
+ * @return Configurable [SpotifyClientApiBuilder] that, when built, creates a new [SpotifyClientApi]
217
+ */
218
+ fun spotifyClientApi (block : SpotifyClientApiBuilder .() -> Unit ) = SpotifyClientApiBuilder ().apply (block)
29
219
30
- fun spotifyAppApi (block : SpotifyClientApiBuilder .() -> Unit ) =
31
- spotifyClientApi(block)
32
220
33
221
/* *
34
222
* Spotify API builder
35
223
*/
36
224
class SpotifyApiBuilder (
37
- private var clientId : String? ,
38
- private var clientSecret : String? ,
39
- private var redirectUri : String?
225
+ private var clientId : String? ,
226
+ private var clientSecret : String? ,
227
+ private var redirectUri : String?
40
228
) {
41
229
/* *
42
230
* Allows you to authenticate a [SpotifyClientApi] with an authorization code
@@ -313,9 +501,9 @@ interface ISpotifyClientApiBuilder : ISpotifyApiBuilder<SpotifyClientApi, Spotif
313
501
* [SpotifyClientApi] builder for api creation using client authorization
314
502
*/
315
503
class SpotifyClientApiBuilder (
316
- override var credentials : SpotifyCredentials = SpotifyCredentialsBuilder ().build(),
317
- override var authorization : SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder ().build(),
318
- override var options : SpotifyApiOptions = SpotifyApiOptionsBuilder ().build()
504
+ override var credentials : SpotifyCredentials = SpotifyCredentialsBuilder ().build(),
505
+ override var authorization : SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder ().build(),
506
+ override var options : SpotifyApiOptions = SpotifyApiOptionsBuilder ().build()
319
507
) : ISpotifyClientApiBuilder {
320
508
override fun getAuthorizationUrl (vararg scopes : SpotifyScope ): String {
321
509
require(credentials.redirectUri != null && credentials.clientId != null ) { " You didn't specify a redirect uri or client id in the credentials block!" }
@@ -425,9 +613,9 @@ interface ISpotifyAppApiBuilder : ISpotifyApiBuilder<SpotifyAppApi, SpotifyAppAp
425
613
* [SpotifyAppApi] builder for api creation using client authorization
426
614
*/
427
615
class SpotifyAppApiBuilder (
428
- override var credentials : SpotifyCredentials = SpotifyCredentialsBuilder ().build(),
429
- override var authorization : SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder ().build(),
430
- override var options : SpotifyApiOptions = SpotifyApiOptionsBuilder ().build()
616
+ override var credentials : SpotifyCredentials = SpotifyCredentialsBuilder ().build(),
617
+ override var authorization : SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder ().build(),
618
+ override var options : SpotifyApiOptions = SpotifyApiOptionsBuilder ().build()
431
619
) : ISpotifyAppApiBuilder {
432
620
/* *
433
621
* Build a public [SpotifyAppApi] using the provided credentials
@@ -546,10 +734,10 @@ data class SpotifyCredentials(val clientId: String?, val clientSecret: String?,
546
734
* limited time constraint on these before the API automatically refreshes them
547
735
*/
548
736
class SpotifyUserAuthorizationBuilder (
549
- var authorizationCode : String? = null ,
550
- var tokenString : String? = null ,
551
- var token : Token ? = null ,
552
- var refreshTokenString : String? = null
737
+ var authorizationCode : String? = null ,
738
+ var tokenString : String? = null ,
739
+ var token : Token ? = null ,
740
+ var refreshTokenString : String? = null
553
741
) {
554
742
fun build () = SpotifyUserAuthorization (authorizationCode, tokenString, token, refreshTokenString)
555
743
}
@@ -566,10 +754,10 @@ class SpotifyUserAuthorizationBuilder(
566
754
* @property refreshTokenString Refresh token, given as a string, to be exchanged to Spotify for a new token
567
755
*/
568
756
data class SpotifyUserAuthorization (
569
- var authorizationCode : String? ,
570
- var tokenString : String? ,
571
- var token : Token ? ,
572
- var refreshTokenString : String?
757
+ var authorizationCode : String? = null ,
758
+ var tokenString : String? = null ,
759
+ var token : Token ? = null ,
760
+ var refreshTokenString : String? = null
573
761
)
574
762
575
763
/* *
@@ -589,17 +777,17 @@ data class SpotifyUserAuthorization(
589
777
*
590
778
*/
591
779
class SpotifyApiOptionsBuilder (
592
- var useCache : Boolean = true ,
593
- var cacheLimit : Int? = 200 ,
594
- var automaticRefresh : Boolean = true ,
595
- var retryWhenRateLimited : Boolean = true ,
596
- var enableLogger : Boolean = true ,
597
- var testTokenValidity : Boolean = false ,
598
- var enableAllOptions : Boolean = false ,
599
- var defaultLimit : Int = 50 ,
600
- var allowBulkRequests : Boolean = true ,
601
- var requestTimeoutMillis : Long? = null ,
602
- var json : Json = nonstrictJson
780
+ var useCache : Boolean = true ,
781
+ var cacheLimit : Int? = 200 ,
782
+ var automaticRefresh : Boolean = true ,
783
+ var retryWhenRateLimited : Boolean = true ,
784
+ var enableLogger : Boolean = true ,
785
+ var testTokenValidity : Boolean = false ,
786
+ var enableAllOptions : Boolean = false ,
787
+ var defaultLimit : Int = 50 ,
788
+ var allowBulkRequests : Boolean = true ,
789
+ var requestTimeoutMillis : Long? = null ,
790
+ var json : Json = nonstrictJson
603
791
) {
604
792
fun build () =
605
793
if (enableAllOptions)
@@ -647,16 +835,16 @@ class SpotifyApiOptionsBuilder(
647
835
*/
648
836
649
837
data class SpotifyApiOptions (
650
- var useCache : Boolean ,
651
- var cacheLimit : Int? ,
652
- var automaticRefresh : Boolean ,
653
- var retryWhenRateLimited : Boolean ,
654
- var enableLogger : Boolean ,
655
- var testTokenValidity : Boolean ,
656
- var defaultLimit : Int ,
657
- var allowBulkRequests : Boolean ,
658
- var requestTimeoutMillis : Long? ,
659
- var json : Json
838
+ var useCache : Boolean ,
839
+ var cacheLimit : Int? ,
840
+ var automaticRefresh : Boolean ,
841
+ var retryWhenRateLimited : Boolean ,
842
+ var enableLogger : Boolean ,
843
+ var testTokenValidity : Boolean ,
844
+ var defaultLimit : Int ,
845
+ var allowBulkRequests : Boolean ,
846
+ var requestTimeoutMillis : Long? ,
847
+ var json : Json
660
848
)
661
849
662
850
@Deprecated(" Name has been replaced by `options`" , ReplaceWith (" SpotifyApiOptions" ))
0 commit comments