@@ -22,9 +22,8 @@ import com.google.gson.GsonBuilder
2222import org.jsoup.Jsoup
2323import java.util.concurrent.Executors
2424import java.util.concurrent.TimeUnit
25- import java.util.stream.Collectors
2625
27- open class SpotifyAPI internal constructor(val clientId : String? , val clientSecret : String? , var token : Token ) {
26+ open class SpotifyAPI internal constructor(val clientId : String , val clientSecret : String , var token : Token ) {
2827 internal var expireTime = System .currentTimeMillis() + token.expires_in * 1000
2928 internal val executor = Executors .newScheduledThreadPool(1 )
3029 val gson = GsonBuilder ().setLenient().create()!!
@@ -38,17 +37,15 @@ open class SpotifyAPI internal constructor(val clientId: String?, val clientSecr
3837 val publicFollowing = PublicFollowingAPI (this )
3938 val logger = SpotifyLogger (true )
4039
41- class Builder (private var clientId : String? , private var clientSecret : String? ) {
40+ class Builder (private var clientId : String , private var clientSecret : String ) {
4241 fun build (): SpotifyAPI {
4342 return try {
4443 val token = Gson ().fromJson(Jsoup .connect(" https://accounts.spotify.com/api/token" )
4544 .data(" grant_type" , " client_credentials" )
4645 .header(" Authorization" , " Basic " + (" $clientId :$clientSecret " .byteEncode()))
4746 .ignoreContentType(true ).post().body().text(), Token ::class .java)
4847 ? : throw IllegalArgumentException (" Invalid credentials provided" )
49- if (clientId != null && clientSecret != null ) {
50- SpotifyAPI (clientId, clientSecret, token)
51- } else throw IllegalArgumentException (" ID and Secret must not be null!" )
48+ SpotifyAPI (clientId, clientSecret, token)
5249 } catch (e: Exception ) {
5350 println (" Invalid credentials provided" )
5451 throw e
@@ -66,9 +63,19 @@ open class SpotifyAPI internal constructor(val clientId: String?, val clientSecr
6663 fun useLogger (enable : Boolean ) {
6764 logger.enabled = enable
6865 }
66+
67+ fun authorizeUser (authorizationCode : String , redirectUri : String , automaticRefresh : Boolean = true): SpotifyClientAPI {
68+ return SpotifyClientAPI .Builder (clientId, clientSecret, redirectUri).buildAuthCode(authorizationCode, automaticRefresh)
69+ }
70+
71+ fun authorizeUserToken (oauthToken : String , redirectUri : String ): SpotifyClientAPI {
72+ return SpotifyClientAPI .Builder (clientId, clientSecret, redirectUri).buildToken(oauthToken)
73+ }
74+
75+ fun getAuthUrl (vararg scopes : SpotifyClientAPI .Scope , redirectUri : String ): String = getAuthUrlFull(* scopes, clientId = clientId, redirectUri = redirectUri)
6976}
7077
71- class SpotifyClientAPI private constructor(clientId : String , clientSecret : String , token : Token , automaticRefresh : Boolean = false ) : SpotifyAPI(clientId, clientSecret, token) {
78+ class SpotifyClientAPI private constructor(clientId : String , clientSecret : String , token : Token , automaticRefresh : Boolean = false , var redirectUri : String ) : SpotifyAPI(clientId, clientSecret, token) {
7279 val personalization = PersonalizationAPI (this )
7380 val clientProfile = ClientProfileAPI (this )
7481 val clientLibrary = ClientLibraryAPI (this )
@@ -84,7 +91,7 @@ class SpotifyClientAPI private constructor(clientId: String, clientSecret: Strin
8491
8592 fun cancelRefresh () = executor.shutdown()
8693
87- fun refreshToken () {
94+ private fun refreshToken () {
8895 val tempToken = gson.fromJson(Jsoup .connect(" https://accounts.spotify.com/api/token" )
8996 .data(" grant_type" , " client_credentials" )
9097 .data(" refresh_token" , token.refresh_token ? : " " )
@@ -98,6 +105,8 @@ class SpotifyClientAPI private constructor(clientId: String, clientSecret: Strin
98105 }
99106 }
100107
108+ fun getAuthUrl (vararg scopes : Scope ): String = getAuthUrlFull(* scopes, clientId = clientId, redirectUri = redirectUri)
109+
101110 class Builder (val clientId : String , val clientSecret : String , val redirectUri : String ) {
102111 fun buildAuthCode (authorizationCode : String , automaticRefresh : Boolean = true): SpotifyClientAPI {
103112 return try {
@@ -106,7 +115,7 @@ class SpotifyClientAPI private constructor(clientId: String, clientSecret: Strin
106115 .data(" code" , authorizationCode)
107116 .data(" redirect_uri" , redirectUri)
108117 .header(" Authorization" , " Basic " + (" $clientId :$clientSecret " ).byteEncode())
109- .ignoreContentType(true ).post().body().text().toObject(Gson ()), automaticRefresh)
118+ .ignoreContentType(true ).post().body().text().toObject(Gson ()), automaticRefresh, redirectUri )
110119 } catch (e: Exception ) {
111120 println (" Invalid credentials provided" )
112121 throw e
@@ -115,15 +124,10 @@ class SpotifyClientAPI private constructor(clientId: String, clientSecret: Strin
115124
116125 fun buildToken (oauthToken : String ): SpotifyClientAPI {
117126 return SpotifyClientAPI (clientId, clientSecret, Token (oauthToken, " client_credentials" , 1000 ,
118- null , null ), false )
127+ null , null ), false , redirectUri )
119128 }
120129
121- fun getAuthUrl (vararg scopes : Scope ): String {
122- return " https://accounts.spotify.com/authorize/?client_id=$clientId " +
123- " &response_type=code" +
124- " &redirect_uri=$redirectUri " +
125- if (scopes.isEmpty()) " " else " &scope=${scopes.map { it.uri }.stream().collect(Collectors .joining(" %20" ))} "
126- }
130+ fun getAuthUrl (vararg scopes : Scope ): String = getAuthUrlFull(* scopes, clientId = clientId, redirectUri = redirectUri)
127131 }
128132
129133 enum class Scope (val uri : String ) {
@@ -145,3 +149,10 @@ class SpotifyClientAPI private constructor(clientId: String, clientSecret: Strin
145149 USER_READ_RECENTLY_PLAYED (" user-read-recently-played" );
146150 }
147151}
152+
153+ private fun getAuthUrlFull (vararg scopes : SpotifyClientAPI .Scope , clientId : String , redirectUri : String ): String {
154+ return " https://accounts.spotify.com/authorize/?client_id=$clientId " +
155+ " &response_type=code" +
156+ " &redirect_uri=$redirectUri " +
157+ if (scopes.isEmpty()) " " else " &scope=${scopes.map { it.uri }.joinToString(" %20" )} "
158+ }
0 commit comments