@@ -15,13 +15,15 @@ import com.adamratzman.spotify.endpoints.public.PlaylistsAPI
1515import com.adamratzman.spotify.endpoints.public.SearchAPI
1616import com.adamratzman.spotify.endpoints.public.TracksAPI
1717import com.adamratzman.spotify.endpoints.public.UserAPI
18+ import com.adamratzman.spotify.utils.HttpConnection
19+ import com.adamratzman.spotify.utils.HttpHeader
20+ import com.adamratzman.spotify.utils.HttpRequestMethod
1821import com.adamratzman.spotify.utils.SpotifyEndpoint
1922import com.adamratzman.spotify.utils.Token
2023import com.adamratzman.spotify.utils.byteEncode
2124import com.adamratzman.spotify.utils.toObject
2225import com.google.gson.Gson
2326import com.google.gson.GsonBuilder
24- import org.jsoup.Jsoup
2527import java.util.concurrent.Executors
2628import java.util.concurrent.TimeUnit
2729
@@ -36,26 +38,17 @@ class SpotifyApiBuilderJava(val clientId: String, val clientSecret: String) {
3638 var authorizationCode: String? = null
3739 var tokenString: String? = null
3840 var token: Token ? = null
41+ var useCache: Boolean = true
3942
40- fun redirectUri (redirectUri : String? ): SpotifyApiBuilderJava {
41- this .redirectUri = redirectUri
42- return this
43- }
43+ fun useCache (useCache : Boolean ) = apply { this .useCache = useCache }
4444
45- fun authorizationCode (authorizationCode : String? ): SpotifyApiBuilderJava {
46- this .authorizationCode = authorizationCode
47- return this
48- }
45+ fun redirectUri (redirectUri : String? ) = apply { this .redirectUri = redirectUri }
4946
50- fun tokenString (tokenString : String? ): SpotifyApiBuilderJava {
51- this .tokenString = tokenString
52- return this
53- }
47+ fun authorizationCode (authorizationCode : String? ) = apply { this .authorizationCode = authorizationCode }
5448
55- fun token (token : Token ? ): SpotifyApiBuilderJava {
56- this .token = token
57- return this
58- }
49+ fun tokenString (tokenString : String? ) = apply { this .tokenString = tokenString }
50+
51+ fun token (token : Token ? ) = apply { this .token = token }
5952
6053 fun buildCredentialed () = spotifyApi {
6154 credentials {
@@ -118,6 +111,7 @@ class SpotifyUserAuthorizationBuilder(
118111class SpotifyApiBuilder {
119112 private var credentials: SpotifyCredentials = SpotifyCredentials (null , null , null )
120113 private var authentication = SpotifyUserAuthorizationBuilder ()
114+ var useCache: Boolean = true
121115
122116 fun credentials (block : SpotifyCredentialsBuilder .() -> Unit ) {
123117 credentials = SpotifyCredentialsBuilder ().apply (block).build()
@@ -138,6 +132,8 @@ class SpotifyApiBuilder {
138132 return getAuthUrlFull(* scopes, clientId = credentials.clientId!! , redirectUri = credentials.redirectUri!! )
139133 }
140134
135+ fun buildCredentialedAsync (consumer : (SpotifyAPI ) -> Unit ) = Runnable { consumer(buildCredentialed()) }.run ()
136+
141137 fun buildCredentialed (): SpotifyAPI {
142138 val clientId = credentials.clientId
143139 val clientSecret = credentials.clientSecret
@@ -146,7 +142,7 @@ class SpotifyApiBuilder {
146142 }
147143 return when {
148144 authentication.token != null -> {
149- SpotifyAppAPI (clientId ? : " not-set" , clientSecret ? : " not-set" , authentication.token!! )
145+ SpotifyAppAPI (clientId ? : " not-set" , clientSecret ? : " not-set" , authentication.token!! , useCache )
150146 }
151147 authentication.tokenString != null -> {
152148 SpotifyAppAPI (
@@ -155,27 +151,24 @@ class SpotifyApiBuilder {
155151 Token (
156152 authentication.tokenString!! , " client_credentials" ,
157153 60000 , null , null
158- )
154+ ),
155+ useCache
159156 )
160157 }
161158 else -> try {
162- val token = Gson ().fromJson(
163- Jsoup .connect(" https://accounts.spotify.com/api/token" )
164- .data(" grant_type" , " client_credentials" )
165- .header(" Authorization" , " Basic " + (" $clientId :$clientSecret " .byteEncode()))
166- .ignoreContentType(true ).post().body().text(), Token ::class .java
167- ) ? : throw IllegalArgumentException (" Invalid credentials provided" )
168- SpotifyAppAPI (
169- clientId ? : throw IllegalArgumentException (),
170- clientSecret ? : throw IllegalArgumentException (),
171- token
172- )
159+ if (clientId == null || clientSecret == null ) throw IllegalArgumentException (" Illegal credentials provided" )
160+ val token = getCredentialedToken(clientId, clientSecret)
161+ ? : throw IllegalArgumentException (" Invalid credentials provided" )
162+ SpotifyAppAPI (clientId, clientSecret, token, useCache)
173163 } catch (e: Exception ) {
174164 throw SpotifyException (" Invalid credentials provided in the login process" , e)
175165 }
176166 }
177167 }
178168
169+ fun buildClientAsync (consumer : (SpotifyClientAPI ) -> Unit , automaticRefresh : Boolean = false) =
170+ Runnable { consumer(buildClient(automaticRefresh)) }.run ()
171+
179172 fun buildClient (automaticRefresh : Boolean = false): SpotifyClientAPI =
180173 buildClient(
181174 authentication.authorizationCode, authentication.tokenString,
@@ -210,14 +203,20 @@ class SpotifyApiBuilder {
210203 SpotifyClientAPI (
211204 clientId ? : throw IllegalArgumentException (),
212205 clientSecret ? : throw IllegalArgumentException (),
213- Jsoup .connect(" https://accounts.spotify.com/api/token" )
214- .data(" grant_type" , " authorization_code" )
215- .data(" code" , authorizationCode)
216- .data(" redirect_uri" , redirectUri)
217- .header(" Authorization" , " Basic " + (" $clientId :$clientSecret " ).byteEncode())
218- .ignoreContentType(true ).post().body().text().toObject(Gson (), Token ::class .java),
206+ HttpConnection (
207+ url = " https://accounts.spotify.com/api/token" ,
208+ method = HttpRequestMethod .POST ,
209+ body = " grant_type=authorization_code&code=$authorizationCode &redirect_uri=$redirectUri " ,
210+ contentType = " application/x-www-form-urlencoded"
211+ ).execute(
212+ HttpHeader (
213+ " Authorization" ,
214+ " Basic ${" $clientId :$clientSecret " .byteEncode()} "
215+ )
216+ ).body.toObject(Gson (), Token ::class .java),
219217 automaticRefresh,
220- redirectUri ? : throw IllegalArgumentException ()
218+ redirectUri ? : throw IllegalArgumentException (),
219+ useCache
221220 )
222221 } catch (e: Exception ) {
223222 throw SpotifyException (" Invalid credentials provided in the login process" , e)
@@ -227,13 +226,15 @@ class SpotifyApiBuilder {
227226 clientSecret ? : " not-set" ,
228227 token,
229228 automaticRefresh,
230- redirectUri ? : " not-set"
229+ redirectUri ? : " not-set" ,
230+ useCache
231231 )
232232 tokenString != null -> SpotifyClientAPI (
233233 clientId ? : " not-set" , clientSecret ? : " not-set" , Token (
234234 tokenString, " client_credentials" , 1000 ,
235235 null , null
236- ), false , redirectUri ? : " not-set"
236+ ), false , redirectUri ? : " not-set" ,
237+ useCache
237238 )
238239 else -> throw IllegalArgumentException (
239240 " At least one of: authorizationCode, tokenString, or token must be provided " +
@@ -243,7 +244,10 @@ class SpotifyApiBuilder {
243244 }
244245}
245246
246- abstract class SpotifyAPI internal constructor(val clientId : String , val clientSecret : String , var token : Token ) {
247+ abstract class SpotifyAPI internal constructor(
248+ val clientId : String , val clientSecret : String ,
249+ var token : Token , var useCache : Boolean
250+ ) {
247251 internal var expireTime = System .currentTimeMillis() + token.expires_in * 1000
248252 internal val executor = Executors .newScheduledThreadPool(2 )
249253 internal val gson = GsonBuilder ().setLenient().create()!!
@@ -262,8 +266,6 @@ abstract class SpotifyAPI internal constructor(val clientId: String, val clientS
262266 abstract fun refreshToken ()
263267 abstract fun clearCache ()
264268
265- var useCache: Boolean = true
266-
267269 init {
268270 executor.scheduleAtFixedRate(::clearCache, 10 , 10 , TimeUnit .MINUTES )
269271 }
@@ -281,8 +283,8 @@ abstract class SpotifyAPI internal constructor(val clientId: String, val clientS
281283 }
282284}
283285
284- class SpotifyAppAPI internal constructor(clientId : String , clientSecret : String , token : Token ) :
285- SpotifyAPI (clientId, clientSecret, token) {
286+ class SpotifyAppAPI internal constructor(clientId : String , clientSecret : String , token : Token , useCache : Boolean ) :
287+ SpotifyAPI (clientId, clientSecret, token, useCache ) {
286288 override val search: SearchAPI = SearchAPI (this )
287289 override val albums: AlbumAPI = AlbumAPI (this )
288290 override val browse: BrowseAPI = BrowseAPI (this )
@@ -300,12 +302,7 @@ class SpotifyAppAPI internal constructor(clientId: String, clientSecret: String,
300302
301303 override fun refreshToken () {
302304 if (clientId != " not-set" && clientSecret != " not-set" )
303- token = gson.fromJson(
304- Jsoup .connect(" https://accounts.spotify.com/api/token" )
305- .data(" grant_type" , " client_credentials" )
306- .header(" Authorization" , " Basic " + (" $clientId :$clientSecret " .byteEncode()))
307- .ignoreContentType(true ).post().body().text(), Token ::class .java
308- )
305+ token = getCredentialedToken(clientId, clientSecret)
309306 expireTime = System .currentTimeMillis() + token.expires_in * 1000
310307 }
311308
@@ -326,8 +323,9 @@ class SpotifyClientAPI internal constructor(
326323 clientSecret : String ,
327324 token : Token ,
328325 automaticRefresh : Boolean = false ,
329- var redirectUri : String
330- ) : SpotifyAPI(clientId, clientSecret, token) {
326+ var redirectUri : String ,
327+ useCache : Boolean
328+ ) : SpotifyAPI(clientId, clientSecret, token, useCache) {
331329 override val search: SearchAPI = SearchAPI (this )
332330 override val albums: AlbumAPI = AlbumAPI (this )
333331 override val browse: BrowseAPI = BrowseAPI (this )
@@ -372,11 +370,13 @@ class SpotifyClientAPI internal constructor(
372370
373371 override fun refreshToken () {
374372 val tempToken = gson.fromJson(
375- Jsoup .connect(" https://accounts.spotify.com/api/token" )
376- .data(" grant_type" , " refresh_token" )
377- .data(" refresh_token" , token.refresh_token ? : " " )
378- .header(" Authorization" , " Basic " + (" $clientId :$clientSecret " ).byteEncode())
379- .ignoreContentType(true ).post().body().text(), Token ::class .java
373+ HttpConnection (
374+ url = " https://accounts.spotify.com/api/token" ,
375+ method = HttpRequestMethod .POST ,
376+ body = " grant_type=refresh_token&refresh_token=${token.refresh_token ? : " " } " ,
377+ contentType = " application/x-www-form-urlencoded"
378+ ).execute(HttpHeader (" Authorization" , " Basic ${" $clientId :$clientSecret " .byteEncode()} " )).body,
379+ Token ::class .java
380380 )
381381 if (tempToken == null ) {
382382 logger.logWarning(" Spotify token refresh failed" )
@@ -411,3 +411,13 @@ private fun getAuthUrlFull(vararg scopes: SpotifyScope, clientId: String, redire
411411 " &redirect_uri=$redirectUri " +
412412 if (scopes.isEmpty()) " " else " &scope=${scopes.joinToString(" %20" ) { it.uri }} "
413413}
414+
415+ private fun getCredentialedToken (clientId : String , clientSecret : String ) = Gson ().fromJson(
416+ HttpConnection (
417+ url = " https://accounts.spotify.com/api/token" ,
418+ method = HttpRequestMethod .POST ,
419+ body = " grant_type=client_credentials" ,
420+ contentType = " application/x-www-form-urlencoded"
421+ ).execute(HttpHeader (" Authorization" , " Basic ${" $clientId :$clientSecret " .byteEncode()} " )).body,
422+ Token ::class .java
423+ )
0 commit comments