From: Alexander Goussas Date: Tue, 2 Jun 2026 03:32:19 +0000 (-0500) Subject: feat: add support for multilang definitions X-Git-Url: http://git.frustrated-labs.net/?a=commitdiff_plain;h=d54e8103ea72b6027ebff7b02768d40deab739e6;p=larousseapi feat: add support for multilang definitions --- diff --git a/collections/larousse API/Define a word.yml b/collections/larousse API/Define a word.yml index 96fcef1..905fda1 100644 --- a/collections/larousse API/Define a word.yml +++ b/collections/larousse API/Define a word.yml @@ -5,8 +5,11 @@ info: http: method: GET - url: "{{api.base_url}}/words/:word/definition" + url: "{{api.base_url}}/words/:word/definition?lang=de" params: + - name: lang + value: de + type: query - name: word value: voiture type: path diff --git a/collections/larousse API/Translate a word.yml b/collections/larousse API/Translate a word.yml index 9f08930..9e31518 100644 --- a/collections/larousse API/Translate a word.yml +++ b/collections/larousse API/Translate a word.yml @@ -5,8 +5,11 @@ info: http: method: GET - url: "{{api.base_url}}/words/:word/translation" + url: "{{api.base_url}}/words/:word/translation?lang=de" params: + - name: lang + value: de + type: query - name: word value: voiture type: path diff --git a/src/main/java/net/frustratedfunctor/core/Lang.java b/src/main/java/net/frustratedfunctor/core/Lang.java new file mode 100644 index 0000000..a58a4ae --- /dev/null +++ b/src/main/java/net/frustratedfunctor/core/Lang.java @@ -0,0 +1,28 @@ +package net.frustratedfunctor.core; + +import java.util.Optional; + +public enum Lang { + French("fr"), + German("de"); + + public final String code; + + public final static Lang DEFAULT = French; + + Lang(String code) { + this.code = code; + } + + public static Optional parse(String s) { + return Optional.ofNullable(switch (s.toLowerCase()) { + case "fr" -> Lang.French; + case "de" -> Lang.German; + default -> null; + }); + } + + public static Lang parseOrDefault(String s) { + return parse(s).orElse(DEFAULT); + } +} diff --git a/src/main/java/net/frustratedfunctor/definitions/FrenchWordDefinitionRepository.java b/src/main/java/net/frustratedfunctor/definitions/FrenchWordDefinitionRepository.java new file mode 100644 index 0000000..0b26252 --- /dev/null +++ b/src/main/java/net/frustratedfunctor/definitions/FrenchWordDefinitionRepository.java @@ -0,0 +1,29 @@ +package net.frustratedfunctor.definitions; + +import io.quarkus.logging.Log; +import jakarta.enterprise.context.ApplicationScoped; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Element; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +@ApplicationScoped +public class FrenchWordDefinitionRepository implements WordDefinitionRepository { + @Override + public List definitionsForWord(String word) { + try { + final var larousseUrl = URI.create("https://www.larousse.fr/dictionnaires/francais/" + word).toURL(); + final var doc = Jsoup.parse(larousseUrl, 10_000); + return doc + .select("li.DivisionDefinition") + .stream() + .map(Element::ownText) + .toList(); + } catch (Exception e) { + Log.error("Error while fetching word translations", e); + return new ArrayList<>(); + } + } +} diff --git a/src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java b/src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java deleted file mode 100644 index 96e7d78..0000000 --- a/src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.frustratedfunctor.definitions; - -import io.quarkus.logging.Log; -import jakarta.enterprise.context.ApplicationScoped; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Element; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -@ApplicationScoped -public class JsoupWordDefinitionRepository implements WordDefinitionRepository { - @Override - public List definitionsForWord(String word) { - try { - final var larousseUrl = URI.create("https://www.larousse.fr/dictionnaires/francais/" + word).toURL(); - final var doc = Jsoup.parse(larousseUrl, 10_000); - return doc - .select("li.DivisionDefinition") - .stream() - .map(Element::ownText) - .toList(); - } catch (Exception e) { - Log.error("Error while fetching word translations", e); - return new ArrayList<>(); - } - } -} diff --git a/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java b/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java new file mode 100644 index 0000000..fd43308 --- /dev/null +++ b/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java @@ -0,0 +1,29 @@ +package net.frustratedfunctor.definitions; + +import jakarta.annotation.Priority; +import jakarta.enterprise.context.ApplicationScoped; +import net.frustratedfunctor.core.Lang; + +import java.util.List; + +@Priority(1) +@ApplicationScoped +public class LanguageAwareDefinitionsRepository implements WordDefinitionRepository { + private final FrenchWordDefinitionRepository french; + + public LanguageAwareDefinitionsRepository(FrenchWordDefinitionRepository french) { + this.french = french; + } + + @Override + public List definitionsForWord(String word) { + return french.definitionsForWord(word); + } + + public List definitionsForWord(String word, String lang) { + return switch (Lang.parseOrDefault(lang)) { + case French -> french.definitionsForWord(word); + case German -> List.of("OOPS! NOT IMPLEMENTED"); + }; + } +} diff --git a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java index 6f3b78d..7e9e9b1 100644 --- a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java +++ b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java @@ -1,9 +1,6 @@ package net.frustratedfunctor.definitions; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; +import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; @Path("/words") @@ -18,8 +15,11 @@ public class WordDefinitionResource { @Path("/{word}/definition") @GET @Produces(MediaType.APPLICATION_JSON) - public WordDefinition definition(@PathParam("word") String word) { - return definitions.define(word); + public WordDefinition definition( + @PathParam("word") String word, + @QueryParam("lang") String lang + ) { + return definitions.define(word, lang); } } diff --git a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java index 44696e2..564aafa 100644 --- a/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java +++ b/src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java @@ -5,17 +5,15 @@ import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class WordDefinitionService { - private final WordDefinitionRepository definitions; + private final LanguageAwareDefinitionsRepository definitions; - public WordDefinitionService(WordDefinitionRepository definitions) { + public WordDefinitionService(LanguageAwareDefinitionsRepository definitions) { this.definitions = definitions; } - public WordDefinition define(String word) { - return new WordDefinition( - word, - definitions.definitionsForWord(word) - ); + public WordDefinition define(String word, String lang) { + final var defs = definitions.definitionsForWord(word, lang); + return new WordDefinition(word, defs); } } diff --git a/src/main/java/net/frustratedfunctor/ui/UiResource.java b/src/main/java/net/frustratedfunctor/ui/UiResource.java index 0fe5dc2..00e688d 100644 --- a/src/main/java/net/frustratedfunctor/ui/UiResource.java +++ b/src/main/java/net/frustratedfunctor/ui/UiResource.java @@ -28,10 +28,13 @@ public class UiResource { @Path("getTranslationsDefinitions") @POST @Produces(MediaType.TEXT_HTML) - public TemplateInstance getTranslationsDefinitions(@FormParam("word") String word) { + public TemplateInstance getTranslationsDefinitions( + @FormParam("word") String word, + @FormParam("lang") String lang + ) { final var data = new WordTranslationsDefinitions( translations.translate(word).translations(), - definitions.define(word).definitions() + definitions.define(word, lang).definitions() ); return index.data("translationsDefinitions", data); } diff --git a/src/main/resources/templates/pub/contributing.html b/src/main/resources/templates/pub/contributing.html index 78b98b3..80d1079 100644 --- a/src/main/resources/templates/pub/contributing.html +++ b/src/main/resources/templates/pub/contributing.html @@ -56,8 +56,7 @@ You can send me a patch implementing support for your language. Take a look at the codebase. I think everything is pretty self-explanatory. You should create a new implementation of the - WordDefinitionRepository and WordTranslationRepository interfaces and add it to the - corresponding composite classes. + WordDefinitionRepository and WordTranslationRepository interfaces.

The patches should be sent over email with the subject [larousseapi] PATCH: description diff --git a/src/main/resources/templates/pub/index.html b/src/main/resources/templates/pub/index.html index 34bcd6f..69ad8cb 100644 --- a/src/main/resources/templates/pub/index.html +++ b/src/main/resources/templates/pub/index.html @@ -54,6 +54,11 @@

+ +