From: Alexander Goussas Date: Fri, 22 May 2026 00:01:01 +0000 (-0500) Subject: feat: implement first version of translation service X-Git-Url: http://git.frustrated-labs.net/?a=commitdiff_plain;ds=inline;p=larousseapi feat: implement first version of translation service --- diff --git a/src/main/java/net/frustratedfunctor/WordDefinitionResource.java b/src/main/java/net/frustratedfunctor/WordDefinitionResource.java deleted file mode 100644 index 82b3fb0..0000000 --- a/src/main/java/net/frustratedfunctor/WordDefinitionResource.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.frustratedfunctor; - - -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import org.jboss.resteasy.reactive.RestQuery; - -@Path("/search") -public class WordDefinitionResource { - - private final WordDefinitionService words; - - public WordDefinitionResource(WordDefinitionService words) { - this.words = words; - } - - @GET - @Produces(MediaType.APPLICATION_JSON) - public WordDefinition search(@RestQuery String word) { - final var definition = words.search(word); - return definition; - } - -} diff --git a/src/main/java/net/frustratedfunctor/WordDefinitionService.java b/src/main/java/net/frustratedfunctor/WordDefinitionService.java deleted file mode 100644 index 53474c1..0000000 --- a/src/main/java/net/frustratedfunctor/WordDefinitionService.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.frustratedfunctor; - -import jakarta.enterprise.context.ApplicationScoped; - -@ApplicationScoped -public class WordDefinitionService { - - public WordDefinition search(String word) { - if (word == null || word.isEmpty()) { - throw new InvalidWordException("The word cannot be empty"); - } - return null; - } - -} diff --git a/src/main/java/net/frustratedfunctor/WordTranslationResource.java b/src/main/java/net/frustratedfunctor/WordTranslationResource.java new file mode 100644 index 0000000..5145dfe --- /dev/null +++ b/src/main/java/net/frustratedfunctor/WordTranslationResource.java @@ -0,0 +1,26 @@ +package net.frustratedfunctor; + + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import org.jboss.resteasy.reactive.RestQuery; + +@Path("/translate") +public class WordTranslationResource { + + private final WordTranslationService words; + + public WordTranslationResource(WordTranslationService words) { + this.words = words; + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public WordDefinition translate(@RestQuery("q") String word) throws Exception { + final var definition = words.translate(word); + return definition; + } + +} diff --git a/src/main/java/net/frustratedfunctor/WordTranslationService.java b/src/main/java/net/frustratedfunctor/WordTranslationService.java new file mode 100644 index 0000000..7ea96a2 --- /dev/null +++ b/src/main/java/net/frustratedfunctor/WordTranslationService.java @@ -0,0 +1,36 @@ +package net.frustratedfunctor; + +import jakarta.enterprise.context.ApplicationScoped; +import org.jsoup.Jsoup; + +import java.net.URI; +import java.util.ArrayList; + +@ApplicationScoped +public class WordTranslationService { + + public WordDefinition translate(String word) throws Exception { + if (word == null || word.isEmpty()) { + throw new InvalidWordException("The word cannot be empty"); + } + + 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 new WordDefinition( + word, + wordDefs + ); + } + +}