Skip to content

Commit f203ebb

Browse files
committed
feat: add endpoint to remove episodes from user's library
1 parent 986b3f7 commit f203ebb

File tree

5 files changed

+253
-0
lines changed

5 files changed

+253
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ access token only once, after which it becomes invalid.
272272
- [Get User's Saved Tracks](examples/data/library/GetUsersSavedTracksExample.java)
273273
- [Remove Albums for Current User](examples/data/library/RemoveAlbumsForCurrentUserExample.java)
274274
- [Remove User's Saved Shows](examples/data/library/RemoveUsersSavedShowsExample.java)
275+
- [Remove User's Saved Episodes](examples/data/library/RemoveUsersSavedEpisodesExample.java)
275276
- [Remove User's Saved Tracks](examples/data/library/RemoveUsersSavedTracksExample.java)
276277
- [Save Albums for Current User](examples/data/library/SaveAlbumsForCurrentUserExample.java)
277278
- [Save Shows for Current User](examples/data/library/SaveShowsForCurrentUserExample.java)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package data.library;
2+
3+
import se.michaelthelin.spotify.SpotifyApi;
4+
import se.michaelthelin.spotify.exceptions.SpotifyWebApiException;
5+
import se.michaelthelin.spotify.requests.data.library.RemoveUsersSavedEpisodesRequest;
6+
import org.apache.hc.core5.http.ParseException;
7+
8+
import java.io.IOException;
9+
import java.util.concurrent.CancellationException;
10+
import java.util.concurrent.CompletableFuture;
11+
import java.util.concurrent.CompletionException;
12+
13+
public class RemoveUsersSavedEpisodesExample {
14+
private static final String accessToken = "taHZ2SdB-bPA3FsK3D7ZN5npZS47cMy-IEySVEGttOhXmqaVAIo0ESvTCLjLBifhHOHOIuhFUKPW1WMDP7w6dj3MAZdWT8CLI2MkZaXbYLTeoDvXesf2eeiLYPBGdx8tIwQJKgV8XdnzH_DONk";
15+
private static final String[] ids = new String[]{"4GI3dxEafwap1sFiTGPKd1"};
16+
17+
private static final SpotifyApi spotifyApi = new SpotifyApi.Builder()
18+
.setAccessToken(accessToken)
19+
.build();
20+
private static final RemoveUsersSavedEpisodesRequest removeUsersSavedEpisodesRequest = spotifyApi
21+
.removeUsersSavedEpisodes(ids)
22+
.build();
23+
24+
public static void removeUsersSavedEpisodes_Sync() {
25+
try {
26+
final String string = removeUsersSavedEpisodesRequest.execute();
27+
28+
System.out.println("Null: " + string);
29+
} catch (IOException | SpotifyWebApiException | ParseException e) {
30+
System.out.println("Error: " + e.getMessage());
31+
}
32+
}
33+
34+
public static void removeUsersSavedEpisodes_Async() {
35+
try {
36+
final CompletableFuture<String> stringFuture = removeUsersSavedEpisodesRequest.executeAsync();
37+
38+
// Thread free to do other tasks...
39+
40+
// Example Only. Never block in production code.
41+
final String string = stringFuture.join();
42+
43+
System.out.println("Null: " + string);
44+
} catch (CompletionException e) {
45+
System.out.println("Error: " + e.getCause().getMessage());
46+
} catch (CancellationException e) {
47+
System.out.println("Async operation cancelled.");
48+
}
49+
}
50+
51+
public static void main(String[] args) {
52+
removeUsersSavedEpisodes_Sync();
53+
removeUsersSavedEpisodes_Async();
54+
}
55+
}

src/main/java/se/michaelthelin/spotify/SpotifyApi.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,34 @@ public RemoveUsersSavedShowsRequest.Builder removeUsersSavedShows(JsonArray ids)
10591059
.ids(ids);
10601060
}
10611061

1062+
/**
1063+
* Remove one or more episodes from the current user's library.
1064+
*
1065+
* @param ids The Spotify IDs for the episodes to be removed. Maximum: 50 IDs.
1066+
* @return A {@link RemoveUsersSavedEpisodesRequest.Builder}.
1067+
* @see <a href="https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids">Spotify: URLs &amp; IDs</a>
1068+
* @apiNote This endpoint is in <b>beta</b> and could change without warning.
1069+
*/
1070+
public RemoveUsersSavedEpisodesRequest.Builder removeUsersSavedEpisodes(String... ids) {
1071+
return new RemoveUsersSavedEpisodesRequest.Builder(accessToken)
1072+
.setDefaults(httpManager, scheme, host, port)
1073+
.ids(concat(ids, ','));
1074+
}
1075+
1076+
/**
1077+
* Remove one or more episodes from the current user's library.
1078+
*
1079+
* @param ids The Spotify IDs for the episodes to be removed. Maximum: 50 IDs.
1080+
* @return A {@link RemoveUsersSavedEpisodesRequest.Builder}.
1081+
* @see <a href="https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids">Spotify: URLs &amp; IDs</a>
1082+
* @apiNote This endpoint is in <b>beta</b> and could change without warning.
1083+
*/
1084+
public RemoveUsersSavedEpisodesRequest.Builder removeUsersSavedEpisodes(JsonArray ids) {
1085+
return new RemoveUsersSavedEpisodesRequest.Builder(accessToken)
1086+
.setDefaults(httpManager, scheme, host, port)
1087+
.ids(ids);
1088+
}
1089+
10621090
/**
10631091
* Remove a track if saved to the user's "Your Music" library.
10641092
*
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package se.michaelthelin.spotify.requests.data.library;
2+
3+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
4+
import com.google.gson.JsonArray;
5+
import org.apache.hc.core5.http.ContentType;
6+
import org.apache.hc.core5.http.ParseException;
7+
import se.michaelthelin.spotify.exceptions.SpotifyWebApiException;
8+
import se.michaelthelin.spotify.requests.data.AbstractDataRequest;
9+
10+
import java.io.IOException;
11+
12+
/**
13+
* Remove one or more episodes from the current user's library.
14+
*/
15+
@JsonDeserialize(builder = RemoveUsersSavedEpisodesRequest.Builder.class)
16+
public class RemoveUsersSavedEpisodesRequest extends AbstractDataRequest<String> {
17+
18+
/**
19+
* The private {@link RemoveUsersSavedEpisodesRequest} constructor.
20+
*
21+
* @param builder A {@link RemoveUsersSavedEpisodesRequest.Builder}.
22+
*/
23+
private RemoveUsersSavedEpisodesRequest(final RemoveUsersSavedEpisodesRequest.Builder builder) {
24+
super(builder);
25+
}
26+
27+
/**
28+
* Remove one or more episodes from current Spotify user’s library.
29+
*
30+
* @return A string. <b>Note:</b> This endpoint doesn't return something in its response body.
31+
* @throws IOException In case of networking issues.
32+
* @throws SpotifyWebApiException The Web API returned an error further specified in this exception's root cause.
33+
*/
34+
@Override
35+
public String execute() throws
36+
IOException,
37+
SpotifyWebApiException,
38+
ParseException {
39+
return deleteJson();
40+
}
41+
42+
/**
43+
* Builder class for building a {@link RemoveUsersSavedEpisodesRequest}.
44+
*/
45+
public static final class Builder extends AbstractDataRequest.Builder<String, RemoveUsersSavedEpisodesRequest.Builder> {
46+
47+
/**
48+
* Create a new {@link RemoveUsersSavedEpisodesRequest.Builder} instance.
49+
* <p>
50+
* Modification of the current user's "Your Music" collection requires authorization of the
51+
* {@code user-library-modify} scope.
52+
*
53+
* @param accessToken Required. A valid access token from the Spotify Accounts service.
54+
* @see <a href="https://developer.spotify.com/documentation/web-api/concepts/scopes">Spotify: Using Scopes</a>
55+
*/
56+
public Builder(final String accessToken) {
57+
super(accessToken);
58+
}
59+
60+
/**
61+
* The episode IDs setter.
62+
*
63+
* @param ids Optional. A comma-separated list of Spotify IDs for the episodes to be deleted from the user’s library. Maximum: 50 IDs.
64+
* @return A {@link RemoveUsersSavedEpisodesRequest.Builder}.
65+
* @see <a href="https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids">Spotify: URIs &amp; IDs</a>
66+
*/
67+
public RemoveUsersSavedEpisodesRequest.Builder ids(final String ids) {
68+
assert (ids != null);
69+
assert (ids.split(",").length <= 50);
70+
return setQueryParameter("ids", ids);
71+
}
72+
73+
/**
74+
* The episode IDs setter.
75+
* <p>
76+
* <b>Note:</b> If the ids have already been set with {@link #ids(String)}, any ids added here will be ignored.
77+
*
78+
* @param ids Optional. A JSON array of Spotify IDs for the episodes to be deleted from the user’s library. Maximum: 50 IDs.
79+
* @return A {@link RemoveUsersSavedEpisodesRequest.Builder}.
80+
* @see <a href="https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids">Spotify: URIs &amp; IDs</a>
81+
*/
82+
public RemoveUsersSavedEpisodesRequest.Builder ids(final JsonArray ids) {
83+
assert (ids != null);
84+
assert (!ids.isJsonNull());
85+
assert (ids.size() <= 50);
86+
return setBodyParameter("ids", ids);
87+
}
88+
89+
/**
90+
* The request build method.
91+
*
92+
* @return A custom {@link RemoveUsersSavedEpisodesRequest}.
93+
*/
94+
@Override
95+
public RemoveUsersSavedEpisodesRequest build() {
96+
setContentType(ContentType.APPLICATION_JSON);
97+
setPath("/v1/me/episodes");
98+
return new RemoveUsersSavedEpisodesRequest(this);
99+
}
100+
101+
@Override
102+
protected RemoveUsersSavedEpisodesRequest.Builder self() {
103+
return this;
104+
}
105+
}
106+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package se.michaelthelin.spotify.requests.data.library;
2+
3+
import org.apache.hc.core5.http.ParseException;
4+
import org.junit.jupiter.api.Test;
5+
import se.michaelthelin.spotify.ITest;
6+
import se.michaelthelin.spotify.TestUtil;
7+
import se.michaelthelin.spotify.exceptions.SpotifyWebApiException;
8+
import se.michaelthelin.spotify.requests.data.AbstractDataTest;
9+
10+
import java.io.IOException;
11+
import java.util.concurrent.ExecutionException;
12+
13+
import static org.junit.jupiter.api.Assertions.assertEquals;
14+
import static org.junit.jupiter.api.Assertions.assertNull;
15+
import static se.michaelthelin.spotify.Assertions.assertHasBodyParameter;
16+
import static se.michaelthelin.spotify.Assertions.assertHasHeader;
17+
18+
public class RemoveUsersSavedEpisodesRequestTest extends AbstractDataTest<String> {
19+
private final RemoveUsersSavedEpisodesRequest defaultRequest = ITest.SPOTIFY_API
20+
.removeUsersSavedEpisodes(ITest.ID_EPISODE, ITest.ID_EPISODE)
21+
.setHttpManager(
22+
TestUtil.MockedHttpManager.returningJson(null))
23+
.build();
24+
private final RemoveUsersSavedEpisodesRequest bodyRequest = ITest.SPOTIFY_API
25+
.removeUsersSavedEpisodes(ITest.EPISODES)
26+
.setHttpManager(
27+
TestUtil.MockedHttpManager.returningJson(null))
28+
.build();
29+
30+
public RemoveUsersSavedEpisodesRequestTest() throws Exception {
31+
}
32+
33+
@Test
34+
public void shouldComplyWithReference() {
35+
assertHasAuthorizationHeader(defaultRequest);
36+
assertEquals(
37+
"https://api.spotify.com:443/v1/me/episodes?ids=4GI3dxEafwap1sFiTGPKd1%2C4GI3dxEafwap1sFiTGPKd1",
38+
defaultRequest.getUri().toString());
39+
40+
assertHasAuthorizationHeader(bodyRequest);
41+
assertHasHeader(defaultRequest, "Content-Type", "application/json");
42+
assertHasBodyParameter(bodyRequest,
43+
"ids",
44+
ITest.EPISODES);
45+
assertEquals("https://api.spotify.com:443/v1/me/episodes",
46+
bodyRequest.getUri().toString());
47+
}
48+
49+
@Test
50+
public void shouldReturnDefault_sync() throws IOException, SpotifyWebApiException, ParseException {
51+
shouldReturnDefault(defaultRequest.execute());
52+
}
53+
54+
@Test
55+
public void shouldReturnDefault_async() throws ExecutionException, InterruptedException {
56+
shouldReturnDefault(defaultRequest.executeAsync().get());
57+
}
58+
59+
public void shouldReturnDefault(final String string) {
60+
assertNull(
61+
string);
62+
}
63+
}

0 commit comments

Comments
 (0)