paginate follow requests (#460)
[akkoma] / lib / pleroma / akkoma / translators / argos_translate.ex
1 defmodule Pleroma.Akkoma.Translators.ArgosTranslate do
2 @behaviour Pleroma.Akkoma.Translator
3
4 alias Pleroma.Config
5
6 defp argos_translate do
7 Config.get([:argos_translate, :command_argos_translate])
8 end
9
10 defp argospm do
11 Config.get([:argos_translate, :command_argospm])
12 end
13
14 defp strip_html? do
15 Config.get([:argos_translate, :strip_html])
16 end
17
18 defp safe_languages() do
19 try do
20 System.cmd(argospm(), ["list"], stderr_to_stdout: true, parallelism: true)
21 rescue
22 _ -> {"Command #{argospm()} not found", 1}
23 end
24 end
25
26 @impl Pleroma.Akkoma.Translator
27 def languages do
28 with {response, 0} <- safe_languages() do
29 langs =
30 response
31 |> String.split("\n", trim: true)
32 |> Enum.map(fn
33 "translate-" <> l -> String.split(l, "_")
34 end)
35
36 source_langs =
37 langs
38 |> Enum.map(fn [l, _] -> %{code: l, name: l} end)
39 |> Enum.uniq()
40
41 dest_langs =
42 langs
43 |> Enum.map(fn [_, l] -> %{code: l, name: l} end)
44 |> Enum.uniq()
45
46 {:ok, source_langs, dest_langs}
47 else
48 {response, _} -> {:error, "ArgosTranslate failed to fetch languages (#{response})"}
49 end
50 end
51
52 defp safe_translate(string, from_language, to_language) do
53 try do
54 System.cmd(
55 argos_translate(),
56 ["--from-lang", from_language, "--to-lang", to_language, string],
57 stderr_to_stdout: true,
58 parallelism: true
59 )
60 rescue
61 _ -> {"Command #{argos_translate()} not found", 1}
62 end
63 end
64
65 defp clean_string(string, true) do
66 string
67 |> String.replace("<p>", "\n")
68 |> String.replace("</p>", "\n")
69 |> String.replace("<br>", "\n")
70 |> String.replace("<br/>", "\n")
71 |> String.replace("<li>", "\n")
72 |> Pleroma.HTML.strip_tags()
73 |> HtmlEntities.decode()
74 end
75
76 defp clean_string(string, _), do: string
77
78 defp htmlify_response(string, true) do
79 string
80 |> HtmlEntities.encode()
81 |> String.replace("\n", "<br/>")
82 end
83
84 defp htmlify_response(string, _), do: string
85
86 @impl Pleroma.Akkoma.Translator
87 def translate(string, nil, to_language) do
88 # Akkoma's Pleroma-fe expects us to detect the source language automatically.
89 # Argos-translate doesn't have that option (yet?)
90 # see <https://github.com/argosopentech/argos-translate/issues/9>
91 # For now we return the text unchanged, supposedly translated from the target language.
92 # Afterwards people get the option to overwrite the source language from a dropdown.
93 {:ok, to_language, string}
94 end
95
96 def translate(string, from_language, to_language) do
97 # Argos Translate doesn't properly translate HTML (yet?)
98 # For now we give admins the option to strip the html before translating
99 # Note that we have to add some html back to the response afterwards
100 string = clean_string(string, strip_html?())
101
102 with {translated, 0} <-
103 safe_translate(string, from_language, to_language) do
104 {:ok, from_language, translated |> htmlify_response(strip_html?())}
105 else
106 {response, _} -> {:error, "ArgosTranslate failed to translate (#{response})"}
107 end
108 end
109 end