forked from AkkomaGang/akkoma
CommonAPI: Extend api with conversation replies.
This commit is contained in:
parent
f88560accd
commit
56b1c3af13
4 changed files with 70 additions and 13 deletions
|
@ -93,4 +93,10 @@ def for_user_with_last_activity_id(user, params \\ %{}) do
|
||||||
end)
|
end)
|
||||||
|> Enum.filter(& &1.last_activity_id)
|
|> Enum.filter(& &1.last_activity_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get(nil), do: nil
|
||||||
|
|
||||||
|
def get(id) do
|
||||||
|
Repo.get(__MODULE__, id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.CommonAPI do
|
defmodule Pleroma.Web.CommonAPI do
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Conversation.Participation
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.ThreadMute
|
alias Pleroma.ThreadMute
|
||||||
|
@ -171,21 +172,25 @@ defp normalize_and_validate_choice_indices(choices, count) do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_visibility(%{"visibility" => visibility}, in_reply_to)
|
def get_visibility(_, _, %Participation{}) do
|
||||||
|
{"direct", "direct"}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_visibility(%{"visibility" => visibility}, in_reply_to, _)
|
||||||
when visibility in ~w{public unlisted private direct},
|
when visibility in ~w{public unlisted private direct},
|
||||||
do: {visibility, get_replied_to_visibility(in_reply_to)}
|
do: {visibility, get_replied_to_visibility(in_reply_to)}
|
||||||
|
|
||||||
def get_visibility(%{"visibility" => "list:" <> list_id}, in_reply_to) do
|
def get_visibility(%{"visibility" => "list:" <> list_id}, in_reply_to, _) do
|
||||||
visibility = {:list, String.to_integer(list_id)}
|
visibility = {:list, String.to_integer(list_id)}
|
||||||
{visibility, get_replied_to_visibility(in_reply_to)}
|
{visibility, get_replied_to_visibility(in_reply_to)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_visibility(_, in_reply_to) when not is_nil(in_reply_to) do
|
def get_visibility(_, in_reply_to, _) when not is_nil(in_reply_to) do
|
||||||
visibility = get_replied_to_visibility(in_reply_to)
|
visibility = get_replied_to_visibility(in_reply_to)
|
||||||
{visibility, visibility}
|
{visibility, visibility}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_visibility(_, in_reply_to), do: {"public", get_replied_to_visibility(in_reply_to)}
|
def get_visibility(_, in_reply_to, _), do: {"public", get_replied_to_visibility(in_reply_to)}
|
||||||
|
|
||||||
def get_replied_to_visibility(nil), do: nil
|
def get_replied_to_visibility(nil), do: nil
|
||||||
|
|
||||||
|
@ -201,7 +206,9 @@ def post(user, %{"status" => status} = data) do
|
||||||
with status <- String.trim(status),
|
with status <- String.trim(status),
|
||||||
attachments <- attachments_from_ids(data),
|
attachments <- attachments_from_ids(data),
|
||||||
in_reply_to <- get_replied_to_activity(data["in_reply_to_status_id"]),
|
in_reply_to <- get_replied_to_activity(data["in_reply_to_status_id"]),
|
||||||
{visibility, in_reply_to_visibility} <- get_visibility(data, in_reply_to),
|
in_reply_to_conversation <- Participation.get(data["in_reply_to_conversation_id"]),
|
||||||
|
{visibility, in_reply_to_visibility} <-
|
||||||
|
get_visibility(data, in_reply_to, in_reply_to_conversation),
|
||||||
{_, false} <-
|
{_, false} <-
|
||||||
{:private_to_public, in_reply_to_visibility == "direct" && visibility != "direct"},
|
{:private_to_public, in_reply_to_visibility == "direct" && visibility != "direct"},
|
||||||
{content_html, mentions, tags} <-
|
{content_html, mentions, tags} <-
|
||||||
|
@ -214,7 +221,8 @@ def post(user, %{"status" => status} = data) do
|
||||||
mentioned_users <- for({_, mentioned_user} <- mentions, do: mentioned_user.ap_id),
|
mentioned_users <- for({_, mentioned_user} <- mentions, do: mentioned_user.ap_id),
|
||||||
addressed_users <- get_addressed_users(mentioned_users, data["to"]),
|
addressed_users <- get_addressed_users(mentioned_users, data["to"]),
|
||||||
{poll, poll_emoji} <- make_poll_data(data),
|
{poll, poll_emoji} <- make_poll_data(data),
|
||||||
{to, cc} <- get_to_and_cc(user, addressed_users, in_reply_to, visibility),
|
{to, cc} <-
|
||||||
|
get_to_and_cc(user, addressed_users, in_reply_to, visibility, in_reply_to_conversation),
|
||||||
context <- make_context(in_reply_to),
|
context <- make_context(in_reply_to),
|
||||||
cw <- data["spoiler_text"] || "",
|
cw <- data["spoiler_text"] || "",
|
||||||
sensitive <- data["sensitive"] || Enum.member?(tags, {"#nsfw", "nsfw"}),
|
sensitive <- data["sensitive"] || Enum.member?(tags, {"#nsfw", "nsfw"}),
|
||||||
|
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
||||||
alias Calendar.Strftime
|
alias Calendar.Strftime
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.Conversation.Participation
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Plugs.AuthenticationPlug
|
alias Pleroma.Plugs.AuthenticationPlug
|
||||||
|
@ -64,9 +65,21 @@ def attachments_from_ids_descs(ids, descs_str) do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec get_to_and_cc(User.t(), list(String.t()), Activity.t() | nil, String.t()) ::
|
@spec get_to_and_cc(
|
||||||
|
User.t(),
|
||||||
|
list(String.t()),
|
||||||
|
Activity.t() | nil,
|
||||||
|
String.t(),
|
||||||
|
Participation.t() | nil
|
||||||
|
) ::
|
||||||
{list(String.t()), list(String.t())}
|
{list(String.t()), list(String.t())}
|
||||||
def get_to_and_cc(user, mentioned_users, inReplyTo, "public") do
|
|
||||||
|
def get_to_and_cc(_, _, _, _, %Participation{} = participation) do
|
||||||
|
participation = Repo.preload(participation, :recipients)
|
||||||
|
{Enum.map(participation.recipients, & &1.ap_id), []}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_to_and_cc(user, mentioned_users, inReplyTo, "public", _) do
|
||||||
to = [Pleroma.Constants.as_public() | mentioned_users]
|
to = [Pleroma.Constants.as_public() | mentioned_users]
|
||||||
cc = [user.follower_address]
|
cc = [user.follower_address]
|
||||||
|
|
||||||
|
@ -77,7 +90,7 @@ def get_to_and_cc(user, mentioned_users, inReplyTo, "public") do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_to_and_cc(user, mentioned_users, inReplyTo, "unlisted") do
|
def get_to_and_cc(user, mentioned_users, inReplyTo, "unlisted", _) do
|
||||||
to = [user.follower_address | mentioned_users]
|
to = [user.follower_address | mentioned_users]
|
||||||
cc = [Pleroma.Constants.as_public()]
|
cc = [Pleroma.Constants.as_public()]
|
||||||
|
|
||||||
|
@ -88,12 +101,12 @@ def get_to_and_cc(user, mentioned_users, inReplyTo, "unlisted") do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_to_and_cc(user, mentioned_users, inReplyTo, "private") do
|
def get_to_and_cc(user, mentioned_users, inReplyTo, "private", _) do
|
||||||
{to, cc} = get_to_and_cc(user, mentioned_users, inReplyTo, "direct")
|
{to, cc} = get_to_and_cc(user, mentioned_users, inReplyTo, "direct", nil)
|
||||||
{[user.follower_address | to], cc}
|
{[user.follower_address | to], cc}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_to_and_cc(_user, mentioned_users, inReplyTo, "direct") do
|
def get_to_and_cc(_user, mentioned_users, inReplyTo, "direct", _) do
|
||||||
if inReplyTo do
|
if inReplyTo do
|
||||||
{Enum.uniq([inReplyTo.data["actor"] | mentioned_users]), []}
|
{Enum.uniq([inReplyTo.data["actor"] | mentioned_users]), []}
|
||||||
else
|
else
|
||||||
|
@ -101,7 +114,7 @@ def get_to_and_cc(_user, mentioned_users, inReplyTo, "direct") do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_to_and_cc(_user, mentions, _inReplyTo, {:list, _}), do: {mentions, []}
|
def get_to_and_cc(_user, mentions, _inReplyTo, {:list, _}, _), do: {mentions, []}
|
||||||
|
|
||||||
def get_addressed_users(_, to) when is_list(to) do
|
def get_addressed_users(_, to) when is_list(to) do
|
||||||
User.get_ap_ids_by_nicknames(to)
|
User.get_ap_ids_by_nicknames(to)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
defmodule Pleroma.Web.CommonAPITest do
|
defmodule Pleroma.Web.CommonAPITest do
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Conversation.Participation
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
@ -12,6 +13,35 @@ defmodule Pleroma.Web.CommonAPITest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
test "when replying to a conversation / participation, it only mentions the recipients explicitly declared in the participation" do
|
||||||
|
har = insert(:user)
|
||||||
|
jafnhar = insert(:user)
|
||||||
|
tridi = insert(:user)
|
||||||
|
|
||||||
|
{:ok, activity} =
|
||||||
|
CommonAPI.post(har, %{
|
||||||
|
"status" => "@#{jafnhar.nickname} hey",
|
||||||
|
"visibility" => "direct"
|
||||||
|
})
|
||||||
|
|
||||||
|
assert har.ap_id in activity.recipients
|
||||||
|
assert jafnhar.ap_id in activity.recipients
|
||||||
|
|
||||||
|
[participation] = Participation.for_user(har)
|
||||||
|
|
||||||
|
{:ok, activity} =
|
||||||
|
CommonAPI.post(har, %{
|
||||||
|
"status" => "I don't really like @#{tridi.nickname}",
|
||||||
|
"visibility" => "direct",
|
||||||
|
"in_reply_to_status_id" => activity.id,
|
||||||
|
"in_reply_to_conversation_id" => participation.id
|
||||||
|
})
|
||||||
|
|
||||||
|
assert har.ap_id in activity.recipients
|
||||||
|
assert jafnhar.ap_id in activity.recipients
|
||||||
|
refute tridi.ap_id in activity.recipients
|
||||||
|
end
|
||||||
|
|
||||||
test "with the safe_dm_mention option set, it does not mention people beyond the initial tags" do
|
test "with the safe_dm_mention option set, it does not mention people beyond the initial tags" do
|
||||||
har = insert(:user)
|
har = insert(:user)
|
||||||
jafnhar = insert(:user)
|
jafnhar = insert(:user)
|
||||||
|
|
Loading…
Reference in a new issue