Implement exclude_reblogs and include_rts
authorVyr Cossont <600-VyrCossont@users.noreply.git.pleroma.social>
Thu, 27 Dec 2018 05:30:01 +0000 (21:30 -0800)
committerVyr Cossont <600-VyrCossont@users.noreply.git.pleroma.social>
Thu, 27 Dec 2018 05:38:00 +0000 (21:38 -0800)
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex
test/web/activity_pub/activity_pub_test.exs
test/web/mastodon_api/mastodon_api_controller_test.exs
test/web/twitter_api/twitter_api_controller_test.exs

index 1880607805ae7859f40a282f2cdc241e331f4bb1..2d4cc9f6850078ba9541f85ec51f391857b5ddb2 100644 (file)
@@ -503,6 +503,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_replies(query, _), do: query
 
+  defp restrict_reblogs(query, %{"exclude_reblogs" => val}) when val == "true" or val == "1" do
+    from(activity in query, where: fragment("?->>'type' != 'Announce'", activity.data))
+  end
+
+  defp restrict_reblogs(query, _), do: query
+
   # Only search through last 100_000 activities by default
   defp restrict_recent(query, %{"whole_db" => true}), do: query
 
@@ -561,6 +567,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> restrict_media(opts)
     |> restrict_visibility(opts)
     |> restrict_replies(opts)
+    |> restrict_reblogs(opts)
   end
 
   def fetch_activities(recipients, opts \\ %{}) do
index c25cb08768f993ace91764da13568167c6cb7f9f..7ae850d71471544f3f48392bdd6fe6a55d1bafe4 100644 (file)
@@ -130,6 +130,15 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
   def user_timeline(%{assigns: %{user: user}} = conn, params) do
     case TwitterAPI.get_user(user, params) do
       {:ok, target_user} ->
+        # Twitter and ActivityPub use a different name and sense for this parameter.
+        {include_rts, params} = Map.pop(params, "include_rts")
+
+        params =
+          case include_rts do
+            x when x == "false" or x == "0" -> Map.put(params, "exclude_reblogs", "true")
+            _ -> params
+          end
+
         activities = ActivityPub.fetch_user_activities(target_user, user, params)
 
         conn
index 4f6b7f058127413e50c68625308234dc6e600e5e..f7c66038d900d98f244aed36669c03d4684b5e5c 100644 (file)
@@ -180,6 +180,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     assert Enum.member?(activities, activity_one)
   end
 
+  test "excludes reblogs on request" do
+    user = insert(:user)
+    {:ok, expected_activity} = ActivityBuilder.insert(%{"type" => "Create"}, %{:user => user})
+    {:ok, _} = ActivityBuilder.insert(%{"type" => "Announce"}, %{:user => user})
+
+    [activity] = ActivityPub.fetch_user_activities(user, nil, %{"exclude_reblogs" => "true"})
+
+    assert activity == expected_activity
+  end
+
   describe "public fetch activities" do
     test "doesn't retrieve unlisted activities" do
       user = insert(:user)
index 433c135f7e67cd6c439672862218a12acda8518a..1737a5ebe07fd65644ab14145264d5a818cf1e9e 100644 (file)
@@ -840,6 +840,26 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       assert [%{"id" => id}] = json_response(conn, 200)
       assert id == to_string(image_post.id)
     end
+
+    test "gets a user's statuses without reblogs", %{conn: conn} do
+      user = insert(:user)
+      {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"})
+      {:ok, _, _} = CommonAPI.repeat(post.id, user)
+
+      conn =
+        conn
+        |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"})
+
+      assert [%{"id" => id}] = json_response(conn, 200)
+      assert id == to_string(post.id)
+
+      conn =
+        conn
+        |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"})
+
+      assert [%{"id" => id}] = json_response(conn, 200)
+      assert id == to_string(post.id)
+    end
   end
 
   describe "user relationships" do
index 0e656f9ca18183a780ee0fda249bd059673f190d..474d72df680755c018232e324d9e7e7043259f5c 100644 (file)
@@ -519,6 +519,34 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       assert length(response) == 1
       assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
     end
+
+    test "with credentials with user_id, excluding RTs", %{conn: conn, user: current_user} do
+      user = insert(:user)
+      {:ok, activity} = ActivityBuilder.insert(%{"id" => 1, "type" => "Create"}, %{user: user})
+      {:ok, _} = ActivityBuilder.insert(%{"id" => 2, "type" => "Announce"}, %{user: user})
+
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> get("/api/statuses/user_timeline.json", %{
+          "user_id" => user.id,
+          "include_rts" => "false"
+        })
+
+      response = json_response(conn, 200)
+
+      assert length(response) == 1
+      assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+
+      conn =
+        conn
+        |> get("/api/statuses/user_timeline.json", %{"user_id" => user.id, "include_rts" => "0"})
+
+      response = json_response(conn, 200)
+
+      assert length(response) == 1
+      assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+    end
   end
 
   describe "POST /friendships/create.json" do