Pleroma API: Add endpoint to get conversation statuses.

This commit is contained in:
lain 2019-08-02 19:53:08 +02:00
parent 56b1c3af13
commit eee98aaa73
6 changed files with 189 additions and 74 deletions

View File

@ -33,4 +33,80 @@ defp param_to_integer(val, default) when is_binary(val) do
end end
defp param_to_integer(_, default), do: default defp param_to_integer(_, default), do: default
def add_link_headers(
conn,
method,
activities,
param \\ nil,
params \\ %{},
func3 \\ nil,
func4 \\ nil
) do
params =
conn.params
|> Map.drop(["since_id", "max_id", "min_id"])
|> Map.merge(params)
last = List.last(activities)
func3 = func3 || (&mastodon_api_url/3)
func4 = func4 || (&mastodon_api_url/4)
if last do
max_id = last.id
limit =
params
|> Map.get("limit", "20")
|> String.to_integer()
min_id =
if length(activities) <= limit do
activities
|> List.first()
|> Map.get(:id)
else
activities
|> Enum.at(limit * -1)
|> Map.get(:id)
end
{next_url, prev_url} =
if param do
{
func4.(
Pleroma.Web.Endpoint,
method,
param,
Map.merge(params, %{max_id: max_id})
),
func4.(
Pleroma.Web.Endpoint,
method,
param,
Map.merge(params, %{min_id: min_id})
)
}
else
{
func3.(
Pleroma.Web.Endpoint,
method,
Map.merge(params, %{max_id: max_id})
),
func3.(
Pleroma.Web.Endpoint,
method,
Map.merge(params, %{min_id: min_id})
)
}
end
conn
|> put_resp_header("link", "<#{next_url}>; rel=\"next\", <#{prev_url}>; rel=\"prev\"")
else
conn
end
end
end end

View File

@ -5,7 +5,8 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [json_response: 3] import Pleroma.Web.ControllerHelper,
only: [json_response: 3, add_link_headers: 5, add_link_headers: 4, add_link_headers: 3]
alias Ecto.Changeset alias Ecto.Changeset
alias Pleroma.Activity alias Pleroma.Activity
@ -342,71 +343,6 @@ def custom_emojis(conn, _params) do
json(conn, mastodon_emoji) json(conn, mastodon_emoji)
end end
defp add_link_headers(conn, method, activities, param \\ nil, params \\ %{}) do
params =
conn.params
|> Map.drop(["since_id", "max_id", "min_id"])
|> Map.merge(params)
last = List.last(activities)
if last do
max_id = last.id
limit =
params
|> Map.get("limit", "20")
|> String.to_integer()
min_id =
if length(activities) <= limit do
activities
|> List.first()
|> Map.get(:id)
else
activities
|> Enum.at(limit * -1)
|> Map.get(:id)
end
{next_url, prev_url} =
if param do
{
mastodon_api_url(
Pleroma.Web.Endpoint,
method,
param,
Map.merge(params, %{max_id: max_id})
),
mastodon_api_url(
Pleroma.Web.Endpoint,
method,
param,
Map.merge(params, %{min_id: min_id})
)
}
else
{
mastodon_api_url(
Pleroma.Web.Endpoint,
method,
Map.merge(params, %{max_id: max_id})
),
mastodon_api_url(
Pleroma.Web.Endpoint,
method,
Map.merge(params, %{min_id: min_id})
)
}
end
conn
|> put_resp_header("link", "<#{next_url}>; rel=\"next\", <#{prev_url}>; rel=\"prev\"")
else
conn
end
end
def home_timeline(%{assigns: %{user: user}} = conn, params) do def home_timeline(%{assigns: %{user: user}} = conn, params) do
params = params =
params params

View File

