From 557a7d736a873bf57c3e3e271669c0815fd6fe28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sun, 30 Oct 2022 18:47:41 +0100 Subject: [PATCH] WIP Translation backends support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- lib/pleroma/application.ex | 3 +- .../api_spec/operations/status_operation.ex | 60 +++++++++++++++++++ .../controllers/status_controller.ex | 29 ++++++++- .../web/mastodon_api/views/status_view.ex | 8 +++ lib/pleroma/web/router.ex | 1 + 5 files changed, 99 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index de668052f..921384be9 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -182,7 +182,8 @@ defmodule Pleroma.Application do expiration: chat_message_id_idempotency_key_expiration(), limit: 500_000 ), - build_cachex("rel_me", limit: 2500) + build_cachex("rel_me", limit: 2500), + build_cachex("translations", default_ttl: :timer.hours(24), limit: 5_000) ] end diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex index ef4e34044..961a2f402 100644 --- a/lib/pleroma/web/api_spec/operations/status_operation.ex +++ b/lib/pleroma/web/api_spec/operations/status_operation.ex @@ -409,6 +409,38 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do } end + def translate_operation do + %Operation{ + tags: ["Retrieve status information"], + summary: "Translate status", + description: "Translate status with an external API", + operationId: "StatusController.translate", + security: [%{"oAuth" => ["read:statuses"]}], + parameters: [id_param()], + requestBody: + request_body( + "Parameters", + %Schema{ + type: :object, + properties: %{ + target_language: %Schema{ + type: :string, + nullable: true, + description: "Translation target language." + } + } + }, + required: false + ), + responses: %{ + 200 => Operation.response("Translation", "application/json", translation()) + 400 => Operation.response("Error", "application/json", ApiError) + 404 => Operation.response("Error", "application/json", ApiError) + 503 => Operation.response("Error", "application/json", ApiError) + } + } + end + def favourites_operation do %Operation{ tags: ["Timelines"], @@ -793,4 +825,32 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do } } end + + defp translation do + %Schema{ + title: "StatusTranslation", + description: "Represents status translation with related information.", + type: :object, + required: [:content, :detected_source_language, :provider], + properties: %{ + content: %Schema{ + type: :string, + description: "Translated status content" + }, + detected_source_language: %Schema{ + type: :string, + description: "Detected source language" + }, + provider: %Schema{ + type: :string, + description: "Translation provider service name" + } + }, + example: %{ + "content" => "Software für die nächste Generation der sozialen Medien.", + "detected_source_language" => "en", + "provider" => "Deepl" + } + } + end end diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index 5aa7bddf0..4e1651596 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -15,6 +15,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do 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 @@ -44,6 +45,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do ] ) + plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action == :translate) + plug( OAuthScopesPlug, %{scopes: ["write:statuses"]} @@ -85,7 +88,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do %{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark] ) - @rate_limited_status_actions ~w(reblog unreblog favourite unfavourite create delete)a + @rate_limited_status_actions ~w(reblog unreblog favourite unfavourite create delete translate)a plug( RateLimiter, @@ -554,6 +557,30 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do end end + @doc "POST /api/v1/statuses/:id/translate" + def translate(%{body_params: params, assigns: %{user: user}} = conn, %{id: status_id}) do + with %Activity{object: object} <- Activity.get_by_id_with_object(status_id), + {:language, language} when is_binary(language) <- + {:language, Map.get(params, :target_language) || user.language}, + {:ok, result} <- + Translation.translate( + object.data["content"], + object.data["language"], + language + ) do + render(conn, "translation.json", result) + else + {:language, nil} -> + render_error(conn, :bad_request, "Language not specified") + + {:error, :not_found} -> + render_error(conn, :not_found, "Translation service not configured") + + {:error, error} when error in [:unexpected_response, :quota_exceeded, :too_many_requests] -> + render_error(conn, :service_unavailable, "Translation service not available") + end + end + @doc "GET /api/v1/favourites" def favourites( %{assigns: %{user: %User{} = user}, private: %{open_api_spex: %{params: params}}} = conn, diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index bae3fd1f8..026429d56 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -656,6 +656,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do } end + def render("translation.json", %{ + content: content, + detected_source_language: detected_source_language, + provider: provider + }) do + %{content: content, detected_source_language: detected_source_language, provider: provider} + end + def get_reply_to(activity, %{replied_to_activities: replied_to_activities}) do object = Object.normalize(activity, fetch: false) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 8ba845364..5c949fc95 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -718,6 +718,7 @@ defmodule Pleroma.Web.Router do post("/statuses/:id/unbookmark", StatusController, :unbookmark) post("/statuses/:id/mute", StatusController, :mute_conversation) post("/statuses/:id/unmute", StatusController, :unmute_conversation) + post("/statuses/:id/translate", StatusController, :translate) post("/push/subscription", SubscriptionController, :create) get("/push/subscription", SubscriptionController, :show)