Merge pull request #6 from sgoudham/main

Add New Endpoint for Getting Series by ID
pull/8/head
Hamothy 4 years ago committed by GitHub
commit 5fd85b6ce8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

1
Jenkinsfile vendored

@ -64,6 +64,7 @@ pipeline {
error "*** Files could not be found"; error "*** Files could not be found";
} }
} }
archiveArtifacts artifacts: 'target/*.jar', onlyIfSuccessful: true
} }
} }
} }

@ -1,6 +1,8 @@
package org.goudham.me; package org.goudham.me;
import org.goudham.me.api.entity.series.Series;
import org.goudham.me.api.entity.waifu.Waifu; import org.goudham.me.api.entity.waifu.Waifu;
import org.goudham.me.exception.APIMapperException;
import org.goudham.me.exception.APIResponseException; import org.goudham.me.exception.APIResponseException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -13,7 +15,8 @@ import java.time.Duration;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
* A MyWaifuClient * A MyWaifuClient, the underlying client used for making requests is {@link HttpClient}
*
* *
* <p> Main entry point for retrieving information from MyWaifuList.</p> * <p> Main entry point for retrieving information from MyWaifuList.</p>
* <p> {@link MyWaifuWrapper} is utilised to make the API requests </p> * <p> {@link MyWaifuWrapper} is utilised to make the API requests </p>
@ -49,14 +52,18 @@ public class MyWaifuClient {
return myWaifuClient; return myWaifuClient;
} }
public Response<Waifu> getWaifu(String slug) throws APIResponseException { public Response<Waifu> getWaifu(String slug) throws APIResponseException, APIMapperException {
return myWaifuWrapper.getWaifu(httpClient, slug); return myWaifuWrapper.getWaifu(httpClient, slug);
} }
public Response<Waifu> getWaifu(Integer id) throws APIResponseException { public Response<Waifu> getWaifu(Integer id) throws APIResponseException, APIMapperException {
return myWaifuWrapper.getWaifu(httpClient, String.valueOf(id)); return myWaifuWrapper.getWaifu(httpClient, String.valueOf(id));
} }
public Response<Series> getSeries(Integer id) throws APIMapperException, APIResponseException {
return myWaifuWrapper.getSeries(httpClient, String.valueOf(id));
}
/** /**
* Sets an instance of HttpClient * Sets an instance of HttpClient
* *

@ -3,7 +3,9 @@ package org.goudham.me;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.goudham.me.api.entity.series.Series;
import org.goudham.me.api.entity.waifu.Waifu; import org.goudham.me.api.entity.waifu.Waifu;
import org.goudham.me.exception.APIMapperException;
import org.goudham.me.exception.APIResponseException; import org.goudham.me.exception.APIResponseException;
import java.net.URI; import java.net.URI;
@ -33,19 +35,24 @@ public class MyWaifuWrapper {
this.apiKey = apiKey; this.apiKey = apiKey;
} }
/** /**
* * Handles sending a request to the API asynchronously using {@link HttpRequest}
* and the underlying {@link HttpClient}
* *
* @param httpClient The {@link HttpClient} to use for sending {@link HttpRequest}'s * @param httpClient The {@link HttpClient} to use for sending {@link HttpRequest}'s
* @param param The end of the endpoint appended onto the host * @param param The end of the endpoint appended onto the host
* @return {@link Result}
* @throws APIResponseException If the {@link CompletableFuture Response}
* cannot be decoded or the thread was interrupted while waiting to receive the data
*
*/ */
private Result sendRequest(HttpClient httpClient, String param) throws APIResponseException { private Result sendRequest(HttpClient httpClient, String param) throws APIResponseException {
HttpRequest request = HttpRequest.newBuilder() HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(host + param)) .uri(URI.create(host + param))
.version(httpClient.version()) .version(httpClient.version())
.timeout(Duration.ofSeconds(30)) .timeout(Duration.ofSeconds(20))
.header("Content-Type", "application/json") .headers("Content-Type", "application/json", "apikey", apiKey)
.header("apikey", apiKey)
.GET() .GET()
.build(); .build();
@ -63,26 +70,35 @@ public class MyWaifuWrapper {
return new Result(responseCode, responseBody); return new Result(responseCode, responseBody);
} }
Response<Waifu> getWaifu(HttpClient httpClient, String param) throws APIResponseException { private <T> Response<T> getPopulatedResponse(Result result, Class<T> entity) throws APIMapperException {
Result waifuResult = sendRequest(httpClient, "waifu/" + param); Integer statusCode = result.getStatusCode();
Integer statusCode = waifuResult.getStatusCode(); String body = result.getBody();
String body = waifuResult.getBody(); T newEntity = null;
Waifu waifu = null;
if (statusCode == 200) { if (statusCode == 200) {
try { try {
JsonNode parent = objectMapper.readTree(body); JsonNode parent = objectMapper.readTree(body);
String waifuData = parent.get("data").toString(); String data = parent.get("data").toString();
waifu = objectMapper.readValue(waifuData, Waifu.class); newEntity = objectMapper.readValue(data, entity);
} catch (JsonProcessingException jpe) { } catch (JsonProcessingException jpe) {
jpe.printStackTrace(); String customExceptionMessage = "If you are seeing this message, this is more than likely a fault in my logic. " +
"Please raise an issue including the printed stacktrace :D";
String exceptionMessage = "\n\n" + customExceptionMessage + "\n\n" + jpe.getMessage();
statusCode = 100; throw new APIMapperException(exceptionMessage, jpe);
body = "{\"message\":\"If you are seeing this message, this is more than likely a fault in my logic. " + }
"Please raise an issue with the printed stacktrace :D\",\"code\":Custom 100}";
} }
return new Response<>(statusCode, body, newEntity);
}
Response<Waifu> getWaifu(HttpClient httpClient, String param) throws APIResponseException, APIMapperException {
Result waifuResult = sendRequest(httpClient, "waifu/" + param);
return getPopulatedResponse(waifuResult, Waifu.class);
} }
return new Response<>(statusCode, body, waifu); Response<Series> getSeries(HttpClient httpClient, String param) throws APIResponseException, APIMapperException {
Result seriesResult = sendRequest(httpClient, "series/" + param);
return getPopulatedResponse(seriesResult, Series.class);
} }
} }