@ -0,0 +1,49 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 7]
alias Pleroma.Conversation.Participation
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Repo
def conversation_statuses(
%{assigns: %{user: user}} = conn,
%{"id" => participation_id} = params
) do
params =
params
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
participation =
participation_id
|> Participation.get()
|> Repo.preload(:conversation)
if user.id == participation.user_id do
activities =
participation.conversation.ap_id
|> ActivityPub.fetch_activities_for_context(params)
|> Enum.reverse()
conn
|> add_link_headers(
:conversation_statuses,
activities,
participation_id,
params,
nil,
&pleroma_api_url/4
)
|> put_view(StatusView)
|> render("index.json", %{activities: activities, for: user, as: :activity})
end
end
end

View File

@ -257,6 +257,15 @@ defmodule Pleroma.Web.Router do
end end
end end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
pipe_through(:authenticated_api)
scope [] do
pipe_through(:oauth_write)
get("/conversations/:id/statuses", PleromaAPIController, :conversation_statuses)
end
end
scope "/api/v1", Pleroma.Web.MastodonAPI do scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:authenticated_api) pipe_through(:authenticated_api)

View File

@ -239,7 +239,7 @@ test "for public posts, not a reply" do
mentioned_user = insert(:user) mentioned_user = insert(:user)
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "public") {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "public", nil)
assert length(to) == 2 assert length(to) == 2
assert length(cc) == 1 assert length(cc) == 1
@ -256,7 +256,7 @@ test "for public posts, a reply" do
{:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"}) {:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"})
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "public") {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "public", nil)
assert length(to) == 3 assert length(to) == 3
assert length(cc) == 1 assert length(cc) == 1
@ -272,7 +272,7 @@ test "for unlisted posts, not a reply" do
mentioned_user = insert(:user) mentioned_user = insert(:user)
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "unlisted") {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "unlisted", nil)
assert length(to) == 2 assert length(to) == 2
assert length(cc) == 1 assert length(cc) == 1
@ -289,7 +289,7 @@ test "for unlisted posts, a reply" do
{:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"}) {:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"})
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "unlisted") {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "unlisted", nil)
assert length(to) == 3 assert length(to) == 3
assert length(cc) == 1 assert length(cc) == 1
@ -305,7 +305,7 @@ test "for private posts, not a reply" do
mentioned_user = insert(:user) mentioned_user = insert(:user)
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "private") {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "private", nil)
assert length(to) == 2 assert length(to) == 2
assert length(cc) == 0 assert length(cc) == 0
@ -321,7 +321,7 @@ test "for private posts, a reply" do
{:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"}) {:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"})
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private") {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private", nil)
assert length(to) == 3 assert length(to) == 3
assert length(cc) == 0 assert length(cc) == 0
@ -336,7 +336,7 @@ test "for direct posts, not a reply" do
mentioned_user = insert(:user) mentioned_user = insert(:user)
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "direct") {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "direct", nil)
assert length(to) == 1 assert length(to) == 1
assert length(cc) == 0 assert length(cc) == 0
@ -351,7 +351,7 @@ test "for direct posts, a reply" do
{:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"}) {:ok, activity} = CommonAPI.post(third_user, %{"status" => "uguu"})
mentions = [mentioned_user.ap_id] mentions = [mentioned_user.ap_id]
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct") {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct", nil)
assert length(to) == 2 assert length(to) == 2
assert length(cc) == 0 assert length(cc) == 0

View File

@ -0,0 +1,45 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Conversation.Participation
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "/api/v1/pleroma/conversations/:id/statuses", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)
{:ok, _activity} =
CommonAPI.post(user, %{"status" => "Hi @#{third_user.nickname}!", "visibility" => "direct"})
{:ok, activity} =
CommonAPI.post(user, %{"status" => "Hi @#{other_user.nickname}!", "visibility" => "direct"})
[participation] = Participation.for_user(other_user)
{:ok, activity_two} =
CommonAPI.post(other_user, %{
"status" => "Hi!",
"in_reply_to_status_id" => activity.id,
"in_reply_to_conversation_id" => participation.id
})
result =
conn
|> assign(:user, other_user)
|> get("/api/v1/pleroma/conversations/#{participation.id}/statuses")
|> json_response(200)
assert length(result) == 2
id_one = activity.id
id_two = activity_two.id
assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result
end
end