X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fuser.ex;h=75e173d0c8eead31074fff12d19a21f901506dce;hb=745072b2cc0ce3be6e1896bcacffb5e48782f6da;hp=20767499966cbea34408f43c3a3dad6ad385df8f;hpb=39c80a3667afec25a187894d67e0d0e9b8713eb1;p=akkoma diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 207674999..75e173d0c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -21,6 +21,7 @@ defmodule Pleroma.User do field(:local, :boolean, default: true) field(:info, :map, default: %{}) field(:follower_address, :string) + field(:search_distance, :float, virtual: true) has_many(:notifications, Notification) timestamps() @@ -66,7 +67,8 @@ defmodule Pleroma.User do %{ following_count: length(user.following) - oneself, note_count: user.info["note_count"] || 0, - follower_count: user.info["follower_count"] || 0 + follower_count: user.info["follower_count"] || 0, + locked: user.info["locked"] || false } end @@ -166,28 +168,62 @@ defmodule Pleroma.User do end end + def maybe_direct_follow(%User{} = follower, %User{info: info} = followed) do + user_info = user_info(followed) + + should_direct_follow = + cond do + # if the account is locked, don't pre-create the relationship + user_info.locked == true -> + false + + # if the users are blocking each other, we shouldn't even be here, but check for it anyway + User.blocks?(follower, followed) == true or User.blocks?(followed, follower) == true -> + false + + # if OStatus, then there is no three-way handshake to follow + User.ap_enabled?(followed) != true -> + true + + # if there are no other reasons not to, just pre-create the relationship + true -> + true + end + + if should_direct_follow do + follow(follower, followed) + else + follower + end + end + def follow(%User{} = follower, %User{info: info} = followed) do ap_followers = followed.follower_address - if following?(follower, followed) or info["deactivated"] do - {:error, "Could not follow user: #{followed.nickname} is already on your list."} - else - if !followed.local && follower.local && !ap_enabled?(followed) do - Websub.subscribe(follower, followed) - end + cond do + following?(follower, followed) or info["deactivated"] -> + {:error, "Could not follow user: #{followed.nickname} is already on your list."} - following = - [ap_followers | follower.following] - |> Enum.uniq() + blocks?(followed, follower) -> + {:error, "Could not follow user: #{followed.nickname} blocked you."} - follower = - follower - |> follow_changeset(%{following: following}) - |> update_and_set_cache + true -> + if !followed.local && follower.local && !ap_enabled?(followed) do + Websub.subscribe(follower, followed) + end - {:ok, _} = update_follower_count(followed) + following = + [ap_followers | follower.following] + |> Enum.uniq() - follower + follower = + follower + |> follow_changeset(%{following: following}) + |> update_and_set_cache + + {:ok, _} = update_follower_count(followed) + + follower end end @@ -222,9 +258,9 @@ defmodule Pleroma.User do def update_and_set_cache(changeset) do with {:ok, user} <- Repo.update(changeset) do - Cachex.set(:user_cache, "ap_id:#{user.ap_id}", user) - Cachex.set(:user_cache, "nickname:#{user.nickname}", user) - Cachex.set(:user_cache, "user_info:#{user.id}", user_info(user)) + Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user) + Cachex.put(:user_cache, "nickname:#{user.nickname}", user) + Cachex.put(:user_cache, "user_info:#{user.id}", user_info(user)) {:ok, user} else e -> e @@ -238,12 +274,12 @@ defmodule Pleroma.User do def get_cached_by_ap_id(ap_id) do key = "ap_id:#{ap_id}" - Cachex.get!(:user_cache, key, fallback: fn _ -> get_by_ap_id(ap_id) end) + Cachex.fetch!(:user_cache, key, fn _ -> get_by_ap_id(ap_id) end) end def get_cached_by_nickname(nickname) do key = "nickname:#{nickname}" - Cachex.get!(:user_cache, key, fallback: fn _ -> get_or_fetch_by_nickname(nickname) end) + Cachex.fetch!(:user_cache, key, fn _ -> get_or_fetch_by_nickname(nickname) end) end def get_by_nickname(nickname) do @@ -259,7 +295,7 @@ defmodule Pleroma.User do def get_cached_user_info(user) do key = "user_info:#{user.id}" - Cachex.get!(:user_cache, key, fallback: fn _ -> user_info(user) end) + Cachex.fetch!(:user_cache, key, fn _ -> user_info(user) end) end def fetch_by_nickname(nickname) do @@ -399,16 +435,24 @@ defmodule Pleroma.User do User.get_or_fetch_by_nickname(query) end - q = + inner = from( u in User, - where: - fragment( - "(to_tsvector('english', ?) || to_tsvector('english', ?)) @@ plainto_tsquery('english', ?)", - u.nickname, - u.name, - ^query - ), + select_merge: %{ + search_distance: + fragment( + "? <-> (? || ?)", + ^query, + u.nickname, + u.name + ) + } + ) + + q = + from( + s in subquery(inner), + order_by: s.search_distance, limit: 20 )