forked from AkkomaGang/akkoma
Pleroma API: Add endpoint to get conversation statuses.
This commit is contained in:
parent
56b1c3af13
commit
eee98aaa73
6 changed files with 189 additions and 74 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
49
lib/pleroma/web/pleroma_api/pleroma_api_controller.ex
Normal file
49
lib/pleroma/web/pleroma_api/pleroma_api_controller.ex
Normal 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
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
45
test/web/pleroma_api/pleroma_api_controller_test.exs
Normal file
45
test/web/pleroma_api/pleroma_api_controller_test.exs
Normal 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
|
Loading…
Reference in a new issue