Add follow information refetching after following/unfollowing
authorrinpatch <rinpatch@sdf.org>
Sat, 13 Jul 2019 22:58:39 +0000 (01:58 +0300)
committerrinpatch <rinpatch@sdf.org>
Sat, 13 Jul 2019 22:58:39 +0000 (01:58 +0300)
lib/pleroma/user.ex
lib/pleroma/user/info.ex
lib/pleroma/web/activity_pub/activity_pub.ex
test/web/activity_pub/activity_pub_test.exs

index c252e8bff6bc9c84b4f1a5d61e97fad6fbba006e..2e9b01205642cc9a05a96978cee304327f1a5924 100644 (file)
@@ -406,6 +406,8 @@ defmodule Pleroma.User do
 
         {1, [follower]} = Repo.update_all(q, [])
 
+        follower = maybe_update_following_count(follower)
+
         {:ok, _} = update_follower_count(followed)
 
         set_cache(follower)
@@ -425,6 +427,8 @@ defmodule Pleroma.User do
 
       {1, [follower]} = Repo.update_all(q, [])
 
+      follower = maybe_update_following_count(follower)
+
       {:ok, followed} = update_follower_count(followed)
 
       set_cache(follower)
@@ -698,32 +702,75 @@ defmodule Pleroma.User do
     |> update_and_set_cache()
   end
 
+  def maybe_fetch_follow_information(user) do
+    with {:ok, user} <- fetch_follow_information(user) do
+      user
+    else
+      e ->
+        Logger.error(
+          "Follower/Following counter update for #{user.ap_id} failed.\n" <> inspect(e)
+        )
+
+        user
+    end
+  end
+
+  def fetch_follow_information(user) do
+    with {:ok, info} <- ActivityPub.fetch_follow_information_for_user(user) do
+      info_cng = User.Info.follow_information_update(user.info, info)
+
+      changeset =
+        user
+        |> change()
+        |> put_embed(:info, info_cng)
+
+      update_and_set_cache(changeset)
+    else
+      {:error, _} = e -> e
+      e -> {:error, e}
+    end
+  end
+
   def update_follower_count(%User{} = user) do
-    follower_count_query =
-      User.Query.build(%{followers: user, deactivated: false})
-      |> select([u], %{count: count(u.id)})
+    unless user.local == false and Pleroma.Config.get([:instance, :external_user_synchronization]) do
+      follower_count_query =
+        User.Query.build(%{followers: user, deactivated: false})
+        |> select([u], %{count: count(u.id)})
+
+      User
+      |> where(id: ^user.id)
+      |> join(:inner, [u], s in subquery(follower_count_query))
+      |> update([u, s],
+        set: [
+          info:
+            fragment(
+              "jsonb_set(?, '{follower_count}', ?::varchar::jsonb, true)",
+              u.info,
+              s.count
+            )
+        ]
+      )
+      |> select([u], u)
+      |> Repo.update_all([])
+      |> case do
+        {1, [user]} -> set_cache(user)
+        _ -> {:error, user}
+      end
+    else
+      {:ok, maybe_fetch_follow_information(user)}
+    end
+  end
 
-    User
-    |> where(id: ^user.id)
-    |> join(:inner, [u], s in subquery(follower_count_query))
-    |> update([u, s],
-      set: [
-        info:
-          fragment(
-            "jsonb_set(?, '{follower_count}', ?::varchar::jsonb, true)",
-            u.info,
-            s.count
-          )
-      ]
-    )
-    |> select([u], u)
-    |> Repo.update_all([])
-    |> case do
-      {1, [user]} -> set_cache(user)
-      _ -> {:error, user}
+  def maybe_update_following_count(%User{local: false} = user) do
+    if Pleroma.Config.get([:instance, :external_user_synchronization]) do
+      {:ok, maybe_fetch_follow_information(user)}
+    else
+      user
     end
   end
 
+  def maybe_update_following_count(user), do: user
+
   def remove_duplicated_following(%User{following: following} = user) do
     uniq_following = Enum.uniq(following)
 
index 67e8801ea53f2cd8f15f70ad69e7504042c44200..4cc3f2f2c0b4ada7f7223ff46c5b457a09ad40ac 100644 (file)
@@ -330,4 +330,14 @@ defmodule Pleroma.User.Info do
 
     cast(info, params, [:muted_reblogs])
   end
+
+  def follow_information_update(info, params) do
+    info
+    |> cast(params, [
+      :hide_followers,
+      :hide_follows,
+      :follower_count,
+      :following_count
+    ])
+  end
 end
index c821ba45ff08cdd81b1c0e73bea1f1c12c264c8a..2dd9dbf7fa2c28afa3c788332f87b67b93cb5ddb 100644 (file)
@@ -1022,15 +1022,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
            Fetcher.fetch_and_contain_remote_object_from_id(user.follower_address),
          followers_count when is_integer(followers_count) <- followers_data["totalItems"],
          {:ok, hide_followers} <- collection_private(followers_data) do
-      info = %{
-        hide_follows: hide_follows,
-        follower_count: followers_count,
-        following_count: following_count,
-        hide_followers: hide_followers
-      }
-
-      info = Map.merge(user.info, info)
-      {:ok, Map.put(user, :info, info)}
+      {:ok,
+       %{
+         hide_follows: hide_follows,
+         follower_count: followers_count,
+         following_count: following_count,
+         hide_followers: hide_followers
+       }}
     else
       {:error, _} = e ->
         e
@@ -1043,8 +1041,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   defp maybe_update_follow_information(data) do
     with {:enabled, true} <-
            {:enabled, Pleroma.Config.get([:instance, :external_user_synchronization])},
-         {:ok, data} <- fetch_follow_information_for_user(data) do
-      data
+         {:ok, info} <- fetch_follow_information_for_user(data) do
+      info = Map.merge(data.info, info)
+      Map.put(data, :info, info)
     else
       {:enabled, false} ->
         data
index 448ffbf5477eb09446b0440b95ae52af9c32fd59..24d8493fe1a399fea5ef6af8c227b8fe82a11b62 100644 (file)
@@ -1232,9 +1232,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
           following_address: "http://localhost:4001/users/fuser2/following"
         )
 
-      {:ok, user} = ActivityPub.fetch_follow_information_for_user(user)
-      assert user.info.follower_count == 527
-      assert user.info.following_count == 267
+      {:ok, info} = ActivityPub.fetch_follow_information_for_user(user)
+      assert info.follower_count == 527
+      assert info.following_count == 267
     end
 
     test "detects hidden followers" do
@@ -1265,9 +1265,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
           following_address: "http://localhost:4001/users/masto_closed/following"
         )
 
-      {:ok, user} = ActivityPub.fetch_follow_information_for_user(user)
-      assert user.info.hide_followers == true
-      assert user.info.hide_follows == false
+      {:ok, info} = ActivityPub.fetch_follow_information_for_user(user)
+      assert info.hide_followers == true
+      assert info.hide_follows == false
     end
 
     test "detects hidden follows" do
@@ -1298,9 +1298,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
           following_address: "http://localhost:4001/users/masto_closed/following"
         )
 
-      {:ok, user} = ActivityPub.fetch_follow_information_for_user(user)
-      assert user.info.hide_followers == false
-      assert user.info.hide_follows == true
+      {:ok, info} = ActivityPub.fetch_follow_information_for_user(user)
+      assert info.hide_followers == false
+      assert info.hide_follows == true
     end
   end
 end