@ -1,5 +1,22 @@
package org.goudham.me; package org.goudham.me;
import org.goudham.me.api.entity.series.Series;
import org.goudham.me.api.entity.waifu.Waifu;
/**
* This is returned to the User when called by methods in {@link MyWaifuClient}
* <br>
* E.g {@link MyWaifuClient#getWaifu(Integer)}
* <br>
* Given a successful response, {@link #entity} will be populated with the requested entity.
* <br>
* No matter successful or unsuccessful response, {@link #responseCode} and {@link #responseBody}
* will be populated to ensure the user has all the information for debugging or extra information within
* the {@link #responseBody}
*
* @param <T> The type of entity to be returned. E.g {@link Waifu} or {@link Series}
*
*/
public class Response<T> { public class Response<T> {
private T entity; private T entity;
private final Integer responseCode; private final Integer responseCode;

@ -27,7 +27,8 @@ import java.util.Objects;
@Generated("jsonschema2pojo") @Generated("jsonschema2pojo")
public class Studio { public class Studio {
@JsonCreator Studio() { }
Studio(String name) { Studio(String name) {
this.name = name; this.name = name;
} }

@ -9,7 +9,6 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import java.util.Objects; import java.util.Objects;
/** /**
* {@link FilteredSeries} * {@link FilteredSeries}
* <p> Contains basic series information for most endpoints </p> * <p> Contains basic series information for most endpoints </p>
@ -18,9 +17,12 @@ import java.util.Objects;
* <ul> * <ul>
* <li>{@link String name}</li> * <li>{@link String name}</li>
* <li>{@link String originalName}</li> * <li>{@link String originalName}</li>
* <li>{@link Integer relevance}</li>
* <li>{@link String romajiName}</li> * <li>{@link String romajiName}</li>
* <li>{@link String slug}</li> * <li>{@link String slug}</li>
* <li>{@link String} type</li>
* <li>{@link String description}</li> * <li>{@link String description}</li>
* <li>{@link String displayPicture}</li>
* <li>{@link String url}</li> * <li>{@link String url}</li>
* <li>{@link Integer id}</li> * <li>{@link Integer id}</li>
* </ul> * </ul>
@ -30,9 +32,12 @@ import java.util.Objects;
@JsonPropertyOrder({ @JsonPropertyOrder({
"name", "name",
"original_name", "original_name",
"relevance",
"romaji_name", "romaji_name",
"slug", "slug",
"type",
"description", "description",
"displayPicture",
"url", "url",
"id" "id"
}) })
@ -55,30 +60,52 @@ public class FilteredSeries {
private String originalName; private String originalName;
/** /**
* If this {@link Series} has a romaji name, we'll put it here. * Relevancy of {@link FilteredSeries}
*/
@JsonProperty("relevance")
@JsonPropertyDescription("Relevancy of FilteredSeries")
private Integer relevance;
/**
* If this {@link FilteredSeries} has a romaji name, we'll put it here.
* *
*/ */
@JsonProperty("romaji_name") @JsonProperty("romaji_name")
@JsonPropertyDescription("if this character has a romaji name, we'll put it here. ") @JsonPropertyDescription("if this series has a romaji name, we'll put it here. ")
private String romajiName; private String romajiName;
/** /**
* Readable URL's for this {@link Series} * Readable URL's for this {@link FilteredSeries}
* *
*/ */
@JsonProperty("slug") @JsonProperty("slug")
@JsonPropertyDescription("Used to generate readable URL's for the Waifu") @JsonPropertyDescription("Used to generate readable URL's for the FilteredSeries")
private String slug; private String slug;
/**
* Type of {@link FilteredSeries}. E.g TV, Game
*
*/
@JsonProperty("type")
@JsonPropertyDescription("Type of FilteredSeries. E.g TV, Game")
private String type;
/** /**
* Truncated, spoiler-free description of this {@link Series} * Truncated, spoiler-free description of this {@link FilteredSeries}
* *
*/ */
@JsonProperty("description") @JsonProperty("description")
@JsonPropertyDescription("Truncated, spoiler-free description of this Waifu") @JsonPropertyDescription("Truncated, spoiler-free description of this FilteredSeries")
private String description; private String description;
/**
* URL of the display picture
*
*/
@JsonProperty("display_picture")
@JsonPropertyDescription("URL of the display picture")
private String displayPicture;
/** /**
* URL to view in browser * URL to view in browser
* *
@ -88,10 +115,10 @@ public class FilteredSeries {
private String url; private String url;
/** /**
* Interal ID of this {@link Series} * Interal ID of this {@link FilteredSeries}
*/ */
@JsonProperty("id") @JsonProperty("id")
@JsonPropertyDescription("Internal ID of the series") @JsonPropertyDescription("Internal ID of this FilteredSeries")
private Integer id; private Integer id;
@JsonProperty("name") @JsonProperty("name")
@ -114,6 +141,12 @@ public class FilteredSeries {
this.originalName = originalName; this.originalName = originalName;
} }
@JsonProperty("relevance")
public Integer getRelevance() { return relevance; }
@JsonProperty("relevance")
public void setRelevance(Integer relevance) { this.relevance = relevance; }
@JsonProperty("romaji_name") @JsonProperty("romaji_name")
public String getRomajiName() { public String getRomajiName() {
return romajiName; return romajiName;
@ -134,6 +167,12 @@ public class FilteredSeries {
this.slug = slug; this.slug = slug;
} }
@JsonProperty("type")
public String getType() { return type; }
@JsonProperty("type")
public void setType(String type) { this.type = type; }
@JsonProperty("description") @JsonProperty("description")
public String getDescription() { public String getDescription() {
return description; return description;
@ -144,6 +183,16 @@ public class FilteredSeries {
this.description = description; this.description = description;
} }
@JsonProperty("display_picture")
public String getDisplayPicture() {
return displayPicture;
}
@JsonProperty("display_picture")
public void setDisplayPicture(String displayPicture) {
this.displayPicture = displayPicture;
}
@JsonProperty("url") @JsonProperty("url")
public String getUrl() { public String getUrl() {
return url; return url;

@ -26,6 +26,7 @@ import java.util.Objects;
* <li>{@link String displayPicture}</li> * <li>{@link String displayPicture}</li>
* <li>{@link String url}</li> * <li>{@link String url}</li>
* <li>{@link Studio}</li> * <li>{@link Studio}</li>
* <li>{@link String} type</li>
* <li>{@link Integer id}</li> * <li>{@link Integer id}</li>
* </ul> * </ul>
* *
@ -44,6 +45,7 @@ import java.util.Objects;
"display_picture", "display_picture",
"url", "url",
"studio", "studio",
"type",
"id" "id"
}) })
@Generated("jsonschema2pojo") @Generated("jsonschema2pojo")
@ -145,6 +147,14 @@ public class Series {
@JsonPropertyDescription("Contains information on a given animation or game development studio") @JsonPropertyDescription("Contains information on a given animation or game development studio")
private Studio studio; private Studio studio;
/**
* Type of {@link Series}. E.g TV, Game
*
*/
@JsonProperty("type")
@JsonPropertyDescription("Type of FilteredSeries. E.g TV, Game")
private String type;
/** /**
* The internal ID of the {@link Series} * The internal ID of the {@link Series}
* *
@ -271,6 +281,12 @@ public class Series {
this.studio = studio; this.studio = studio;
} }
@JsonProperty("type")
public String getType() { return type; }
@JsonProperty("type")
public void setType(String type) { this.type = type; }
@JsonProperty("id") @JsonProperty("id")
public Integer getId() { public Integer getId() {
return id; return id;

@ -1,125 +0,0 @@
package org.goudham.me.api.entity.waifu;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import javax.annotation.processing.Generated;
/**
* {@link Appearance}
* <p>Contains basic series information for most endpoints</p>
*
* <p> Fields included are: </p>
* <ul>
* <li>{@link String name}</li>
* <li>{@link String originalName}</li>
* <li>{@link String romajiName}</li>
* <li>{@link String slug}</li>
* <li>{@link String description}</li>
* <li>{@link String url}</li>
* <li>{@link Integer id}</li>
* </ul>
*
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"name",
"original_name",
"romaji_name",
"slug",
"description",
"url",
"id"
})
@Generated("jsonschema2pojo")
public class Appearance {
@JsonProperty("name")
private String name;
@JsonProperty("original_name")
private String originalName;
@JsonProperty("romaji_name")
private String romajiName;
@JsonProperty("slug")
private String slug;
@JsonProperty("description")
private String description;
@JsonProperty("url")
private String url;
@JsonProperty("id")
@JsonPropertyDescription("Internal ID of the series")
private Integer id;
@JsonProperty("name")
public String getName() {
return name;
}
@JsonProperty("name")
public void setName(String name) {
this.name = name;
}
@JsonProperty("original_name")
public String getOriginalName() {
return originalName;
}
@JsonProperty("original_name")
public void setOriginalName(String originalName) {
this.originalName = originalName;
}
@JsonProperty("romaji_name")
public String getRomajiName() {
return romajiName;
}
@JsonProperty("romaji_name")
public void setRomajiName(String romajiName) {
this.romajiName = romajiName;
}
@JsonProperty("slug")
public String getSlug() {
return slug;
}
@JsonProperty("slug")
public void setSlug(String slug) {
this.slug = slug;
}
@JsonProperty("description")
public String getDescription() {
return description;
}
@JsonProperty("description")
public void setDescription(String description) {
this.description = description;
}
@JsonProperty("url")
public String getUrl() {
return url;
}
@JsonProperty("url")
public void setUrl(String url) {
this.url = url;
}
@JsonProperty("id")
public Integer getId() {
return id;
}
@JsonProperty("id")
public void setId(Integer id) {
this.id = id;
}
}

@ -1,5 +1,7 @@
package org.goudham.me.api.entity.waifu; package org.goudham.me.api.entity.waifu;
import org.goudham.me.api.entity.series.FilteredSeries;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import javax.annotation.processing.Generated; import javax.annotation.processing.Generated;
@ -19,13 +21,14 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
* <li>{@link String slug}</li> * <li>{@link String slug}</li>
* <li>{@link String name}</li> * <li>{@link String name}</li>
* <li>{@link String originalName}</li> * <li>{@link String originalName}</li>
* <li>{@link Integer relevance}</li>
* <li>{@link String romajiName}</li> * <li>{@link String romajiName}</li>
* <li>{@link String displayPicture}</li> * <li>{@link String displayPicture}</li>
* <li>{@link Integer likes}</li> * <li>{@link Integer likes}</li>
* <li>{@link Integer trash}</li> * <li>{@link Integer trash}</li>
* <li>{@link Integer episodeCount}</li> * <li>{@link String type}</li>
* <li>{@link String url}</li> * <li>{@link String url}</li>
* <li>{@link List} of {@link Appearance}'s</li> * <li>{@link List} of {@link FilteredSeries}'s</li>
* <li>{@link Double id}</li> * <li>{@link Double id}</li>
* </ul> * </ul>
* *
@ -35,11 +38,13 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
"slug", "slug",
"name", "name",
"original_name", "original_name",
"relevance",
"romaji_name", "romaji_name",
"display_picture", "display_picture",
"description", "description",
"likes", "likes",
"trash", "trash",
"type",
"url", "url",
"appearances", "appearances",
"id" "id"
@ -47,11 +52,11 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@Generated("jsonschema2pojo") @Generated("jsonschema2pojo")
public class FilteredWaifu { public class FilteredWaifu {
/** /**
* Used to generate readable URL's for the Waifu * Used to generate readable URL's for the {@link FilteredWaifu}
* *
*/ */
@JsonProperty("slug") @JsonProperty("slug")
@JsonPropertyDescription("Used to generate readable URL's for the Waifu") @JsonPropertyDescription("Used to generate readable URL's for the FilteredWaifu")
private String slug; private String slug;
/** /**
@ -70,6 +75,13 @@ public class FilteredWaifu {
@JsonPropertyDescription("Name in the original language (\u65e5\u672c\u8a9e)") @JsonPropertyDescription("Name in the original language (\u65e5\u672c\u8a9e)")
private String originalName; private String originalName;
/**
* Relevancy of {@link FilteredWaifu}
*/
@JsonProperty("relevance")
@JsonPropertyDescription("Relevancy of FilteredWaifu")
private Integer relevance;
/** /**
* If this character has a romaji name, we'll put it here. * If this character has a romaji name, we'll put it here.
* *
@ -87,29 +99,37 @@ public class FilteredWaifu {
private String displayPicture; private String displayPicture;
/** /**
* Truncated, spoiler-free description of this Waifu * Truncated, spoiler-free description of this {@link FilteredWaifu}
* *
*/ */
@JsonProperty("description") @JsonProperty("description")
@JsonPropertyDescription("Truncated, spoiler-free description of this Waifu") @JsonPropertyDescription("Truncated, spoiler-free description of this FilteredWaifu")
private String description; private String description;
/** /**
* Number of likes for this Waifu * Number of likes for this {@link FilteredWaifu}
* *
*/ */
@JsonProperty("likes") @JsonProperty("likes")
@JsonPropertyDescription("Number of likes for this Waifu") @JsonPropertyDescription("Number of likes for this FilteredWaifu")
private Integer likes; private Integer likes;
/** /**
* Number of trashes for this Waifu * Number of trashes for this {@link FilteredWaifu}
* *
*/ */
@JsonProperty("trash") @JsonProperty("trash")
@JsonPropertyDescription("Number of trashes for this Waifu") @JsonPropertyDescription("Number of trashes for this FilteredWaifu")
private Integer trash; private Integer trash;
/**
* Type that is returned. Eg Waifu, Husbando
*
*/
@JsonProperty("type")
@JsonPropertyDescription("Type that is returned. Eg Waifu, Husbando")
private String type;
/** /**
* URL to view in browser * URL to view in browser
* *
@ -119,10 +139,10 @@ public class FilteredWaifu {
private String url; private String url;
/** /**
* <p>{@link List<Appearance>} of Waifu's {@link Appearance}</p> * <p>{@link List} of Waifu's appearances</p>
*/ */
@JsonProperty("appearances") @JsonProperty("appearances")
private List<Appearance> appearances; private List<FilteredSeries> appearances;
/** /**
* {@link FilteredWaifu} ID * {@link FilteredWaifu} ID
@ -140,7 +160,6 @@ public class FilteredWaifu {
this.slug = slug; this.slug = slug;
} }
@JsonProperty("name") @JsonProperty("name")
public String getName() { public String getName() {
return name; return name;
@ -161,6 +180,12 @@ public class FilteredWaifu {
this.originalName = originalName; this.originalName = originalName;
} }
@JsonProperty("relevance")
public Integer getRelevance() { return relevance; }
@JsonProperty("relevance")
public void setRelevance(Integer relevance) { this.relevance = relevance; }
@JsonProperty("romaji_name") @JsonProperty("romaji_name")
public String getRomajiName() { public String getRomajiName() {
return romajiName; return romajiName;
@ -211,6 +236,12 @@ public class FilteredWaifu {
this.trash = trash; this.trash = trash;
} }
@JsonProperty("type")
public String getType() { return type; }
@JsonProperty("type")
public void setType(String type) { this.type = type; }
@JsonProperty("url") @JsonProperty("url")
public String getUrl() { public String getUrl() {
return url; return url;
@ -222,13 +253,11 @@ public class FilteredWaifu {
} }
@JsonProperty("appearances") @JsonProperty("appearances")
public List<Appearance> getAppearances() { public List<FilteredSeries> getAppearances() { return appearances; }
return appearances;
}
@JsonProperty("appearances") @JsonProperty("appearances")
public void setAppearances(List<Appearance> appearances) { public void setAppearances(List<FilteredSeries> filteredSeries) {
this.appearances = appearances; this.appearances = filteredSeries;
} }
@JsonProperty("id") @JsonProperty("id")

@ -0,0 +1,15 @@
package org.goudham.me.exception;
import org.goudham.me.MyWaifuWrapper;
import org.goudham.me.Response;
/**
* Thrown when {@link MyWaifuWrapper} fails to unmarshal json into Java POJO's ({@link Response#getEntity()})
*
*/
public class APIMapperException extends Throwable {
public APIMapperException(String errorMessage, Throwable error) {
super(errorMessage, error);
}
}
Loading…
Cancel
Save