diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index 4f07930..e4d016c 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -8,21 +8,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/core/auth/src/main/java/com/example/mymusic/core/auth/AuthorizationManager.kt b/core/auth/src/main/java/com/example/mymusic/core/auth/AuthorizationManager.kt
index e455909..7423409 100644
--- a/core/auth/src/main/java/com/example/mymusic/core/auth/AuthorizationManager.kt
+++ b/core/auth/src/main/java/com/example/mymusic/core/auth/AuthorizationManager.kt
@@ -7,6 +7,7 @@ import android.text.TextUtils
import android.util.Base64
import android.util.Log
import com.example.mymusic.core.common.ApplicationScope
+import com.example.mymusic.core.common.Constants
import com.example.mymusic.core.common.IoDispatcher
import com.example.mymusic.core.datastore.MyMusicPreferencesDataSource
import dagger.hilt.android.internal.Contexts
@@ -54,10 +55,10 @@ class AuthorizationManager @Inject constructor(
private fun initAuthServiceConfig() {
_authServiceConfig = AuthorizationServiceConfiguration(
- Uri.parse(com.example.mymusic.core.common.Constants.URL_AUTHORIZATION),
- Uri.parse(com.example.mymusic.core.common.Constants.URL_TOKEN_EXCHANGE),
+ Uri.parse(Constants.URL_AUTHORIZATION),
+ Uri.parse(Constants.URL_TOKEN_EXCHANGE),
null,
- Uri.parse(com.example.mymusic.core.common.Constants.URL_AUTH_REDIRECT))
+ Uri.parse(Constants.URL_AUTH_REDIRECT))
}
private fun initAuthService() {
@@ -102,28 +103,29 @@ class AuthorizationManager @Inject constructor(
val encoding = Base64.URL_SAFE or Base64.NO_PADDING or Base64.NO_WRAP
val codeVerifier = Base64.encodeToString(bytes, encoding)
- val digest = MessageDigest.getInstance(com.example.mymusic.core.common.Constants.MESSAGE_DIGEST_ALGORITHM)
+ val digest = MessageDigest.getInstance(Constants.MESSAGE_DIGEST_ALGORITHM)
val hash = digest.digest(codeVerifier.toByteArray())
val codeChallenge = Base64.encodeToString(hash, encoding)
val builder = AuthorizationRequest.Builder(
_authServiceConfig,
- com.example.mymusic.core.common.Constants.CLIENT_ID,
+ Constants.CLIENT_ID,
ResponseTypeValues.CODE,
- Uri.parse(com.example.mymusic.core.common.Constants.URL_AUTH_REDIRECT))
+ Uri.parse(Constants.URL_AUTH_REDIRECT))
.setCodeVerifier(codeVerifier,
codeChallenge,
- com.example.mymusic.core.common.Constants.CODE_VERIFIER_CHALLENGE_METHOD)
+ Constants.CODE_VERIFIER_CHALLENGE_METHOD)
builder.setScopes(
- com.example.mymusic.core.common.Constants.SCOPE_STREAMING,
- com.example.mymusic.core.common.Constants.SCOPE_EMAIL,
- com.example.mymusic.core.common.Constants.SCOPE_APP_REMOTE_CONTROL,
- com.example.mymusic.core.common.Constants.SCOPE_USER_MODIFY_PLAYBACK_STATE,
- com.example.mymusic.core.common.Constants.SCOPE_USER_READ_PRIVATE,
- com.example.mymusic.core.common.Constants.SCOPE_USER_READ_RECENTLY_PLAYED,
- com.example.mymusic.core.common.Constants.SCOPE_USER_LIBRARY_READ,
- com.example.mymusic.core.common.Constants.SCOPE_PLAYLIST_READ_PRIVATE
+ Constants.SCOPE_STREAMING,
+ Constants.SCOPE_EMAIL,
+ Constants.SCOPE_APP_REMOTE_CONTROL,
+ Constants.SCOPE_USER_MODIFY_PLAYBACK_STATE,
+ Constants.SCOPE_USER_READ_PRIVATE,
+ Constants.SCOPE_USER_READ_RECENTLY_PLAYED,
+ Constants.SCOPE_USER_LIBRARY_READ,
+ Constants.SCOPE_PLAYLIST_READ_PRIVATE,
+ Constants.SCOPE_USER_TOP_READ
)
val request = builder.build()
diff --git a/core/common/src/main/java/com/example/mymusic/core/common/Constants.kt b/core/common/src/main/java/com/example/mymusic/core/common/Constants.kt
index d980635..16f74d3 100644
--- a/core/common/src/main/java/com/example/mymusic/core/common/Constants.kt
+++ b/core/common/src/main/java/com/example/mymusic/core/common/Constants.kt
@@ -12,6 +12,7 @@ class Constants {
const val SCOPE_USER_READ_CURRENTLY_PLAYING = "user-read-currently-playing"
const val SCOPE_APP_REMOTE_CONTROL = "app-remote-control"
const val SCOPE_STREAMING = "streaming"
+ const val SCOPE_USER_TOP_READ = "user-top-read"
const val SCOPE_PLAYLIST_READ_PRIVATE = "playlist-read-private"
const val SCOPE_PLAYLIST_MODIFY_PRIVATE = "playlist-modify-private"
const val SCOPE_PLAYLIST_MODIFY_PUBLIC = "playlist-modify-public"
diff --git a/core/data/src/main/java/com/example/mymusic/core/data/repository/OfflineFirstMusicRepository.kt b/core/data/src/main/java/com/example/mymusic/core/data/repository/OfflineFirstMusicRepository.kt
index d6a0b51..396a3e1 100644
--- a/core/data/src/main/java/com/example/mymusic/core/data/repository/OfflineFirstMusicRepository.kt
+++ b/core/data/src/main/java/com/example/mymusic/core/data/repository/OfflineFirstMusicRepository.kt
@@ -171,7 +171,10 @@ class OfflineFirstMusicRepository @Inject constructor(
override suspend fun refresh() {
withContext(dispatcher) {
- val remoteMusic = getRecommendations()
+ // Get recommendations endpoint is deprecated
+ //val remoteMusic = getRecommendations()
+
+ val remoteMusic = networkDataSource.getTopItems("tracks")
if (remoteMusic.isNotEmpty()) {
diff --git a/core/database/src/androidTest/java/com/example/mymusic/core/database/MusicDaoTest.kt b/core/database/src/androidTest/java/com/example/mymusic/core/database/MusicDaoTest.kt
index 59205a9..974c031 100644
--- a/core/database/src/androidTest/java/com/example/mymusic/core/database/MusicDaoTest.kt
+++ b/core/database/src/androidTest/java/com/example/mymusic/core/database/MusicDaoTest.kt
@@ -448,3 +448,5 @@ class MusicDaoTest {
primaryColor = null
)
}
+
+
diff --git a/core/network/src/main/java/com/example/mymusic/core/network/MyMusicAPIService.kt b/core/network/src/main/java/com/example/mymusic/core/network/MyMusicAPIService.kt
index cb7723a..b0d3704 100644
--- a/core/network/src/main/java/com/example/mymusic/core/network/MyMusicAPIService.kt
+++ b/core/network/src/main/java/com/example/mymusic/core/network/MyMusicAPIService.kt
@@ -8,6 +8,7 @@ import com.example.mymusic.core.network.model.RecentlyPlayedTracksResponse
import com.example.mymusic.core.network.model.SavedAlbumsResponse
import com.example.mymusic.core.network.model.SavedPlaylistResponse
import com.example.mymusic.core.network.model.SpotifyTrack
+import com.example.mymusic.core.network.model.UsersTopItemsResponse
import com.haroldadmin.cnradapter.NetworkResponse
import retrofit2.http.GET
import retrofit2.http.Path
@@ -15,6 +16,11 @@ import retrofit2.http.Query
interface MyMusicAPIService {
+ @GET("https://api.spotify.com/v1/me/top/{type}")
+ suspend fun getTopItems(
+ @Path("type") type: String
+ ): NetworkResponse
+
@GET("https://api.spotify.com/v1/recommendations?limit=10&seed_genres=pop")
suspend fun getRecommendations(): NetworkResponse
diff --git a/core/network/src/main/java/com/example/mymusic/core/network/MyMusicNetworkDataSource.kt b/core/network/src/main/java/com/example/mymusic/core/network/MyMusicNetworkDataSource.kt
index f05fd31..f395816 100644
--- a/core/network/src/main/java/com/example/mymusic/core/network/MyMusicNetworkDataSource.kt
+++ b/core/network/src/main/java/com/example/mymusic/core/network/MyMusicNetworkDataSource.kt
@@ -8,6 +8,7 @@ import com.example.mymusic.core.network.model.SpotifySimplifiedTrack
import com.example.mymusic.core.network.model.SpotifyTrack
interface MyMusicNetworkDataSource {
+ suspend fun getTopItems(type: String): List
suspend fun getRecommendations(): List
diff --git a/core/network/src/main/java/com/example/mymusic/core/network/RetrofitNetworkDataSource.kt b/core/network/src/main/java/com/example/mymusic/core/network/RetrofitNetworkDataSource.kt
index 3f8a6f8..c22142a 100644
--- a/core/network/src/main/java/com/example/mymusic/core/network/RetrofitNetworkDataSource.kt
+++ b/core/network/src/main/java/com/example/mymusic/core/network/RetrofitNetworkDataSource.kt
@@ -10,12 +10,19 @@ import com.example.mymusic.core.network.model.SavedAlbumsResponse
import com.example.mymusic.core.network.model.SavedPlaylistResponse
import com.example.mymusic.core.network.model.SpotifySimplifiedTrack
import com.example.mymusic.core.network.model.SpotifyTrack
+import com.example.mymusic.core.network.model.UsersTopItemsResponse
import com.haroldadmin.cnradapter.NetworkResponse
import javax.inject.Inject
class RetrofitNetworkDataSource @Inject constructor(
private val apiService: MyMusicAPIService
): MyMusicNetworkDataSource {
+ override suspend fun getTopItems(type: String): List {
+ val response = apiService.getTopItems(type)
+ val data = (response as? NetworkResponse.Success?)?.body?.items ?: emptyList()
+
+ return processResponse(response, data, emptyList())
+ }
override suspend fun getRecommendations(): List {
val response = apiService.getRecommendations()
diff --git a/core/network/src/main/java/com/example/mymusic/core/network/fake/FakeNetworkDataSource.kt b/core/network/src/main/java/com/example/mymusic/core/network/fake/FakeNetworkDataSource.kt
index 3e02e85..ffceabd 100644
--- a/core/network/src/main/java/com/example/mymusic/core/network/fake/FakeNetworkDataSource.kt
+++ b/core/network/src/main/java/com/example/mymusic/core/network/fake/FakeNetworkDataSource.kt
@@ -13,6 +13,7 @@ import com.example.mymusic.core.network.model.SavedAlbumsResponse
import com.example.mymusic.core.network.model.SavedPlaylistResponse
import com.example.mymusic.core.network.model.SpotifySimplifiedTrack
import com.example.mymusic.core.network.model.SpotifyTrack
+import com.example.mymusic.core.network.model.UsersTopItemsResponse
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
@@ -26,6 +27,14 @@ class FakeNetworkDataSource @Inject constructor(
@IoDispatcher val dispatcher: CoroutineDispatcher,
@ApplicationContext val context: Context
) : MyMusicNetworkDataSource {
+ override suspend fun getTopItems(type: String): List =
+ withContext(dispatcher) {
+ val inputStream = context.resources.openRawResource(R.raw.top_items)
+ .bufferedReader().use { it.readText() }
+
+ val response = Json.decodeFromString(inputStream)
+ response.items
+ }
override suspend fun getRecommendations(): List =
withContext(dispatcher) {
diff --git a/core/network/src/main/java/com/example/mymusic/core/network/model/UsersTopItemsResponse.kt b/core/network/src/main/java/com/example/mymusic/core/network/model/UsersTopItemsResponse.kt
new file mode 100644
index 0000000..caa440f
--- /dev/null
+++ b/core/network/src/main/java/com/example/mymusic/core/network/model/UsersTopItemsResponse.kt
@@ -0,0 +1,14 @@
+package com.example.mymusic.core.network.model
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class UsersTopItemsResponse(
+ val href: String,
+ val limit: Int,
+ val next: String?,
+ val offset: Int,
+ val previous: String?,
+ val total: String,
+ val items: List // OneOf issue https://developer.spotify.com/documentation/web-api/reference/get-users-top-artists-and-tracks
+)
\ No newline at end of file
diff --git a/core/network/src/main/res/raw/top_items.json b/core/network/src/main/res/raw/top_items.json
new file mode 100644
index 0000000..f606adf
--- /dev/null
+++ b/core/network/src/main/res/raw/top_items.json
@@ -0,0 +1,1606 @@
+{
+ "href": "https://api.spotify.com/v1/playlists/3cEYpjA9oz9GiPac4AsH4n/tracks?offset=0&limit=100&locale=en-US,en;q%3D0.5",
+ "items": [
+ {
+ "added_at": "2015-01-15T12:39:22Z",
+ "added_by": {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/user/jmperezperez"
+ },
+ "href": "https://api.spotify.com/v1/users/jmperezperez",
+ "id": "jmperezperez",
+ "type": "user",
+ "uri": "spotify:user:jmperezperez"
+ },
+ "is_local": false,
+ "primary_color": null,
+ "track": {
+ "preview_url": null,
+ "available_markets": [
+ "AR",
+ "AU",
+ "AT",
+ "BE",
+ "BO",
+ "BR",
+ "BG",
+ "CA",
+ "CL",
+ "CO",
+ "CR",
+ "CY",
+ "CZ",
+ "DK",
+ "DO",
+ "DE",
+ "EC",
+ "EE",
+ "SV",
+ "FI",
+ "FR",
+ "GR",
+ "GT",
+ "HN",
+ "HK",
+ "HU",
+ "IS",
+ "IE",
+ "IT",
+ "LV",
+ "LT",
+ "LU",
+ "MY",
+ "MT",
+ "MX",
+ "NL",
+ "NZ",
+ "NI",
+ "NO",
+ "PA",
+ "PY",
+ "PE",
+ "PH",
+ "PL",
+ "PT",
+ "SG",
+ "SK",
+ "ES",
+ "SE",
+ "CH",
+ "TW",
+ "TR",
+ "UY",
+ "US",
+ "GB",
+ "AD",
+ "LI",
+ "MC",
+ "ID",
+ "JP",
+ "TH",
+ "VN",
+ "RO",
+ "IL",
+ "ZA",
+ "SA",
+ "AE",
+ "BH",
+ "QA",
+ "OM",
+ "KW",
+ "EG",
+ "MA",
+ "DZ",
+ "TN",
+ "LB",
+ "JO",
+ "PS",
+ "IN",
+ "BY",
+ "KZ",
+ "MD",
+ "UA",
+ "AL",
+ "BA",
+ "HR",
+ "ME",
+ "MK",
+ "RS",
+ "SI",
+ "KR",
+ "BD",
+ "PK",
+ "LK",
+ "GH",
+ "KE",
+ "NG",
+ "TZ",
+ "UG",
+ "AG",
+ "AM",
+ "BS",
+ "BB",
+ "BZ",
+ "BT",
+ "BW",
+ "BF",
+ "CV",
+ "CW",
+ "DM",
+ "FJ",
+ "GM",
+ "GE",
+ "GD",
+ "GW",
+ "GY",
+ "HT",
+ "JM",
+ "KI",
+ "LS",
+ "LR",
+ "MW",
+ "MV",
+ "ML",
+ "MH",
+ "FM",
+ "NA",
+ "NR",
+ "NE",
+ "PW",
+ "PG",
+ "PR",
+ "WS",
+ "SM",
+ "ST",
+ "SN",
+ "SC",
+ "SL",
+ "SB",
+ "KN",
+ "LC",
+ "VC",
+ "SR",
+ "TL",
+ "TO",
+ "TT",
+ "TV",
+ "VU",
+ "AZ",
+ "BN",
+ "BI",
+ "KH",
+ "CM",
+ "TD",
+ "KM",
+ "GQ",
+ "SZ",
+ "GA",
+ "GN",
+ "KG",
+ "LA",
+ "MO",
+ "MR",
+ "MN",
+ "NP",
+ "RW",
+ "TG",
+ "UZ",
+ "ZW",
+ "BJ",
+ "MG",
+ "MU",
+ "MZ",
+ "AO",
+ "CI",
+ "DJ",
+ "ZM",
+ "CD",
+ "CG",
+ "IQ",
+ "LY",
+ "TJ",
+ "VE",
+ "ET",
+ "XK"
+ ],
+ "explicit": false,
+ "type": "track",
+ "episode": false,
+ "track": true,
+ "album": {
+ "available_markets": [
+ "AR",
+ "AU",
+ "AT",
+ "BE",
+ "BO",
+ "BR",
+ "BG",
+ "CA",
+ "CL",
+ "CO",
+ "CR",
+ "CY",
+ "CZ",
+ "DK",
+ "DO",
+ "DE",
+ "EC",
+ "EE",
+ "SV",
+ "FI",
+ "FR",
+ "GR",
+ "GT",
+ "HN",
+ "HK",
+ "HU",
+ "IS",
+ "IE",
+ "IT",
+ "LV",
+ "LT",
+ "LU",
+ "MY",
+ "MT",
+ "MX",
+ "NL",
+ "NZ",
+ "NI",
+ "NO",
+ "PA",
+ "PY",
+ "PE",
+ "PH",
+ "PL",
+ "PT",
+ "SG",
+ "SK",
+ "ES",
+ "SE",
+ "CH",
+ "TW",
+ "TR",
+ "UY",
+ "US",
+ "GB",
+ "AD",
+ "LI",
+ "MC",
+ "ID",
+ "JP",
+ "TH",
+ "VN",
+ "RO",
+ "IL",
+ "ZA",
+ "SA",
+ "AE",
+ "BH",
+ "QA",
+ "OM",
+ "KW",
+ "EG",
+ "MA",
+ "DZ",
+ "TN",
+ "LB",
+ "JO",
+ "PS",
+ "IN",
+ "BY",
+ "KZ",
+ "MD",
+ "UA",
+ "AL",
+ "BA",
+ "HR",
+ "ME",
+ "MK",
+ "RS",
+ "SI",
+ "KR",
+ "BD",
+ "PK",
+ "LK",
+ "GH",
+ "KE",
+ "NG",
+ "TZ",
+ "UG",
+ "AG",
+ "AM",
+ "BS",
+ "BB",
+ "BZ",
+ "BT",
+ "BW",
+ "BF",
+ "CV",
+ "CW",
+ "DM",
+ "FJ",
+ "GM",
+ "GE",
+ "GD",
+ "GW",
+ "GY",
+ "HT",
+ "JM",
+ "KI",
+ "LS",
+ "LR",
+ "MW",
+ "MV",
+ "ML",
+ "MH",
+ "FM",
+ "NA",
+ "NR",
+ "NE",
+ "PW",
+ "PG",
+ "PR",
+ "WS",
+ "SM",
+ "ST",
+ "SN",
+ "SC",
+ "SL",
+ "SB",
+ "KN",
+ "LC",
+ "VC",
+ "SR",
+ "TL",
+ "TO",
+ "TT",
+ "TV",
+ "VU",
+ "AZ",
+ "BN",
+ "BI",
+ "KH",
+ "CM",
+ "TD",
+ "KM",
+ "GQ",
+ "SZ",
+ "GA",
+ "GN",
+ "KG",
+ "LA",
+ "MO",
+ "MR",
+ "MN",
+ "NP",
+ "RW",
+ "TG",
+ "UZ",
+ "ZW",
+ "BJ",
+ "MG",
+ "MU",
+ "MZ",
+ "AO",
+ "CI",
+ "DJ",
+ "ZM",
+ "CD",
+ "CG",
+ "IQ",
+ "LY",
+ "TJ",
+ "VE",
+ "ET",
+ "XK"
+ ],
+ "type": "album",
+ "album_type": "compilation",
+ "href": "https://api.spotify.com/v1/albums/2pANdqPvxInB0YvcDiw4ko",
+ "id": "2pANdqPvxInB0YvcDiw4ko",
+ "images": [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b273ce6d0eef0c1ce77e5f95bbbc",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e02ce6d0eef0c1ce77e5f95bbbc",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d00004851ce6d0eef0c1ce77e5f95bbbc",
+ "width": 64
+ }
+ ],
+ "name": "Progressive Psy Trance Picks Vol.8",
+ "release_date": "2012-04-02",
+ "release_date_precision": "day",
+ "uri": "spotify:album:2pANdqPvxInB0YvcDiw4ko",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/0LyfQWJT6nXafLPZqxe9Of"
+ },
+ "href": "https://api.spotify.com/v1/artists/0LyfQWJT6nXafLPZqxe9Of",
+ "id": "0LyfQWJT6nXafLPZqxe9Of",
+ "name": "Various Artists",
+ "type": "artist",
+ "uri": "spotify:artist:0LyfQWJT6nXafLPZqxe9Of"
+ }
+ ],
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/2pANdqPvxInB0YvcDiw4ko"
+ },
+ "total_tracks": 20
+ },
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/6eSdhw46riw2OUHgMwR8B5"
+ },
+ "href": "https://api.spotify.com/v1/artists/6eSdhw46riw2OUHgMwR8B5",
+ "id": "6eSdhw46riw2OUHgMwR8B5",
+ "name": "Odiseo",
+ "type": "artist",
+ "uri": "spotify:artist:6eSdhw46riw2OUHgMwR8B5"
+ }
+ ],
+ "disc_number": 1,
+ "track_number": 10,
+ "duration_ms": 376000,
+ "external_ids": {
+ "isrc": "DEKC41200989"
+ },
+ "external_urls": {
+ "spotify": "https://open.spotify.com/track/4rzfv0JLZfVhOhbSQ8o5jZ"
+ },
+ "href": "https://api.spotify.com/v1/tracks/4rzfv0JLZfVhOhbSQ8o5jZ",
+ "id": "4rzfv0JLZfVhOhbSQ8o5jZ",
+ "name": "Api",
+ "popularity": 1,
+ "uri": "spotify:track:4rzfv0JLZfVhOhbSQ8o5jZ",
+ "is_local": false
+ },
+ "video_thumbnail": {
+ "url": null
+ }
+ },
+ {
+ "added_at": "2015-01-15T12:40:03Z",
+ "added_by": {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/user/jmperezperez"
+ },
+ "href": "https://api.spotify.com/v1/users/jmperezperez",
+ "id": "jmperezperez",
+ "type": "user",
+ "uri": "spotify:user:jmperezperez"
+ },
+ "is_local": false,
+ "primary_color": null,
+ "track": {
+ "preview_url": null,
+ "available_markets": [],
+ "explicit": false,
+ "type": "track",
+ "episode": false,
+ "track": true,
+ "album": {
+ "available_markets": [],
+ "type": "album",
+ "album_type": "compilation",
+ "href": "https://api.spotify.com/v1/albums/6nlfkk5GoXRL1nktlATNsy",
+ "id": "6nlfkk5GoXRL1nktlATNsy",
+ "images": [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b273aa2ff29970d9a63a49dfaeb2",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e02aa2ff29970d9a63a49dfaeb2",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d00004851aa2ff29970d9a63a49dfaeb2",
+ "width": 64
+ }
+ ],
+ "name": "Wellness & Dreaming Source",
+ "release_date": "2015-01-09",
+ "release_date_precision": "day",
+ "uri": "spotify:album:6nlfkk5GoXRL1nktlATNsy",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/0LyfQWJT6nXafLPZqxe9Of"
+ },
+ "href": "https://api.spotify.com/v1/artists/0LyfQWJT6nXafLPZqxe9Of",
+ "id": "0LyfQWJT6nXafLPZqxe9Of",
+ "name": "Various Artists",
+ "type": "artist",
+ "uri": "spotify:artist:0LyfQWJT6nXafLPZqxe9Of"
+ }
+ ],
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/6nlfkk5GoXRL1nktlATNsy"
+ },
+ "total_tracks": 25
+ },
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/5VQE4WOzPu9h3HnGLuBoA6"
+ },
+ "href": "https://api.spotify.com/v1/artists/5VQE4WOzPu9h3HnGLuBoA6",
+ "id": "5VQE4WOzPu9h3HnGLuBoA6",
+ "name": "Vlasta Marek",
+ "type": "artist",
+ "uri": "spotify:artist:5VQE4WOzPu9h3HnGLuBoA6"
+ }
+ ],
+ "disc_number": 1,
+ "track_number": 21,
+ "duration_ms": 730066,
+ "external_ids": {
+ "isrc": "FR2X41475057"
+ },
+ "external_urls": {
+ "spotify": "https://open.spotify.com/track/5o3jMYOSbaVz3tkgwhELSV"
+ },
+ "href": "https://api.spotify.com/v1/tracks/5o3jMYOSbaVz3tkgwhELSV",
+ "id": "5o3jMYOSbaVz3tkgwhELSV",
+ "name": "Is",
+ "popularity": 0,
+ "uri": "spotify:track:5o3jMYOSbaVz3tkgwhELSV",
+ "is_local": false
+ },
+ "video_thumbnail": {
+ "url": null
+ }
+ },
+ {
+ "added_at": "2015-01-15T12:22:30Z",
+ "added_by": {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/user/jmperezperez"
+ },
+ "href": "https://api.spotify.com/v1/users/jmperezperez",
+ "id": "jmperezperez",
+ "type": "user",
+ "uri": "spotify:user:jmperezperez"
+ },
+ "is_local": false,
+ "primary_color": null,
+ "track": {
+ "preview_url": null,
+ "available_markets": [
+ "AR",
+ "AU",
+ "AT",
+ "BE",
+ "BO",
+ "BR",
+ "BG",
+ "CA",
+ "CL",
+ "CO",
+ "CR",
+ "CY",
+ "CZ",
+ "DK",
+ "DO",
+ "DE",
+ "EC",
+ "EE",
+ "SV",
+ "FI",
+ "FR",
+ "GR",
+ "GT",
+ "HN",
+ "HK",
+ "HU",
+ "IS",
+ "IE",
+ "IT",
+ "LV",
+ "LT",
+ "LU",
+ "MY",
+ "MT",
+ "MX",
+ "NL",
+ "NZ",
+ "NI",
+ "NO",
+ "PA",
+ "PY",
+ "PE",
+ "PH",
+ "PL",
+ "PT",
+ "SG",
+ "SK",
+ "ES",
+ "SE",
+ "CH",
+ "TW",
+ "TR",
+ "UY",
+ "US",
+ "GB",
+ "AD",
+ "LI",
+ "MC",
+ "ID",
+ "JP",
+ "TH",
+ "VN",
+ "RO",
+ "IL",
+ "ZA",
+ "SA",
+ "AE",
+ "BH",
+ "QA",
+ "OM",
+ "KW",
+ "EG",
+ "MA",
+ "DZ",
+ "TN",
+ "LB",
+ "JO",
+ "PS",
+ "IN",
+ "BY",
+ "KZ",
+ "MD",
+ "UA",
+ "AL",
+ "BA",
+ "HR",
+ "ME",
+ "MK",
+ "RS",
+ "SI",
+ "KR",
+ "BD",
+ "PK",
+ "LK",
+ "GH",
+ "KE",
+ "NG",
+ "TZ",
+ "UG",
+ "AG",
+ "AM",
+ "BS",
+ "BB",
+ "BZ",
+ "BT",
+ "BW",
+ "BF",
+ "CV",
+ "CW",
+ "DM",
+ "FJ",
+ "GM",
+ "GE",
+ "GD",
+ "GW",
+ "GY",
+ "HT",
+ "JM",
+ "KI",
+ "LS",
+ "LR",
+ "MW",
+ "MV",
+ "ML",
+ "MH",
+ "FM",
+ "NA",
+ "NR",
+ "NE",
+ "PW",
+ "PG",
+ "PR",
+ "WS",
+ "SM",
+ "ST",
+ "SN",
+ "SC",
+ "SL",
+ "SB",
+ "KN",
+ "LC",
+ "VC",
+ "SR",
+ "TL",
+ "TO",
+ "TT",
+ "TV",
+ "VU",
+ "AZ",
+ "BN",
+ "BI",
+ "KH",
+ "CM",
+ "TD",
+ "KM",
+ "GQ",
+ "SZ",
+ "GA",
+ "GN",
+ "KG",
+ "LA",
+ "MO",
+ "MR",
+ "MN",
+ "NP",
+ "RW",
+ "TG",
+ "UZ",
+ "ZW",
+ "BJ",
+ "MG",
+ "MU",
+ "MZ",
+ "AO",
+ "CI",
+ "DJ",
+ "ZM",
+ "CD",
+ "CG",
+ "IQ",
+ "LY",
+ "TJ",
+ "VE",
+ "ET",
+ "XK"
+ ],
+ "explicit": false,
+ "type": "track",
+ "episode": false,
+ "track": true,
+ "album": {
+ "available_markets": [
+ "AR",
+ "AU",
+ "AT",
+ "BE",
+ "BO",
+ "BR",
+ "BG",
+ "CA",
+ "CL",
+ "CO",
+ "CR",
+ "CY",
+ "CZ",
+ "DK",
+ "DO",
+ "DE",
+ "EC",
+ "EE",
+ "SV",
+ "FI",
+ "FR",
+ "GR",
+ "GT",
+ "HN",
+ "HK",
+ "HU",
+ "IS",
+ "IE",
+ "IT",
+ "LV",
+ "LT",
+ "LU",
+ "MY",
+ "MT",
+ "MX",
+ "NL",
+ "NZ",
+ "NI",
+ "NO",
+ "PA",
+ "PY",
+ "PE",
+ "PH",
+ "PL",
+ "PT",
+ "SG",
+ "SK",
+ "ES",
+ "SE",
+ "CH",
+ "TW",
+ "TR",
+ "UY",
+ "US",
+ "GB",
+ "AD",
+ "LI",
+ "MC",
+ "ID",
+ "JP",
+ "TH",
+ "VN",
+ "RO",
+ "IL",
+ "ZA",
+ "SA",
+ "AE",
+ "BH",
+ "QA",
+ "OM",
+ "KW",
+ "EG",
+ "MA",
+ "DZ",
+ "TN",
+ "LB",
+ "JO",
+ "PS",
+ "IN",
+ "BY",
+ "KZ",
+ "MD",
+ "UA",
+ "AL",
+ "BA",
+ "HR",
+ "ME",
+ "MK",
+ "RS",
+ "SI",
+ "KR",
+ "BD",
+ "PK",
+ "LK",
+ "GH",
+ "KE",
+ "NG",
+ "TZ",
+ "UG",
+ "AG",
+ "AM",
+ "BS",
+ "BB",
+ "BZ",
+ "BT",
+ "BW",
+ "BF",
+ "CV",
+ "CW",
+ "DM",
+ "FJ",
+ "GM",
+ "GE",
+ "GD",
+ "GW",
+ "GY",
+ "HT",
+ "JM",
+ "KI",
+ "LS",
+ "LR",
+ "MW",
+ "MV",
+ "ML",
+ "MH",
+ "FM",
+ "NA",
+ "NR",
+ "NE",
+ "PW",
+ "PG",
+ "PR",
+ "WS",
+ "SM",
+ "ST",
+ "SN",
+ "SC",
+ "SL",
+ "SB",
+ "KN",
+ "LC",
+ "VC",
+ "SR",
+ "TL",
+ "TO",
+ "TT",
+ "TV",
+ "VU",
+ "AZ",
+ "BN",
+ "BI",
+ "KH",
+ "CM",
+ "TD",
+ "KM",
+ "GQ",
+ "SZ",
+ "GA",
+ "GN",
+ "KG",
+ "LA",
+ "MO",
+ "MR",
+ "MN",
+ "NP",
+ "RW",
+ "TG",
+ "UZ",
+ "ZW",
+ "BJ",
+ "MG",
+ "MU",
+ "MZ",
+ "AO",
+ "CI",
+ "DJ",
+ "ZM",
+ "CD",
+ "CG",
+ "IQ",
+ "LY",
+ "TJ",
+ "VE",
+ "ET",
+ "XK"
+ ],
+ "type": "album",
+ "album_type": "album",
+ "href": "https://api.spotify.com/v1/albums/4hnqM0JK4CM1phwfq1Ldyz",
+ "id": "4hnqM0JK4CM1phwfq1Ldyz",
+ "images": [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b273ee0d0dce888c6c8a70db6e8b",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e02ee0d0dce888c6c8a70db6e8b",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d00004851ee0d0dce888c6c8a70db6e8b",
+ "width": 64
+ }
+ ],
+ "name": "This Is Happening",
+ "release_date": "2010-05-17",
+ "release_date_precision": "day",
+ "uri": "spotify:album:4hnqM0JK4CM1phwfq1Ldyz",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/066X20Nz7iquqkkCW6Jxy6"
+ },
+ "href": "https://api.spotify.com/v1/artists/066X20Nz7iquqkkCW6Jxy6",
+ "id": "066X20Nz7iquqkkCW6Jxy6",
+ "name": "LCD Soundsystem",
+ "type": "artist",
+ "uri": "spotify:artist:066X20Nz7iquqkkCW6Jxy6"
+ }
+ ],
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/4hnqM0JK4CM1phwfq1Ldyz"
+ },
+ "total_tracks": 9
+ },
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/066X20Nz7iquqkkCW6Jxy6"
+ },
+ "href": "https://api.spotify.com/v1/artists/066X20Nz7iquqkkCW6Jxy6",
+ "id": "066X20Nz7iquqkkCW6Jxy6",
+ "name": "LCD Soundsystem",
+ "type": "artist",
+ "uri": "spotify:artist:066X20Nz7iquqkkCW6Jxy6"
+ }
+ ],
+ "disc_number": 1,
+ "track_number": 4,
+ "duration_ms": 401440,
+ "external_ids": {
+ "isrc": "US4GE1000022"
+ },
+ "external_urls": {
+ "spotify": "https://open.spotify.com/track/4Cy0NHJ8Gh0xMdwyM9RkQm"
+ },
+ "href": "https://api.spotify.com/v1/tracks/4Cy0NHJ8Gh0xMdwyM9RkQm",
+ "id": "4Cy0NHJ8Gh0xMdwyM9RkQm",
+ "name": "All I Want",
+ "popularity": 42,
+ "uri": "spotify:track:4Cy0NHJ8Gh0xMdwyM9RkQm",
+ "is_local": false
+ },
+ "video_thumbnail": {
+ "url": null
+ }
+ },
+ {
+ "added_at": "2015-01-15T12:40:35Z",
+ "added_by": {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/user/jmperezperez"
+ },
+ "href": "https://api.spotify.com/v1/users/jmperezperez",
+ "id": "jmperezperez",
+ "type": "user",
+ "uri": "spotify:user:jmperezperez"
+ },
+ "is_local": false,
+ "primary_color": null,
+ "track": {
+ "preview_url": null,
+ "available_markets": [
+ "AR",
+ "AU",
+ "AT",
+ "BE",
+ "BO",
+ "BR",
+ "BG",
+ "CA",
+ "CL",
+ "CO",
+ "CR",
+ "CY",
+ "CZ",
+ "DK",
+ "DO",
+ "DE",
+ "EC",
+ "EE",
+ "SV",
+ "FI",
+ "FR",
+ "GR",
+ "GT",
+ "HN",
+ "HK",
+ "HU",
+ "IS",
+ "IE",
+ "IT",
+ "LV",
+ "LT",
+ "LU",
+ "MY",
+ "MT",
+ "MX",
+ "NL",
+ "NZ",
+ "NI",
+ "NO",
+ "PA",
+ "PY",
+ "PE",
+ "PH",
+ "PL",
+ "PT",
+ "SG",
+ "SK",
+ "ES",
+ "SE",
+ "CH",
+ "TW",
+ "TR",
+ "UY",
+ "US",
+ "GB",
+ "AD",
+ "LI",
+ "MC",
+ "ID",
+ "JP",
+ "TH",
+ "VN",
+ "RO",
+ "IL",
+ "ZA",
+ "SA",
+ "AE",
+ "BH",
+ "QA",
+ "OM",
+ "KW",
+ "EG",
+ "MA",
+ "DZ",
+ "TN",
+ "LB",
+ "JO",
+ "PS",
+ "IN",
+ "BY",
+ "KZ",
+ "MD",
+ "UA",
+ "AL",
+ "BA",
+ "HR",
+ "ME",
+ "MK",
+ "RS",
+ "SI",
+ "KR",
+ "BD",
+ "PK",
+ "LK",
+ "GH",
+ "KE",
+ "NG",
+ "TZ",
+ "UG",
+ "AG",
+ "AM",
+ "BS",
+ "BB",
+ "BZ",
+ "BT",
+ "BW",
+ "BF",
+ "CV",
+ "CW",
+ "DM",
+ "FJ",
+ "GM",
+ "GE",
+ "GD",
+ "GW",
+ "GY",
+ "HT",
+ "JM",
+ "KI",
+ "LS",
+ "LR",
+ "MW",
+ "MV",
+ "ML",
+ "MH",
+ "FM",
+ "NA",
+ "NR",
+ "NE",
+ "PW",
+ "PG",
+ "PR",
+ "WS",
+ "SM",
+ "ST",
+ "SN",
+ "SC",
+ "SL",
+ "SB",
+ "KN",
+ "LC",
+ "VC",
+ "SR",
+ "TL",
+ "TO",
+ "TT",
+ "TV",
+ "VU",
+ "AZ",
+ "BN",
+ "BI",
+ "KH",
+ "CM",
+ "TD",
+ "KM",
+ "GQ",
+ "SZ",
+ "GA",
+ "GN",
+ "KG",
+ "LA",
+ "MO",
+ "MR",
+ "MN",
+ "NP",
+ "RW",
+ "TG",
+ "UZ",
+ "ZW",
+ "BJ",
+ "MG",
+ "MU",
+ "MZ",
+ "AO",
+ "CI",
+ "DJ",
+ "ZM",
+ "CD",
+ "CG",
+ "IQ",
+ "LY",
+ "TJ",
+ "VE",
+ "ET",
+ "XK"
+ ],
+ "explicit": false,
+ "type": "track",
+ "episode": false,
+ "track": true,
+ "album": {
+ "available_markets": [
+ "AR",
+ "AU",
+ "AT",
+ "BE",
+ "BO",
+ "BR",
+ "BG",
+ "CA",
+ "CL",
+ "CO",
+ "CR",
+ "CY",
+ "CZ",
+ "DK",
+ "DO",
+ "DE",
+ "EC",
+ "EE",
+ "SV",
+ "FI",
+ "FR",
+ "GR",
+ "GT",
+ "HN",
+ "HK",
+ "HU",
+ "IS",
+ "IE",
+ "IT",
+ "LV",
+ "LT",
+ "LU",
+ "MY",
+ "MT",
+ "MX",
+ "NL",
+ "NZ",
+ "NI",
+ "NO",
+ "PA",
+ "PY",
+ "PE",
+ "PH",
+ "PL",
+ "PT",
+ "SG",
+ "SK",
+ "ES",
+ "SE",
+ "CH",
+ "TW",
+ "TR",
+ "UY",
+ "US",
+ "GB",
+ "AD",
+ "LI",
+ "MC",
+ "ID",
+ "JP",
+ "TH",
+ "VN",
+ "RO",
+ "IL",
+ "ZA",
+ "SA",
+ "AE",
+ "BH",
+ "QA",
+ "OM",
+ "KW",
+ "EG",
+ "MA",
+ "DZ",
+ "TN",
+ "LB",
+ "JO",
+ "PS",
+ "IN",
+ "BY",
+ "KZ",
+ "MD",
+ "UA",
+ "AL",
+ "BA",
+ "HR",
+ "ME",
+ "MK",
+ "RS",
+ "SI",
+ "KR",
+ "BD",
+ "PK",
+ "LK",
+ "GH",
+ "KE",
+ "NG",
+ "TZ",
+ "UG",
+ "AG",
+ "AM",
+ "BS",
+ "BB",
+ "BZ",
+ "BT",
+ "BW",
+ "BF",
+ "CV",
+ "CW",
+ "DM",
+ "FJ",
+ "GM",
+ "GE",
+ "GD",
+ "GW",
+ "GY",
+ "HT",
+ "JM",
+ "KI",
+ "LS",
+ "LR",
+ "MW",
+ "MV",
+ "ML",
+ "MH",
+ "FM",
+ "NA",
+ "NR",
+ "NE",
+ "PW",
+ "PG",
+ "PR",
+ "WS",
+ "SM",
+ "ST",
+ "SN",
+ "SC",
+ "SL",
+ "SB",
+ "KN",
+ "LC",
+ "VC",
+ "SR",
+ "TL",
+ "TO",
+ "TT",
+ "TV",
+ "VU",
+ "AZ",
+ "BN",
+ "BI",
+ "KH",
+ "CM",
+ "TD",
+ "KM",
+ "GQ",
+ "SZ",
+ "GA",
+ "GN",
+ "KG",
+ "LA",
+ "MO",
+ "MR",
+ "MN",
+ "NP",
+ "RW",
+ "TG",
+ "UZ",
+ "ZW",
+ "BJ",
+ "MG",
+ "MU",
+ "MZ",
+ "AO",
+ "CI",
+ "DJ",
+ "ZM",
+ "CD",
+ "CG",
+ "IQ",
+ "LY",
+ "TJ",
+ "VE",
+ "ET",
+ "XK"
+ ],
+ "type": "album",
+ "album_type": "album",
+ "href": "https://api.spotify.com/v1/albums/2usKFntxa98WHMcyW6xJBz",
+ "id": "2usKFntxa98WHMcyW6xJBz",
+ "images": [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b2738b7447ac3daa1da18811cf7b",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e028b7447ac3daa1da18811cf7b",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d000048518b7447ac3daa1da18811cf7b",
+ "width": 64
+ }
+ ],
+ "name": "Glenn Horiuchi Trio / Gelenn Horiuchi Quartet: Mercy / Jump Start / Endpoints / Curl Out / Earthworks / Mind Probe / Null Set / Another Space (A)",
+ "release_date": "2011-04-01",
+ "release_date_precision": "day",
+ "uri": "spotify:album:2usKFntxa98WHMcyW6xJBz",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/272ArH9SUAlslQqsSgPJA2"
+ },
+ "href": "https://api.spotify.com/v1/artists/272ArH9SUAlslQqsSgPJA2",
+ "id": "272ArH9SUAlslQqsSgPJA2",
+ "name": "Glenn Horiuchi Trio",
+ "type": "artist",
+ "uri": "spotify:artist:272ArH9SUAlslQqsSgPJA2"
+ }
+ ],
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/2usKFntxa98WHMcyW6xJBz"
+ },
+ "total_tracks": 8
+ },
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/272ArH9SUAlslQqsSgPJA2"
+ },
+ "href": "https://api.spotify.com/v1/artists/272ArH9SUAlslQqsSgPJA2",
+ "id": "272ArH9SUAlslQqsSgPJA2",
+ "name": "Glenn Horiuchi Trio",
+ "type": "artist",
+ "uri": "spotify:artist:272ArH9SUAlslQqsSgPJA2"
+ }
+ ],
+ "disc_number": 1,
+ "track_number": 2,
+ "duration_ms": 358760,
+ "external_ids": {
+ "isrc": "USB8U1025969"
+ },
+ "external_urls": {
+ "spotify": "https://open.spotify.com/track/6hvFrZNocdt2FcKGCSY5NI"
+ },
+ "href": "https://api.spotify.com/v1/tracks/6hvFrZNocdt2FcKGCSY5NI",
+ "id": "6hvFrZNocdt2FcKGCSY5NI",
+ "name": "Endpoints",
+ "popularity": 0,
+ "uri": "spotify:track:6hvFrZNocdt2FcKGCSY5NI",
+ "is_local": false
+ },
+ "video_thumbnail": {
+ "url": null
+ }
+ },
+ {
+ "added_at": "2015-01-15T12:41:10Z",
+ "added_by": {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/user/jmperezperez"
+ },
+ "href": "https://api.spotify.com/v1/users/jmperezperez",
+ "id": "jmperezperez",
+ "type": "user",
+ "uri": "spotify:user:jmperezperez"
+ },
+ "is_local": false,
+ "primary_color": null,
+ "track": {
+ "preview_url": null,
+ "available_markets": [],
+ "explicit": false,
+ "type": "track",
+ "episode": false,
+ "track": true,
+ "album": {
+ "available_markets": [],
+ "type": "album",
+ "album_type": "album",
+ "href": "https://api.spotify.com/v1/albums/0ivM6kSawaug0j3tZVusG2",
+ "id": "0ivM6kSawaug0j3tZVusG2",
+ "images": [
+ {
+ "height": 640,
+ "url": "https://i.scdn.co/image/ab67616d0000b27304e57d181ff062f8339d6c71",
+ "width": 640
+ },
+ {
+ "height": 300,
+ "url": "https://i.scdn.co/image/ab67616d00001e0204e57d181ff062f8339d6c71",
+ "width": 300
+ },
+ {
+ "height": 64,
+ "url": "https://i.scdn.co/image/ab67616d0000485104e57d181ff062f8339d6c71",
+ "width": 64
+ }
+ ],
+ "name": "All The Best (Spanish Version)",
+ "release_date": "2007-01-01",
+ "release_date_precision": "day",
+ "uri": "spotify:album:0ivM6kSawaug0j3tZVusG2",
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/2KftmGt9sk1yLjsAoloC3M"
+ },
+ "href": "https://api.spotify.com/v1/artists/2KftmGt9sk1yLjsAoloC3M",
+ "id": "2KftmGt9sk1yLjsAoloC3M",
+ "name": "Zucchero",
+ "type": "artist",
+ "uri": "spotify:artist:2KftmGt9sk1yLjsAoloC3M"
+ }
+ ],
+ "external_urls": {
+ "spotify": "https://open.spotify.com/album/0ivM6kSawaug0j3tZVusG2"
+ },
+ "total_tracks": 18
+ },
+ "artists": [
+ {
+ "external_urls": {
+ "spotify": "https://open.spotify.com/artist/2KftmGt9sk1yLjsAoloC3M"
+ },
+ "href": "https://api.spotify.com/v1/artists/2KftmGt9sk1yLjsAoloC3M",
+ "id": "2KftmGt9sk1yLjsAoloC3M",
+ "name": "Zucchero",
+ "type": "artist",
+ "uri": "spotify:artist:2KftmGt9sk1yLjsAoloC3M"
+ }
+ ],
+ "disc_number": 1,
+ "track_number": 18,
+ "duration_ms": 176093,
+ "external_ids": {
+ "isrc": "ITUM70701043"
+ },
+ "external_urls": {
+ "spotify": "https://open.spotify.com/track/2E2znCPaS8anQe21GLxcvJ"
+ },
+ "href": "https://api.spotify.com/v1/tracks/2E2znCPaS8anQe21GLxcvJ",
+ "id": "2E2znCPaS8anQe21GLxcvJ",
+ "name": "You Are So Beautiful",
+ "popularity": 0,
+ "uri": "spotify:track:2E2znCPaS8anQe21GLxcvJ",
+ "is_local": false
+ },
+ "video_thumbnail": {
+ "url": null
+ }
+ }
+ ],
+ "limit": 100,
+ "next": null,
+ "offset": 0,
+ "previous": null,
+ "total": 5
+}
\ No newline at end of file