Post single-language status with language attribute
This commit is contained in:
parent
c4cec5fd6a
commit
9555e630fd
5 changed files with 153 additions and 20 deletions
|
@ -9,7 +9,7 @@ defp template(:single), do: Pleroma.Config.get([__MODULE__, :single_line_templat
|
||||||
defp sep(:multi), do: Pleroma.Config.get([__MODULE__, :separator])
|
defp sep(:multi), do: Pleroma.Config.get([__MODULE__, :separator])
|
||||||
defp sep(:single), do: Pleroma.Config.get([__MODULE__, :single_line_separator])
|
defp sep(:single), do: Pleroma.Config.get([__MODULE__, :single_line_separator])
|
||||||
|
|
||||||
defp is_good_locale_code?(code) do
|
def is_good_locale_code?(code) do
|
||||||
code
|
code
|
||||||
|> String.codepoints()
|
|> String.codepoints()
|
||||||
|> Enum.all?(&valid_char?/1)
|
|> Enum.all?(&valid_char?/1)
|
||||||
|
@ -68,9 +68,15 @@ defp map_to_str_impl(data, mode) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def str_to_map(data) do
|
def str_to_map(data, opts \\ []) do
|
||||||
|
with lang when is_binary(lang) <- opts[:lang],
|
||||||
|
true <- is_good_locale_code?(lang) do
|
||||||
|
%{lang => data}
|
||||||
|
else
|
||||||
|
_ ->
|
||||||
%{"und" => data}
|
%{"und" => data}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def format_template(template, %{code: code, content: content}) do
|
def format_template(template, %{code: code, content: content}) do
|
||||||
template
|
template
|
||||||
|
|
|
@ -219,20 +219,32 @@ def create(actor, object, recipients) do
|
||||||
def note(%ActivityDraft{} = draft) do
|
def note(%ActivityDraft{} = draft) do
|
||||||
content_fields =
|
content_fields =
|
||||||
if draft.content_html_map do
|
if draft.content_html_map do
|
||||||
|
case Map.keys(draft.content_html_map) do
|
||||||
|
["und"] ->
|
||||||
|
%{"content" => MultiLanguage.map_to_str(draft.content_html_map, multiline: true)}
|
||||||
|
|
||||||
|
_ ->
|
||||||
%{
|
%{
|
||||||
"contentMap" => draft.content_html_map,
|
"contentMap" => draft.content_html_map,
|
||||||
"content" => MultiLanguage.map_to_str(draft.content_html_map, multiline: true)
|
"content" => MultiLanguage.map_to_str(draft.content_html_map, multiline: true)
|
||||||
}
|
}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
%{"content" => draft.content_html}
|
%{"content" => draft.content_html}
|
||||||
end
|
end
|
||||||
|
|
||||||
summary_fields =
|
summary_fields =
|
||||||
if draft.summary_map do
|
if draft.summary_map do
|
||||||
|
case Map.keys(draft.summary_map) do
|
||||||
|
["und"] ->
|
||||||
|
%{"summary" => MultiLanguage.map_to_str(draft.summary_map, multiline: false)}
|
||||||
|
|
||||||
|
_ ->
|
||||||
%{
|
%{
|
||||||
"summaryMap" => draft.summary_map,
|
"summaryMap" => draft.summary_map,
|
||||||
"summary" => MultiLanguage.map_to_str(draft.summary_map, multiline: false)
|
"summary" => MultiLanguage.map_to_str(draft.summary_map, multiline: false)
|
||||||
}
|
}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
%{"summary" => draft.summary}
|
%{"summary" => draft.summary}
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,6 +26,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|
||||||
errors: [],
|
errors: [],
|
||||||
user: nil,
|
user: nil,
|
||||||
params: %{},
|
params: %{},
|
||||||
|
language: nil,
|
||||||
status: nil,
|
status: nil,
|
||||||
status_map: nil,
|
status_map: nil,
|
||||||
summary: nil,
|
summary: nil,
|
||||||
|
@ -65,6 +66,7 @@ def new(user, params) do
|
||||||
def create(user, params) do
|
def create(user, params) do
|
||||||
user
|
user
|
||||||
|> new(params)
|
|> new(params)
|
||||||
|
|> language()
|
||||||
|> status()
|
|> status()
|
||||||
|> summary()
|
|> summary()
|
||||||
|> with_valid(&attachments/1)
|
|> with_valid(&attachments/1)
|
||||||
|
@ -153,6 +155,16 @@ defp put_params(draft, params) do
|
||||||
%__MODULE__{draft | params: params}
|
%__MODULE__{draft | params: params}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp language(%{params: %{language: language}} = draft) do
|
||||||
|
if MultiLanguage.is_good_locale_code?(language) do
|
||||||
|
%__MODULE__{draft | language: language}
|
||||||
|
else
|
||||||
|
add_error(draft, dgettext("errors", "language \"%{language}\" is invalid", language: language))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp language(draft), do: draft
|
||||||
|
|
||||||
defp status(%{params: %{status_map: %{} = status_map}} = draft) do
|
defp status(%{params: %{status_map: %{} = status_map}} = draft) do
|
||||||
with {:ok, %{}} <- MultiLanguage.validate_map(status_map) do
|
with {:ok, %{}} <- MultiLanguage.validate_map(status_map) do
|
||||||
%__MODULE__{draft | status_map: status_map}
|
%__MODULE__{draft | status_map: status_map}
|
||||||
|
@ -178,16 +190,25 @@ defp summary(%{params: params} = draft) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp full_payload(%{status: status, status_map: nil} = draft) do
|
defp full_payload(%{status: status, status_map: nil} = draft) do
|
||||||
full_payload(%__MODULE__{draft | status_map: MultiLanguage.str_to_map(status)})
|
full_payload(%__MODULE__{
|
||||||
|
draft
|
||||||
|
| status_map: MultiLanguage.str_to_map(status, lang: draft.language)
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp full_payload(%{summary: summary, summary_map: nil} = draft) do
|
defp full_payload(%{summary: summary, summary_map: nil} = draft) do
|
||||||
full_payload(%__MODULE__{draft | summary_map: MultiLanguage.str_to_map(summary)})
|
full_payload(%__MODULE__{
|
||||||
|
draft
|
||||||
|
| summary_map: MultiLanguage.str_to_map(summary, lang: draft.language)
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp full_payload(%{status_map: %{} = status_map, summary_map: %{} = summary_map} = draft) do
|
defp full_payload(%{status_map: %{} = status_map, summary_map: %{} = summary_map} = draft) do
|
||||||
status = status_map |> Enum.reduce("", fn {_lang, content}, acc -> acc <> content end)
|
status = status_map |> Enum.reduce("", fn {_lang, content}, acc -> acc <> " " <> content end)
|
||||||
summary = summary_map |> Enum.reduce("", fn {_lang, content}, acc -> acc <> content end)
|
|
||||||
|
summary =
|
||||||
|
summary_map |> Enum.reduce("", fn {_lang, content}, acc -> acc <> " " <> content end)
|
||||||
|
|
||||||
full_payload = String.trim(status <> summary)
|
full_payload = String.trim(status <> summary)
|
||||||
|
|
||||||
case Utils.validate_character_limit(full_payload, draft.attachments) do
|
case Utils.validate_character_limit(full_payload, draft.attachments) do
|
||||||
|
|
|
@ -151,7 +151,6 @@ def make_poll_data(%{"poll" => %{"expires_in" => expires_in}} = data)
|
||||||
def make_poll_data(%{poll: %{options_map: options_map, expires_in: expires_in}} = data)
|
def make_poll_data(%{poll: %{options_map: options_map, expires_in: expires_in}} = data)
|
||||||
when is_list(options_map) do
|
when is_list(options_map) do
|
||||||
limits = Config.get([:instance, :poll_limits])
|
limits = Config.get([:instance, :poll_limits])
|
||||||
is_single_language = data.poll[:is_single_language]
|
|
||||||
|
|
||||||
options = options |> Enum.uniq()
|
options = options |> Enum.uniq()
|
||||||
|
|
||||||
|
@ -161,6 +160,8 @@ def make_poll_data(%{poll: %{options_map: options_map, expires_in: expires_in}}
|
||||||
:ok <- validate_poll_options_length(options_map, limits) do
|
:ok <- validate_poll_options_length(options_map, limits) do
|
||||||
{option_notes, emoji} =
|
{option_notes, emoji} =
|
||||||
Enum.map_reduce(options_map, %{}, fn option, emoji ->
|
Enum.map_reduce(options_map, %{}, fn option, emoji ->
|
||||||
|
is_single_language = Map.keys(option) == ["und"]
|
||||||
|
|
||||||
name_attrs =
|
name_attrs =
|
||||||
if is_single_language do
|
if is_single_language do
|
||||||
%{"name" => option["und"]}
|
%{"name" => option["und"]}
|
||||||
|
@ -196,8 +197,10 @@ def make_poll_data(%{poll: %{options_map: options_map, expires_in: expires_in}}
|
||||||
def make_poll_data(%{poll: %{options: options}} = data) when is_list(options) do
|
def make_poll_data(%{poll: %{options: options}} = data) when is_list(options) do
|
||||||
new_poll =
|
new_poll =
|
||||||
data.poll
|
data.poll
|
||||||
|> Map.put(:options_map, Enum.map(options, &MultiLanguage.str_to_map/1))
|
|> Map.put(
|
||||||
|> Map.put(:is_single_language, true)
|
:options_map,
|
||||||
|
Enum.map(options, &MultiLanguage.str_to_map(&1, lang: data[:language]))
|
||||||
|
)
|
||||||
|
|
||||||
data
|
data
|
||||||
|> Map.put(:poll, new_poll)
|
|> Map.put(:poll, new_poll)
|
||||||
|
|
|
@ -83,8 +83,13 @@ test "posting a status", %{conn: conn} do
|
||||||
"sensitive" => "0"
|
"sensitive" => "0"
|
||||||
})
|
})
|
||||||
|
|
||||||
assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
|
assert %{
|
||||||
json_response_and_validate_schema(conn_one, 200)
|
"content" => "cofe",
|
||||||
|
"id" => id,
|
||||||
|
"spoiler_text" => "2hu",
|
||||||
|
"sensitive" => false,
|
||||||
|
"language" => nil
|
||||||
|
} = json_response_and_validate_schema(conn_one, 200)
|
||||||
|
|
||||||
assert Activity.get_by_id(id)
|
assert Activity.get_by_id(id)
|
||||||
|
|
||||||
|
@ -139,6 +144,52 @@ test "posting a status", %{conn: conn} do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "posting a single lang status ", %{conn: conn} do
|
||||||
|
idempotency_key = "Pikachu rocks!"
|
||||||
|
|
||||||
|
conn_one =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> put_req_header("idempotency-key", idempotency_key)
|
||||||
|
|> post("/api/v1/statuses", %{
|
||||||
|
"status" => "mew mew",
|
||||||
|
"spoiler_text" => "mew",
|
||||||
|
"sensitive" => "0",
|
||||||
|
"language" => "a"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert %{
|
||||||
|
"content" => "mew mew",
|
||||||
|
"content_map" => %{"a" => "mew mew"},
|
||||||
|
"id" => id,
|
||||||
|
"spoiler_text" => "mew",
|
||||||
|
"spoiler_text_map" => %{"a" => "mew"},
|
||||||
|
"sensitive" => false,
|
||||||
|
"language" => "a"
|
||||||
|
} = json_response_and_validate_schema(conn_one, 200)
|
||||||
|
|
||||||
|
assert Activity.get_by_id(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "posting a single lang status, bad language code", %{conn: conn} do
|
||||||
|
idempotency_key = "Pikachu rocks!"
|
||||||
|
|
||||||
|
conn_one =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> put_req_header("idempotency-key", idempotency_key)
|
||||||
|
|> post("/api/v1/statuses", %{
|
||||||
|
"status" => "mew mew",
|
||||||
|
"spoiler_text" => "mew",
|
||||||
|
"sensitive" => "0",
|
||||||
|
"language" => "a_"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert %{
|
||||||
|
"error" => _
|
||||||
|
} = json_response_and_validate_schema(conn_one, 422)
|
||||||
|
end
|
||||||
|
|
||||||
test "posting a multilang status", %{conn: conn} do
|
test "posting a multilang status", %{conn: conn} do
|
||||||
idempotency_key = "Pikachu rocks!"
|
idempotency_key = "Pikachu rocks!"
|
||||||
|
|
||||||
|
@ -748,6 +799,46 @@ test "posting a poll", %{conn: conn} do
|
||||||
assert question.data["closed"] =~ "Z"
|
assert question.data["closed"] =~ "Z"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "posting a single-language poll", %{conn: conn} do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post("/api/v1/statuses", %{
|
||||||
|
"status" => "Who is the #bestgrill?",
|
||||||
|
"poll" => %{
|
||||||
|
"options" => ["Rei", "Asuka", "Misato"],
|
||||||
|
"expires_in" => 420
|
||||||
|
},
|
||||||
|
"language" => "a"
|
||||||
|
})
|
||||||
|
|
||||||
|
response = json_response_and_validate_schema(conn, 200)
|
||||||
|
|
||||||
|
assert Enum.all?(response["poll"]["options"], fn %{"title_map" => title} ->
|
||||||
|
title in [
|
||||||
|
%{"a" => "Rei"},
|
||||||
|
%{"a" => "Asuka"},
|
||||||
|
%{"a" => "Misato"}
|
||||||
|
]
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "posting a single-language poll, invalid language code", %{conn: conn} do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/json")
|
||||||
|
|> post("/api/v1/statuses", %{
|
||||||
|
"status" => "Who is the #bestgrill?",
|
||||||
|
"poll" => %{
|
||||||
|
"options" => ["Rei", "Asuka", "Misato"],
|
||||||
|
"expires_in" => 420
|
||||||
|
},
|
||||||
|
"language" => "a_"
|
||||||
|
})
|
||||||
|
|
||||||
|
json_response_and_validate_schema(conn, 422)
|
||||||
|
end
|
||||||
|
|
||||||
test "posting a multilang poll", %{conn: conn} do
|
test "posting a multilang poll", %{conn: conn} do
|
||||||
time = NaiveDateTime.utc_now()
|
time = NaiveDateTime.utc_now()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue