Make force_mentions_in_content multilang aware

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
tusooa 2023-01-15 14:29:13 -05:00 committed by marcin mikołajczak
parent cd0260f309
commit 2d66faf9a4
2 changed files with 100 additions and 25 deletions

View file

@ -78,23 +78,55 @@ defp clean_recipients(recipients, object) do
def filter(
%{
"type" => type,
"object" => %{"type" => "Note", "to" => to, "inReplyTo" => in_reply_to}
} = object
"object" => %{"type" => "Note", "to" => to, "inReplyTo" => in_reply_to} = object
} = activity
)
when type in ["Create", "Update"] and is_list(to) and is_binary(in_reply_to) do
# image-only posts from pleroma apparently reach this MRF without the content field
content = object["object"]["content"] || ""
# Get the replied-to user for sorting
replied_to_user = get_replied_to_user(object["object"])
replied_to_user = get_replied_to_user(object)
mention_users =
to
|> clean_recipients(object)
|> clean_recipients(activity)
|> Enum.map(&User.get_cached_by_ap_id/1)
|> Enum.reject(&is_nil/1)
|> sort_replied_user(replied_to_user)
fixed_object =
with %{} = content_map <- object["contentMap"] do
fixed_content_map =
Enum.reduce(content_map, %{}, fn {lang, content}, acc ->
fixed_content = fix_content(content, mention_users)
Map.put(acc, lang, fixed_content)
end)
object
|> Map.put("contentMap", fixed_content_map)
|> Map.put(
"content",
Pleroma.MultiLanguage.map_to_str(fixed_content_map, multiline: true)
)
else
_ ->
# image-only posts from pleroma apparently reach this MRF without the content field
content = object["content"] || ""
fixed_content = fix_content(content, mention_users)
Map.put(object, "content", fixed_content)
end
{:ok, put_in(activity["object"], fixed_object)}
end
@impl true
def filter(object), do: {:ok, object}
@impl true
def describe, do: {:ok, %{}}
defp fix_content(content, mention_users) do
explicitly_mentioned_uris =
extract_mention_uris_from_content(content)
|> MapSet.new()
@ -113,25 +145,16 @@ def filter(
do: "<span class=\"recipients-inline\">#{added_mentions}</span>",
else: ""
content =
cond do
# For Markdown posts, insert the mentions inside the first <p> tag
recipients_inline != "" && String.starts_with?(content, "<p>") ->
"<p>" <> recipients_inline <> String.trim_leading(content, "<p>")
cond do
# For Markdown posts, insert the mentions inside the first <p> tag
recipients_inline != "" && String.starts_with?(content, "<p>") ->
"<p>" <> recipients_inline <> String.trim_leading(content, "<p>")
recipients_inline != "" ->
recipients_inline <> content
recipients_inline != "" ->
recipients_inline <> content
true ->
content
end
{:ok, put_in(object["object"]["content"], content)}
true ->
content
end
end
@impl true
def filter(object), do: {:ok, object}
@impl true
def describe, do: {:ok, %{}}
end

View file

@ -87,6 +87,58 @@ test "the replied-to user is sorted to the left" do
"<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
end
test "supports mulitlang" do
[mario, luigi, wario] = [
insert(:user, nickname: "mario"),
insert(:user, nickname: "luigi"),
insert(:user, nickname: "wario")
]
{:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
{:ok, post2} =
CommonAPI.post(luigi, %{status: "Oh yaah", in_reply_to_id: post1.id, to: [mario.ap_id]})
activity = %{
"type" => "Create",
"actor" => wario.ap_id,
"object" => %{
"type" => "Note",
"actor" => wario.ap_id,
"content" => "WHA-HA!",
"contentMap" => %{
"a" => "mew mew",
"b" => "lol lol"
},
"to" => [
mario.ap_id,
luigi.ap_id,
Constants.as_public()
],
"inReplyTo" => Object.normalize(post2).data["id"]
}
}
{:ok,
%{
"object" => %{
"content" => content,
"contentMap" =>
%{
"a" => content_a,
"b" => content_b
} = content_map
}
}} = ForceMentionsInContent.filter(activity)
mentions_part =
"<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>"
assert content_a == mentions_part <> "mew mew"
assert content_b == mentions_part <> "lol lol"
assert content == Pleroma.MultiLanguage.map_to_str(content_map, multiline: true)
end
test "don't mention self" do
mario = insert(:user, nickname: "mario")