Skip to content

Commit

Permalink
Added ability to parse SpotifyProfile info into object (#5)
Browse files Browse the repository at this point in the history
* Added ability to parse SpotifyProfile info into object

* Added parsing for top tracks and top artists
  • Loading branch information
VigneshSK17 authored Mar 25, 2024
1 parent 72e565e commit 16ebe09
Show file tree
Hide file tree
Showing 15 changed files with 560 additions and 14 deletions.
2 changes: 2 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified .idea/copilot/chatSessions/00000000000.xd
Binary file not shown.
4 changes: 2 additions & 2 deletions .idea/copilot/chatSessions/xd.lck

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ dependencies {

implementation("com.spotify.android:auth:2.1.1")
implementation("com.squareup.okhttp3:okhttp:4.9.3")

implementation("com.google.code.gson:gson:2.8.6")
}
20 changes: 16 additions & 4 deletions app/src/main/java/com/t1r2340/spotifystats/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import com.spotify.sdk.android.auth.AuthorizationResponse;
import com.t1r2340.spotifystats.helpers.FailureCallback;
import com.t1r2340.spotifystats.helpers.SpotifyApi;
import com.t1r2340.spotifystats.models.api.SpotifyProfile;
import com.t1r2340.spotifystats.models.api.TopArtists;
import com.t1r2340.spotifystats.models.api.TopTracks;

import org.json.JSONException;
import org.json.JSONObject;
Expand Down Expand Up @@ -127,9 +130,18 @@ public void onGetUserProfileClicked() {
}

// Create a request to get the user profile
spotifyApi.getProfile((jsonObject) -> {
Log.d("JSON", jsonObject);
});
// spotifyApi.getProfile((SpotifyProfile jsonObject) -> {
// Log.d("JSON", jsonObject.toString());
// });

// TODO: Create class for top artists and test here
spotifyApi.getTopArtists((TopArtists jsonObject) -> {
Log.d("JSON", jsonObject.toString());
}, 5, SpotifyApi.TimeRange.LONG_TERM);

spotifyApi.getTopTracks((TopTracks jsonObject) -> {
Log.d("JSON", jsonObject.toString());
}, 5, SpotifyApi.TimeRange.SHORT_TERM);

}

