add libretranslate as well
This commit is contained in:
parent
55fc134817
commit
83d881dcb1
|
@ -843,12 +843,19 @@ config :pleroma, Pleroma.Search.Elasticsearch.Cluster,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config :pleroma, :deepl,
|
config :pleroma, :translator,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
module: Akkoma.Translators.DeepL
|
||||||
|
|
||||||
|
config :pleroma, :deepl,
|
||||||
# either :free or :pro
|
# either :free or :pro
|
||||||
tier: :free,
|
tier: :free,
|
||||||
api_key: ""
|
api_key: ""
|
||||||
|
|
||||||
|
config :pleroma, :libre_translate,
|
||||||
|
url: "http://127.0.0.1:5000",
|
||||||
|
api_key: nil
|
||||||
|
|
||||||
# Import environment specific config. This must remain at the bottom
|
# Import environment specific config. This must remain at the bottom
|
||||||
# of this file so it overrides the configuration defined above.
|
# of this file so it overrides the configuration defined above.
|
||||||
import_config "#{Mix.env()}.exs"
|
import_config "#{Mix.env()}.exs"
|
||||||
|
|
43
lib/pleroma/translators/deepl.ex
Normal file
43
lib/pleroma/translators/deepl.ex
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
defmodule Akkoma.Translators.DeepL do
|
||||||
|
@behaviour Akkoma.Translator
|
||||||
|
|
||||||
|
use Tesla
|
||||||
|
alias Pleroma.Config
|
||||||
|
|
||||||
|
plug(Tesla.Middleware.EncodeFormUrlencoded)
|
||||||
|
plug(Tesla.Middleware.DecodeJson)
|
||||||
|
|
||||||
|
defp base_url(:free) do
|
||||||
|
"https://api-free.deepl.com/v2/"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp base_url(:pro) do
|
||||||
|
"https://api.deepl.com/v2/"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp api_key do
|
||||||
|
Config.get([:deepl, :api_key])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp tier do
|
||||||
|
Config.get([:deepl, :tier])
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl Akkoma.Translator
|
||||||
|
def translate(string, to_language) do
|
||||||
|
with {:ok, response} <- do_request(api_key(), tier(), string, to_language) do
|
||||||
|
%{"translations" => [%{"text" => translated, "detected_source_language" => detected}]} = response.body
|
||||||
|
{:ok, detected, translated}
|
||||||
|
else
|
||||||
|
{:error, reason} -> {:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_request(api_key, tier, string, to_language) do
|
||||||
|
post(base_url(tier) <> "translate", %{
|
||||||
|
auth_key: api_key,
|
||||||
|
text: string,
|
||||||
|
target_lang: to_language
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
38
lib/pleroma/translators/libre_translate.ex
Normal file
38
lib/pleroma/translators/libre_translate.ex
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
defmodule Akkoma.Translators.LibreTranslate do
|
||||||
|
@behaviour Akkoma.Translator
|
||||||
|
|
||||||
|
use Tesla
|
||||||
|
alias Pleroma.Config
|
||||||
|
|
||||||
|
plug(Tesla.Middleware.JSON)
|
||||||
|
|
||||||
|
defp api_key do
|
||||||
|
Config.get([:libre_translate, :api_key])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp url do
|
||||||
|
Config.get([:libre_translate, :url])
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl Akkoma.Translator
|
||||||
|
def translate(string, to_language) do
|
||||||
|
with {:ok, response} <- do_request(string, to_language) do
|
||||||
|
%{"translatedText" => translated, "detectedLanguage" => %{"language" => detected}} = response.body
|
||||||
|
{:ok, detected, translated}
|
||||||
|
else
|
||||||
|
{:error, reason} -> {:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_request(string, to_language) do
|
||||||
|
url = URI.parse(url())
|
||||||
|
url = %{url | path: "/translate"}
|
||||||
|
|
||||||
|
post(url, %{
|
||||||
|
q: string,
|
||||||
|
source: "auto",
|
||||||
|
target: to_language,
|
||||||
|
api_key: api_key()
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
3
lib/pleroma/translators/translator.ex
Normal file
3
lib/pleroma/translators/translator.ex
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
defmodule Akkoma.Translator do
|
||||||
|
@callback translate(String.t(), String.t()) :: {:ok, String.t(), String.t()} | {:error, any()}
|
||||||
|
end
|
|
@ -593,28 +593,6 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp translation_result do
|
|
||||||
%Schema{
|
|
||||||
title: "StatusTranslation",
|
|
||||||
description: "The translation of a status.",
|
|
||||||
type: :object,
|
|
||||||
required: [:detected_source_language, :text],
|
|
||||||
properties: %{
|
|
||||||
detected_source_language: %Schema{
|
|
||||||
type: :string,
|
|
||||||
description: "The detected source language of the status."
|
|
||||||
},
|
|
||||||
text: %Schema{
|
|
||||||
type: :string,
|
|
||||||
description: "The translated text of the status."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
example: %{
|
|
||||||
"detected_source_language" => "en",
|
|
||||||
"text" => "Hear, Feel, Think"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp translation do
|
defp translation do
|
||||||
|
@ -622,9 +600,10 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
||||||
title: "StatusTranslation",
|
title: "StatusTranslation",
|
||||||
description: "The translation of a status.",
|
description: "The translation of a status.",
|
||||||
type: :object,
|
type: :object,
|
||||||
required: [:translations],
|
required: [:detected_language, :text],
|
||||||
properties: %{
|
properties: %{
|
||||||
translations: %Schema{type: :array, items: translation_result()}
|
detected_language: %Schema{type: :string, description: "The detected language of the text"},
|
||||||
|
text: %Schema{type: :string, description: "The translated text"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -422,13 +422,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||||
|
|
||||||
@doc "GET /api/v1/statuses/:id/translations/:language"
|
@doc "GET /api/v1/statuses/:id/translations/:language"
|
||||||
def translate(%{assigns: %{user: user}} = conn, %{id: id, language: language}) do
|
def translate(%{assigns: %{user: user}} = conn, %{id: id, language: language}) do
|
||||||
with {:enabled, true} <- {:enabled, Config.get([:deepl, :enabled])},
|
with {:enabled, true} <- {:enabled, Config.get([:translator, :enabled])},
|
||||||
%Activity{} = activity <- IO.inspect(Activity.get_by_id_with_object(id)),
|
%Activity{} = activity <- Activity.get_by_id_with_object(id),
|
||||||
{:visible, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
|
{:visible, true} <- {:visible, Visibility.visible_for_user?(activity, user)},
|
||||||
api_key <- Config.get([:deepl, :api_key]),
|
translation_module <- Config.get([:translator, :module]),
|
||||||
tier <- Config.get([:deepl, :tier]),
|
{:ok, detected, translation} <-
|
||||||
{:ok, translation} <- DeepLex.translate(api_key, tier, activity.object.data["content"], language) do
|
translation_module.translate(activity.object.data["content"], language) do
|
||||||
json(conn, translation)
|
json(conn, %{detected_lanugage: detected, text: translation})
|
||||||
else
|
else
|
||||||
{:enabled, false} ->
|
{:enabled, false} ->
|
||||||
conn
|
conn
|
||||||
|
@ -437,6 +437,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||||
|
|
||||||
{:visible, false} ->
|
{:visible, false} ->
|
||||||
{:error, :not_found}
|
{:error, :not_found}
|
||||||
|
|
||||||
|
_e ->
|
||||||
|
{:error, :internal_server_error}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
3
mix.exs
3
mix.exs
|
@ -161,9 +161,6 @@ defmodule Pleroma.Mixfile do
|
||||||
{:ueberauth, "~> 0.4"},
|
{:ueberauth, "~> 0.4"},
|
||||||
{:linkify,
|
{:linkify,
|
||||||
git: "https://akkoma.dev/AkkomaGang/linkify.git", branch: "bugfix/line-ending-buffer"},
|
git: "https://akkoma.dev/AkkomaGang/linkify.git", branch: "bugfix/line-ending-buffer"},
|
||||||
{:deep_lex,
|
|
||||||
git: "https://akkoma.dev/AkkomaGang/deep_lex.git",
|
|
||||||
ref: "fd72e36419848138ef257b52867e7504a2a7808b"},
|
|
||||||
{:http_signatures, "~> 0.1.1"},
|
{:http_signatures, "~> 0.1.1"},
|
||||||
{:telemetry, "~> 0.3"},
|
{:telemetry, "~> 0.3"},
|
||||||
{:poolboy, "~> 1.5"},
|
{:poolboy, "~> 1.5"},
|
||||||
|
|
|
@ -2071,4 +2071,32 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
||||||
|> json_response_and_validate_schema(422)
|
|> json_response_and_validate_schema(422)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "translating statuses" do
|
||||||
|
setup do: oauth_access(["read:statuses"])
|
||||||
|
|
||||||
|
test "translating a status with deepl", %{conn: conn} do
|
||||||
|
Tesla.Mock.mock(fn
|
||||||
|
%{method: :post, url: "http://api-free.deepl.com/translate"} ->
|
||||||
|
{:ok,
|
||||||
|
%{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
~s({"data": {"translations": [{"translatedText": "Tell me, for whom do you fight?"}]}})
|
||||||
|
}}
|
||||||
|
end)
|
||||||
|
|
||||||
|
user = insert(:user)
|
||||||
|
{:ok, quoted_status} = CommonAPI.post(user, %{status: "何のために闘う?"})
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> get("/api/v1/statuses/#{quoted_status.id}/translations/en")
|
||||||
|
|
||||||
|
response = json_response_and_validate_schema(conn, 200)
|
||||||
|
|
||||||
|
assert response["text"] == "Tell me, for whom do you fight?"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue