@@ -16,54 +16,40 @@ fun spotifyApi(block: SpotifyApiBuilderDsl.() -> Unit) = SpotifyApiBuilderDsl().
16
16
* Spotify traditional Java style API builder
17
17
*/
18
18
class SpotifyApiBuilder (
19
- val clientId : String ,
20
- val clientSecret : String ,
21
- var redirectUri : String? = null ,
22
- var authorizationCode : String? = null ,
23
- var tokenString : String? = null ,
24
- var token : Token ? = null ,
25
- var useCache : Boolean = true ,
26
- var cacheLimit : Int? = 200 ,
27
- var automaticRefresh : Boolean = true ,
28
- var retryWhenRateLimited : Boolean = false ,
29
- var enableLogger : Boolean = false
19
+ private var clientId : String ,
20
+ private var clientSecret : String
30
21
) {
31
- /* *
32
- * Instantiate the builder with the application [clientId] and [clientSecret]
33
- */
34
- constructor (clientId: String , clientSecret: String ) : this (clientId, clientSecret, null )
35
-
36
- /* *
37
- * Instantiate the builder with the application [clientId], [clientSecret], and whether to use a cache
38
- */
39
- constructor (clientId: String , clientSecret: String , useCache: Boolean ) : this (clientId, clientSecret, null , useCache = useCache)
22
+ private var redirectUri: String? = null
23
+ private var authorizationCode: String? = null
24
+ private var tokenString: String? = null
25
+ private var token: Token ? = null
26
+ private var useCache: Boolean = true
27
+ private var cacheLimit: Int? = 200
28
+ private var automaticRefresh: Boolean = true
29
+ private var retryWhenRateLimited: Boolean = false
30
+ private var enableLogger: Boolean = false
31
+ private var testTokenValidity: Boolean = false
32
+ private var enableAllUtilities: Boolean = false
40
33
41
34
/* *
42
- * Instantiate the builder with the application [clientId], [clientSecret], and application
43
- * [redirectUri]
35
+ * Set whether to enable all utilities ([automaticRefresh], [retryWhenRateLimited], [useCache], [enableLogger], [testTokenValidity])
44
36
*/
45
- constructor (clientId : String , clientSecret : String , redirectUri : String ) : this (clientId, clientSecret, redirectUri, null )
37
+ fun enableAllUtilities ( enableAllUtilities : Boolean ) = apply { this .enableAllUtilities = enableAllUtilities }
46
38
47
39
/* *
48
- * Instantiate the builder with the application [clientId], [clientSecret], application
49
- * [redirectUri], and an [authorizationCode]
40
+ * After API creation, set whether to test whether the token is valid by performing a lightweight request
50
41
*/
51
- constructor (clientId: String , clientSecret: String , redirectUri: String? , authorizationCode: String , useCache: Boolean ) :
52
- this (clientId, clientSecret, redirectUri, authorizationCode, null , useCache = useCache)
42
+ fun testTokenValidity (testTokenValidity : Boolean ) = apply { this .testTokenValidity = testTokenValidity }
53
43
54
44
/* *
55
- * Instantiate the builder with the application [clientId], [clientSecret], application
56
- * [redirectUri], and an access token string ([tokenString])
45
+ * Set the application client id
57
46
*/
58
- constructor (clientId: String , clientSecret: String , redirectUri: String? , tokenString: String ) :
59
- this (clientId, clientSecret, redirectUri, null , tokenString)
47
+ fun clientId (clientId : String ) = apply { this .clientId = clientId }
60
48
61
49
/* *
62
- * Instantiate the builder with the application [clientId], [clientSecret], application
63
- * [redirectUri], and a [token]
50
+ * Set the application client secret
64
51
*/
65
- constructor (clientId: String , clientSecret: String , redirectUri: String? , token: Token , useCache: Boolean ) :
66
- this (clientId, clientSecret, redirectUri, null , null , token, useCache)
52
+ fun clientSecret (clientSecret : String ) = apply { this .clientSecret = clientSecret }
67
53
68
54
/* *
69
55
* Set whether to cache requests. Default: true
@@ -136,10 +122,15 @@ class SpotifyApiBuilder(
136
122
token = this @SpotifyApiBuilder.token
137
123
tokenString = this @SpotifyApiBuilder.tokenString
138
124
}
139
-
140
- automaticRefresh = this @SpotifyApiBuilder.automaticRefresh
141
- retryWhenRateLimited = this @SpotifyApiBuilder.retryWhenRateLimited
142
- enableLogger = this @SpotifyApiBuilder.enableLogger
125
+ utilities {
126
+ useCache = this @SpotifyApiBuilder.useCache
127
+ cacheLimit = this @SpotifyApiBuilder.cacheLimit
128
+ automaticRefresh = this @SpotifyApiBuilder.automaticRefresh
129
+ retryWhenRateLimited = this @SpotifyApiBuilder.retryWhenRateLimited
130
+ enableLogger = this @SpotifyApiBuilder.enableLogger
131
+ testTokenValidity = this @SpotifyApiBuilder.testTokenValidity
132
+ enableAllUtilities = this @SpotifyApiBuilder.enableAllUtilities
133
+ }
143
134
}.buildCredentialed()
144
135
145
136
/* *
@@ -157,10 +148,15 @@ class SpotifyApiBuilder(
157
148
tokenString = this @SpotifyApiBuilder.tokenString
158
149
token = this @SpotifyApiBuilder.token
159
150
}
160
-
161
- automaticRefresh = this @SpotifyApiBuilder.automaticRefresh
162
- retryWhenRateLimited = this @SpotifyApiBuilder.retryWhenRateLimited
163
- enableLogger = this @SpotifyApiBuilder.enableLogger
151
+ utilities {
152
+ useCache = this @SpotifyApiBuilder.useCache
153
+ cacheLimit = this @SpotifyApiBuilder.cacheLimit
154
+ automaticRefresh = this @SpotifyApiBuilder.automaticRefresh
155
+ retryWhenRateLimited = this @SpotifyApiBuilder.retryWhenRateLimited
156
+ enableLogger = this @SpotifyApiBuilder.enableLogger
157
+ testTokenValidity = this @SpotifyApiBuilder.testTokenValidity
158
+ enableAllUtilities = this @SpotifyApiBuilder.enableAllUtilities
159
+ }
164
160
}.buildClient()
165
161
}
166
162
@@ -184,7 +180,7 @@ class SpotifyCredentialsBuilder {
184
180
data class SpotifyCredentials (val clientId : String? , val clientSecret : String? , val redirectUri : String? )
185
181
186
182
/* *
187
- * Authentication methods.
183
+ * Authentication methods
188
184
*
189
185
* @property authorizationCode Only available when building [SpotifyClientAPI]. Spotify auth code
190
186
* @property token Build the API using an existing token. If you're building [SpotifyClientAPI], this
@@ -197,28 +193,78 @@ class SpotifyUserAuthorizationBuilder(
197
193
var authorizationCode : String? = null ,
198
194
var tokenString : String? = null ,
199
195
var token : Token ? = null
196
+ ) {
197
+ fun build () = if (authorizationCode == null && tokenString == null && token == null ) throw IllegalArgumentException (" An authorization method must be supplied" )
198
+ else SpotifyUserAuthorization (authorizationCode, tokenString, token)
199
+ }
200
+
201
+ data class SpotifyUserAuthorization (
202
+ val authorizationCode : String? ,
203
+ val tokenString : String? ,
204
+ val token : Token ?
200
205
)
201
206
202
207
/* *
203
- * Spotify API mutable parameters
208
+ * API Utilities
204
209
*
205
- * @property credentials A holder for application-specific credentials
206
- * @property authentication A holder for authentication methods. At least one needs to be provided in order to create
207
- * a **client** api
208
210
* @property useCache Set whether to cache requests. Default: true
209
211
* @property cacheLimit The maximum amount of cached requests allowed at one time. Null means no limit
210
212
* @property automaticRefresh Enable or disable automatic refresh of the Spotify access token
211
213
* @property retryWhenRateLimited Set whether to block the current thread and wait until the API can retry the request
212
214
* @property enableLogger Set whether to enable to the exception logger
215
+ * @property testTokenValidity After API creation, test whether the token is valid by performing a lightweight request
216
+ * @property enableAllUtilities Whether to enable all provided utilities
217
+ */
218
+ class SpotifyUtilitiesBuilder (
219
+ var useCache : Boolean = true ,
220
+ var cacheLimit : Int? = 200 ,
221
+ var automaticRefresh : Boolean = true ,
222
+ var retryWhenRateLimited : Boolean = true ,
223
+ var enableLogger : Boolean = true ,
224
+ var testTokenValidity : Boolean = false ,
225
+ var enableAllUtilities : Boolean = false
226
+ ) {
227
+ fun build () =
228
+ if (enableAllUtilities)
229
+ SpotifyUtilities (true ,
230
+ 200 ,
231
+ automaticRefresh = true ,
232
+ retryWhenRateLimited = true ,
233
+ enableLogger = true ,
234
+ testTokenValidity = true
235
+ )
236
+ else
237
+ SpotifyUtilities (
238
+ useCache,
239
+ cacheLimit,
240
+ automaticRefresh,
241
+ retryWhenRateLimited,
242
+ enableLogger,
243
+ testTokenValidity
244
+ )
245
+ }
246
+
247
+ data class SpotifyUtilities (
248
+ val useCache : Boolean ,
249
+ val cacheLimit : Int? ,
250
+ val automaticRefresh : Boolean ,
251
+ val retryWhenRateLimited : Boolean ,
252
+ val enableLogger : Boolean ,
253
+ val testTokenValidity : Boolean
254
+ )
255
+
256
+ /* *
257
+ * Spotify API mutable parameters
258
+ *
259
+ * @property credentials A holder for application-specific credentials
260
+ * @property authentication A holder for authentication methods. At least one needs to be provided in order to create
261
+ * a **client** api
262
+ * @property utilities A holder for API utilities such as caching and token refresh
213
263
*/
214
264
class SpotifyApiBuilderDsl {
215
- private var credentials: SpotifyCredentials = SpotifyCredentials (null , null , null )
216
- private var authentication = SpotifyUserAuthorizationBuilder ()
217
- var useCache: Boolean = true
218
- var cacheLimit: Int? = 200
219
- var automaticRefresh: Boolean = true
220
- var retryWhenRateLimited: Boolean = false
221
- var enableLogger: Boolean = false
265
+ private var credentials: SpotifyCredentials = SpotifyCredentialsBuilder ().build()
266
+ private var authentication: SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder ().build()
267
+ private var utilities: SpotifyUtilities = SpotifyUtilitiesBuilder ().build()
222
268
223
269
/* *
224
270
* A block in which Spotify application credentials (accessible via the Spotify [dashboard](https://developer.spotify.com/dashboard/applications))
@@ -233,7 +279,14 @@ class SpotifyApiBuilderDsl {
233
279
* or build [SpotifyAPI] using a refresh token
234
280
*/
235
281
fun authentication (block : SpotifyUserAuthorizationBuilder .() -> Unit ) {
236
- authentication = SpotifyUserAuthorizationBuilder ().apply (block)
282
+ authentication = SpotifyUserAuthorizationBuilder ().apply (block).build()
283
+ }
284
+
285
+ /* *
286
+ * Allows you to override default values for caching, token refresh, and logging
287
+ */
288
+ fun utilities (block : SpotifyUtilitiesBuilder .() -> Unit ) {
289
+ utilities = SpotifyUtilitiesBuilder ().apply (block).build()
237
290
}
238
291
239
292
/* *
@@ -268,8 +321,17 @@ class SpotifyApiBuilderDsl {
268
321
}
269
322
return when {
270
323
authentication.token != null -> {
271
- SpotifyAppAPI (clientId ? : " not-set" , clientSecret
272
- ? : " not-set" , authentication.token!! , useCache, cacheLimit, false , retryWhenRateLimited, enableLogger)
324
+ SpotifyAppAPI (
325
+ clientId ? : " not-set" ,
326
+ clientSecret ? : " not-set" ,
327
+ authentication.token!! ,
328
+ utilities.useCache,
329
+ utilities.cacheLimit,
330
+ false ,
331
+ utilities.retryWhenRateLimited,
332
+ utilities.enableLogger,
333
+ utilities.testTokenValidity
334
+ )
273
335
}
274
336
authentication.tokenString != null -> {
275
337
SpotifyAppAPI (
@@ -279,17 +341,28 @@ class SpotifyApiBuilderDsl {
279
341
authentication.tokenString!! , " client_credentials" ,
280
342
60000 , null , null
281
343
),
282
- useCache,
283
- cacheLimit,
284
- automaticRefresh,
285
- retryWhenRateLimited,
286
- enableLogger
344
+ utilities.useCache,
345
+ utilities.cacheLimit,
346
+ false ,
347
+ utilities.retryWhenRateLimited,
348
+ utilities.enableLogger,
349
+ utilities.testTokenValidity
287
350
)
288
351
}
289
352
else -> try {
290
353
if (clientId == null || clientSecret == null ) throw IllegalArgumentException (" Illegal credentials provided" )
291
354
val token = getCredentialedToken(clientId, clientSecret, null )
292
- SpotifyAppAPI (clientId, clientSecret, token, useCache, cacheLimit, automaticRefresh, retryWhenRateLimited, enableLogger)
355
+ SpotifyAppAPI (
356
+ clientId,
357
+ clientSecret,
358
+ token,
359
+ utilities.useCache,
360
+ utilities.cacheLimit,
361
+ false ,
362
+ utilities.retryWhenRateLimited,
363
+ utilities.enableLogger,
364
+ utilities.testTokenValidity
365
+ )
293
366
} catch (e: Exception ) {
294
367
throw SpotifyException (" Invalid credentials provided in the login process" , e)
295
368
}
@@ -311,7 +384,8 @@ class SpotifyApiBuilderDsl {
311
384
*/
312
385
fun buildClient (): SpotifyClientAPI =
313
386
buildClient(
314
- authentication.authorizationCode, authentication.tokenString,
387
+ authentication.authorizationCode,
388
+ authentication.tokenString,
315
389
authentication.token
316
390
)
317
391
@@ -322,8 +396,6 @@ class SpotifyApiBuilderDsl {
322
396
* @param authorizationCode Spotify authorization code retrieved after authentication
323
397
* @param tokenString Spotify authorization token
324
398
* @param token [Token] object (useful if you already have exchanged an authorization code yourself
325
- * @param automaticRefresh automatically refresh the token. otherwise, the authorization will eventually expire. **only** valid when
326
- * [authorizationCode] or [token] is provided
327
399
*/
328
400
private fun buildClient (
329
401
authorizationCode : String? = null,
@@ -356,12 +428,13 @@ class SpotifyApiBuilderDsl {
356
428
clientId,
357
429
clientSecret,
358
430
response.body.toObject(null ),
359
- automaticRefresh,
360
- redirectUri ? : throw IllegalArgumentException (),
361
- useCache,
362
- cacheLimit,
363
- retryWhenRateLimited,
364
- enableLogger
431
+ utilities.automaticRefresh,
432
+ redirectUri ? : throw IllegalArgumentException (" No redirect uri provided" ),
433
+ utilities.useCache,
434
+ utilities.cacheLimit,
435
+ utilities.retryWhenRateLimited,
436
+ utilities.enableLogger,
437
+ utilities.testTokenValidity
365
438
)
366
439
} catch (e: Exception ) {
367
440
throw SpotifyException (" Invalid credentials provided in the login process" , e)
@@ -370,12 +443,13 @@ class SpotifyApiBuilderDsl {
370
443
clientId ? : " not-set" ,
371
444
clientSecret ? : " not-set" ,
372
445
token,
373
- automaticRefresh,
446
+ utilities. automaticRefresh,
374
447
redirectUri ? : " not-set" ,
375
- useCache,
376
- cacheLimit,
377
- retryWhenRateLimited,
378
- enableLogger
448
+ utilities.useCache,
449
+ utilities.cacheLimit,
450
+ utilities.retryWhenRateLimited,
451
+ utilities.enableLogger,
452
+ utilities.testTokenValidity
379
453
)
380
454
tokenString != null -> SpotifyClientAPI (
381
455
clientId ? : " not-set" ,
@@ -389,10 +463,11 @@ class SpotifyApiBuilderDsl {
389
463
),
390
464
false ,
391
465
redirectUri ? : " not-set" ,
392
- useCache,
393
- cacheLimit,
394
- retryWhenRateLimited,
395
- enableLogger
466
+ utilities.useCache,
467
+ utilities.cacheLimit,
468
+ utilities.retryWhenRateLimited,
469
+ utilities.enableLogger,
470
+ utilities.testTokenValidity
396
471
)
397
472
else -> throw IllegalArgumentException (
398
473
" At least one of: authorizationCode, tokenString, or token must be provided " +
0 commit comments