Merge branch 'develop' into global-status-expiration
[akkoma] / lib / pleroma / following_relationship.ex
index 2f89eb4cf6ccdbe5fa945f888e18cc59780c6c42..a9538ea4e4d613b8020b835781268890ca229b5a 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.FollowingRelationship do
@@ -58,8 +58,8 @@ defmodule Pleroma.FollowingRelationship do
 
   def unfollow(%User{} = follower, %User{} = following) do
     case get(follower, following) do
-      nil -> {:ok, nil}
       %__MODULE__{} = following_relationship -> Repo.delete(following_relationship)
+      _ -> {:ok, nil}
     end
   end
 
@@ -101,7 +101,7 @@ defmodule Pleroma.FollowingRelationship do
       |> select([r, u], u.follower_address)
       |> Repo.all()
 
-    if not user.local or user.nickname in [nil, "internal.fetch"] do
+    if not user.local or user.invisible do
       following
     else
       [user.follower_address | following]
@@ -109,26 +109,52 @@ defmodule Pleroma.FollowingRelationship do
   end
 
   def move_following(origin, target) do
-    following_relationships =
-      __MODULE__
-      |> where(following_id: ^origin.id)
-      |> preload([:follower])
-      |> limit(50)
-      |> Repo.all()
-
-    case following_relationships do
+    __MODULE__
+    |> join(:inner, [r], f in assoc(r, :follower))
+    |> where(following_id: ^origin.id)
+    |> where([r, f], f.allow_following_move == true)
+    |> limit(50)
+    |> preload([:follower])
+    |> Repo.all()
+    |> Enum.map(fn following_relationship ->
+      Repo.delete(following_relationship)
+      Pleroma.Web.CommonAPI.follow(following_relationship.follower, target)
+    end)
+    |> case do
       [] ->
+        User.update_follower_count(origin)
         :ok
 
-      following_relationships ->
-        Enum.each(following_relationships, fn following_relationship ->
-          Repo.transaction(fn ->
-            Repo.delete(following_relationship)
-            User.follow(following_relationship.follower, target)
-          end)
-        end)
-
+      _ ->
         move_following(origin, target)
     end
   end
+
+  def all_between_user_sets(
+        source_users,
+        target_users
+      )
+      when is_list(source_users) and is_list(target_users) do
+    source_user_ids = User.binary_id(source_users)
+    target_user_ids = User.binary_id(target_users)
+
+    __MODULE__
+    |> where(
+      fragment(
+        "(follower_id = ANY(?) AND following_id = ANY(?)) OR \
+        (follower_id = ANY(?) AND following_id = ANY(?))",
+        ^source_user_ids,
+        ^target_user_ids,
+        ^target_user_ids,
+        ^source_user_ids
+      )
+    )
+    |> Repo.all()
+  end
+
+  def find(following_relationships, follower, following) do
+    Enum.find(following_relationships, fn
+      fr -> fr.follower_id == follower.id and fr.following_id == following.id
+    end)
+  end
 end