From: Alexander Goussas Date: Tue, 2 Jun 2026 16:41:34 +0000 (-0500) Subject: feat: enable multi lingual word translations X-Git-Url: http://git.frustrated-labs.net/?a=commitdiff_plain;h=0de22b55de1be87599e95929693168794af81a28;p=larousseapi feat: enable multi lingual word translations --- diff --git a/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java b/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java index a2059e1..b7b8f2c 100644 --- a/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java +++ b/src/main/java/net/frustratedfunctor/definitions/LanguageAwareDefinitionsRepository.java @@ -1,12 +1,10 @@ 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; diff --git a/src/main/java/net/frustratedfunctor/translations/FrenchWordTranslationRepository.java b/src/main/java/net/frustratedfunctor/translations/FrenchWordTranslationRepository.java new file mode 100644 index 0000000..4d4ac05 --- /dev/null +++ b/src/main/java/net/frustratedfunctor/translations/FrenchWordTranslationRepository.java @@ -0,0 +1,36 @@ +package net.frustratedfunctor.translations; + +import io.quarkus.logging.Log; +import jakarta.enterprise.context.ApplicationScoped; +import org.jsoup.Jsoup; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +@ApplicationScoped +public class FrenchWordTranslationRepository implements WordTranslationRepository { + + @Override + public List translationsForWord(String word) { + try { + final var larousseUrl = URI.create("https://www.larousse.fr/dictionnaires/francais-anglais/" + word).toURL(); + final var doc = Jsoup.parse(larousseUrl, 10_000); + + final var defs = doc.select("li.itemZONESEM"); + final var wordDefs = new ArrayList(); + + for (final var def : defs) { + final var translation = def.selectFirst("span.Traduction"); + if (translation != null) { + wordDefs.add(translation.text()); + } + } + + return wordDefs; + } catch (Exception e) { + Log.error("", e); + return new ArrayList<>(); + } + } +} diff --git a/src/main/java/net/frustratedfunctor/translations/JsoupWordTranslationRepository.java b/src/main/java/net/frustratedfunctor/translations/JsoupWordTranslationRepository.java deleted file mode 100644 index 553b645..0000000 --- a/src/main/java/net/frustratedfunctor/translations/JsoupWordTranslationRepository.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.frustratedfunctor.translations; - -import io.quarkus.logging.Log; -import jakarta.enterprise.context.ApplicationScoped; -import org.jsoup.Jsoup; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -@ApplicationScoped -public class JsoupWordTranslationRepository implements WordTranslationRepository { - - @Override - public List translationsForWord(String word) { - try { - final var larousseUrl = URI.create("https://www.larousse.fr/dictionnaires/francais-anglais/" + word).toURL(); - final var doc = Jsoup.parse(larousseUrl, 10_000); - - final var defs = doc.select("li.itemZONESEM"); - final var wordDefs = new ArrayList(); - - for (final var def : defs) { - final var translation = def.selectFirst("span.Traduction"); - if (translation != null) { - wordDefs.add(translation.text()); - } - } - - return wordDefs; - } catch (Exception e) { - Log.error("", e); - return new ArrayList<>(); - } - } -} diff --git a/src/main/java/net/frustratedfunctor/translations/LanguageAwareTranslationsRepository.java b/src/main/java/net/frustratedfunctor/translations/LanguageAwareTranslationsRepository.java new file mode 100644 index 0000000..7727fde --- /dev/null +++ b/src/main/java/net/frustratedfunctor/translations/LanguageAwareTranslationsRepository.java @@ -0,0 +1,27 @@ +package net.frustratedfunctor.translations; + +import jakarta.enterprise.context.ApplicationScoped; +import net.frustratedfunctor.core.Lang; + +import java.util.List; + +@ApplicationScoped +public class LanguageAwareTranslationsRepository implements WordTranslationRepository { + private final FrenchWordTranslationRepository french; + + public LanguageAwareTranslationsRepository(FrenchWordTranslationRepository french) { + this.french = french; + } + + @Override + public List translationsForWord(String word) { + return translationsForWord(word, Lang.DEFAULT); + } + + public List translationsForWord(String word, Lang lang) { + return switch (lang) { + case French -> french.translationsForWord(word); + case German -> List.of("NOT IMPLEMENTED"); + }; + } +} diff --git a/src/main/java/net/frustratedfunctor/translations/WordTranslationResource.java b/src/main/java/net/frustratedfunctor/translations/WordTranslationResource.java index b1b2cae..0c185fa 100644 --- a/src/main/java/net/frustratedfunctor/translations/WordTranslationResource.java +++ b/src/main/java/net/frustratedfunctor/translations/WordTranslationResource.java @@ -1,10 +1,7 @@ package net.frustratedfunctor.translations; -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") @@ -19,8 +16,11 @@ public class WordTranslationResource { @Path("/{word}/translation") @GET @Produces(MediaType.APPLICATION_JSON) - public WordTranslation translation(@PathParam("word") String word) { - return words.translate(word); + public WordTranslation translation( + @PathParam("word") String word, + @QueryParam("lang") String lang + ) { + return words.translate(word, lang); } } diff --git a/src/main/java/net/frustratedfunctor/translations/WordTranslationService.java b/src/main/java/net/frustratedfunctor/translations/WordTranslationService.java index 6f547f9..88b2eb5 100644 --- a/src/main/java/net/frustratedfunctor/translations/WordTranslationService.java +++ b/src/main/java/net/frustratedfunctor/translations/WordTranslationService.java @@ -2,22 +2,23 @@ package net.frustratedfunctor.translations; import jakarta.enterprise.context.ApplicationScoped; import net.frustratedfunctor.InvalidWordException; +import net.frustratedfunctor.core.Lang; @ApplicationScoped public class WordTranslationService { - private final WordTranslationRepository repository; + private final LanguageAwareTranslationsRepository repository; - public WordTranslationService(WordTranslationRepository repository) { + public WordTranslationService(LanguageAwareTranslationsRepository repository) { this.repository = repository; } - public WordTranslation translate(String word) { + public WordTranslation translate(String word, String lang) { if (word == null || word.isEmpty()) { throw new InvalidWordException("The word cannot be empty:" + word); } - final var wordDefs = repository.translationsForWord(word); + final var wordDefs = repository.translationsForWord(word, Lang.parseOrDefault(lang)); return new WordTranslation( word, diff --git a/src/main/java/net/frustratedfunctor/ui/UiResource.java b/src/main/java/net/frustratedfunctor/ui/UiResource.java index 06b07e7..589b11d 100644 --- a/src/main/java/net/frustratedfunctor/ui/UiResource.java +++ b/src/main/java/net/frustratedfunctor/ui/UiResource.java @@ -40,7 +40,7 @@ public class UiResource { @FormParam("lang") String lang ) throws Exception { final var encodedWord = URLEncoder.encode(word, StandardCharsets.UTF_8); - final var f1 = exec.submit(() -> translations.translate(encodedWord).translations()); + final var f1 = exec.submit(() -> translations.translate(encodedWord, lang).translations()); final var f2 = exec.submit(() -> definitions.define(encodedWord, lang).definitions()); // TODO: Handle error final var data = new WordTranslationsDefinitions(f1.get(), f2.get());