Improve auto translate

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2023-10-11 23:11:09 +02:00
parent 664f64a3fc
commit ac76bc011a
6 changed files with 40 additions and 40 deletions

View file

@ -7,8 +7,8 @@ defmodule Pleroma.StatusTranslation do
import Ecto.Changeset
alias Pleroma.Activity
alias Pleroma.Language.Translation
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.StatusTranslation
@ -18,20 +18,20 @@ defmodule Pleroma.StatusTranslation do
field(:detected_source_language, :string)
field(:content, {:map, :string})
belongs_to(:object, Object)
belongs_to(:activity, Activity, type: FlakeId.Ecto.CompatType)
timestamps()
end
def changeset(%StatusTranslation{} = status_translation, params \\ %{}) do
status_translation
|> cast(params, [:object_id, :language, :provider, :detected_source_language, :content])
|> validate_required([:object_id, :language, :content])
|> unique_constraint([:object_id, :language])
|> cast(params, [:activity_id, :language, :provider, :detected_source_language, :content])
|> validate_required([:activity_id, :language, :content])
|> unique_constraint([:activity_id, :language])
end
def get(%Object{} = object, language, options \\ [fetch: true]) do
translation = Repo.get_by(StatusTranslation, object_id: object.id, language: language)
def get(%Activity{} = activity, language, options \\ [fetch: true]) do
translation = Repo.get_by(StatusTranslation, activity_id: activity.id, language: language)
if translation || not Keyword.get(options, :fetch) do
translation
@ -43,13 +43,13 @@ def get(%Object{} = object, language, options \\ [fetch: true]) do
provider: provider
}} <-
Translation.translate(
object.data["content"],
object.data["language"],
activity.object.data["content"],
activity.object.data["language"],
language
) do
%StatusTranslation{}
|> changeset(%{
object_id: object.id,
activity_id: activity.id,
language: language,
provider: provider,
detected_source_language: detected_source_language,

View file

@ -466,23 +466,16 @@ def translate_many_operation do
description: "Translate status with an external API",
operationId: "StatusController.translate_many",
security: [%{"oAuth" => ["read:statuses"]}],
parameters: [
Operation.parameter(
:id,
:query,
%Schema{
oneOf: [%Schema{type: :array, items: %Schema{type: :string}}, %Schema{type: :string}]
},
"Status IDs",
example: "123"
)
],
requestBody:
request_body(
"Parameters",
%Schema{
type: :object,
properties: %{
ids: %Schema{
type: :array,
items: %Schema{type: :string}
},
target_language: %Schema{
type: :string,
nullable: true,

View file

@ -622,18 +622,18 @@ def translate(
end
end
@doc "POST /api/v1/pleroma/statuses/translate"
def translate_many(%{body_params: params, assigns: %{user: user}} = conn, %{id: status_id}) do
with {:list, status_ids} <- {:list, List.wrap(status_id)},
{:language, language} when is_binary(language) <-
@doc "POST /api/v1/bigbuffet/statuses/translate"
def translate_many(%{body_params: %{ids: status_ids} = params, assigns: %{user: user}} = conn, _) do
with {:language, language} when is_binary(language) <-
{:language, Map.get(params, :target_language) || user.language},
{:results, results} <-
{:results, Enum.each(status_ids, &translate_one(&1, language, user))},
{:results, Enum.map(status_ids, &translate_one(&1, language, user))},
{:filtered_results, results} <-
Enum.filter(results, fn
%StatusTranslation{} -> true
_ -> false
end) do
{:filtered_results,
Enum.filter(results, fn
%StatusTranslation{} -> true
_ -> false
end)} do
render(conn, "translations.json", results: results)
end
end
@ -643,7 +643,7 @@ defp translate_one(status_id, language, user \\ nil) do
{:authentication,
!is_nil(user) ||
Pleroma.Config.get([Pleroma.Language.Translation, :allow_unauthenticated])},
%Activity{object: object} <- Activity.get_by_id_with_object(status_id),
%Activity{object: object} = activity <- Activity.get_by_id_with_object(status_id),
{:visibility, visibility} when visibility in ["public", "unlisted"] <-
{:visibility, Visibility.get_visibility(object)},
{:allow_remote, true} <-
@ -651,7 +651,7 @@ defp translate_one(status_id, language, user \\ nil) do
Object.local?(object) ||
Pleroma.Config.get([Pleroma.Language.Translation, :allow_remote])},
%StatusTranslation{} = result <-
StatusTranslation.get(object, language) do
StatusTranslation.get(activity, language) do
result
else
result -> result

View file

@ -244,7 +244,7 @@ def render(
end
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
object = Object.normalize(activity, fetch: false)
%Activity{object: object} = activity = Activity.get_by_id_with_object(activity.id)
user = CommonAPI.get_user(activity.data["actor"])
user_follower_address = user.follower_address
@ -473,7 +473,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
quotes_count: object.data["quotesCount"] || 0,
event: build_event(object.data, opts[:for]),
bookmark_folder: bookmark_folder,
translation: get_translation(object, opts[:language])
translation: get_translation(activity, opts[:language])
}
}
end
@ -698,20 +698,27 @@ def render("translations.json", %{results: results}) do
def render("translation.json", %{
result: %{
activity_id: id,
content: %{"content" => content},
detected_source_language: detected_source_language,
provider: provider
}
}) do
%{content: content, detected_source_language: detected_source_language, provider: provider}
%{
id: id,
content: content,
detected_source_language: detected_source_language,
provider: provider
}
end
defp get_translation(object, language) when is_binary(language) or is_list(language) do
defp get_translation(%Activity{object: object} = activity, language)
when is_binary(language) or is_list(language) do
with languages <- List.wrap(language),
true <- is_binary(object.data["language"]),
true <- object.data["language"] not in languages,
%StatusTranslation{} = translation <-
StatusTranslation.get(object, language, fetch: false) do
StatusTranslation.get(activity, language, fetch: false) do
render("translation.json", %{result: translation})
else
_ -> nil

View file

@ -235,7 +235,7 @@ defmodule Pleroma.Web.Router do
post("/uploader_callback/:upload_path", UploaderController, :callback)
end
scope "/api/v1/pleroma", Pleroma.Web.MastodonAPI do
scope "/api/v1/bigbuffet", Pleroma.Web.MastodonAPI do
pipe_through(:api)
post("/statuses/translate", StatusController, :translate_many)

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Repo.Migrations.CreateStatusTranslations do
def change do
create_if_not_exists table(:status_translations) do
add(:object_id, references(:objects, on_delete: :delete_all), null: false)
add(:activity_id, references(:activities, type: :uuid, on_delete: :delete_all), null: false)
add(:language, :text, null: false)
add(:provider, :text)
add(:detected_source_language, :text)
@ -16,6 +16,6 @@ def change do
timestamps()
end
create_if_not_exists(unique_index(:status_translations, [:object_id, :language]))
create_if_not_exists(unique_index(:status_translations, [:activity_id, :language]))
end
end