X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fpleroma%2Ffollowing_relationship.ex;h=c489ccbbe0d44cea41b4806ba4313259011179f3;hb=a8cd859ef930d968bebeb2afb373ed002e8824f7;hp=0343a20d44b5cf1b6a939cf5eff76c79e4418674;hpb=805ab86933d90d4284c83e4a8ebfd6bf4b0395b3;p=akkoma
diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex
index 0343a20d4..c489ccbbe 100644
--- a/lib/pleroma/following_relationship.ex
+++ b/lib/pleroma/following_relationship.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors
+# Copyright © 2017-2021 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.FollowingRelationship do
@@ -14,6 +14,8 @@ defmodule Pleroma.FollowingRelationship do
alias Pleroma.Repo
alias Pleroma.User
+ @type follow_state :: :follow_pending | :follow_accept | :follow_reject | :unfollow
+
schema "following_relationships" do
field(:state, State, default: :follow_pending)
@@ -62,26 +64,53 @@ defmodule Pleroma.FollowingRelationship do
follow(follower, following, state)
following_relationship ->
- {:ok, relationship} =
- following_relationship
- |> cast(%{state: state}, [:state])
- |> validate_required([:state])
- |> Repo.update()
-
- {:ok, relationship}
+ with {:ok, _following_relationship} <-
+ following_relationship
+ |> cast(%{state: state}, [:state])
+ |> validate_required([:state])
+ |> Repo.update() do
+ after_update(state, follower, following)
+ end
end
end
+ @spec follow(User.t(), User.t()) :: {:ok, User.t(), User.t()} | {:error, any}
def follow(%User{} = follower, %User{} = following, state \\ :follow_accept) do
- %__MODULE__{}
- |> changeset(%{follower: follower, following: following, state: state})
- |> Repo.insert(on_conflict: :nothing)
+ with {:ok, _following_relationship} <-
+ %__MODULE__{}
+ |> changeset(%{follower: follower, following: following, state: state})
+ |> Repo.insert(on_conflict: :nothing) do
+ after_update(state, follower, following)
+ end
end
+ @spec unfollow(User.t(), User.t()) :: {:ok, User.t(), User.t()} | {:error, any}
def unfollow(%User{} = follower, %User{} = following) do
case get(follower, following) do
- %__MODULE__{} = following_relationship -> Repo.delete(following_relationship)
- _ -> {:ok, nil}
+ %__MODULE__{} = following_relationship ->
+ with {:ok, _following_relationship} <- Repo.delete(following_relationship) do
+ after_update(:unfollow, follower, following)
+ end
+
+ _ ->
+ {:ok, follower, following}
+ end
+ end
+
+ @spec after_update(follow_state(), User.t(), User.t()) ::
+ {:ok, User.t(), User.t()} | {:error, any()}
+ defp after_update(state, %User{} = follower, %User{} = following) do
+ with {:ok, following} <- User.update_follower_count(following),
+ {:ok, follower} <- User.update_following_count(follower) do
+ Pleroma.Web.Streamer.stream("follow_relationship", %{
+ state: state,
+ following: following,
+ follower: follower
+ })
+
+ {:ok, follower, following}
+ else
+ err -> {:error, err}
end
end
@@ -98,7 +127,11 @@ defmodule Pleroma.FollowingRelationship do
|> where([r], r.state == ^:follow_accept)
end
- def followers_ap_ids(%User{} = user, from_ap_ids \\ nil) do
+ def followers_ap_ids(user, from_ap_ids \\ nil)
+
+ def followers_ap_ids(_, []), do: []
+
+ def followers_ap_ids(%User{} = user, from_ap_ids) do
query =
user
|> followers_query()
@@ -127,6 +160,7 @@ defmodule Pleroma.FollowingRelationship do
|> join(:inner, [r], f in assoc(r, :follower))
|> where([r], r.state == ^:follow_pending)
|> where([r], r.following_id == ^id)
+ |> where([r, f], f.is_active == true)
|> select([r, f], f)
|> Repo.all()
end
@@ -144,6 +178,12 @@ defmodule Pleroma.FollowingRelationship do
|> where([r], r.state == ^:follow_accept)
end
+ def outgoing_pending_follow_requests_query(%User{} = follower) do
+ __MODULE__
+ |> where([r], r.follower_id == ^follower.id)
+ |> where([r], r.state == ^:follow_pending)
+ end
+
def following(%User{} = user) do
following =
following_query(user)
@@ -162,12 +202,13 @@ defmodule Pleroma.FollowingRelationship do
|> join(:inner, [r], f in assoc(r, :follower))
|> where(following_id: ^origin.id)
|> where([r, f], f.allow_following_move == true)
+ |> where([r, f], f.local == true)
|> limit(50)
|> preload([:follower])
|> Repo.all()
|> Enum.map(fn following_relationship ->
- Repo.delete(following_relationship)
Pleroma.Web.CommonAPI.follow(following_relationship.follower, target)
+ Pleroma.Web.CommonAPI.unfollow(following_relationship.follower, origin)
end)
|> case do
[] ->
@@ -207,30 +248,6 @@ defmodule Pleroma.FollowingRelationship do
end)
end
- @doc """
- For a query with joined activity,
- keeps rows where activity's actor is followed by user -or- is NOT domain-blocked by user.
- """
- def keep_following_or_not_domain_blocked(query, user) do
- where(
- query,
- [_, activity],
- fragment(
- # "(actor's domain NOT in domain_blocks) OR (actor IS in followed AP IDs)"
- """
- NOT (substring(? from '.*://([^/]*)') = ANY(?)) OR
- ? = ANY(SELECT ap_id FROM users AS u INNER JOIN following_relationships AS fr
- ON u.id = fr.following_id WHERE fr.follower_id = ? AND fr.state = ?)
- """,
- activity.actor,
- ^user.domain_blocks,
- activity.actor,
- ^User.binary_id(user.id),
- ^accept_state_code()
- )
- )
- end
-
defp validate_not_self_relationship(%Changeset{} = changeset) do
changeset
|> validate_follower_id_following_id_inequality()
@@ -256,4 +273,12 @@ defmodule Pleroma.FollowingRelationship do
end
end)
end
+
+ @spec following_ap_ids(User.t()) :: [String.t()]
+ def following_ap_ids(%User{} = user) do
+ user
+ |> following_query()
+ |> select([r, u], u.ap_id)
+ |> Repo.all()
+ end
end