From 33240c86044c92237ea4084fd2c0181728fc70eb 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 05ab898f3e..e4916389dd 100644 --- a/lib/pleroma/language/translation.ex +++ b/lib/pleroma/language/translation.ex @@ -63,6 +63,32 @@ def supported_languages(type) when type in [:source, :target] 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 0b56b35d73..4f668fbba5 100644 --- a/lib/pleroma/language/translation/deepl.ex +++ b/lib/pleroma/language/translation/deepl.ex @@ -97,6 +97,17 @@ def supported_languages(type) when type in [:source, :target] 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 92bde87726..b793b166e0 100644 --- a/lib/pleroma/language/translation/libretranslate.ex +++ b/lib/pleroma/language/translation/libretranslate.ex @@ -67,6 +67,17 @@ def supported_languages(_) 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 a8b151fd7a..f12cba2cde 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 c73628c35d..f58012de66 100644 --- a/lib/pleroma/web/api_spec/operations/instance_operation.ex +++ b/lib/pleroma/web/api_spec/operations/instance_operation.ex @@ -73,6 +73,29 @@ def domain_blocks_operation 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: "Supportede 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 1e1e350c7a..821ced528e 100644 --- a/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/instance_controller.ex @@ -35,4 +35,9 @@ def rules(conn, _params) do def domain_blocks(conn, _params) do render(conn, "domain_blocks.json") 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 2c13954a01..5a220588a2 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -133,6 +133,15 @@ def render("domain_blocks.json", _) do end 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 ce158e230c..21f87cf072 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -833,6 +833,7 @@ defmodule Pleroma.Web.Router do get("/instance/peers", InstanceController, :peers) get("/instance/rules", InstanceController, :rules) get("/instance/domain_blocks", InstanceController, :domain_blocks) + 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 8568ef604c..04e1360569 100644 --- a/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/instance_controller_test.exs @@ -195,4 +195,13 @@ test "instance languages", %{conn: conn} do |> get("/api/v1/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 2047d64261..95da738d10 100644 --- a/test/support/translation_mock.ex +++ b/test/support/translation_mock.ex @@ -24,7 +24,16 @@ def translate(content, source_language, _target_language) 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