Skip to content

Commit 31e307d

Browse files
authored
Add missing ids body parameter (#71)
The endpoints endpoint-save-shows-user and endpoint-remove-shows-user are missing the optional `ids` body parameter. This also updates the `ResponseTypeMapper` to always update the endpoint hashes. Fixes #70
1 parent 0f1529d commit 31e307d

File tree

7 files changed

+128
-23
lines changed

7 files changed

+128
-23
lines changed

spotify-web-api-core/src/main/resources/spotify-web-api.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3752,6 +3752,14 @@ categories:
37523752
\ their account in the [account settings](https://www.spotify.com/se/account/overview/)."
37533753
type: String
37543754
required: false
3755+
- location: BODY
3756+
name: ids
3757+
description: "A JSON array of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids).\
3758+
\ \nA maximum of 50 items can be specified in one request. *Note: if\
3759+
\ the `ids` parameter is present in the query string, any IDs listed here\
3760+
\ in the body will be ignored.*"
3761+
type: "Array[String]"
3762+
required: false
37553763
responseDescription: "On success, the HTTP status code in the response header\
37563764
\ is `200` OK.\nOn error, the header status code is an [error code](https://developer.spotify.com/documentation/web-api/#response-status-codes)\
37573765
\ and the response body contains an [error object](https://developer.spotify.com/documentation/web-api/#error-details).\
@@ -3931,6 +3939,14 @@ categories:
39313939
\ Maximum: 50 IDs."
39323940
type: String
39333941
required: true
3942+
- location: BODY
3943+
name: ids
3944+
description: "A JSON array of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids).\
3945+
\ \nA maximum of 50 items can be specified in one request. *Note: if\
3946+
\ the `ids` parameter is present in the query string, any IDs listed here\
3947+
\ in the body will be ignored.*"
3948+
type: "Array[String]"
3949+
required: false
39343950
responseDescription: "On success, the HTTP status code in the response header\
39353951
\ is `200` OK. On error, the header status code is an [error code](https://developer.spotify.com/documentation/web-api/#response-status-codes)\
39363952
\ and the response body contains an [error object](https://developer.spotify.com/documentation/web-api/#error-details).\

spotify-web-api-generator-open-api/spotify-web-api-openapi.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,6 +2695,21 @@ paths:
26952695
required: true
26962696
schema:
26972697
type: string
2698+
requestBody:
2699+
content:
2700+
application/json:
2701+
schema:
2702+
type: object
2703+
properties:
2704+
ids:
2705+
type: array
2706+
description: "A JSON array of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids).\
2707+
\ \nA maximum of 50 items can be specified in one request. *Note:\
2708+
\ if the `ids` parameter is present in the query string, any IDs\
2709+
\ listed here in the body will be ignored.*"
2710+
items:
2711+
type: string
2712+
required: false
26982713
responses:
26992714
default:
27002715
$ref: '#/components/responses/ErrorResponse'
@@ -2747,6 +2762,21 @@ paths:
27472762
required: false
27482763
schema:
27492764
type: string
2765+
requestBody:
2766+
content:
2767+
application/json:
2768+
schema:
2769+
type: object
2770+
properties:
2771+
ids:
2772+
type: array
2773+
description: "A JSON array of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids).\
2774+
\ \nA maximum of 50 items can be specified in one request. *Note:\
2775+
\ if the `ids` parameter is present in the query string, any IDs\
2776+
\ listed here in the body will be ignored.*"
2777+
items:
2778+
type: string
2779+
required: false
27502780
responses:
27512781
default:
27522782
$ref: '#/components/responses/ErrorResponse'

spotify-web-api-parser/response-types.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ category-library:
6565
- type: "Array[Boolean]"
6666
status: 200
6767
endpoint-get-users-saved-episodes:
68-
md5Hash: 8c34757f341b78f13871c0642765aa84
68+
md5Hash: 80f3e189edc6742d8348ebee029f2a6d
6969
responseTypes:
7070
- type: "PagingObject[SavedEpisodeObject]"
7171
status: 200

spotify-web-api-parser/src/main/java/de/sonallux/spotify/parser/ApiEndpointFixes.java

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.sonallux.spotify.parser;
22

33
import de.sonallux.spotify.core.model.SpotifyWebApiCategory;
4+
import de.sonallux.spotify.core.model.SpotifyWebApiEndpoint;
45
import lombok.extern.slf4j.Slf4j;
56

67
import java.util.List;
@@ -18,6 +19,8 @@ static void fixApiEndpoints(SortedMap<String, SpotifyWebApiCategory> categories)
1819
fixGetUsersSavedShowsScope(categories);
1920
fixCheckUsersSavedShowsScope(categories);
2021
fixReplaceAndReorderPlaylistTrackUrisParameter(categories);
22+
fixSaveShowsForCurrentUserBodyParameter(categories);
23+
fixRemoveUsersSavedShowsBodyParameter(categories);
2124
}
2225

2326
private static void fixChangePlaylistsDetails(SortedMap<String, SpotifyWebApiCategory> categories) {
@@ -29,9 +32,9 @@ private static void fixChangePlaylistsDetails(SortedMap<String, SpotifyWebApiCat
2932
.orElse(null);
3033
if (paramPath == null) {
3134
log.warn("change-playlist-details wrong playlist_id parameter type has been fixed");
32-
} else {
33-
paramPath.setType("String");
35+
return;
3436
}
37+
paramPath.setType("String");
3538
}
3639

3740
private static void fixGetInfoAboutUsersCurrentPlayback(SortedMap<String, SpotifyWebApiCategory> categories) {
@@ -43,9 +46,9 @@ private static void fixGetInfoAboutUsersCurrentPlayback(SortedMap<String, Spotif
4346
}
4447
if (endpoint.getScopes().size() != 0) {
4548
log.warn("endpoint-get-information-about-the-users-current-playback missing scope has been fixed");
46-
} else {
47-
endpoint.getScopes().add("user-read-playback-state");
49+
return;
4850
}
51+
endpoint.getScopes().add("user-read-playback-state");
4952
}
5053

5154
private static void fixStartAUsersPlayback(SortedMap<String, SpotifyWebApiCategory> categories) {
@@ -100,19 +103,19 @@ private static void fixGetUsersSavedShowsScope(SortedMap<String, SpotifyWebApiCa
100103
.getEndpoints().get("endpoint-get-users-saved-shows");
101104
if (!endpoint.getScopes().contains("user-libary-read")) {
102105
log.warn("endpoint-get-users-saved-shows scope user-libary-read has been fixed");
103-
} else {
104-
endpoint.setScopes(List.of("user-library-read"));
106+
return;
105107
}
108+
endpoint.setScopes(List.of("user-library-read"));
106109
}
107110

108111
private static void fixCheckUsersSavedShowsScope(SortedMap<String, SpotifyWebApiCategory> categories) {
109112
var endpoint = categories.get("category-library")
110113
.getEndpoints().get("endpoint-check-users-saved-shows");
111114
if (!endpoint.getScopes().contains("user-libary-read")) {
112115
log.warn("endpoint-check-users-saved-shows scope user-libary-read has been fixed");
113-
} else {
114-
endpoint.setScopes(List.of("user-library-read"));
116+
return;
115117
}
118+
endpoint.setScopes(List.of("user-library-read"));
116119
}
117120

118121
private static void fixReplaceAndReorderPlaylistTrackUrisParameter(SortedMap<String, SpotifyWebApiCategory> categories) {
@@ -125,8 +128,10 @@ private static void fixReplaceAndReorderPlaylistTrackUrisParameter(SortedMap<Str
125128
if (urisBodyParameter == null) {
126129
log.warn("Can not find uris body parameter in endpoint-reorder-or-replace-playlists-tracks");
127130
return;
128-
} else if (!urisBodyParameter.getDescription().isBlank()) {
131+
}
132+
if (!urisBodyParameter.getDescription().isBlank()) {
129133
log.warn("Missing description on uris body parameter in endpoint-reorder-or-replace-playlists-tracks has been fixed");
134+
return;
130135
}
131136

132137
var urisQueryParameter = endpoint.getParameters().stream()
@@ -139,4 +144,42 @@ private static void fixReplaceAndReorderPlaylistTrackUrisParameter(SortedMap<Str
139144

140145
urisBodyParameter.setDescription(urisQueryParameter.getDescription());
141146
}
147+
148+
private static void fixSaveShowsForCurrentUserBodyParameter(SortedMap<String, SpotifyWebApiCategory> categories) {
149+
var endpoint = categories.get("category-library")
150+
.getEndpoints().get("endpoint-save-shows-user");
151+
152+
if (endpoint.getParameters().stream().anyMatch(parameter -> parameter.getLocation() == BODY && "ids".equals(parameter.getName()))) {
153+
log.warn("Missing body parameter for endpoint-save-shows-user has been fixed");
154+
return;
155+
}
156+
157+
endpoint.getParameters().add(new SpotifyWebApiEndpoint.Parameter(
158+
BODY,
159+
"ids",
160+
"A JSON array of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids). \n" +
161+
"A maximum of 50 items can be specified in one request. *Note: if the `ids` parameter is present in the query string, " +
162+
"any IDs listed here in the body will be ignored.*",
163+
"Array[String]",
164+
false));
165+
}
166+
167+
private static void fixRemoveUsersSavedShowsBodyParameter(SortedMap<String, SpotifyWebApiCategory> categories) {
168+
var endpoint = categories.get("category-library")
169+
.getEndpoints().get("endpoint-remove-shows-user");
170+
171+
if (endpoint.getParameters().stream().anyMatch(parameter -> parameter.getLocation() == BODY && "ids".equals(parameter.getName()))) {
172+
log.warn("Missing body parameter for endpoint-remove-shows-user has been fixed");
173+
return;
174+
}
175+
176+
endpoint.getParameters().add(new SpotifyWebApiEndpoint.Parameter(
177+
BODY,
178+
"ids",
179+
"A JSON array of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids). \n" +
180+
"A maximum of 50 items can be specified in one request. *Note: if the `ids` parameter is present in the query string, " +
181+
"any IDs listed here in the body will be ignored.*",
182+
"Array[String]",
183+
false));
184+
}
142185
}

spotify-web-api-parser/src/main/java/de/sonallux/spotify/parser/ApiEndpointParser.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,21 @@ private void addResponseTypes(SortedMap<String, SpotifyWebApiCategory> categorie
5959
try {
6060
if (isInteractive) {
6161
responseTypeMapper.update(new ArrayList<>(categories.values()));
62-
responseTypeMapper.save();
6362
}
6463

6564
for (var category : categories.values()) {
6665
for (var endpoint : category.getEndpointList()) {
67-
var endpointResponse = responseTypeMapper.getEndpointResponse(category.getId(), endpoint.getId());
68-
if (endpointResponse == null || endpointResponse.getResponseTypes().isEmpty()) {
66+
var responseTypes = responseTypeMapper.getEndpointResponseTypes(category.getId(), endpoint);
67+
if (responseTypes == null || responseTypes.isEmpty()) {
6968
log.warn("Missing response type in {} for {} {} with response: \n{}\n", category.getId(),
7069
endpoint.getHttpMethod(), endpoint.getId(), endpoint.getResponseDescription());
7170
continue;
7271
}
73-
endpoint.setResponseTypes(endpointResponse.getResponseTypes());
72+
endpoint.setResponseTypes(responseTypes);
7473
}
7574
}
75+
76+
responseTypeMapper.save();
7677
} catch (IOException e) {
7778
log.error("Failed to load missing response types", e);
7879
}

spotify-web-api-parser/src/main/java/de/sonallux/spotify/parser/Html2Markdown.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import java.util.Set;
1616
import java.util.stream.Collectors;
1717

18-
public class Html2Markdown {
18+
class Html2Markdown {
1919

2020
private static final FlexmarkHtmlConverter CONVERTER;
2121

@@ -27,11 +27,11 @@ public class Html2Markdown {
2727
.build();
2828
}
2929

30-
public static String convert(Node node) {
30+
static String convert(Node node) {
3131
return CONVERTER.convert(node).trim();
3232
}
3333

34-
public static String convert(List<? extends Node> nodes) {
34+
static String convert(List<? extends Node> nodes) {
3535
return nodes.stream()
3636
.map(CONVERTER::convert)
3737
.collect(Collectors.joining("\n"))

spotify-web-api-parser/src/main/java/de/sonallux/spotify/parser/ResponseTypeMapper.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import lombok.Getter;
1010
import lombok.NoArgsConstructor;
1111
import lombok.Setter;
12+
import lombok.extern.slf4j.Slf4j;
1213

1314
import java.io.IOException;
1415
import java.math.BigInteger;
@@ -19,14 +20,15 @@
1920
import java.security.NoSuchAlgorithmException;
2021
import java.util.*;
2122

22-
public class ResponseTypeMapper {
23+
@Slf4j
24+
class ResponseTypeMapper {
2325

2426
private final Path responseTypesFile;
2527
private final Map<String, Map<String, EndpointResponse>> responseTypes;
2628
private final MessageDigest md5Digest;
2729
private final ObjectMapper objectMapper;
2830

29-
public ResponseTypeMapper(Path responseTypesFile) throws IOException, NoSuchAlgorithmException {
31+
ResponseTypeMapper(Path responseTypesFile) throws IOException, NoSuchAlgorithmException {
3032
this.responseTypesFile = responseTypesFile;
3133
this.objectMapper = Yaml.create();
3234
this.md5Digest = MessageDigest.getInstance("MD5");
@@ -39,13 +41,26 @@ private Map<String, Map<String, EndpointResponse>> load() throws IOException {
3941
}
4042
}
4143

42-
public void save() throws IOException {
44+
List<SpotifyWebApiEndpoint.ResponseType> getEndpointResponseTypes(String categoryId, SpotifyWebApiEndpoint endpoint) {
45+
var endpointResponse = getEndpointResponse(categoryId, endpoint.getId());
46+
if (endpointResponse == null) {
47+
return null;
48+
}
49+
var currentHash = calculateMD5Hash(endpoint);
50+
if (!currentHash.equals(endpointResponse.getMd5Hash())) {
51+
log.warn("Response description for endpoint {} has changed", endpoint.getId());
52+
endpointResponse.setMd5Hash(currentHash);
53+
}
54+
return endpointResponse.getResponseTypes();
55+
}
56+
57+
void save() throws IOException {
4358
try (var outputStream = Files.newOutputStream(this.responseTypesFile)) {
4459
objectMapper.writeValue(outputStream, responseTypes);
4560
}
4661
}
4762

48-
public void update(List<SpotifyWebApiCategory> categories) {
63+
void update(List<SpotifyWebApiCategory> categories) {
4964
var scanner = new Scanner(System.in);
5065
for (var category : categories) {
5166
for (var endpoint : category.getEndpointList()) {
@@ -104,7 +119,7 @@ private static int readInt(Scanner scanner, int defaultValue) {
104119
}
105120
}
106121

107-
public EndpointResponse getEndpointResponse(String categoryId, String endpointId) {
122+
private EndpointResponse getEndpointResponse(String categoryId, String endpointId) {
108123
var endpointTypes = responseTypes.get(categoryId);
109124
if (endpointTypes == null) {
110125
return null;
@@ -135,7 +150,7 @@ private String calculateMD5Hash(SpotifyWebApiEndpoint endpoint) {
135150
@Setter
136151
@AllArgsConstructor
137152
@NoArgsConstructor
138-
public static class EndpointResponse {
153+
static class EndpointResponse {
139154
private String md5Hash;
140155
private List<SpotifyWebApiEndpoint.ResponseType> responseTypes = new ArrayList<>();
141156
}

0 commit comments

Comments
 (0)