diff --git a/README.md b/README.md index e69de29..28f9f39 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,19 @@ +# RecipeParser +![t](https://shields.io/github/v/release/joethei/RecipeParser?include_prereleases) + +Parse Recipes from Websites and files that use the json-ld format + +## Getting started + +```xml + + xyz.joethei + receipe-parser + ${version} + +``` + +```java +var url = //Website url / path to text file containing recipe data +Recipe recipe = RecipeParser.parse(url); +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml index 35a26c0..b649fe9 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ xyz.joethei recipe-parser - 1.0-SNAPSHOT + 1.1-SNAPSHOT UTF-8 @@ -175,6 +175,12 @@ 1.8 + + com.github.sisyphsu + dateparser + 1.0.7 + + diff --git a/src/main/java/xyz/joethei/recipe/Recipe.java b/src/main/java/xyz/joethei/recipe/Recipe.java index 70b1143..0b3f7f7 100644 --- a/src/main/java/xyz/joethei/recipe/Recipe.java +++ b/src/main/java/xyz/joethei/recipe/Recipe.java @@ -10,6 +10,7 @@ import org.immutables.value.Value; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -39,7 +40,7 @@ public interface Recipe { String recipeInstructions(); - Optional datePublished(); + Optional datePublished(); List recipeIngredient(); diff --git a/src/main/java/xyz/joethei/recipe/RecipeDeserializer.java b/src/main/java/xyz/joethei/recipe/RecipeDeserializer.java index d08797a..7a5f474 100644 --- a/src/main/java/xyz/joethei/recipe/RecipeDeserializer.java +++ b/src/main/java/xyz/joethei/recipe/RecipeDeserializer.java @@ -4,17 +4,18 @@ package xyz.joethei.recipe; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.Optional; + import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.github.sisyphsu.dateparser.DateParserUtils; import org.apache.commons.text.StringEscapeUtils; -import java.io.IOException; -import java.time.LocalDate; -import java.util.Optional; - /** * @author Johannes Theiner * @version 0.1 @@ -22,6 +23,8 @@ **/ public class RecipeDeserializer extends StdDeserializer { + private static final long serialVersionUID = -7183438859870030590L; + public RecipeDeserializer() { this(null); } @@ -68,7 +71,7 @@ public Recipe deserialize(JsonParser jsonParser, DeserializationContext deserial if (node.get("datePublished") != null) { var date = getIfExists(node, "datePublished"); date.ifPresent(s -> { - var localDate = LocalDate.parse(s); + LocalDateTime localDate = DateParserUtils.parseDateTime(s); builder.datePublished(localDate); }); } diff --git a/src/test/java/xyz/joethei/recipe/test/TextParsing.java b/src/test/java/xyz/joethei/recipe/test/TextParsing.java index 5f7dc65..0acd303 100644 --- a/src/test/java/xyz/joethei/recipe/test/TextParsing.java +++ b/src/test/java/xyz/joethei/recipe/test/TextParsing.java @@ -4,10 +4,6 @@ package xyz.joethei.recipe.test; -import org.junit.jupiter.api.Test; -import xyz.joethei.recipe.Recipe; -import xyz.joethei.recipe.RecipeParser; - import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Path; @@ -15,6 +11,10 @@ import java.util.Objects; import java.util.Optional; +import org.junit.jupiter.api.Test; +import xyz.joethei.recipe.Recipe; +import xyz.joethei.recipe.RecipeParser; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -27,7 +27,6 @@ public class TextParsing { @Test public void validParsing() throws IOException, URISyntaxException { - Recipe recipe = RecipeParser.parse(Path.of(Objects.requireNonNull(getClass().getClassLoader().getResource("recipe.json")).toURI())); assertNotNull(recipe); assertEquals("Tomatenspaghetti", recipe.name()); @@ -35,4 +34,11 @@ public void validParsing() throws IOException, URISyntaxException { assertEquals(Optional.empty(), recipe.cookTime()); assertEquals(Optional.of("P0DT0H15M"), recipe.totalTime()); } + + @Test + public void parse() throws URISyntaxException, IOException { + var recipe = RecipeParser.parse(Path.of(Objects.requireNonNull(getClass().getClassLoader().getResource("recipe1.json")).toURI())); + assertNotNull(recipe); + assertEquals("Tomatensuppe", recipe.name()); + } } \ No newline at end of file diff --git a/src/test/resources/recipe1.json b/src/test/resources/recipe1.json new file mode 100644 index 0000000..11361d4 --- /dev/null +++ b/src/test/resources/recipe1.json @@ -0,0 +1,43 @@ +{ + "@context": "http://schema.org", + "@type": "Recipe", + "name": "Tomatensuppe", + "author": { + "@type": "Person", + "name": "Mustermann" + }, + "image": "https://example.com/image.png", + "datePublished": "2017-07-10T09:09:10+02:00", + "aggregateRating": { + "@type": "AggregateRating", + "ratingValue": "3.47902", + "reviewCount": "42" + }, + "prepTime": "PT10M", + "totalTime": "PT25M", + "recipeYield": "4 servings", + "nutrition": { + "@type": "NutritionInformation", + "servingSize": "1 bowl" + }, + "recipeIngredient": [ + "80 g Zwiebel", + "600 g Tomate", + "4 EL Oliven\u00f6l", + "2 EL Tomatenmark", + "20 g Mehl", + "60 ml Fleischbr\u00fche", + "8 Stk. Pfefferkorn", + "1 Lorbeerblatt", + "1 EL Zucker", + "1 EL Zitronensaft", + " etwas Salz", + "60 ml Gem\u00fcsebr\u00fche", + "100 ml Sahne" + ], + "recipeInstructions": [ + "1. Zwiebeln sch\u00e4len und fein w\u00fcrfelig schneiden. Tomaten waschen, Strunk entfernen und w\u00fcrfelig schneiden.\r\n", + "2. \u00d6l in einem Suppentopf erhitzen. Zwiebeln darin glasig schwitzen. Mehl hinzuf\u00fcgen und kurz mitr\u00f6sten. Tomaten und \u2013Mark unterr\u00fchren. Mit Br\u00fche aufgie\u00dfen und Gew\u00fcrze hinzuf\u00fcge.\r\n", + "3. Etwa 30 Minuten k\u00f6cheln lassen. Suppe durch ein Sieb streichen. Nochmals kurz aufkochen und mit Sahne verfeinern und nochmals aufmixen.\r\n" + ] +} \ No newline at end of file