]> git.frustrated-labs.net Git - larousseapi/commitdiff
feat: add endpoint to define a word
authorAlexander Goussas <[email protected]>
Sun, 31 May 2026 15:26:10 +0000 (10:26 -0500)
committerAlexander Goussas <[email protected]>
Sun, 31 May 2026 15:26:10 +0000 (10:26 -0500)
collections/larousse API/Define a word.yml [new file with mode: 0644]
collections/larousse API/Translate a word.yml
collections/larousse API/opencollection.yml
src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java [new file with mode: 0644]
src/main/java/net/frustratedfunctor/definitions/WordDefinition.java
src/main/java/net/frustratedfunctor/definitions/WordDefinitionRepository.java
src/main/java/net/frustratedfunctor/definitions/WordDefinitionResource.java
src/main/java/net/frustratedfunctor/definitions/WordDefinitionService.java
src/main/resources/application.properties

diff --git a/collections/larousse API/Define a word.yml b/collections/larousse API/Define a word.yml
new file mode 100644 (file)
index 0000000..bf0eea8
--- /dev/null
@@ -0,0 +1,19 @@
+info:
+  name: Define a word
+  type: http
+  seq: 2
+
+http:
+  method: GET
+  url: "{{api.base_url}}/words/:word/definition"
+  params:
+    - name: word
+      value: chien
+      type: path
+  auth: inherit
+
+settings:
+  encodeUrl: true
+  timeout: 0
+  followRedirects: true
+  maxRedirects: 5
index 18b0b7abe4e76eb28089e9e9975907ff6ab0c9a1..dc7cbf16637903ae4e9606014cd799861b70ed9e 100644 (file)
@@ -5,10 +5,10 @@ info:
 
 http:
   method: GET
-  url: http://localhost:8080/words/:word/translation
+  url: "{{api.base_url}}/words/:word/translation"
   params:
     - name: word
-      value: voiture
+      value: grenouille
       type: path
   auth: inherit
 
index 5cfa09e101aadbd801b5f3a5f57305f4b2b8beec..edae82983683b2ca29ff5ccdc613b51e12d95124 100644 (file)
@@ -2,6 +2,25 @@ opencollection: 1.0.0
 
 info:
   name: larousse API
+config:
+  proxy:
+    inherit: true
+    config:
+      protocol: http
+      hostname: ""
+      port: ""
+      auth:
+        username: ""
+        password: ""
+      bypassProxy: ""
+
+request:
+  variables:
+    - name: api.base_url
+      value: https://lang.frustrated-labs.net
+      disabled: true
+    - name: api.base_url
+      value: http://localhost:8080
 bundled: false
 extensions:
   bruno:
diff --git a/src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java b/src/main/java/net/frustratedfunctor/definitions/JsoupWordDefinitionRepository.java
new file mode 100644 (file)
index 0000000..b1bb296
--- /dev/null
@@ -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 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 definitions", e);
+            return new ArrayList<>();
+        }
+    }
+}
index 178f95de13614c05ce045704c7021f5e9e20e4a4..f59ad8b77c6018f43aac462786a80b2fbf666604 100644 (file)
@@ -1,5 +1,10 @@
 package net.frustratedfunctor.definitions;
 
-public record WordDefinition() {
+import java.util.List;
+
+public record WordDefinition(
+        String word,
+        List<String> definitions
+) {
 }
 
index 226b517abb3f13eaece5c67666bd7f536f95a255..de8dd353cfecc406ef97df3461f2789bf3727973 100644 (file)
@@ -1,4 +1,15 @@
 package net.frustratedfunctor.definitions;
 
+import java.util.List;
+
 public interface WordDefinitionRepository {
+
+    /**
+     * Get a list of definitions for the given word.
+     *
+     * @param word The word to get definitions for.
+     * @return A list of found definitions for the word.
+     */
+    List<String> definitionsForWord(String word);
+
 }
index 2c2410ffb3fa51c87312661e2928c66866bf1561..6f3b78deebe1254aaede217a6c5c4e6ee7bc3582 100644 (file)
@@ -9,11 +9,17 @@ import jakarta.ws.rs.core.MediaType;
 @Path("/words")
 public class WordDefinitionResource {
 
+    private final WordDefinitionService definitions;
+
+    public WordDefinitionResource(WordDefinitionService definitions) {
+        this.definitions = definitions;
+    }
+
     @Path("/{word}/definition")
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public WordDefinition definition(@PathParam("word") String word) {
-        return null;
+        return definitions.define(word);
     }
 
 }
index 32bd003db2f2b0330603323a5a8d75c41a6e3ffd..44696e252798a8b62b2f1c5330c03c083e0f38da 100644 (file)
@@ -4,4 +4,18 @@ import jakarta.enterprise.context.ApplicationScoped;
 
 @ApplicationScoped
 public class WordDefinitionService {
+
+    private final WordDefinitionRepository definitions;
+
+    public WordDefinitionService(WordDefinitionRepository definitions) {
+        this.definitions = definitions;
+    }
+
+    public WordDefinition define(String word) {
+        return new WordDefinition(
+                word,
+                definitions.definitionsForWord(word)
+        );
+    }
+
 }
index 5860cd8384965a50ce1fb7acbc4cebee426a3feb..a2c0b74070c766500f5dd4c8e1eaeda408ffa47f 100644 (file)
@@ -5,6 +5,7 @@ quarkus.docker.buildx.platform=linux/amd64
 quarkus.kubernetes.namespace=default
 quarkus.kubernetes.service-type=node-port
 quarkus.otel.exporter.otlp.endpoint=http://localhost:4317
+%prod.quarkus.otel.exporter.otlp.endpoint=http://otel-collector.default.svc.cluster.local:4317
 quarkus.application.name=larousse-api
 quarkus.otel.simple=true
 %prod.quarkus.otel.simple=false