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
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
--- /dev/null
+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<Lang> 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);
+ }
+}
--- /dev/null
+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<String> 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<>();
+ }
+ }
+}
+++ /dev/null
-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<String> 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<>();
- }
- }
-}
--- /dev/null
+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<String> definitionsForWord(String word) {
+ return french.definitionsForWord(word);
+ }
+
+ public List<String> definitionsForWord(String word, String lang) {
+ return switch (Lang.parseOrDefault(lang)) {
+ case French -> french.definitionsForWord(word);
+ case German -> List.of("OOPS! NOT IMPLEMENTED");
+ };
+ }
+}
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")
@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);
}
}
@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);
}
}
@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);
}
You can send me a patch implementing support for your language. Take a look at the <a
href="https://git.frustrated-labs.net/?p=larousseapi;a=summary">codebase</a>.
I think everything is pretty self-explanatory. You should create a new implementation of the
- <code>WordDefinitionRepository</code> and <code>WordTranslationRepository</code> interfaces and add it to the
- corresponding composite classes.
+ <code>WordDefinitionRepository</code> and <code>WordTranslationRepository</code> interfaces.
</p>
<p>
The patches should be sent over email with the subject <code>[larousseapi] PATCH: description</code>
</small>
<form method="POST" action="/ui/getTranslationsDefinitions">
<fieldset>
+ <label for="lang">Language</label>
+ <select id="lang" name="lang" style="margin-bottom: 5px;">
+ <option value="fr">French</option>
+ <option value="de">German</option>
+ </select>
<label class="stack"><input name="word" type="text" placeholder="Jambon..."></label>
<button class="stack">Let's Go!</button>
</fieldset>