Add an endpoint to get multiple statuses by IDs
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 3 Sep 2019 09:23:03 +0000 (16:23 +0700)
committerEgor Kislitsyn <egor@kislitsyn.com>
Tue, 10 Sep 2019 06:39:45 +0000 (13:39 +0700)
CHANGELOG.md
docs/api/differences_in_mastoapi_responses.md
lib/pleroma/activity.ex
lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
lib/pleroma/web/router.ex
test/activity_test.exs
test/web/mastodon_api/mastodon_api_controller_test.exs

index a3fa9dfb67600a9699a2fa63abf31055df0cda30..f7f1aee0e38bb5facefd87e7600b00a6d3f2de21 100644 (file)
@@ -110,6 +110,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Federation: Remove `likes` from objects.
 - Admin API: Added moderation log
 - Web response cache (currently, enabled for ActivityPub)
+- Mastodon API: Added an endpoint to get multiple statuses by IDs (`GET /api/v1/statuses/?ids[]=1&ids[]=2`)
 
 ### Changed
 - Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
index 02f90f3e89dd294e30a8adeb91af6f64fe05bb13..a21eebc962d9ffb79e19bc05f0c0a03f45e84508 100644 (file)
@@ -91,6 +91,18 @@ Additional parameters can be added to the JSON body/Form data:
 - `expires_in`: The number of seconds the posted activity should expire in. When a posted activity expires it will be deleted from the server, and a delete request for it will be federated. This needs to be longer than an hour.
 - `in_reply_to_conversation_id`: Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`.
 
+## GET `/api/v1/statuses`
+
+An endpoint to get multiple statuses by IDs.
+
+Required parameters:
+
+- `ids`: array of activity ids
+
+Usage example: `GET /api/v1/statuses/?ids[]=1&ids[]=2`.
+
+Returns: array of Status.
+
 ## PATCH `/api/v1/update_credentials`
 
 Additional parameters can be added to the JSON body/Form data:
index 6a51d4cf36a8de08c0d802904bb81c857ac53c1d..44f1e30110bcaaa3c206ab082fa062ccb3626bcc 100644 (file)
@@ -173,6 +173,13 @@ defmodule Pleroma.Activity do
     |> Repo.one()
   end
 
+  def all_by_ids_with_object(ids) do
+    Activity
+    |> where([a], a.id in ^ids)
+    |> with_preloaded_object()
+    |> Repo.all()
+  end
+
   def by_object_ap_id(ap_id) do
     from(
       activity in Activity,
index 8dfad7a54e8d695c664508c6398e269b201e76e6..c54462bb38a51d4a4d3ed04cf39b50b26f494ec0 100644 (file)
@@ -427,6 +427,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     |> render("index.json", %{activities: activities, for: user, as: :activity})
   end
 
+  def get_statuses(%{assigns: %{user: user}} = conn, %{"ids" => ids}) do
+    limit = 100
+
+    activities =
+      ids
+      |> Enum.take(limit)
+      |> Activity.all_by_ids_with_object()
+      |> Enum.filter(&Visibility.visible_for_user?(&1, user))
+
+    conn
+    |> put_view(StatusView)
+    |> render("index.json", activities: activities, for: user, as: :activity)
+  end
+
   def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
     with %Activity{} = activity <- Activity.get_by_id_with_object(id),
          true <- Visibility.visible_for_user?(activity, user) do
index cfb973f532def19d8b81029763db4015dad20ed0..7cd59acb2725d28d4b9ca04b66556a0f24fcaece 100644 (file)
@@ -443,6 +443,7 @@ defmodule Pleroma.Web.Router do
       get("/timelines/tag/:tag", MastodonAPIController, :hashtag_timeline)
       get("/timelines/list/:list_id", MastodonAPIController, :list_timeline)
 
+      get("/statuses", MastodonAPIController, :get_statuses)
       get("/statuses/:id", MastodonAPIController, :get_status)
       get("/statuses/:id/context", MastodonAPIController, :get_context)
 
index 785c4b3cf2bff8897fe655f960a7b900ac8f8b45..49654bd67f157497d433aba609532ab87fc9e6a2 100644 (file)
@@ -173,4 +173,12 @@ defmodule Pleroma.ActivityTest do
     |> where([a], a.activity_id == ^activity.id)
     |> Repo.one!()
   end
+
+  test "all_by_ids_with_object/1" do
+    %{id: id1} = insert(:note_activity)
+    %{id: id2} = insert(:note_activity)
+
+    assert [%{id: ^id1, object: %Object{}}, %{id: ^id2, object: %Object{}}] =
+             Activity.all_by_ids_with_object([id1, id2])
+  end
 end
index e18f8f0d1df842035d08ab14f8738204c07adab2..f4902d04398843c8463afeabc109afb834d56531 100644 (file)
@@ -744,6 +744,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
     assert id == to_string(activity.id)
   end
 
+  test "get statuses by IDs", %{conn: conn} do
+    %{id: id1} = insert(:note_activity)
+    %{id: id2} = insert(:note_activity)
+
+    query_string = "ids[]=#{id1}&ids[]=#{id2}"
+    conn = get(conn, "/api/v1/statuses/?#{query_string}")
+
+    assert [%{"id" => ^id1}, %{"id" => ^id2}] = json_response(conn, :ok)
+  end
+
   describe "deleting a status" do
     test "when you created it", %{conn: conn} do
       activity = insert(:note_activity)