From f954f98fb7a1dd2503f5929de7589d43df9d5c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 13 May 2023 13:22:04 +0200 Subject: [PATCH] Implement /api/v1/instance/translation_languages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- lib/pleroma/language/translation.ex | 26 +++++++++++++++++++ lib/pleroma/language/translation/deepl.ex | 11 ++++++++ .../language/translation/libretranslate.ex | 11 ++++++++ lib/pleroma/language/translation/provider.ex | 2 ++ .../api_spec/operations/instance_operation.ex | 23 ++++++++++++++++ .../controllers/instance_controller.ex | 5 ++++ .../web/mastodon_api/views/instance_view.ex | 9 +++++++ lib/pleroma/web/router.ex | 1 + .../controllers/instance_controller_test.exs | 9 +++++++ test/support/translation_mock.ex | 11 +++++++- 10 files changed, 107 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/language/translation.ex b/lib/pleroma/language/translation.ex index 05ab898f3..e4916389d 100644 --- a/lib/pleroma/language/translation.ex +++ b/lib/pleroma/language/translation.ex @@ -63,6 +63,32 @@ defmodule Pleroma.Language.Translation do end end + def languages_matrix do + provider = get_provider() + + cache_key = "languages_matrix/#{provider.name()}" + + case @cachex.get(:translations_cache, cache_key) do + {:ok, nil} -> + result = + if !configured?() do + {:error, :not_found} + else + provider.languages_matrix() + 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 diff --git a/lib/pleroma/language/translation/deepl.ex b/lib/pleroma/language/translation/deepl.ex index 0b56b35d7..4f668fbba 100644 --- a/lib/pleroma/language/translation/deepl.ex +++ b/lib/pleroma/language/translation/deepl.ex @@ -97,6 +97,17 @@ defmodule Pleroma.Language.Translation.Deepl do end end + @impl Provider + def languages_matrix do + with {:ok, source_languages} <- supported_languages(:source), + {:ok, target_languages} <- supported_languages(:target) do + {:ok, + Map.new(source_languages, fn language -> {language, target_languages -- [language]} end)} + else + {:error, error} -> {:error, error} + end + end + @impl Provider def name, do: @name diff --git a/lib/pleroma/language/translation/libretranslate.ex b/lib/pleroma/language/translation/libretranslate.ex index 92bde8772..b793b166e 100644 --- a/lib/pleroma/language/translation/libretranslate.ex +++ b/lib/pleroma/language/translation/libretranslate.ex @@ -67,6 +67,17 @@ defmodule Pleroma.Language.Translation.Libretranslate do end end + @impl Provider + def languages_matrix do + with {:ok, source_languages} <- supported_languages(:source), + {:ok, target_languages} <- supported_languages(:target) do + {:ok, + Map.new(source_languages, fn language -> {language, target_languages -- [language]} end)} + else + {:error, error} -> {:error, error} + end + end + @impl Provider def name, do: @name diff --git a/lib/pleroma/language/translation/provider.ex b/lib/pleroma/language/translation/provider.ex index a8b151fd7..f12cba2cd 100644 --- a/lib/pleroma/language/translation/provider.ex +++ b/lib/pleroma/language/translation/provider.ex @@ -21,5 +21,7 @@ defmodule Pleroma.Language.Translation.Provider do @callback supported_languages(type :: :string | :target) :: {:ok, [String.t()]} | {:error, atom()} + @callback languages_matrix() :: {:ok, Map.t()} | {:error, atom()} + @callback name() :: String.t() end diff --git a/lib/pleroma/web/api_spec/operations/instance_operation.ex b/lib/pleroma/web/api_spec/operations/instance_operation.ex index 708b74b12..30f4c2a97 100644 --- a/lib/pleroma/web/api_spec/operations/instance_operation.ex +++ b/lib/pleroma/web/api_spec/operations/instance_operation.ex @@ -46,6 +46,29 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do } end + def translation_languages_operation do + %Operation{ + tags: ["Instance misc"], + 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, diff --git a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex index 3e664903a..bce64cf6e 100644 --- a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex @@ -24,5 +24,10 @@ defmodule Pleroma.Web.MastodonAPI.InstanceController do @doc "GET /api/v1/instance/peers" 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 + render(conn, "translation_languages.json") end end diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index b6b99c477..096ed00ad 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -84,6 +84,15 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do } end + def render("translation_languages.json", _) do + with true <- Pleroma.Language.Translation.configured?(), + {:ok, languages} <- Pleroma.Language.Translation.languages_matrix() do + languages + else + _ -> %{} + end + end + def features do [ "pleroma_api", diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 5c949fc95..fcf6edfd7 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -760,6 +760,7 @@ defmodule Pleroma.Web.Router do get("/instance", InstanceController, :show) get("/instance/peers", InstanceController, :peers) + get("/instance/translation_languages", InstanceController, :translation_languages) get("/statuses", StatusController, :index) get("/statuses/:id", StatusController, :show) diff --git a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs index 2243b0d4a..8ffcff9f3 100644 --- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs @@ -113,4 +113,13 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do assert get(conn, "/api/v2/instance") |> json_response_and_validate_schema(200) end + + test "translation languages matrix", %{conn: conn} do + clear_config([Pleroma.Language.Translation, :provider], TranslationMock) + + assert %{"en" => ["pl"], "pl" => ["en"]} = + conn + |> get("/api/v1/instance/translation_languages") + |> json_response_and_validate_schema(200) + end end diff --git a/test/support/translation_mock.ex b/test/support/translation_mock.ex index 2047d6426..95da738d1 100644 --- a/test/support/translation_mock.ex +++ b/test/support/translation_mock.ex @@ -24,7 +24,16 @@ defmodule TranslationMock do @impl Provider def supported_languages(_) do - ["en", "pl"] + {:ok, ["en", "pl"]} + end + + @impl Provider + def languages_matrix do + {:ok, + %{ + "en" => ["pl"], + "pl" => ["en"] + }} end @impl Provider