Allow listing languages, setting source language (#192)
[akkoma] / lib / pleroma / akkoma / translators / deepl.ex
index 0a4a7fe1090b131f8990307faf3e36642d9c138c..f93fb7e59faa4a3d7c4e438067a866b63fe2e2dd 100644 (file)
@@ -22,8 +22,27 @@ defmodule Pleroma.Akkoma.Translators.DeepL do
   end
 
   @impl Pleroma.Akkoma.Translator
-  def translate(string, to_language) do
-    with {:ok, %{status: 200} = response} <- do_request(api_key(), tier(), string, to_language),
+  def languages do
+    with {:ok, %{status: 200} = response} <- do_languages(),
+         {:ok, body} <- Jason.decode(response.body) do
+      resp =
+        Enum.map(body, fn %{"language" => code, "name" => name} -> %{code: code, name: name} end)
+
+      {:ok, resp}
+    else
+      {:ok, %{status: status} = response} ->
+        Logger.warning("DeepL: Request rejected: #{inspect(response)}")
+        {:error, "DeepL request failed (code #{status})"}
+
+      {:error, reason} ->
+        {:error, reason}
+    end
+  end
+
+  @impl Pleroma.Akkoma.Translator
+  def translate(string, from_language, to_language) do
+    with {:ok, %{status: 200} = response} <-
+           do_request(api_key(), tier(), string, from_language, to_language),
          {:ok, body} <- Jason.decode(response.body) do
       %{"translations" => [%{"text" => translated, "detected_source_language" => detected}]} =
         body
@@ -39,14 +58,16 @@ defmodule Pleroma.Akkoma.Translators.DeepL do
     end
   end
 
-  defp do_request(api_key, tier, string, to_language) do
+  defp do_request(api_key, tier, string, from_language, to_language) do
     HTTP.post(
       base_url(tier) <> "translate",
       URI.encode_query(
         %{
           text: string,
-          target_lang: to_language
-        },
+          target_lang: to_language,
+          tag_handling: "html"
+        }
+        |> maybe_add_source(from_language),
         :rfc3986
       ),
       [
@@ -55,4 +76,16 @@ defmodule Pleroma.Akkoma.Translators.DeepL do
       ]
     )
   end
+
+  defp maybe_add_source(opts, nil), do: opts
+  defp maybe_add_source(opts, lang), do: Map.put(opts, :source_lang, lang)
+
+  defp do_languages() do
+    HTTP.get(
+      base_url(tier()) <> "languages?type=target",
+      [
+        {"authorization", "DeepL-Auth-Key #{api_key()}"}
+      ]
+    )
+  end
 end