Add language support on /api/v1/statuses
This commit is contained in:
parent
6965a2f163
commit
f86bf16430
6 changed files with 64 additions and 5 deletions
11
lib/pleroma/iso639.ex
Normal file
11
lib/pleroma/iso639.ex
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
defmodule Pleroma.ISO639 do
|
||||||
|
@file "priv/language-codes.json"
|
||||||
|
@data File.read!(@file)
|
||||||
|
|> Jason.decode!()
|
||||||
|
|
||||||
|
for %{"alpha2" => alpha2} <- @data do
|
||||||
|
def valid_alpha2?(unquote(alpha2)), do: true
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid_alpha2?(_alpha2), do: false
|
||||||
|
end
|
|
@ -30,6 +30,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
||||||
|
|
||||||
field(:replies, {:array, ObjectValidators.ObjectID}, default: [])
|
field(:replies, {:array, ObjectValidators.ObjectID}, default: [])
|
||||||
field(:source, :map)
|
field(:source, :map)
|
||||||
|
field(:content_map, :map)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cast_and_apply(data) do
|
def cast_and_apply(data) do
|
||||||
|
@ -146,6 +147,20 @@ defp fix_source(%{"source" => source} = object) when is_binary(source) do
|
||||||
|
|
||||||
defp fix_source(object), do: object
|
defp fix_source(object), do: object
|
||||||
|
|
||||||
|
defp fix_content_map_languages(%{"contentMap" => content_map} = object)
|
||||||
|
when is_map(content_map) do
|
||||||
|
# Only allow valid languages
|
||||||
|
content_map =
|
||||||
|
content_map
|
||||||
|
|> Enum.reject(fn {lang, content} ->
|
||||||
|
!Pleroma.ISO639.valid_alpha2?(lang)
|
||||||
|
end)
|
||||||
|
|
||||||
|
Map.put(object, "contentMap", content_map)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp fix_content_map_languages(object), do: object
|
||||||
|
|
||||||
defp fix(data) do
|
defp fix(data) do
|
||||||
data
|
data
|
||||||
|> CommonFixes.fix_actor()
|
|> CommonFixes.fix_actor()
|
||||||
|
@ -158,6 +173,7 @@ defp fix(data) do
|
||||||
|> Transmogrifier.fix_attachments()
|
|> Transmogrifier.fix_attachments()
|
||||||
|> Transmogrifier.fix_emoji()
|
|> Transmogrifier.fix_emoji()
|
||||||
|> Transmogrifier.fix_content_map()
|
|> Transmogrifier.fix_content_map()
|
||||||
|
|> fix_content_map_languages()
|
||||||
end
|
end
|
||||||
|
|
||||||
def changeset(struct, data) do
|
def changeset(struct, data) do
|
||||||
|
|
|
@ -22,6 +22,8 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
|
||||||
attachments: [],
|
attachments: [],
|
||||||
in_reply_to: nil,
|
in_reply_to: nil,
|
||||||
in_reply_to_conversation: nil,
|
in_reply_to_conversation: nil,
|
||||||
|
language: nil,
|
||||||
|
content_map: %{},
|
||||||
quote_id: nil,
|
quote_id: nil,
|
||||||
quote: nil,
|
quote: nil,
|
||||||
visibility: nil,
|
visibility: nil,
|
||||||
|
@ -58,6 +60,7 @@ def create(user, params) do
|
||||||
|> with_valid(&visibility/1)
|
|> with_valid(&visibility/1)
|
||||||
|> with_valid("e_id/1)
|
|> with_valid("e_id/1)
|
||||||
|> content()
|
|> content()
|
||||||
|
|> with_valid(&language/1)
|
||||||
|> with_valid(&to_and_cc/1)
|
|> with_valid(&to_and_cc/1)
|
||||||
|> with_valid(&context/1)
|
|> with_valid(&context/1)
|
||||||
|> sensitive()
|
|> sensitive()
|
||||||
|
@ -133,6 +136,17 @@ defp quote_id(%{params: %{quote_id: %Activity{} = quote}} = draft) do
|
||||||
|
|
||||||
defp quote_id(draft), do: draft
|
defp quote_id(draft), do: draft
|
||||||
|
|
||||||
|
defp language(%{params: %{language: language}, content_html: content} = draft)
|
||||||
|
when is_binary(language) do
|
||||||
|
if Pleroma.ISO639.valid_alpha2?(language) do
|
||||||
|
%__MODULE__{draft | content_map: %{language => content}}
|
||||||
|
else
|
||||||
|
add_error(draft, dgettext("errors", "Invalid language"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp language(draft), do: draft
|
||||||
|
|
||||||
defp visibility(%{params: params} = draft) do
|
defp visibility(%{params: params} = draft) do
|
||||||
case CommonAPI.get_visibility(params, draft.in_reply_to, draft.in_reply_to_conversation) do
|
case CommonAPI.get_visibility(params, draft.in_reply_to, draft.in_reply_to_conversation) do
|
||||||
{visibility, "direct"} when visibility != "direct" ->
|
{visibility, "direct"} when visibility != "direct" ->
|
||||||
|
@ -224,6 +238,7 @@ defp object(draft) do
|
||||||
"mediaType" => Utils.get_content_type(draft.params[:content_type])
|
"mediaType" => Utils.get_content_type(draft.params[:content_type])
|
||||||
})
|
})
|
||||||
|> Map.put("generator", draft.params[:generator])
|
|> Map.put("generator", draft.params[:generator])
|
||||||
|
|> Map.put("contentMap", draft.content_map)
|
||||||
|
|
||||||
%__MODULE__{draft | object: object}
|
%__MODULE__{draft | object: object}
|
||||||
end
|
end
|
||||||
|
|
|
@ -169,6 +169,7 @@ def render(
|
||||||
|> Enum.map(fn user -> AccountView.render("mention.json", %{user: user}) end)
|
|> Enum.map(fn user -> AccountView.render("mention.json", %{user: user}) end)
|
||||||
|
|
||||||
{pinned?, pinned_at} = pin_data(object, user)
|
{pinned?, pinned_at} = pin_data(object, user)
|
||||||
|
lang = language(object)
|
||||||
|
|
||||||
%{
|
%{
|
||||||
id: to_string(activity.id),
|
id: to_string(activity.id),
|
||||||
|
@ -199,7 +200,7 @@ def render(
|
||||||
mentions: mentions,
|
mentions: mentions,
|
||||||
tags: reblogged[:tags] || [],
|
tags: reblogged[:tags] || [],
|
||||||
application: build_application(object.data["generator"]),
|
application: build_application(object.data["generator"]),
|
||||||
language: nil,
|
language: lang,
|
||||||
emojis: [],
|
emojis: [],
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
local: activity.local,
|
local: activity.local,
|
||||||
|
@ -357,6 +358,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
||||||
{pinned?, pinned_at} = pin_data(object, user)
|
{pinned?, pinned_at} = pin_data(object, user)
|
||||||
|
|
||||||
quote = Activity.get_quoted_activity_from_object(object)
|
quote = Activity.get_quoted_activity_from_object(object)
|
||||||
|
lang = language(object)
|
||||||
|
|
||||||
%{
|
%{
|
||||||
id: to_string(activity.id),
|
id: to_string(activity.id),
|
||||||
|
@ -391,7 +393,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
||||||
mentions: mentions,
|
mentions: mentions,
|
||||||
tags: build_tags(tags),
|
tags: build_tags(tags),
|
||||||
application: build_application(object.data["generator"]),
|
application: build_application(object.data["generator"]),
|
||||||
language: nil,
|
language: lang,
|
||||||
emojis: build_emojis(object.data["emoji"]),
|
emojis: build_emojis(object.data["emoji"]),
|
||||||
quote_id: if(quote, do: quote.id, else: nil),
|
quote_id: if(quote, do: quote.id, else: nil),
|
||||||
quote: maybe_render_quote(quote, opts),
|
quote: maybe_render_quote(quote, opts),
|
||||||
|
@ -784,4 +786,12 @@ defp get_source_content_type(%{"mediaType" => type} = _source) do
|
||||||
defp get_source_content_type(_source) do
|
defp get_source_content_type(_source) do
|
||||||
Utils.get_content_type(nil)
|
Utils.get_content_type(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp language(%Object{data: %{"contentMap" => contentMap}}) when is_map(contentMap) do
|
||||||
|
contentMap
|
||||||
|
|> Map.keys()
|
||||||
|
|> Enum.at(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp language(_), do: nil
|
||||||
end
|
end
|
||||||
|
|
1
priv/language-codes.json
Normal file
1
priv/language-codes.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -67,11 +67,17 @@ test "posting a status", %{conn: conn} do
|
||||||
|> post("/api/v1/statuses", %{
|
|> post("/api/v1/statuses", %{
|
||||||
"status" => "cofe",
|
"status" => "cofe",
|
||||||
"spoiler_text" => "2hu",
|
"spoiler_text" => "2hu",
|
||||||
"sensitive" => "0"
|
"sensitive" => "0",
|
||||||
|
"language" => "ja"
|
||||||
})
|
})
|
||||||
|
|
||||||
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" => "ja"
|
||||||
|
} = json_response_and_validate_schema(conn_one, 200)
|
||||||
|
|
||||||
assert Activity.get_by_id(id)
|
assert Activity.get_by_id(id)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue