forked from AkkomaGang/akkoma
floatingghost
decbca0c91
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk> Reviewed-on: AkkomaGang/akkoma#193
100 lines
2.7 KiB
Elixir
100 lines
2.7 KiB
Elixir
defmodule Pleroma.Akkoma.Translators.DeepL do
|
|
@behaviour Pleroma.Akkoma.Translator
|
|
|
|
alias Pleroma.HTTP
|
|
alias Pleroma.Config
|
|
require Logger
|
|
|
|
defp base_url(:free) do
|
|
"https://api-free.deepl.com/v2/"
|
|
end
|
|
|
|
defp base_url(:pro) do
|
|
"https://api.deepl.com/v2/"
|
|
end
|
|
|
|
defp api_key do
|
|
Config.get([:deepl, :api_key])
|
|
end
|
|
|
|
defp tier do
|
|
Config.get([:deepl, :tier])
|
|
end
|
|
|
|
@impl Pleroma.Akkoma.Translator
|
|
def languages do
|
|
with {:ok, %{status: 200} = source_response} <- do_languages("source"),
|
|
{:ok, %{status: 200} = dest_response} <- do_languages("target"),
|
|
{:ok, source_body} <- Jason.decode(source_response.body),
|
|
{:ok, dest_body} <- Jason.decode(dest_response.body) do
|
|
source_resp =
|
|
Enum.map(source_body, fn %{"language" => code, "name" => name} ->
|
|
%{code: code, name: name}
|
|
end)
|
|
|
|
dest_resp =
|
|
Enum.map(dest_body, fn %{"language" => code, "name" => name} ->
|
|
%{code: code, name: name}
|
|
end)
|
|
|
|
{:ok, source_resp, dest_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
|
|
|
|
{:ok, detected, translated}
|
|
else
|
|
{:ok, %{status: status} = response} ->
|
|
Logger.warning("DeepL: Request rejected: #{inspect(response)}")
|
|
{:error, "DeepL request failed (code #{status})"}
|
|
|
|
{:error, reason} ->
|
|
{:error, reason}
|
|
end
|
|
end
|
|
|
|
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,
|
|
tag_handling: "html"
|
|
}
|
|
|> maybe_add_source(from_language),
|
|
:rfc3986
|
|
),
|
|
[
|
|
{"authorization", "DeepL-Auth-Key #{api_key}"},
|
|
{"content-type", "application/x-www-form-urlencoded"}
|
|
]
|
|
)
|
|
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(type) do
|
|
HTTP.get(
|
|
base_url(tier()) <> "languages?type=#{type}",
|
|
[
|
|
{"authorization", "DeepL-Auth-Key #{api_key()}"}
|
|
]
|
|
)
|
|
end
|
|
end
|