diff options
| -rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 12 | ||||
| -rw-r--r-- | priv/repo/migrations/20190303120636_update_user_note_counters.exs | 41 | ||||
| -rw-r--r-- | test/web/activity_pub/activity_pub_test.exs | 43 | 
3 files changed, 94 insertions, 2 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 7282d4239..783491b67 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -81,6 +81,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do    defp check_remote_limit(_), do: true +  def increase_note_count_if_public(actor, object) do +    if is_public?(object), do: User.increase_note_count(actor), else: {:ok, actor} +  end + +  def decrease_note_count_if_public(actor, object) do +    if is_public?(object), do: User.decrease_note_count(actor), else: {:ok, actor} +  end +    def insert(map, local \\ true) when is_map(map) do      with nil <- Activity.normalize(map),           map <- lazy_put_activity_defaults(map), @@ -163,7 +171,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do             ),           {:ok, activity} <- insert(create_data, local),           # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info -         {:ok, _actor} <- User.increase_note_count(actor), +         {:ok, _actor} <- increase_note_count_if_public(actor, activity),           :ok <- maybe_federate(activity) do        {:ok, activity}      end @@ -312,7 +320,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do      with {:ok, _} <- Object.delete(object),           {:ok, activity} <- insert(data, local),           # Changing note count prior to enqueuing federation task in order to avoid race conditions on updating user.info -         {:ok, _actor} <- User.decrease_note_count(user), +         {:ok, _actor} <- decrease_note_count_if_public(user, object),           :ok <- maybe_federate(activity) do        {:ok, activity}      end diff --git a/priv/repo/migrations/20190303120636_update_user_note_counters.exs b/priv/repo/migrations/20190303120636_update_user_note_counters.exs new file mode 100644 index 000000000..54e68f7c9 --- /dev/null +++ b/priv/repo/migrations/20190303120636_update_user_note_counters.exs @@ -0,0 +1,41 @@ +defmodule Pleroma.Repo.Migrations.UpdateUserNoteCounters do +  use Ecto.Migration + +  @public "https://www.w3.org/ns/activitystreams#Public" + +  def up do +    execute """ +      WITH public_note_count AS ( +        SELECT +          data->>'actor' AS actor, +          count(id) AS count +        FROM objects +        WHERE data->>'type' = 'Note' AND ( +          data->'cc' ? '#{@public}' OR data->'to' ? '#{@public}' +        ) +        GROUP BY data->>'actor' +      ) +      UPDATE users AS u +      SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true) +      FROM public_note_count AS o +      WHERE u.ap_id = o.actor +    """ +  end + +  def down do +    execute """ +      WITH public_note_count AS ( +        SELECT +          data->>'actor' AS actor, +          count(id) AS count +        FROM objects +        WHERE data->>'type' = 'Note' +        GROUP BY data->>'actor' +      ) +      UPDATE users AS u +      SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true) +      FROM public_note_count AS o +      WHERE u.ap_id = o.actor +    """ +  end +end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 950ce17dd..f4029896c 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -213,6 +213,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do        assert activity.actor == user.ap_id        assert activity.recipients == ["user1", "user2", user.ap_id]      end + +    test "increases user note count only for public activities" do +      user = insert(:user) + +      {:ok, _} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "1", "visibility" => "public"}) + +      {:ok, _} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "2", "visibility" => "unlisted"}) + +      {:ok, _} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "2", "visibility" => "private"}) + +      {:ok, _} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "3", "visibility" => "direct"}) + +      user = Repo.get(User, user.id) +      assert user.info.note_count == 2 +    end    end    describe "fetch activities for recipients" do @@ -648,6 +667,30 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do        assert Repo.get(Object, object.id).data["type"] == "Tombstone"      end + +    test "decrements user note count only for public activities" do +      user = insert(:user, info: %{note_count: 10}) + +      {:ok, a1} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "public"}) + +      {:ok, a2} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "unlisted"}) + +      {:ok, a3} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "private"}) + +      {:ok, a4} = +        CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "direct"}) + +      {:ok, _} = a1.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() +      {:ok, _} = a2.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() +      {:ok, _} = a3.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() +      {:ok, _} = a4.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() + +      user = Repo.get(User, user.id) +      assert user.info.note_count == 10 +    end    end    describe "timeline post-processing" do  | 
