Allow listing languages, setting source language (#192)
[akkoma] / lib / pleroma / akkoma / translators / libre_translate.ex
1 defmodule Pleroma.Akkoma.Translators.LibreTranslate do
2 @behaviour Pleroma.Akkoma.Translator
3
4 alias Pleroma.Config
5 alias Pleroma.HTTP
6 require Logger
7
8 defp api_key do
9 Config.get([:libre_translate, :api_key])
10 end
11
12 defp url do
13 Config.get([:libre_translate, :url])
14 end
15
16 @impl Pleroma.Akkoma.Translator
17 def languages do
18 with {:ok, %{status: 200} = response} <- do_languages(),
19 {:ok, body} <- Jason.decode(response.body) do
20 resp = Enum.map(body, fn %{"code" => code, "name" => name} -> %{code: code, name: name} end)
21 {:ok, resp}
22 else
23 {:ok, %{status: status} = response} ->
24 Logger.warning("LibreTranslate: Request rejected: #{inspect(response)}")
25 {:error, "LibreTranslate request failed (code #{status})"}
26
27 {:error, reason} ->
28 {:error, reason}
29 end
30 end
31
32 @impl Pleroma.Akkoma.Translator
33 def translate(string, from_language, to_language) do
34 with {:ok, %{status: 200} = response} <- do_request(string, from_language, to_language),
35 {:ok, body} <- Jason.decode(response.body) do
36 %{"translatedText" => translated} = body
37
38 detected =
39 if Map.has_key?(body, "detectedLanguage") do
40 get_in(body, ["detectedLanguage", "language"])
41 else
42 from_language
43 end
44
45 {:ok, detected, translated}
46 else
47 {:ok, %{status: status} = response} ->
48 Logger.warning("libre_translate: request failed, #{inspect(response)}")
49 {:error, "libre_translate: request failed (code #{status})"}
50
51 {:error, reason} ->
52 {:error, reason}
53 end
54 end
55
56 defp do_request(string, from_language, to_language) do
57 url = URI.parse(url())
58 url = %{url | path: "/translate"}
59
60 HTTP.post(
61 to_string(url),
62 Jason.encode!(%{
63 q: string,
64 source: if(is_nil(from_language), do: "auto", else: from_language),
65 target: to_language,
66 format: "html",
67 api_key: api_key()
68 }),
69 [
70 {"content-type", "application/json"}
71 ]
72 )
73 end
74
75 defp do_languages() do
76 url = URI.parse(url())
77 url = %{url | path: "/languages"}
78
79 HTTP.get(to_string(url))
80 end
81 end