Add supported languages list to /api/v2/instance
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
28c8948765
commit
1553b651dc
9 changed files with 148 additions and 23 deletions
|
@ -37,6 +37,32 @@ def translate(text, source_language, target_language) do
|
|||
end
|
||||
end
|
||||
|
||||
def supported_languages(type) when type in [:source, :target] do
|
||||
provider = get_provider()
|
||||
|
||||
cache_key = "#{type}_languages/#{provider.name()}"
|
||||
|
||||
case @cachex.get(:translations_cache, cache_key) do
|
||||
{:ok, nil} ->
|
||||
result =
|
||||
if !configured?() do
|
||||
{:error, :not_found}
|
||||
else
|
||||
provider.supported_languages(type)
|
||||
end
|
||||
|
||||
store_result(result, cache_key)
|
||||
|
||||
result
|
||||
|
||||
{:ok, result} ->
|
||||
{:ok, result}
|
||||
|
||||
{:error, error} ->
|
||||
{:error, error}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_provider, do: Pleroma.Config.get([__MODULE__, :provider])
|
||||
|
||||
defp get_cache_key(text, source_language, target_language) do
|
||||
|
|
|
@ -9,14 +9,17 @@ defmodule Pleroma.Language.Translation.Deepl do
|
|||
|
||||
@behaviour Provider
|
||||
|
||||
@name "DeepL"
|
||||
|
||||
@impl Provider
|
||||
def configured? do
|
||||
not_empty_string(get_base_url()) and not_empty_string(get_api_key())
|
||||
end
|
||||
def configured?, do: not_empty_string(base_url()) and not_empty_string(api_key())
|
||||
|
||||
@impl Provider
|
||||
def translate(content, source_language, target_language) do
|
||||
endpoint = get_endpoint()
|
||||
endpoint =
|
||||
base_url()
|
||||
|> URI.merge("/v2/translate")
|
||||
|> URI.to_string()
|
||||
|
||||
case Pleroma.HTTP.post(
|
||||
endpoint <>
|
||||
|
@ -30,7 +33,7 @@ def translate(content, source_language, target_language) do
|
|||
"",
|
||||
[
|
||||
{"Content-Type", "application/x-www-form-urlencoded"},
|
||||
{"Authorization", "DeepL-Auth-Key #{get_api_key()}"}
|
||||
{"Authorization", "DeepL-Auth-Key #{api_key()}"}
|
||||
]
|
||||
) do
|
||||
{:ok, %{status: 429}} ->
|
||||
|
@ -50,7 +53,7 @@ def translate(content, source_language, target_language) do
|
|||
%{
|
||||
content: content,
|
||||
detected_source_language: detected_source_language,
|
||||
provider: "DeepL"
|
||||
provider: @name
|
||||
}}
|
||||
|
||||
_ ->
|
||||
|
@ -58,17 +61,42 @@ def translate(content, source_language, target_language) do
|
|||
end
|
||||
end
|
||||
|
||||
defp get_endpoint do
|
||||
get_base_url()
|
||||
|> URI.merge("/v2/translate")
|
||||
|> URI.to_string()
|
||||
@impl Provider
|
||||
def supported_languages(type) when type in [:source, :target] do
|
||||
endpoint =
|
||||
base_url()
|
||||
|> URI.merge("/v2/languages")
|
||||
|> URI.to_string()
|
||||
|
||||
case Pleroma.HTTP.post(
|
||||
endpoint <> "?" <> URI.encode_query(%{type: type}),
|
||||
"",
|
||||
[
|
||||
{"Content-Type", "application/x-www-form-urlencoded"},
|
||||
{"Authorization", "DeepL-Auth-Key #{api_key()}"}
|
||||
]
|
||||
) do
|
||||
{:ok, %{status: 200} = res} ->
|
||||
IO.inspect(res.body)
|
||||
languages =
|
||||
Jason.decode!(res.body)
|
||||
|> Enum.map(fn %{"language" => language} -> language |> String.downcase() end)
|
||||
|
||||
{:ok, languages}
|
||||
|
||||
_ ->
|
||||
{:error, :internal_server_error}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_base_url do
|
||||
@impl Provider
|
||||
def name, do: @name
|
||||
|
||||
defp base_url do
|
||||
Pleroma.Config.get([__MODULE__, :base_url])
|
||||
end
|
||||
|
||||
defp get_api_key do
|
||||
defp api_key do
|
||||
Pleroma.Config.get([__MODULE__, :api_key])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,21 +9,21 @@ defmodule Pleroma.Language.Translation.Libretranslate do
|
|||
|
||||
@behaviour Provider
|
||||
|
||||
@name "LibreTranslate"
|
||||
|
||||
@impl Provider
|
||||
def configured?, do: not_empty_string(get_base_url())
|
||||
def configured?, do: not_empty_string(base_url()) and not_empty_string(api_key())
|
||||
|
||||
@impl Provider
|
||||
def translate(content, source_language, target_language) do
|
||||
endpoint = endpoint_url()
|
||||
|
||||
case Pleroma.HTTP.post(
|
||||
endpoint,
|
||||
base_url() <> "/translate",
|
||||
Jason.encode!(%{
|
||||
q: content,
|
||||
source: source_language |> String.upcase(),
|
||||
target: target_language,
|
||||
format: "html",
|
||||
api_key: get_api_key()
|
||||
api_key: api_key()
|
||||
}),
|
||||
[
|
||||
{"Content-Type", "application/json"}
|
||||
|
@ -52,15 +52,29 @@ def translate(content, source_language, target_language) do
|
|||
end
|
||||
end
|
||||
|
||||
defp endpoint_url do
|
||||
get_base_url() <> "/translate"
|
||||
@impl Provider
|
||||
def supported_languages(_) do
|
||||
case Pleroma.HTTP.get(base_url() <> "/languages") do
|
||||
{:ok, %{status: 200} = res} ->
|
||||
languages =
|
||||
Jason.decode!(res.body)
|
||||
|> Enum.map(fn %{"code" => code} -> code end)
|
||||
|
||||
{:ok, languages}
|
||||
|
||||
_ ->
|
||||
{:error, :internal_server_error}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_base_url do
|
||||
@impl Provider
|
||||
def name, do: @name
|
||||
|
||||
defp base_url do
|
||||
Pleroma.Config.get([__MODULE__, :base_url])
|
||||
end
|
||||
|
||||
defp get_api_key do
|
||||
defp api_key do
|
||||
Pleroma.Config.get([__MODULE__, :api_key], "")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,4 +17,9 @@ defmodule Pleroma.Language.Translation.Provider do
|
|||
provider: String.t()
|
||||
}}
|
||||
| {:error, atom()}
|
||||
|
||||
@callback supported_languages(type :: :string | :target) ::
|
||||
{:ok, [String.t()]} | {:error, atom()}
|
||||
|
||||
@callback name() :: String.t()
|
||||
end
|
||||
|
|
|
@ -204,10 +204,32 @@ def configuration2 do
|
|||
configuration()
|
||||
|> Map.merge(%{
|
||||
urls: %{streaming: Pleroma.Web.Endpoint.websocket_url()},
|
||||
translation: %{enabled: Pleroma.Language.Translation.configured?()}
|
||||
translation: translation_config()
|
||||
})
|
||||
end
|
||||
|
||||
defp translation_config do
|
||||
enabled = Pleroma.Language.Translation.configured?()
|
||||
|
||||
source_languages =
|
||||
case Pleroma.Language.Translation.supported_languages(:source) do
|
||||
{:ok, languages} -> languages
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
target_languages =
|
||||
case Pleroma.Language.Translation.supported_languages(:target) do
|
||||
{:ok, languages} -> languages
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
%{
|
||||
enabled: enabled,
|
||||
source_languages: source_languages,
|
||||
target_languages: target_languages
|
||||
}
|
||||
end
|
||||
|
||||
defp pleroma_configuration(instance) do
|
||||
%{
|
||||
metadata: %{
|
||||
|
|
1
test/fixtures/tesla_mock/deepl-languages-list.json
vendored
Normal file
1
test/fixtures/tesla_mock/deepl-languages-list.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
[{"language":"BG","name":"Bulgarian","supports_formality":false},{"language":"CS","name":"Czech","supports_formality":false},{"language":"DA","name":"Danish","supports_formality":false},{"language":"DE","name":"German","supports_formality":true},{"language":"EL","name":"Greek","supports_formality":false},{"language":"EN-GB","name":"English (British)","supports_formality":false},{"language":"EN-US","name":"English (American)","supports_formality":false},{"language":"ES","name":"Spanish","supports_formality":true},{"language":"ET","name":"Estonian","supports_formality":false},{"language":"FI","name":"Finnish","supports_formality":false},{"language":"FR","name":"French","supports_formality":true},{"language":"HU","name":"Hungarian","supports_formality":false},{"language":"ID","name":"Indonesian","supports_formality":false},{"language":"IT","name":"Italian","supports_formality":true},{"language":"JA","name":"Japanese","supports_formality":false},{"language":"LT","name":"Lithuanian","supports_formality":false},{"language":"LV","name":"Latvian","supports_formality":false},{"language":"NL","name":"Dutch","supports_formality":true},{"language":"PL","name":"Polish","supports_formality":true},{"language":"PT-BR","name":"Portuguese (Brazilian)","supports_formality":true},{"language":"PT-PT","name":"Portuguese (European)","supports_formality":true},{"language":"RO","name":"Romanian","supports_formality":false},{"language":"RU","name":"Russian","supports_formality":true},{"language":"SK","name":"Slovak","supports_formality":false},{"language":"SL","name":"Slovenian","supports_formality":false},{"language":"SV","name":"Swedish","supports_formality":false},{"language":"TR","name":"Turkish","supports_formality":false},{"language":"UK","name":"Ukrainian","supports_formality":false},{"language":"ZH","name":"Chinese (simplified)","supports_formality":false}]
|
|
@ -24,4 +24,14 @@ test "it translates text" do
|
|||
provider: "DeepL"
|
||||
} = res
|
||||
end
|
||||
|
||||
test "it returns languages list" do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
clear_config([Pleroma.Language.Translation.Deepl, :base_url], "https://api-free.deepl.com")
|
||||
clear_config([Pleroma.Language.Translation.Deepl, :api_key], "API_KEY")
|
||||
|
||||
assert {:ok, [language | _languages]} = Deepl.supported_languages(:target)
|
||||
|
||||
assert is_binary(language)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1569,6 +1569,15 @@ def post("https://api-free.deepl.com/v2/translate" <> _, _, _, _) do
|
|||
}}
|
||||
end
|
||||
|
||||
def post("https://api-free.deepl.com/v2/languages" <> _, _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/deepl-languages-list.json"),
|
||||
headers: [{"content-type", "application/json"}]
|
||||
}}
|
||||
end
|
||||
|
||||
def post(url, query, body, headers) do
|
||||
{:error,
|
||||
"Mock response not implemented for POST #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
|
||||
|
|
|
@ -7,6 +7,8 @@ defmodule TranslationMock do
|
|||
|
||||
@behaviour Provider
|
||||
|
||||
@name "TranslationMock"
|
||||
|
||||
@impl Provider
|
||||
def configured?, do: true
|
||||
|
||||
|
@ -16,7 +18,15 @@ def translate(content, source_language, _target_language) do
|
|||
%{
|
||||
content: content |> String.reverse(),
|
||||
detected_source_language: source_language,
|
||||
provider: "TranslationMock"
|
||||
provider: @name
|
||||
}}
|
||||
end
|
||||
|
||||
@impl Provider
|
||||
def supported_languages(_) do
|
||||
["en", "pl"]
|
||||
end
|
||||
|
||||
@impl Provider
|
||||
def name, do: @name
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue