expanding filtration for home timeline
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Tue, 26 Jan 2021 08:58:54 +0000 (11:58 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Mon, 1 Feb 2021 11:11:11 +0000 (14:11 +0300)
added local & remote statuses filtration for home timeline

lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/api_spec/operations/timeline_operation.ex
lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs

index d0bb07aab8f2327a2acab59901bf1f7a671a2a70..58e868119daa3444b4b111a6e44758d8abee6eea 100644 (file)
@@ -735,6 +735,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_local(query, _), do: query
 
+  defp restrict_remote(query, %{only_remote: true}) do
+    from(activity in query, where: activity.local == false)
+  end
+
+  defp restrict_remote(query, _), do: query
+
   defp restrict_actor(query, %{actor_id: actor_id}) do
     from(activity in query, where: activity.actor == ^actor_id)
   end
@@ -1111,6 +1117,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> restrict_tag_all(opts)
     |> restrict_since(opts)
     |> restrict_local(opts)
+    |> restrict_remote(opts)
     |> restrict_actor(opts)
     |> restrict_type(opts)
     |> restrict_state(opts)
index e1ebdab389c781b643d4ce05ab0c0d907393340a..2f44cb70d9c2bd88f7d3fb72d11c5d19b5fdf7a4 100644 (file)
@@ -25,6 +25,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
       security: [%{"oAuth" => ["read:statuses"]}],
       parameters: [
         local_param(),
+        remote_param(),
         with_muted_param(),
         exclude_visibilities_param(),
         reply_visibility_param() | pagination_params()
@@ -198,4 +199,13 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
       "Show only statuses with media attached?"
     )
   end
+
+  defp remote_param do
+    Operation.parameter(
+      :only_remote,
+      :query,
+      %Schema{allOf: [BooleanLike], default: false},
+      "Show only remote statuses?"
+    )
+  end
 end
index 08e6f23b98cf8eb8fa8a261c030795359e37a7da..b63945912a513a7ae5543bfabfd44604d3df33a9 100644 (file)
@@ -51,6 +51,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
       |> Map.put(:reply_filtering_user, user)
       |> Map.put(:announce_filtering_user, user)
       |> Map.put(:user, user)
+      |> Map.put(:local_only, params[:local])
+      |> Map.delete(:local)
 
     activities =
       [user.ap_id | User.following(user)]
index 664375fef162a362091f3fee4437f9b12e7b5d83..30118f74eaa0f53a3a22ee7d2f1d73201f221e05 100644 (file)
@@ -90,6 +90,82 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
                }
              ] = result
     end
+
+    test "local/remote filtering", %{conn: conn, user: user} do
+      local = insert(:user)
+      remote = insert(:user, local: false)
+
+      {:ok, user, local} = User.follow(user, local)
+      {:ok, _user, remote} = User.follow(user, remote)
+
+      object1 =
+        insert(:note, %{
+          data: %{
+            "to" => ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(local)]
+          },
+          user: local
+        })
+
+      activity1 =
+        insert(:note_activity, %{
+          note: object1,
+          recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(local)],
+          user: local
+        })
+
+      object2 =
+        insert(:note, %{
+          data: %{
+            "to" => ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(remote)]
+          },
+          user: remote
+        })
+
+      activity2 =
+        insert(:note_activity, %{
+          note: object2,
+          recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(remote)],
+          user: remote,
+          local: false
+        })
+
+      resp1 =
+        conn
+        |> get("/api/v1/timelines/home")
+        |> json_response_and_validate_schema(200)
+
+      without_filter_ids = Enum.map(resp1, & &1["id"])
+
+      assert activity1.id in without_filter_ids
+      assert activity2.id in without_filter_ids
+
+      resp2 =
+        conn
+        |> get("/api/v1/timelines/home?local=true")
+        |> json_response_and_validate_schema(200)
+
+      only_local_ids = Enum.map(resp2, & &1["id"])
+
+      assert activity1.id in only_local_ids
+      refute activity2.id in only_local_ids
+
+      resp3 =
+        conn
+        |> get("/api/v1/timelines/home?only_remote=true")
+        |> json_response_and_validate_schema(200)
+
+      only_remote_ids = Enum.map(resp3, & &1["id"])
+
+      refute activity1.id in only_remote_ids
+      assert activity2.id in only_remote_ids
+
+      resp4 =
+        conn
+        |> get("/api/v1/timelines/home?only_remote=true&local=true")
+        |> json_response_and_validate_schema(200)
+
+      assert resp4 == []
+    end
   end
 
   describe "public" do