Merge pull request #32 from cato447/recipe-rest-update
Restructuring of recipe api endpoint
This commit is contained in:
3
.env.example
Normal file
3
.env.example
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
SPOONACCULAR_API_URL=
|
||||||
|
SPOONACCULAR_API_KEY=
|
||||||
|
SPOONACCULAR_API_SEARCH_RANKING=
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -92,3 +92,7 @@ out
|
|||||||
!gradle/wrapper/gradle-wrapper.jar
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
frontend/src/index.js
|
frontend/src/index.js
|
||||||
|
|
||||||
|
.env
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
|||||||
20
backend/src/main/spoonaccular/APIAuthentication.java
Normal file
20
backend/src/main/spoonaccular/APIAuthentication.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package spoonaccular;
|
||||||
|
|
||||||
|
import io.github.cdimascio.dotenv.Dotenv;
|
||||||
|
import okhttp3.Request;
|
||||||
|
|
||||||
|
public class APIAuthentication {
|
||||||
|
|
||||||
|
private static final Dotenv dotenv = Dotenv.configure().ignoreIfMissing().ignoreIfMalformed().load();
|
||||||
|
|
||||||
|
private APIAuthentication(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Request.Builder addAuthHeaders(Request.Builder builder){
|
||||||
|
return builder
|
||||||
|
.get()
|
||||||
|
.addHeader("X-RapidAPI-Key", dotenv.get("X-RapidAPI-Key"))
|
||||||
|
.addHeader("X-RapidAPI-Host", dotenv.get("X-RapidAPI-Host"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
61
backend/src/main/spoonaccular/RecipeInformation.java
Normal file
61
backend/src/main/spoonaccular/RecipeInformation.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package spoonaccular;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.github.cdimascio.dotenv.Dotenv;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import spoonaccular.models.recipe_by_ingredient.ExtendedRecipeByIngredient;
|
||||||
|
import spoonaccular.models.recipe_by_ingredient.RecipeByIngredient;
|
||||||
|
import spoonaccular.models.recipe_information.Recipe;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RecipeInformation {
|
||||||
|
|
||||||
|
private final Dotenv dotenv;
|
||||||
|
private final OkHttpClient client;
|
||||||
|
|
||||||
|
public RecipeInformation(){
|
||||||
|
dotenv = Dotenv.configure().ignoreIfMissing().ignoreIfMalformed().load();
|
||||||
|
client = new OkHttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Recipe> getRecipeFromIds(List<Integer> ids) throws IOException {
|
||||||
|
String idsString = ids.stream().map(String::valueOf)
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
return new ObjectMapper().readValue(queryInformationBulk(idsString).body().string(), new TypeReference<>(){});
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ExtendedRecipeByIngredient> getExtendedRecipeFromIds(List<Integer> ids) throws IOException {
|
||||||
|
String idsString = ids.stream().map(String::valueOf)
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
return new ObjectMapper().readValue(queryInformationBulk(idsString).body().string(), new TypeReference<>() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response queryInformationBulk(String idsString) throws IOException {
|
||||||
|
Request request = APIAuthentication.addAuthHeaders(new Request.Builder()
|
||||||
|
.url("https://" + dotenv.get("X-RapidAPI-Host") +
|
||||||
|
"/recipes/informationBulk?ids=" + idsString))
|
||||||
|
.build();
|
||||||
|
return client.newCall(request).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ExtendedRecipeByIngredient> getRecepieByIngredientsExtended(List<RecipeByIngredient> recipeByIngredients) throws IOException {
|
||||||
|
List<Integer> ids = recipeByIngredients.stream().map(RecipeByIngredient::getId).toList();
|
||||||
|
List<ExtendedRecipeByIngredient> extendedRecipeByIngredients = getExtendedRecipeFromIds(ids);
|
||||||
|
Iterator<RecipeByIngredient> recipeByIngredientIterator = recipeByIngredients.iterator();
|
||||||
|
Iterator<ExtendedRecipeByIngredient> extendedRecipeByIngredientIterator = extendedRecipeByIngredients.iterator();
|
||||||
|
while(recipeByIngredientIterator.hasNext() && extendedRecipeByIngredientIterator.hasNext()){
|
||||||
|
extendedRecipeByIngredientIterator.next().addMissingInfo(recipeByIngredientIterator.next());
|
||||||
|
}
|
||||||
|
return extendedRecipeByIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
74
backend/src/main/spoonaccular/RecipeSearch.java
Normal file
74
backend/src/main/spoonaccular/RecipeSearch.java
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package spoonaccular;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.github.cdimascio.dotenv.Dotenv;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import spoonaccular.models.recipe_by_ingredient.ExtendedRecipeByIngredient;
|
||||||
|
import spoonaccular.models.recipe_by_ingredient.RecipeByIngredient;
|
||||||
|
import spoonaccular.models.recipe_information.Recipe;
|
||||||
|
import whattocook.models.Item;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RecipeSearch {
|
||||||
|
private static final boolean IGNOREPANTRY = true;
|
||||||
|
|
||||||
|
private final Random rnd;
|
||||||
|
private final Dotenv dotenv;
|
||||||
|
private final RecipeInformation recipeInformation;
|
||||||
|
|
||||||
|
private final OkHttpClient client;
|
||||||
|
|
||||||
|
public RecipeSearch(){
|
||||||
|
rnd = new Random();
|
||||||
|
dotenv = Dotenv.configure().ignoreIfMissing().ignoreIfMalformed().load();
|
||||||
|
recipeInformation = new RecipeInformation();
|
||||||
|
client = new OkHttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ExtendedRecipeByIngredient> getForIngridients(Iterable<Item> items, int number) throws java.io.IOException {
|
||||||
|
List<String> itemNames = new LinkedList<>();
|
||||||
|
items.forEach(item -> itemNames.add(item.getName()));
|
||||||
|
String ingridients = String.join(",", itemNames);
|
||||||
|
|
||||||
|
Request request =
|
||||||
|
APIAuthentication.addAuthHeaders(new Request.Builder()
|
||||||
|
.url("https://" + dotenv.get("X-RapidAPI-Host") +
|
||||||
|
"/recipes/findByIngredients?ingredients="
|
||||||
|
+ ingridients + "&number=" + number + "&ignorePantry="
|
||||||
|
+ IGNOREPANTRY + "&ranking=" + dotenv.get("X-RapidAPI-SearchRanking")))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Response response = client.newCall(request).execute();
|
||||||
|
String responseString = response.body().string();
|
||||||
|
|
||||||
|
List<RecipeByIngredient> recipeByIngredients = new ObjectMapper().readValue(responseString, new TypeReference<>(){});
|
||||||
|
return recipeInformation.getRecepieByIngredientsExtended(recipeByIngredients);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedRecipeByIngredient getOneForIngridients(Iterable<Item> items, int number) throws IOException {
|
||||||
|
return this.getForIngridients(items, number).get(rnd.nextInt(number));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Recipe> getRandom(List<String> tags, int number) throws java.io.IOException, JSONException {
|
||||||
|
String tagString = String.join(",", tags);
|
||||||
|
Request request = APIAuthentication.addAuthHeaders(new Request.Builder()
|
||||||
|
.url("https://" + dotenv.get("X-RapidAPI-Host") +
|
||||||
|
"/recipes/random?number=" + number + "&tags=" + tagString))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Response response = client.newCall(request).execute();
|
||||||
|
JSONObject jsonObject = new JSONObject(response.body().string());
|
||||||
|
return new ObjectMapper().readValue(jsonObject.getJSONArray("recipes").toString(), new TypeReference<>(){});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package spoonaccular.models.recipe_by_ingredient;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import spoonaccular.models.recipe_information.Recipe;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ExtendedRecipeByIngredient extends Recipe {
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredientCount")
|
||||||
|
private Integer usedIngredientCount;
|
||||||
|
@JsonProperty("missedIngredientCount")
|
||||||
|
private Integer missedIngredientCount;
|
||||||
|
@JsonProperty("missedIngredients")
|
||||||
|
private List<MissedIngredient> missedIngredients = null;
|
||||||
|
@JsonProperty("usedIngredients")
|
||||||
|
private List<UsedIngredient> usedIngredients = null;
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredientCount")
|
||||||
|
public Integer getUsedIngredientCount() {
|
||||||
|
return usedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredientCount")
|
||||||
|
public void setUsedIngredientCount(Integer usedIngredientCount) {
|
||||||
|
this.usedIngredientCount = usedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredientCount")
|
||||||
|
public Integer getMissedIngredientCount() {
|
||||||
|
return missedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredientCount")
|
||||||
|
public void setMissedIngredientCount(Integer missedIngredientCount) {
|
||||||
|
this.missedIngredientCount = missedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredients")
|
||||||
|
public List<MissedIngredient> getMissedIngredients() {
|
||||||
|
return missedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredients")
|
||||||
|
public void setMissedIngredients(List<MissedIngredient> missedIngredients) {
|
||||||
|
this.missedIngredients = missedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredients")
|
||||||
|
public List<UsedIngredient> getUsedIngredients() {
|
||||||
|
return usedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredients")
|
||||||
|
public void setUsedIngredients(List<UsedIngredient> usedIngredients) {
|
||||||
|
this.usedIngredients = usedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMissingInfo(RecipeByIngredient recipeByIngredient){
|
||||||
|
this.setMissedIngredientCount(recipeByIngredient.getMissedIngredientCount());
|
||||||
|
this.setUsedIngredientCount(recipeByIngredient.getUsedIngredientCount());
|
||||||
|
this.setMissedIngredients(recipeByIngredient.getMissedIngredients());
|
||||||
|
this.setUsedIngredients(recipeByIngredient.getUsedIngredients());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
package spoonaccular.models.recipe_by_ingredient;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"name"
|
||||||
|
})
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class MissedIngredient {
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
|
||||||
|
package spoonaccular.models.recipe_by_ingredient;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"id",
|
||||||
|
"title",
|
||||||
|
"image",
|
||||||
|
"usedIngredientCount",
|
||||||
|
"missedIngredientCount",
|
||||||
|
"missedIngredients",
|
||||||
|
"usedIngredients",
|
||||||
|
})
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class RecipeByIngredient {
|
||||||
|
|
||||||
|
@JsonProperty("id")
|
||||||
|
private Integer id;
|
||||||
|
@JsonProperty("title")
|
||||||
|
private String title;
|
||||||
|
@JsonProperty("image")
|
||||||
|
private String image;
|
||||||
|
@JsonProperty("usedIngredientCount")
|
||||||
|
private Integer usedIngredientCount;
|
||||||
|
@JsonProperty("missedIngredientCount")
|
||||||
|
private Integer missedIngredientCount;
|
||||||
|
@JsonProperty("missedIngredients")
|
||||||
|
private List<MissedIngredient> missedIngredients = null;
|
||||||
|
@JsonProperty("usedIngredients")
|
||||||
|
private List<UsedIngredient> usedIngredients = null;
|
||||||
|
|
||||||
|
@JsonProperty("id")
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("id")
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("title")
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("title")
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("image")
|
||||||
|
public String getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("image")
|
||||||
|
public void setImage(String image) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredientCount")
|
||||||
|
public Integer getUsedIngredientCount() {
|
||||||
|
return usedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredientCount")
|
||||||
|
public void setUsedIngredientCount(Integer usedIngredientCount) {
|
||||||
|
this.usedIngredientCount = usedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredientCount")
|
||||||
|
public Integer getMissedIngredientCount() {
|
||||||
|
return missedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredientCount")
|
||||||
|
public void setMissedIngredientCount(Integer missedIngredientCount) {
|
||||||
|
this.missedIngredientCount = missedIngredientCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredients")
|
||||||
|
public List<MissedIngredient> getMissedIngredients() {
|
||||||
|
return missedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("missedIngredients")
|
||||||
|
public void setMissedIngredients(List<MissedIngredient> missedIngredients) {
|
||||||
|
this.missedIngredients = missedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredients")
|
||||||
|
public List<UsedIngredient> getUsedIngredients() {
|
||||||
|
return usedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("usedIngredients")
|
||||||
|
public void setUsedIngredients(List<UsedIngredient> usedIngredients) {
|
||||||
|
this.usedIngredients = usedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
package spoonaccular.models.recipe_by_ingredient;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"name"
|
||||||
|
})
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class UsedIngredient {
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
package spoonaccular.models.recipe_information;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.*;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"name",
|
||||||
|
"measures"
|
||||||
|
})
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class ExtendedIngredient {
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
@JsonProperty("measures")
|
||||||
|
private Measures measures;
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("measures")
|
||||||
|
public Measures getMeasures() {
|
||||||
|
return measures;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("measures")
|
||||||
|
public void setMeasures(Measures measures) {
|
||||||
|
this.measures = measures;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
package spoonaccular.models.recipe_information;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.*;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"metric"
|
||||||
|
})
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class Measures {
|
||||||
|
|
||||||
|
@JsonProperty("metric")
|
||||||
|
private Metric metric;
|
||||||
|
|
||||||
|
@JsonProperty("metric")
|
||||||
|
public Metric getMetric() {
|
||||||
|
return metric;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("metric")
|
||||||
|
public void setMetric(Metric metric) {
|
||||||
|
this.metric = metric;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
package spoonaccular.models.recipe_information;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.*;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"amount",
|
||||||
|
"unitShort"
|
||||||
|
})
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class Metric {
|
||||||
|
|
||||||
|
@JsonProperty("amount")
|
||||||
|
private Double amount;
|
||||||
|
@JsonProperty("unitShort")
|
||||||
|
private String unitShort;
|
||||||
|
|
||||||
|
@JsonProperty("amount")
|
||||||
|
public Double getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("amount")
|
||||||
|
public void setAmount(Double amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("unitShort")
|
||||||
|
public String getUnitShort() {
|
||||||
|
return unitShort;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("unitShort")
|
||||||
|
public void setUnitShort(String unitShort) {
|
||||||
|
this.unitShort = unitShort;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
|
||||||
|
package spoonaccular.models.recipe_information;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.*;
|
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonPropertyOrder({
|
||||||
|
"vegetarian",
|
||||||
|
"vegan",
|
||||||
|
"glutenFree",
|
||||||
|
"dairyFree",
|
||||||
|
"extendedIngredients",
|
||||||
|
"id",
|
||||||
|
"title",
|
||||||
|
"readyInMinutes",
|
||||||
|
"servings",
|
||||||
|
"image",
|
||||||
|
"spoonacularSourceUrl"
|
||||||
|
})
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class Recipe {
|
||||||
|
|
||||||
|
@JsonProperty("vegetarian")
|
||||||
|
private Boolean vegetarian;
|
||||||
|
@JsonProperty("vegan")
|
||||||
|
private Boolean vegan;
|
||||||
|
@JsonProperty("glutenFree")
|
||||||
|
private Boolean glutenFree;
|
||||||
|
@JsonProperty("dairyFree")
|
||||||
|
private Boolean diaryFree;
|
||||||
|
@JsonProperty("extendedIngredients")
|
||||||
|
private List<ExtendedIngredient> extendedIngredients = null;
|
||||||
|
@JsonProperty("id")
|
||||||
|
private Integer id;
|
||||||
|
@JsonProperty("title")
|
||||||
|
private String title;
|
||||||
|
@JsonProperty("readyInMinutes")
|
||||||
|
private Integer readyInMinutes;
|
||||||
|
@JsonProperty("servings")
|
||||||
|
private Integer servings;
|
||||||
|
@JsonProperty("image")
|
||||||
|
private String image;
|
||||||
|
@JsonProperty("spoonacularSourceUrl")
|
||||||
|
private String spoonacularSourceUrl;
|
||||||
|
|
||||||
|
@JsonProperty("vegetarian")
|
||||||
|
public Boolean getVegetarian() {
|
||||||
|
return vegetarian;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("vegetarian")
|
||||||
|
public void setVegetarian(Boolean vegetarian) {
|
||||||
|
this.vegetarian = vegetarian;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("vegan")
|
||||||
|
public Boolean getVegan() {
|
||||||
|
return vegan;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("vegan")
|
||||||
|
public void setVegan(Boolean vegan) {
|
||||||
|
this.vegan = vegan;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("glutenFree")
|
||||||
|
public Boolean getGlutenFree() {
|
||||||
|
return glutenFree;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("glutenFree")
|
||||||
|
public void setGlutenFree(Boolean glutenFree) {
|
||||||
|
this.glutenFree = glutenFree;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("extendedIngredients")
|
||||||
|
public List<ExtendedIngredient> getExtendedIngredients() {
|
||||||
|
return extendedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("extendedIngredients")
|
||||||
|
public void setExtendedIngredients(List<ExtendedIngredient> extendedIngredients) {
|
||||||
|
this.extendedIngredients = extendedIngredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("id")
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("id")
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("title")
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("title")
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("readyInMinutes")
|
||||||
|
public Integer getReadyInMinutes() {
|
||||||
|
return readyInMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("readyInMinutes")
|
||||||
|
public void setReadyInMinutes(Integer readyInMinutes) {
|
||||||
|
this.readyInMinutes = readyInMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("servings")
|
||||||
|
public Integer getServings() {
|
||||||
|
return servings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("servings")
|
||||||
|
public void setServings(Integer servings) {
|
||||||
|
this.servings = servings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("image")
|
||||||
|
public String getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("image")
|
||||||
|
public void setImage(String image) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("spoonacularSourceUrl")
|
||||||
|
public String getSpoonacularSourceUrl() {
|
||||||
|
return spoonacularSourceUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("spoonacularSourceUrl")
|
||||||
|
public void setSpoonacularSourceUrl(String spoonacularSourceUrl) {
|
||||||
|
this.spoonacularSourceUrl = spoonacularSourceUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import org.springframework.web.filter.CorsFilter;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication(scanBasePackages = {"spoonaccular", "whattocook"})
|
||||||
public class Application {
|
public class Application {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
package whattocook.Controller;
|
|
||||||
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.HttpEntity;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import whattocook.services.SpoonacularApiService;
|
|
||||||
import whattocook.repositories.ItemRepository;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/recipes")
|
|
||||||
public class SpoonacularController {
|
|
||||||
private int nextRecepies=10;
|
|
||||||
private int nextRecepiesForOneRandom=20;
|
|
||||||
@Autowired
|
|
||||||
private ItemRepository itemRepository;
|
|
||||||
@Autowired
|
|
||||||
private SpoonacularApiService service;
|
|
||||||
|
|
||||||
@GetMapping("/forFridge")
|
|
||||||
public HttpEntity<JSONArray> getForFridge() throws IOException, InterruptedException, JSONException {
|
|
||||||
return new HttpEntity<JSONArray>(service.getForIngridients(itemRepository.findAll(), nextRecepies));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/random")
|
|
||||||
public HttpEntity<JSONArray> getRandom() throws IOException, InterruptedException, JSONException {
|
|
||||||
return new HttpEntity<JSONArray>(service.getRandom(new LinkedList<>(), nextRecepies));
|
|
||||||
//when user has food preferences apply instead of linked list.
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/oneFridge")
|
|
||||||
public HttpEntity<JSONObject> getOneFridge() throws IOException, InterruptedException, JSONException {
|
|
||||||
return new HttpEntity<JSONObject>(service.getOneForIngridients(itemRepository.findAll(), nextRecepiesForOneRandom));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNextRecepies(int nextRecepies) {
|
|
||||||
this.nextRecepies = nextRecepies;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package whattocook.controller;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.rest.webmvc.BasePathAwareController;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import spoonaccular.RecipeInformation;
|
||||||
|
import spoonaccular.RecipeSearch;
|
||||||
|
import spoonaccular.models.recipe_by_ingredient.ExtendedRecipeByIngredient;
|
||||||
|
import spoonaccular.models.recipe_information.Recipe;
|
||||||
|
import whattocook.repositories.ItemRepository;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController()
|
||||||
|
@BasePathAwareController()
|
||||||
|
public class SpoonacularController {
|
||||||
|
private int nextRecepies=10;
|
||||||
|
private int nextRecepiesForOneRandom=20;
|
||||||
|
@Autowired
|
||||||
|
private ItemRepository itemRepository;
|
||||||
|
@Autowired
|
||||||
|
private RecipeInformation recipeInformation;
|
||||||
|
@Autowired
|
||||||
|
private RecipeSearch recipeSearch;
|
||||||
|
|
||||||
|
@GetMapping("/recipe/forFridge")
|
||||||
|
public List<ExtendedRecipeByIngredient> getForFridge() throws IOException {
|
||||||
|
return recipeSearch.getForIngridients(itemRepository.findAll(), nextRecepies);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/recipe/random")
|
||||||
|
public List<Recipe> getRandom() throws IOException, InterruptedException, JSONException {
|
||||||
|
return recipeSearch.getRandom(new LinkedList<>(), nextRecepies);
|
||||||
|
//when user has food preferences apply instead of linked list.
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/recipe/oneFridge")
|
||||||
|
public ExtendedRecipeByIngredient getOneFridge() throws IOException {
|
||||||
|
return recipeSearch.getOneForIngridients(itemRepository.findAll(), nextRecepiesForOneRandom);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package whattocook.implementation;
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import whattocook.models.Item;
|
|
||||||
import whattocook.services.SpoonacularApiService;
|
|
||||||
import org.json.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.http.HttpResponse;
|
|
||||||
import java.net.http.HttpRequest;
|
|
||||||
import java.net.http.HttpClient;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class SpoonacularApiServiceImpl implements SpoonacularApiService {
|
|
||||||
private final String KEY = "85cc006d508b447a88e659cd748899db";
|
|
||||||
private final String RANKING = "2";
|
|
||||||
private final boolean IGNOREPANTRY = true;
|
|
||||||
Random rnd=new Random();
|
|
||||||
|
|
||||||
public JSONArray getForIngridients(Iterable<Item> items, int number) throws java.io.IOException, InterruptedException, JSONException {
|
|
||||||
Iterator<Item> itemIterator = items.iterator();
|
|
||||||
if (!itemIterator.hasNext()) {
|
|
||||||
return getRandom(new java.util.LinkedList<String>(), number);
|
|
||||||
} else {
|
|
||||||
String ingridients = itemIterator.next().getName();
|
|
||||||
for (Iterator<Item> it = itemIterator; it.hasNext(); ) {
|
|
||||||
Item curryItem = it.next();
|
|
||||||
|
|
||||||
|
|
||||||
ingridients += "," + curryItem.getName();
|
|
||||||
}
|
|
||||||
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
|
|
||||||
.uri(java.net.URI.create("https://api.spoonacular.com/recipes/findByIngredients?apiKey=" + KEY + "&ingredients=" + ingridients + "&ranking=" + RANKING + "&ignorePantry=" + IGNOREPANTRY + "&number=" + number))
|
|
||||||
.method("GET", java.net.http.HttpRequest.BodyPublishers.noBody())
|
|
||||||
.build();
|
|
||||||
java.net.http.HttpResponse<String> response = java.net.http.HttpClient.newHttpClient().send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
JSONArray array=new JSONArray(response.body());
|
|
||||||
return array;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONObject getOneForIngridients(Iterable<Item> items, int number) throws IOException, InterruptedException, JSONException {
|
|
||||||
JSONArray array= getForIngridients(items, number);
|
|
||||||
|
|
||||||
|
|
||||||
return array.getJSONObject(rnd.nextInt(20));
|
|
||||||
}
|
|
||||||
|
|
||||||
public JSONArray getRandom(java.util.List<String> tags, int number) throws java.io.IOException, InterruptedException, JSONException {
|
|
||||||
if (tags.isEmpty()) {
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create("https://api.spoonacular.com/recipes/random?apiKey=" + KEY + "&number=" + number))
|
|
||||||
.method("GET", HttpRequest.BodyPublishers.noBody())
|
|
||||||
.build();
|
|
||||||
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
|
|
||||||
JSONArray array=new JSONArray(response.body());
|
|
||||||
return array;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
String tagString = tags.get(0);
|
|
||||||
for (int i = 1; i < tags.size(); i++) {
|
|
||||||
tagString += "," + tags.get(i);
|
|
||||||
}
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
|
||||||
.uri(URI.create("https://api.spoonacular.com/recipes/random?apiKey=" + KEY + "&number=" + number + "&tags=" + tagString))
|
|
||||||
.method("GET", HttpRequest.BodyPublishers.noBody())
|
|
||||||
.build();
|
|
||||||
HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
|
|
||||||
JSONArray array=new JSONArray(response.body());
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package whattocook.services;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import whattocook.models.Item;
|
|
||||||
|
|
||||||
public interface SpoonacularApiService {
|
|
||||||
JSONArray getForIngridients(Iterable<Item> items, int number) throws java.io.IOException, InterruptedException, JSONException;
|
|
||||||
JSONObject getOneForIngridients(Iterable<Item> items, int number) throws java.io.IOException, InterruptedException, JSONException;
|
|
||||||
|
|
||||||
JSONArray getRandom(java.util.List<String> tags, int number) throws java.io.IOException, InterruptedException, JSONException;
|
|
||||||
}
|
|
||||||
@@ -29,10 +29,15 @@ dependencies {
|
|||||||
// https://mvnrepository.com/artifact/com.h2database/h2
|
// https://mvnrepository.com/artifact/com.h2database/h2
|
||||||
implementation group: 'com.h2database', name: 'h2', version: '1.3.148'
|
implementation group: 'com.h2database', name: 'h2', version: '1.3.148'
|
||||||
|
|
||||||
//lombok
|
// okhttp
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:4.10.0")
|
||||||
|
|
||||||
|
// lombok
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||||
|
|
||||||
|
implementation 'io.github.cdimascio:dotenv-java:2.2.4'
|
||||||
|
|
||||||
testCompileOnly 'org.projectlombok:lombok:1.18.24'
|
testCompileOnly 'org.projectlombok:lombok:1.18.24'
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.24'
|
testAnnotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user