add seperate source and dest entries in language listing (#193)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk> Reviewed-on: #193
This commit is contained in:
parent
c3fde9577d
commit
decbca0c91
8 changed files with 94 additions and 20 deletions
|
@ -23,12 +23,21 @@ defp tier do
|
||||||
|
|
||||||
@impl Pleroma.Akkoma.Translator
|
@impl Pleroma.Akkoma.Translator
|
||||||
def languages do
|
def languages do
|
||||||
with {:ok, %{status: 200} = response} <- do_languages(),
|
with {:ok, %{status: 200} = source_response} <- do_languages("source"),
|
||||||
{:ok, body} <- Jason.decode(response.body) do
|
{:ok, %{status: 200} = dest_response} <- do_languages("target"),
|
||||||
resp =
|
{:ok, source_body} <- Jason.decode(source_response.body),
|
||||||
Enum.map(body, fn %{"language" => code, "name" => name} -> %{code: code, name: name} end)
|
{:ok, dest_body} <- Jason.decode(dest_response.body) do
|
||||||
|
source_resp =
|
||||||
|
Enum.map(source_body, fn %{"language" => code, "name" => name} ->
|
||||||
|
%{code: code, name: name}
|
||||||
|
end)
|
||||||
|
|
||||||
{:ok, resp}
|
dest_resp =
|
||||||
|
Enum.map(dest_body, fn %{"language" => code, "name" => name} ->
|
||||||
|
%{code: code, name: name}
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:ok, source_resp, dest_resp}
|
||||||
else
|
else
|
||||||
{:ok, %{status: status} = response} ->
|
{:ok, %{status: status} = response} ->
|
||||||
Logger.warning("DeepL: Request rejected: #{inspect(response)}")
|
Logger.warning("DeepL: Request rejected: #{inspect(response)}")
|
||||||
|
@ -80,9 +89,9 @@ defp do_request(api_key, tier, string, from_language, to_language) do
|
||||||
defp maybe_add_source(opts, nil), do: opts
|
defp maybe_add_source(opts, nil), do: opts
|
||||||
defp maybe_add_source(opts, lang), do: Map.put(opts, :source_lang, lang)
|
defp maybe_add_source(opts, lang), do: Map.put(opts, :source_lang, lang)
|
||||||
|
|
||||||
defp do_languages() do
|
defp do_languages(type) do
|
||||||
HTTP.get(
|
HTTP.get(
|
||||||
base_url(tier()) <> "languages?type=target",
|
base_url(tier()) <> "languages?type=#{type}",
|
||||||
[
|
[
|
||||||
{"authorization", "DeepL-Auth-Key #{api_key()}"}
|
{"authorization", "DeepL-Auth-Key #{api_key()}"}
|
||||||
]
|
]
|
||||||
|
|
|
@ -18,7 +18,8 @@ def languages do
|
||||||
with {:ok, %{status: 200} = response} <- do_languages(),
|
with {:ok, %{status: 200} = response} <- do_languages(),
|
||||||
{:ok, body} <- Jason.decode(response.body) do
|
{:ok, body} <- Jason.decode(response.body) do
|
||||||
resp = Enum.map(body, fn %{"code" => code, "name" => name} -> %{code: code, name: name} end)
|
resp = Enum.map(body, fn %{"code" => code, "name" => name} -> %{code: code, name: name} end)
|
||||||
{:ok, resp}
|
# No separate source/dest
|
||||||
|
{:ok, resp, resp}
|
||||||
else
|
else
|
||||||
{:ok, %{status: status} = response} ->
|
{:ok, %{status: status} = response} ->
|
||||||
Logger.warning("LibreTranslate: Request rejected: #{inspect(response)}")
|
Logger.warning("LibreTranslate: Request rejected: #{inspect(response)}")
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
defmodule Pleroma.Akkoma.Translator do
|
defmodule Pleroma.Akkoma.Translator do
|
||||||
@callback translate(String.t(), String.t() | nil, String.t()) ::
|
@callback translate(String.t(), String.t() | nil, String.t()) ::
|
||||||
{:ok, String.t(), String.t()} | {:error, any()}
|
{:ok, String.t(), String.t()} | {:error, any()}
|
||||||
@callback languages() :: {:ok, [%{name: String.t(), code: String.t()}]} | {:error, any()}
|
@callback languages() ::
|
||||||
|
{:ok, [%{name: String.t(), code: String.t()}],
|
||||||
|
[%{name: String.t(), code: String.t()}]}
|
||||||
|
| {:error, any()}
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,9 +21,9 @@ defmodule Pleroma.Web.AkkomaAPI.TranslationController do
|
||||||
|
|
||||||
@doc "GET /api/v1/akkoma/translation/languages"
|
@doc "GET /api/v1/akkoma/translation/languages"
|
||||||
def languages(conn, _params) do
|
def languages(conn, _params) do
|
||||||
with {:ok, languages} <- get_languages() do
|
with {:ok, source_languages, dest_languages} <- get_languages() do
|
||||||
conn
|
conn
|
||||||
|> json(languages)
|
|> json(%{source: source_languages, target: dest_languages})
|
||||||
else
|
else
|
||||||
e -> IO.inspect(e)
|
e -> IO.inspect(e)
|
||||||
end
|
end
|
||||||
|
@ -33,8 +33,8 @@ defp get_languages do
|
||||||
module = Pleroma.Config.get([:translator, :module])
|
module = Pleroma.Config.get([:translator, :module])
|
||||||
|
|
||||||
@cachex.fetch!(:translations_cache, "languages:#{module}}", fn _ ->
|
@cachex.fetch!(:translations_cache, "languages:#{module}}", fn _ ->
|
||||||
with {:ok, languages} <- module.languages() do
|
with {:ok, source_languages, dest_languages} <- module.languages() do
|
||||||
{:ok, languages}
|
{:ok, source_languages, dest_languages}
|
||||||
else
|
else
|
||||||
{:error, err} -> {:ignore, {:error, err}}
|
{:error, err} -> {:ignore, {:error, err}}
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,22 +17,34 @@ def languages_operation() do
|
||||||
operationId: "AkkomaAPI.TranslationController.languages",
|
operationId: "AkkomaAPI.TranslationController.languages",
|
||||||
security: [%{"oAuth" => ["read:statuses"]}],
|
security: [%{"oAuth" => ["read:statuses"]}],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => Operation.response("Translation", "application/json", languages_schema())
|
200 =>
|
||||||
|
Operation.response("Translation", "application/json", source_dest_languages_schema())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp source_dest_languages_schema do
|
||||||
|
%Schema{
|
||||||
|
type: :object,
|
||||||
|
required: [:source, :target],
|
||||||
|
properties: %{
|
||||||
|
source: languages_schema(),
|
||||||
|
target: languages_schema()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp languages_schema do
|
defp languages_schema do
|
||||||
%Schema{
|
%Schema{
|
||||||
type: "array",
|
type: :array,
|
||||||
items: %Schema{
|
items: %Schema{
|
||||||
type: "object",
|
type: :object,
|
||||||
properties: %{
|
properties: %{
|
||||||
code: %Schema{
|
code: %Schema{
|
||||||
type: "string"
|
type: :string
|
||||||
},
|
},
|
||||||
name: %Schema{
|
name: %Schema{
|
||||||
type: "string"
|
type: :string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,23 @@ test "should list supported languages" do
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%{method: :get, url: "https://api-free.deepl.com/v2/languages?type=source"} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
Jason.encode!([
|
||||||
|
%{
|
||||||
|
"language" => "JA",
|
||||||
|
"name" => "Japanese",
|
||||||
|
"supports_formality" => false
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert {:ok, [%{code: "BG", name: "Bulgarian"}, %{code: "CS", name: "Czech"}]} =
|
assert {:ok, [%{code: "JA", name: "Japanese"}],
|
||||||
|
[%{code: "BG", name: "Bulgarian"}, %{code: "CS", name: "Czech"}]} =
|
||||||
DeepL.languages()
|
DeepL.languages()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@ test "should list supported languages" do
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
assert {:ok, [%{code: "en", name: "English"}, %{code: "ar", name: "Arabic"}]} =
|
assert {:ok, [%{code: "en", name: "English"}, %{code: "ar", name: "Arabic"}],
|
||||||
|
[%{code: "en", name: "English"}, %{code: "ar", name: "Arabic"}]} =
|
||||||
LibreTranslate.languages()
|
LibreTranslate.languages()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2080,6 +2080,40 @@ test "posting a quote of a status that doesn't exist", %{conn: conn} do
|
||||||
oauth_access(["read:statuses"])
|
oauth_access(["read:statuses"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "listing languages", %{conn: conn} do
|
||||||
|
Tesla.Mock.mock_global(fn
|
||||||
|
%{method: :get, url: "https://api-free.deepl.com/v2/languages?type=source"} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
Jason.encode!([
|
||||||
|
%{language: "en", name: "English"}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
%{method: :get, url: "https://api-free.deepl.com/v2/languages?type=target"} ->
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body:
|
||||||
|
Jason.encode!([
|
||||||
|
%{language: "ja", name: "Japanese"}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> get("/api/v1/akkoma/translation/languages")
|
||||||
|
|
||||||
|
response = json_response_and_validate_schema(conn, 200)
|
||||||
|
|
||||||
|
assert %{
|
||||||
|
"source" => [%{"code" => "en", "name" => "English"}],
|
||||||
|
"target" => [%{"code" => "ja", "name" => "Japanese"}]
|
||||||
|
} = response
|
||||||
|
end
|
||||||
|
|
||||||
test "should return text and detected language", %{conn: conn} do
|
test "should return text and detected language", %{conn: conn} do
|
||||||
clear_config([:deepl, :tier], :free)
|
clear_config([:deepl, :tier], :free)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue