Add /api/v1/instance/translation_languages
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
parent
d65758d8f7
commit
b147d2b19d
12 changed files with 118 additions and 35 deletions
|
|
@ -3495,7 +3495,7 @@ config :pleroma, :config_description, [
|
|||
key: :module,
|
||||
type: :module,
|
||||
description: "Translation module.",
|
||||
suggestions: {:list_behaviour_implementations, Pleroma.Akkoma.Translator}
|
||||
suggestions: {:list_behaviour_implementations, Pleroma.Akkoma.Translator.Provider}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
defmodule Pleroma.Akkoma.Translator do
|
||||
@callback translate(String.t(), String.t() | nil, String.t()) ::
|
||||
{:ok, String.t(), String.t()} | {:error, any()}
|
||||
@callback languages() ::
|
||||
{:ok, [%{name: String.t(), code: String.t()}],
|
||||
[%{name: String.t(), code: String.t()}]}
|
||||
| {:error, any()}
|
||||
@callback name() :: String.t()
|
||||
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||
|
||||
def languages do
|
||||
module = Pleroma.Config.get([:translator, :module])
|
||||
|
||||
@cachex.fetch!(:translations_cache, "languages:#{module}}", fn _ ->
|
||||
with {:ok, source_languages, dest_languages} <- module.languages() do
|
||||
{:commit, {:ok, source_languages, dest_languages}}
|
||||
else
|
||||
{:error, err} -> {:ignore, {:error, err}}
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Pleroma.Akkoma.Translators.ArgosTranslate do
|
||||
@behaviour Pleroma.Akkoma.Translator
|
||||
@behaviour Pleroma.Akkoma.Translator.Provider
|
||||
|
||||
alias Pleroma.Config
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ defmodule Pleroma.Akkoma.Translators.ArgosTranslate do
|
|||
end
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def languages do
|
||||
with {response, 0} <- safe_languages() do
|
||||
langs =
|
||||
|
|
@ -83,7 +83,7 @@ defmodule Pleroma.Akkoma.Translators.ArgosTranslate do
|
|||
|
||||
defp htmlify_response(string, _), do: string
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def translate(string, nil, to_language) do
|
||||
# Akkoma's Pleroma-fe expects us to detect the source language automatically.
|
||||
# Argos-translate doesn't have that option (yet?)
|
||||
|
|
@ -107,6 +107,6 @@ defmodule Pleroma.Akkoma.Translators.ArgosTranslate do
|
|||
end
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def name, do: "Argos Translate"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Pleroma.Akkoma.Translators.DeepL do
|
||||
@behaviour Pleroma.Akkoma.Translator
|
||||
@behaviour Pleroma.Akkoma.Translator.Provider
|
||||
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.Config
|
||||
|
|
@ -21,7 +21,7 @@ defmodule Pleroma.Akkoma.Translators.DeepL do
|
|||
Config.get([:deepl, :tier])
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def languages do
|
||||
with {:ok, %{status: 200} = source_response} <- do_languages("source"),
|
||||
{:ok, %{status: 200} = dest_response} <- do_languages("target"),
|
||||
|
|
@ -48,7 +48,7 @@ defmodule Pleroma.Akkoma.Translators.DeepL do
|
|||
end
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def translate(string, from_language, to_language) do
|
||||
with {:ok, %{status: 200} = response} <-
|
||||
do_request(api_key(), tier(), string, from_language, to_language),
|
||||
|
|
@ -98,6 +98,6 @@ defmodule Pleroma.Akkoma.Translators.DeepL do
|
|||
)
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def name, do: "DeepL"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
defmodule Pleroma.Akkoma.Translators.LibreTranslate do
|
||||
@behaviour Pleroma.Akkoma.Translator
|
||||
@behaviour Pleroma.Akkoma.Translator.Provider
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.HTTP
|
||||
|
|
@ -13,7 +13,7 @@ defmodule Pleroma.Akkoma.Translators.LibreTranslate do
|
|||
Config.get([:libre_translate, :url])
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def languages do
|
||||
with {:ok, %{status: 200} = response} <- do_languages(),
|
||||
{:ok, body} <- Jason.decode(response.body) do
|
||||
|
|
@ -30,7 +30,7 @@ defmodule Pleroma.Akkoma.Translators.LibreTranslate do
|
|||
end
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def translate(string, from_language, to_language) do
|
||||
with {:ok, %{status: 200} = response} <- do_request(string, from_language, to_language),
|
||||
{:ok, body} <- Jason.decode(response.body) do
|
||||
|
|
@ -80,6 +80,6 @@ defmodule Pleroma.Akkoma.Translators.LibreTranslate do
|
|||
HTTP.get(to_string(url))
|
||||
end
|
||||
|
||||
@impl Pleroma.Akkoma.Translator
|
||||
@impl Pleroma.Akkoma.Translator.Provider
|
||||
def name, do: "LibreTranslate"
|
||||
end
|
||||
|
|
|
|||
9
lib/pleroma/akkoma/translators/provider.ex
Normal file
9
lib/pleroma/akkoma/translators/provider.ex
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
defmodule Pleroma.Akkoma.Translator.Provider do
|
||||
@callback translate(String.t(), String.t() | nil, String.t()) ::
|
||||
{:ok, String.t(), String.t()} | {:error, any()}
|
||||
@callback languages() ::
|
||||
{:ok, [%{name: String.t(), code: String.t()}],
|
||||
[%{name: String.t(), code: String.t()}]}
|
||||
| {:error, any()}
|
||||
@callback name() :: String.t()
|
||||
end
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
defmodule Pleroma.Web.AkkomaAPI.TranslationController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
alias Pleroma.Akkoma.Translator
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
|
||||
require Logger
|
||||
|
||||
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
|
||||
|
||||
@unauthenticated_access %{fallback: :proceed_unauthenticated, scopes: []}
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
|
|
@ -24,7 +23,7 @@ defmodule Pleroma.Web.AkkomaAPI.TranslationController do
|
|||
@doc "GET /api/v1/akkoma/translation/languages"
|
||||
def languages(conn, _params) do
|
||||
with {:enabled, true} <- {:enabled, Pleroma.Config.get([:translator, :enabled])},
|
||||
{:ok, source_languages, dest_languages} <- get_languages() do
|
||||
{:ok, source_languages, dest_languages} <- Translator.languages() do
|
||||
conn
|
||||
|> json(%{source: source_languages, target: dest_languages})
|
||||
else
|
||||
|
|
@ -36,16 +35,4 @@ defmodule Pleroma.Web.AkkomaAPI.TranslationController do
|
|||
{:error, e}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_languages do
|
||||
module = Pleroma.Config.get([:translator, :module])
|
||||
|
||||
@cachex.fetch!(:translations_cache, "languages:#{module}}", fn _ ->
|
||||
with {:ok, source_languages, dest_languages} <- module.languages() do
|
||||
{:commit, {:ok, source_languages, dest_languages}}
|
||||
else
|
||||
{:error, err} -> {:ignore, {:error, err}}
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -34,6 +34,29 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
|
|||
}
|
||||
end
|
||||
|
||||
def translation_languages_operation do
|
||||
%Operation{
|
||||
tags: ["Instance"],
|
||||
summary: "Retrieve supported languages matrix",
|
||||
operationId: "InstanceController.translation_languages",
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response(
|
||||
"Translation languages matrix",
|
||||
"application/json",
|
||||
%Schema{
|
||||
type: :object,
|
||||
additionalProperties: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string},
|
||||
description: "Supported target languages for a source language"
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp instance do
|
||||
%Schema{
|
||||
type: :object,
|
||||
|
|
|
|||
|
|
@ -20,4 +20,18 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do
|
|||
def peers(conn, _params) do
|
||||
json(conn, Pleroma.Stats.get_peers())
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/instance/translation_languages"
|
||||
def translation_languages(conn, _params) do
|
||||
with {:ok, source_languages, destination_languages} <- Pleroma.Akkoma.Translator.languages() do
|
||||
conn
|
||||
|> render("translation_languages.json", %{
|
||||
source_languages: source_languages,
|
||||
destination_languages: destination_languages
|
||||
})
|
||||
else
|
||||
{:enabled, false} -> json(conn, %{})
|
||||
e -> {:error, e}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -55,6 +55,18 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
}
|
||||
end
|
||||
|
||||
def render("translation_languages.json", %{
|
||||
source_languages: source_languages,
|
||||
destination_languages: destination_languages
|
||||
}) do
|
||||
source_language_codes = Enum.map(source_languages, fn lang -> lang.code end)
|
||||
dest_language_codes = Enum.map(destination_languages, fn lang -> lang.code end)
|
||||
|
||||
Map.new(source_language_codes, fn language ->
|
||||
{language, dest_language_codes -- [language]}
|
||||
end)
|
||||
end
|
||||
|
||||
def features do
|
||||
[
|
||||
"pleroma_api",
|
||||
|
|
|
|||
|
|
@ -668,6 +668,7 @@ defmodule Pleroma.Web.Router do
|
|||
post("/accounts", AccountController, :create)
|
||||
|
||||
get("/instance", InstanceController, :show)
|
||||
get("/instance/translation_languages", InstanceController, :translation_languages)
|
||||
get("/instance/peers", InstanceController, :peers)
|
||||
|
||||
get("/statuses", StatusController, :index)
|
||||
|
|
|
|||
|
|
@ -108,4 +108,35 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
|
|||
|
||||
assert ["peer1.com", "peer2.com"] == Enum.sort(result)
|
||||
end
|
||||
|
||||
test "get translation languages", %{conn: conn} do
|
||||
Tesla.Mock.mock_global(fn
|
||||
%{method: :get, url: "https://api-free.deepl.com/v2/languages?type=source"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
Jason.encode!([
|
||||
%{language: "en", name: "English"}
|
||||
])
|
||||
}
|
||||
|
||||
%{method: :get, url: "https://api-free.deepl.com/v2/languages?type=target"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
Jason.encode!([
|
||||
%{language: "ja", name: "Japanese"}
|
||||
])
|
||||
}
|
||||
end)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> get("/api/v1/instance/translation_languages")
|
||||
|
||||
response = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
assert %{"en" => ["ja"]} = response
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue