logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/
commit: 2b739faa7edc69781eab85da4f122bad05d0576d
parent 066ec8fe955b9ff1e3cf15a76a8f2c4968015213
Author: marcin mikołajczak <git@mkljczk.pl>
Date:   Mon, 31 Oct 2022 21:58:10 +0100

Rename

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>

Diffstat:

Mconfig/description.exs17++++++++++-------
Alib/pleroma/language/translation.ex53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Alib/pleroma/language/translation/deepl.ex75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alib/pleroma/language/translation/libretranslate.ex66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alib/pleroma/language/translation/provider.ex20++++++++++++++++++++
Dlib/pleroma/translation.ex53-----------------------------------------------------
Dlib/pleroma/translation/deepl.ex75---------------------------------------------------------------------------
Dlib/pleroma/translation/libretranslate.ex66------------------------------------------------------------------
Dlib/pleroma/translation/service.ex20--------------------
Mlib/pleroma/web/mastodon_api/controllers/status_controller.ex2+-
Mlib/pleroma/web/mastodon_api/views/instance_view.ex4++--
Atest/pleroma/language/translation_test.ex29+++++++++++++++++++++++++++++
Dtest/pleroma/translation_test.ex29-----------------------------
Mtest/pleroma/web/mastodon_api/controllers/status_controller_test.exs2+-
Mtest/support/translation_mock.ex8++++----
15 files changed, 261 insertions(+), 258 deletions(-)

diff --git a/config/description.exs b/config/description.exs @@ -3526,38 +3526,41 @@ config :pleroma, :config_description, [ }, %{ group: :pleroma, - key: Pleroma.Translation, + key: Pleroma.Language.Translation, type: :group, description: "Translation providers", children: [ %{ - key: :service, + key: :provider, type: :module, - suggestions: [Pleroma.Translation.Deepl, Pleroma.Translation.Libretranslate] + suggestions: [ + Pleroma.Language.Translation.Deepl, + Pleroma.Language.Translation.Libretranslate + ] }, %{ - group: {:subgroup, Pleroma.Translation.Deepl}, + group: {:subgroup, Pleroma.Language.Translation.Deepl}, key: :plan, label: "DeepL plan", type: {:dropdown, :atom}, suggestions: [:free, :pro] }, %{ - group: {:subgroup, Pleroma.Translation.Deepl}, + group: {:subgroup, Pleroma.Language.Translation.Deepl}, key: :api_key, label: "DeepL API Key", type: :string, suggestions: ["YOUR_API_KEY"] }, %{ - group: {:subgroup, Pleroma.Translation.Libretranslate}, + group: {:subgroup, Pleroma.Language.Translation.Libretranslate}, key: :base_url, label: "LibreTranslate plan", type: :string, suggestions: ["https://libretranslate.com"] }, %{ - group: {:subgroup, Pleroma.Translation.Libretranslate}, + group: {:subgroup, Pleroma.Language.Translation.Libretranslate}, key: :api_key, label: "LibreTranslate API Key", type: :string, diff --git a/lib/pleroma/language/translation.ex b/lib/pleroma/language/translation.ex @@ -0,0 +1,53 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Language.Translation do + @cachex Pleroma.Config.get([:cachex, :provider], Cachex) + + def configured? do + service = get_service() + + !!service and service.configured? + end + + def translate(text, source_language, target_language) do + cache_key = get_cache_key(text, source_language, target_language) + + case @cachex.get(:translations_cache, cache_key) do + {:ok, nil} -> + service = get_service() + + result = + if !service or !service.configured? do + {:error, :not_found} + else + service.translate(text, source_language, target_language) + end + + store_result(result, cache_key) + + result + + {:ok, result} -> + {:ok, result} + + {:error, error} -> + {:error, error} + end + end + + defp get_service, do: Pleroma.Config.get([__MODULE__, :provider]) + + defp get_cache_key(text, source_language, target_language) do + "#{source_language}/#{target_language}/#{content_hash(text)}" + end + + defp store_result({:ok, result}, cache_key) do + @cachex.put(:translations_cache, cache_key, result) + end + + defp store_result(_, _), do: nil + + defp content_hash(text), do: :crypto.hash(:sha256, text) |> Base.encode64() +end diff --git a/lib/pleroma/language/translation/deepl.ex b/lib/pleroma/language/translation/deepl.ex @@ -0,0 +1,75 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Language.Translation.Deepl do + import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1] + + alias Pleroma.Language.Translation.Provider + + @behaviour Provider + + @impl Provider + def configured? do + not_empty_string(get_plan()) and not_empty_string(get_api_key()) + end + + @impl Provider + def translate(content, source_language, target_language) do + endpoint = endpoint_url() + + case Pleroma.HTTP.post( + endpoint <> + "?" <> + URI.encode_query(%{ + text: content, + source_lang: source_language |> String.upcase(), + target_lang: target_language, + tag_handling: "html" + }), + "", + [ + {"Content-Type", "application/x-www-form-urlencoded"}, + {"Authorization", "DeepL-Auth-Key #{get_api_key()}"} + ] + ) do + {:ok, %{status: 429}} -> + {:error, :too_many_requests} + + {:ok, %{status: 456}} -> + {:error, :quota_exceeded} + + {:ok, %{status: 200} = res} -> + %{ + "translations" => [ + %{"text" => content, "detected_source_language" => detected_source_language} + ] + } = Jason.decode!(res.body) + + {:ok, + %{ + content: content, + detected_source_language: detected_source_language, + provider: "DeepL" + }} + + _ -> + {:error, :internal_server_error} + end + end + + defp endpoint_url do + case get_plan() do + :free -> "https://api-free.deepl.com/v2/translate" + _ -> "https://api.deepl.com/v2/translate" + end + end + + defp get_plan do + Pleroma.Config.get([__MODULE__, :plan]) + end + + defp get_api_key do + Pleroma.Config.get([__MODULE__, :api_key]) + end +end diff --git a/lib/pleroma/language/translation/libretranslate.ex b/lib/pleroma/language/translation/libretranslate.ex @@ -0,0 +1,66 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Language.Translation.Libretranslate do + import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1] + + alias Pleroma.Language.Translation.Provider + + @behaviour Provider + + @impl Provider + def configured?, do: not_empty_string(get_base_url()) + + @impl Provider + def translate(content, source_language, target_language) do + endpoint = endpoint_url() + + case Pleroma.HTTP.post( + endpoint, + Jason.encode!(%{ + q: content, + source: source_language |> String.upcase(), + target: target_language, + format: "html", + api_key: get_api_key() + }), + [ + {"Content-Type", "application/json"} + ] + ) do + {:ok, %{status: 429}} -> + {:error, :too_many_requests} + + {:ok, %{status: 403}} -> + {:error, :quota_exceeded} + + {:ok, %{status: 200} = res} -> + %{ + "translatedText" => content + } = Jason.decode!(res.body) + + {:ok, + %{ + content: content, + detected_source_language: source_language, + provider: "LibreTranslate" + }} + + _ -> + {:error, :internal_server_error} + end + end + + defp endpoint_url do + get_base_url() <> "/translate" + end + + defp get_base_url do + Pleroma.Config.get([__MODULE__, :base_url]) + end + + defp get_api_key do + Pleroma.Config.get([__MODULE__, :api_key], "") + end +end diff --git a/lib/pleroma/language/translation/provider.ex b/lib/pleroma/language/translation/provider.ex @@ -0,0 +1,20 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Language.Translation.Provider do + @callback configured?() :: boolean() + + @callback translate( + content :: String.t(), + source_language :: String.t(), + target_language :: String.t() + ) :: + {:ok, + %{ + content: String.t(), + detected_source_language: String.t(), + provider: String.t() + }} + | {:error, atom()} +end diff --git a/lib/pleroma/translation.ex b/lib/pleroma/translation.ex @@ -1,53 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Translation do - @cachex Pleroma.Config.get([:cachex, :provider], Cachex) - - def configured? do - service = get_service() - - !!service and service.configured? - end - - def translate(text, source_language, target_language) do - cache_key = get_cache_key(text, source_language, target_language) - - case @cachex.get(:translations_cache, cache_key) do - {:ok, nil} -> - service = get_service() - - result = - if !service or !service.configured? do - {:error, :not_found} - else - service.translate(text, source_language, target_language) - end - - store_result(result, cache_key) - - result - - {:ok, result} -> - {:ok, result} - - {:error, error} -> - {:error, error} - end - end - - defp get_service, do: Pleroma.Config.get([__MODULE__, :service]) - - defp get_cache_key(text, source_language, target_language) do - "#{source_language}/#{target_language}/#{content_hash(text)}" - end - - defp store_result({:ok, result}, cache_key) do - @cachex.put(:translations_cache, cache_key, result) - end - - defp store_result(_, _), do: nil - - defp content_hash(text), do: :crypto.hash(:sha256, text) |> Base.encode64() -end diff --git a/lib/pleroma/translation/deepl.ex b/lib/pleroma/translation/deepl.ex @@ -1,75 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Translation.Deepl do - import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1] - - alias Pleroma.Translation.Service - - @behaviour Service - - @impl Service - def configured? do - not_empty_string(get_plan()) and not_empty_string(get_api_key()) - end - - @impl Service - def translate(content, source_language, target_language) do - endpoint = endpoint_url() - - case Pleroma.HTTP.post( - endpoint <> - "?" <> - URI.encode_query(%{ - text: content, - source_lang: source_language |> String.upcase(), - target_lang: target_language, - tag_handling: "html" - }), - "", - [ - {"Content-Type", "application/x-www-form-urlencoded"}, - {"Authorization", "DeepL-Auth-Key #{get_api_key()}"} - ] - ) do - {:ok, %{status: 429}} -> - {:error, :too_many_requests} - - {:ok, %{status: 456}} -> - {:error, :quota_exceeded} - - {:ok, %{status: 200} = res} -> - %{ - "translations" => [ - %{"text" => content, "detected_source_language" => detected_source_language} - ] - } = Jason.decode!(res.body) - - {:ok, - %{ - content: content, - detected_source_language: detected_source_language, - provider: "DeepL" - }} - - _ -> - {:error, :internal_server_error} - end - end - - defp endpoint_url do - case get_plan() do - :free -> "https://api-free.deepl.com/v2/translate" - _ -> "https://api.deepl.com/v2/translate" - end - end - - defp get_plan do - Pleroma.Config.get([__MODULE__, :plan]) - end - - defp get_api_key do - Pleroma.Config.get([__MODULE__, :api_key]) - end -end diff --git a/lib/pleroma/translation/libretranslate.ex b/lib/pleroma/translation/libretranslate.ex @@ -1,66 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Translation.Libretranslate do - import Pleroma.Web.Utils.Guards, only: [not_empty_string: 1] - - alias Pleroma.Translation.Service - - @behaviour Service - - @impl Service - def configured?, do: not_empty_string(get_base_url()) - - @impl Service - def translate(content, source_language, target_language) do - endpoint = endpoint_url() - - case Pleroma.HTTP.post( - endpoint, - Jason.encode!(%{ - q: content, - source: source_language |> String.upcase(), - target: target_language, - format: "html", - api_key: get_api_key() - }), - [ - {"Content-Type", "application/json"} - ] - ) do - {:ok, %{status: 429}} -> - {:error, :too_many_requests} - - {:ok, %{status: 403}} -> - {:error, :quota_exceeded} - - {:ok, %{status: 200} = res} -> - %{ - "translatedText" => content - } = Jason.decode!(res.body) - - {:ok, - %{ - content: content, - detected_source_language: source_language, - provider: "LibreTranslate" - }} - - _ -> - {:error, :internal_server_error} - end - end - - defp endpoint_url do - get_base_url() <> "/translate" - end - - defp get_base_url do - Pleroma.Config.get([__MODULE__, :base_url]) - end - - defp get_api_key do - Pleroma.Config.get([__MODULE__, :api_key], "") - end -end diff --git a/lib/pleroma/translation/service.ex b/lib/pleroma/translation/service.ex @@ -1,20 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Translation.Service do - @callback configured?() :: boolean() - - @callback translate( - content :: String.t(), - source_language :: String.t(), - target_language :: String.t() - ) :: - {:ok, - %{ - content: String.t(), - detected_source_language: String.t(), - provider: String.t() - }} - | {:error, atom()} -end diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -12,10 +12,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do alias Pleroma.Activity alias Pleroma.Bookmark + alias Pleroma.Language.Translation alias Pleroma.Object alias Pleroma.Repo alias Pleroma.ScheduledActivity - alias Pleroma.Translation alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Visibility diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -130,7 +130,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do end, "pleroma:get:main/ostatus", "pleroma:group_actors", - if Pleroma.Translation.configured?() do + if Pleroma.Language.Translation.configured?() do "translation" end ] @@ -206,7 +206,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do vapid: %{ public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key) }, - translation: %{enabled: Pleroma.Translation.configured?()} + translation: %{enabled: Pleroma.Language.Translation.configured?()} }) end diff --git a/test/pleroma/language/translation_test.ex b/test/pleroma/language/translation_test.ex @@ -0,0 +1,29 @@ +defmodule Pleroma.Language.TranslationTest do + use Pleroma.Web.ConnCase + + alias Pleroma.Language.Translation + # use Oban.Testing, repo: Pleroma.Repo + + setup do: clear_config([Pleroma.Language.Translation, :provider], TranslationMock) + + test "it translates text" do + assert {:ok, + %{ + content: "txet emos", + detected_source_language: _, + provider: _ + }} = Translation.translate("some text", "en", "uk") + end + + test "it stores translation result in cache" do + Translation.translate("some text", "en", "uk") + + assert {:ok, result} = + Cachex.get( + :translations_cache, + "en/uk/#{:crypto.hash(:sha256, "some text") |> Base.encode64()}" + ) + + assert result.content == "txet emos" + end +end diff --git a/test/pleroma/translation_test.ex b/test/pleroma/translation_test.ex @@ -1,29 +0,0 @@ -defmodule Pleroma.TranslationTest do - use Pleroma.Web.ConnCase - - alias Pleroma.Translation - # use Oban.Testing, repo: Pleroma.Repo - - setup do: clear_config([Pleroma.Translation, :service], TranslationMock) - - test "it translates text" do - assert {:ok, - %{ - content: "txet emos", - detected_source_language: _, - provider: _ - }} = Translation.translate("some text", "en", "uk") - end - - test "it stores translation result in cache" do - Translation.translate("some text", "en", "uk") - - assert {:ok, result} = - Cachex.get( - :translations_cache, - "en/uk/#{:crypto.hash(:sha256, "some text") |> Base.encode64()}" - ) - - assert result.content == "txet emos" - end -end diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -2552,7 +2552,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end describe "translating statuses" do - setup do: clear_config([Pleroma.Translation, :service], TranslationMock) + setup do: clear_config([Pleroma.Language.Translation, :provider], TranslationMock) test "it translates a status to user language" do user = insert(:user, language: "fr") diff --git a/test/support/translation_mock.ex b/test/support/translation_mock.ex @@ -3,14 +3,14 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule TranslationMock do - alias Pleroma.Translation.Service + alias Pleroma.Language.Translation.Provider - @behaviour Service + @behaviour Provider - @impl Service + @impl Provider def configured?, do: true - @impl Service + @impl Provider def translate(content, source_language, _target_language) do {:ok, %{