Expand All @@ -153,7 +165,7 @@ private void setTextAsync(final String text, TextView textView) {
private AuthorizationRequest getAuthenticationRequest(AuthorizationResponse.Type type) {
return new AuthorizationRequest.Builder(CLIENT_ID, type, getRedirectUri().toString())
.setShowDialog(false)
.setScopes(new String[] { "user-read-email" }) // <--- Change the scope of your requested token here
.setScopes(new String[] { "user-read-email", "user-follow-read", "user-top-read" }) // <--- Change the scope of your requested token here
.setCampaign("your-campaign-token")
.build();
}
Expand Down
43 changes: 35 additions & 8 deletions app/src/main/java/com/t1r2340/spotifystats/helpers/SpotifyApi.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package com.t1r2340.spotifystats.helpers;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.t1r2340.spotifystats.models.api.SpotifyProfile;
import com.t1r2340.spotifystats.models.api.TopArtists;
import com.t1r2340.spotifystats.models.api.TopTracks;

import org.json.JSONException;
import org.json.JSONObject;

Expand All @@ -22,13 +30,21 @@
*/
public class SpotifyApi {

/** Access token for Spotify API */
private String accessToken;
/** Callback for API call failures */
private FailureCallback failureCallback;
/** HTTP client for API calls */
private OkHttpClient okHttpClient;

/** Current API call */
private Call call;
/** JSON parser */
private Gson gson;

// TODO: Determine if more time ranges can be used
/**
* Time range for top artists and tracks
*/
public enum TimeRange {
/** 1 month */
SHORT_TERM("short_term"),
Expand All @@ -48,19 +64,28 @@ public String getValue() {
}
}

/**
* Constructor for Spotify API
* @param failureCallback callback for API call failures
* @param accessToken access token for Spotify API
* @param okHttpClient HTTP client for API calls
* @param mCall current API call
*/
public SpotifyApi(FailureCallback failureCallback, String accessToken, OkHttpClient okHttpClient, Call mCall) {
this.failureCallback = failureCallback;
this.accessToken = accessToken;
this.okHttpClient = okHttpClient;
this.call = mCall;

this.gson = new Gson();
}

/**
* Gets user profile
* @param successConsumer consumer for successful response
*/
public void getProfile(Consumer<String> successConsumer) {
getJson(successConsumer, "https://api.spotify.com/v1/me");
public void getProfile(Consumer<SpotifyProfile> successConsumer) {
getJson(successConsumer, SpotifyProfile.class, "https://api.spotify.com/v1/me");
}

/**
Expand All @@ -69,9 +94,10 @@ public void getProfile(Consumer<String> successConsumer) {
* @param limit number of artists to retrieve
* @param timeRange time range for top artists
*/
public void getTopArtists(Consumer<String> successConsumer, int limit, TimeRange timeRange) {
public void getTopArtists(Consumer<TopArtists> successConsumer, int limit, TimeRange timeRange) {
getJson(
successConsumer,
TopArtists.class,
"https://api.spotify.com/v1/me/top/artists?limit=" + limit + "&time_range=" + timeRange.getValue()
);
}
Expand All @@ -82,9 +108,10 @@ public void getTopArtists(Consumer<String> successConsumer, int limit, TimeRange
* @param limit number of tracks to retrieve
* @param timeRange time range for top tracks
*/
public void getTopTracks(Consumer<String> successConsumer, int limit, TimeRange timeRange) {
public void getTopTracks(Consumer<TopTracks> successConsumer, int limit, TimeRange timeRange) {
getJson(
successConsumer,
TopTracks.class,
"https://api.spotify.com/v1/me/top/tracks?limit=" + limit + "&time_range=" + timeRange.getValue()
);
// TODO: Extract soundbite
Expand All @@ -96,7 +123,7 @@ public void getTopTracks(Consumer<String> successConsumer, int limit, TimeRange
* @param successConsumer consumer for successful response
* @param url url for API request
*/
private void getJson(Consumer<String> successConsumer, String url) {
private <T> void getJson(Consumer<T> successConsumer, Class<T> c, String url) {
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer " + accessToken)
Expand All @@ -115,8 +142,8 @@ public void onFailure(Call call, IOException e) {
public void onResponse(Call call, Response response) throws IOException {
try {
final JSONObject jsonObject = new JSONObject(response.body().string());
// TODO: Convert JSON to object, not string
successConsumer.accept(jsonObject.toString(3));
T object = gson.fromJson(jsonObject.toString(), c);
successConsumer.accept(object);
} catch (JSONException e) {
failureCallback.onFailure(e);
}
Expand Down
60 changes: 60 additions & 0 deletions app/src/main/java/com/t1r2340/spotifystats/models/api/Album.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.t1r2340.spotifystats.models.api;


/**
* Class holding album information
*/
public class Album {

/** The Spotify ID for the album */
private String id;
/** The type of the album */
private String albumType;
/** The images of the album */
private ImageObject[] images;
/** The name of the album */
private String name;


/**
* Constructor for Album
*/
public Album(String id, String albumType, ImageObject[] images, String name) {
this.id = id;
this.albumType = albumType;
this.images = images;
this.name = name;
}

/**
* Gets the Spotify ID for the album
* @return the Spotify ID for the album
*/
public String getId() {
return id;
}

/**
* Gets the type of the album
* @return the type of the album
*/
public String getAlbumType() {
return albumType;
}

/**
* Gets the images of the album
* @return the images of the album
*/
public ImageObject[] getImages() {
return images;
}

/**
* Gets the name of the album
* @return the name of the album
*/
public String getName() {
return name;
}
}
36 changes: 36 additions & 0 deletions app/src/main/java/com/t1r2340/spotifystats/models/api/Artist.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.t1r2340.spotifystats.models.api;

/**
* Class holding artist information
*/
public class Artist {

/** The Spotify ID for the artist */
private String id;
/** The name of the artist */
private String name;

/**
* Constructor for Artist
*/
public Artist(String id, String name) {
this.id = id;
this.name = name;
}

/**
* Gets the Spotify ID for the artist
* @return the Spotify ID for the artist
*/
public String getId() {
return id;
}

/**
* Gets the name of the artist
* @return the name of the artist
*/
public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.t1r2340.spotifystats.models.api;

/**
* Class holding more specific artist information
*/
public class ArtistObject extends Artist {

/** Genres of the artist */
private String[] genres;
/** Images of the artist */
private ImageObject[] images;

/**
* Constructor for ArtistObject
*/
public ArtistObject(String id, String name, String[] genres, ImageObject[] images) {
super(id, name);
this.genres = genres;
this.images = images;
}

/**
* Gets the genres of the artist
* @return the genres of the artist
*/
public String[] getGenres() {
return genres;
}

/**
* Gets the images of the artist
* @return the images of the artist
*/
public ImageObject[] getImages() {
return images;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.t1r2340.spotifystats.models.api;

import org.json.JSONObject;

/**
* Represents an image object.
*/
public class ImageObject {
/**
* The height of the image in pixels.
*/
private int height;
/**
* The width of the image in pixels.
*/
private int width;
/**
* The URL of the image.
*/
private String url;

/**
* Creates an image object from JSON.
*/
public ImageObject(int height, int width, String url) {
this.height = height;
this.width = width;
this.url = url;
}

/**
* Gets the height of the image.
* @return the height of the image
*/
public int getHeight() {
return height;
}

/**
* Gets the width of the image.
* @return the width of the image
*/
public int getWidth() {
return width;
}

/**
* Gets the URL of the image.
* @return the URL of the image
*/
public String getUrl() {
return url;
}
}
Loading

0 comments on commit 16ebe09

Please sign in to comment.