Store translations in database

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2023-10-07 00:49:57 +02:00
parent e99a41405d
commit 6428acc248
4 changed files with 108 additions and 11 deletions

View file

@ -0,0 +1,65 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.StatusTranslation do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias Pleroma.Language.Translation
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.StatusTranslation
schema "status_translations" do
field(:language, :string)
field(:provider, :string)
field(:detected_source_language, :string)
field(:content, {:map, :string})
belongs_to(:object, Object)
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])
end
def get(%Object{} = object, language, fetch_unavailable \\ true) do
translation = Repo.get_by(StatusTranslation, object_id: object.id, language: language)
if translation or not fetch_unavailable do
translation
else
with {:ok,
%{
content: content,
detected_source_language: detected_source_language,
provider: provider
}} <-
Translation.translate(
object.data["content"],
object.data["language"],
language
) do
%StatusTranslation{}
|> changeset(%{
object_id: object.id,
language: language,
provider: provider,
detected_source_language: detected_source_language,
content: %{
"content" => content
}
})
|> Repo.insert!()
end
end
end
end

View file

@ -592,13 +592,9 @@ def translate(
Pleroma.Config.get([Pleroma.Language.Translation, :allow_remote])},
{: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)
%Pleroma.StatusTranslation{} = result <-
Pleroma.StatusTranslation.get(object, language) do
render(conn, "translation.json", result: result)
else
{:authentication, false} ->
render_error(conn, :unauthorized, "Authorization is required to translate statuses")

View file

@ -471,7 +471,8 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
content_type: opts[:with_source] && (object.data["content_type"] || "text/plain"),
quotes_count: object.data["quotesCount"] || 0,
event: build_event(object.data, opts[:for]),
bookmark_folder: bookmark_folder
bookmark_folder: bookmark_folder,
translation: get_translation(object, opts[:language])
}
}
end
@ -480,6 +481,18 @@ def render("show.json", _) do
nil
end
defp get_translation(object, language) when is_binary(language) do
translation = Pleroma.StatusTranslation.get(object, language)
if translation do
render("translation.json", %{result: translation})
else
nil
end
end
defp get_translation(_, _), do: nil
def render("card.json", %{embed: %Embed{} = embed}) do
with {:ok, %Card{} = card} <- Card.parse(embed) do
Card.to_map(card)
@ -691,9 +704,11 @@ def render("context.json", %{activity: activity, activities: activities, user: u
end
def render("translation.json", %{
content: content,
detected_source_language: detected_source_language,
provider: provider
result: %{
content: %{"content" => content},
detected_source_language: detected_source_language,
provider: provider
}
}) do
%{content: content, detected_source_language: detected_source_language, provider: provider}
end

View file

@ -0,0 +1,21 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Repo.Migrations.CreateStatusTranslations do
use Ecto.Migration
def change do
create_if_not_exists table(:status_translations) do
add(:object_id, references(:objects, on_delete: :delete_all), null: false)
add(:language, :text, null: false)
add(:provider, :text)
add(:detected_source_language, :text)
add(:content, {:map, :string})
timestamps()
end
create_if_not_exists(unique_index(:status_translations, [:object_id, :language]))
end
end