Merge remote-tracking branch 'origin/develop' into quote-post
This commit is contained in:
commit
deff42f034
3 changed files with 115 additions and 7 deletions
|
@ -10,7 +10,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy do
|
|||
require Pleroma.Constants
|
||||
|
||||
defp check_by_actor_type(user), do: user.actor_type in ["Application", "Service"]
|
||||
defp check_by_nickname(user), do: Regex.match?(~r/bot@|ebooks@/i, user.nickname)
|
||||
defp check_by_nickname(user), do: Regex.match?(~r/.bot@|ebooks@/i, user.nickname)
|
||||
|
||||
defp check_if_bot(user), do: check_by_actor_type(user) or check_by_nickname(user)
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Formatter
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
|
@ -58,9 +60,25 @@ defp sort_replied_user(users, %User{id: user_id} = user) do
|
|||
|
||||
defp sort_replied_user(users, _), do: users
|
||||
|
||||
# Drop constants and the actor's own AP ID
|
||||
defp clean_recipients(recipients, object) do
|
||||
Enum.reject(recipients, fn ap_id ->
|
||||
ap_id in [
|
||||
object["object"]["actor"],
|
||||
Pleroma.Constants.as_public(),
|
||||
Pleroma.Web.ActivityPub.Utils.as_local_public()
|
||||
]
|
||||
end)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Create", "object" => %{"type" => "Note", "to" => to}} = object)
|
||||
when is_list(to) do
|
||||
def filter(
|
||||
%{
|
||||
"type" => "Create",
|
||||
"object" => %{"type" => "Note", "to" => to, "inReplyTo" => in_reply_to}
|
||||
} = object
|
||||
)
|
||||
when 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"] || ""
|
||||
|
||||
|
@ -69,6 +87,7 @@ def filter(%{"type" => "Create", "object" => %{"type" => "Note", "to" => to}} =
|
|||
|
||||
mention_users =
|
||||
to
|
||||
|> clean_recipients(object)
|
||||
|> Enum.map(&User.get_cached_by_ap_id/1)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> sort_replied_user(replied_to_user)
|
||||
|
@ -84,10 +103,23 @@ def filter(%{"type" => "Create", "object" => %{"type" => "Note", "to" => to}} =
|
|||
end
|
||||
end)
|
||||
|
||||
content =
|
||||
recipients_inline =
|
||||
if added_mentions != "",
|
||||
do: "<span class=\"recipients-inline\">#{added_mentions}</span>" <> content,
|
||||
else: content
|
||||
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>")
|
||||
|
||||
recipients_inline != "" ->
|
||||
recipients_inline <> content
|
||||
|
||||
true ->
|
||||
content
|
||||
end
|
||||
|
||||
{:ok, put_in(object["object"]["content"], content)}
|
||||
end
|
||||
|
|
|
@ -49,7 +49,7 @@ test "adds mentions to post content" do
|
|||
{:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
|
||||
|
||||
assert filtered ==
|
||||
"<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{dielan.id}\" href=\"https://shitposter.club/users/dielan\" rel=\"ugc\">@<span>dielan</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{coolboymew.id}\" href=\"https://shitposter.club/users/coolboymew\" rel=\"ugc\">@<span>coolboymew</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{fence.id}\" href=\"https://xyzzy.link/users/fence\" rel=\"ugc\">@<span>fence</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{hakui.id}\" href=\"https://tuusin.misono-ya.info/users/hakui\" rel=\"ugc\">@<span>hakui</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{lain.id}\" href=\"https://lain.com/users/lain\" rel=\"ugc\">@<span>lain</span></a></span> </span><p>Haha yeah, you can control who you reply to.</p>"
|
||||
"<p><span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{dielan.id}\" href=\"https://shitposter.club/users/dielan\" rel=\"ugc\">@<span>dielan</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{coolboymew.id}\" href=\"https://shitposter.club/users/coolboymew\" rel=\"ugc\">@<span>coolboymew</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{fence.id}\" href=\"https://xyzzy.link/users/fence\" rel=\"ugc\">@<span>fence</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{hakui.id}\" href=\"https://tuusin.misono-ya.info/users/hakui\" rel=\"ugc\">@<span>hakui</span></a></span> <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{lain.id}\" href=\"https://lain.com/users/lain\" rel=\"ugc\">@<span>lain</span></a></span> </span>Haha yeah, you can control who you reply to.</p>"
|
||||
end
|
||||
|
||||
test "the replied-to user is sorted to the left" do
|
||||
|
@ -85,4 +85,80 @@ test "the replied-to user is sorted to the left" do
|
|||
assert filtered ==
|
||||
"<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 "don't mention self" do
|
||||
mario = insert(:user, nickname: "mario")
|
||||
|
||||
{:ok, post} = CommonAPI.post(mario, %{status: "Mama mia"})
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => mario.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => mario.ap_id,
|
||||
"content" => "I'ma tired...",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => Object.normalize(post).data["id"]
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
|
||||
assert filtered == "I'ma tired..."
|
||||
end
|
||||
|
||||
test "don't mention in top-level posts" do
|
||||
mario = insert(:user, nickname: "mario")
|
||||
luigi = insert(:user, nickname: "luigi")
|
||||
|
||||
{:ok, post} = CommonAPI.post(mario, %{status: "Letsa go"})
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => mario.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => mario.ap_id,
|
||||
"content" => "Mama mia!",
|
||||
"to" => [
|
||||
luigi.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"quoteUrl" => Object.normalize(post).data["id"]
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
|
||||
assert filtered == "Mama mia!"
|
||||
end
|
||||
|
||||
test "with markdown formatting" do
|
||||
mario = insert(:user, nickname: "mario")
|
||||
luigi = insert(:user, nickname: "luigi")
|
||||
|
||||
{:ok, post} = CommonAPI.post(luigi, %{status: "Mama mia"})
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => mario.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => mario.ap_id,
|
||||
"content" => "<p>I'ma tired...</p>",
|
||||
"to" => [
|
||||
luigi.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => Object.normalize(post).data["id"]
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
|
||||
|
||||
assert filtered ==
|
||||
"<p><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>I'ma tired...</p>"
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue