X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fuser.ex;h=1c62f238ec1b511bb42446651814631c440069de;hb=0bcdaf378ee41c3845151b59d8820b799532c9a8;hp=4a41a15c77eba6893602518a1f94bbd9fea8cf7b;hpb=c349573791bfaca6e8c8c86c519c23397b088967;p=akkoma diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 4a41a15c7..1c62f238e 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -10,6 +10,7 @@ defmodule Pleroma.User do alias Comeonin.Pbkdf2 alias Pleroma.Activity + alias Pleroma.Bookmark alias Pleroma.Formatter alias Pleroma.Notification alias Pleroma.Object @@ -53,8 +54,8 @@ defmodule Pleroma.User do field(:search_rank, :float, virtual: true) field(:search_type, :integer, virtual: true) field(:tags, {:array, :string}, default: []) - field(:bookmarks, {:array, :string}, default: []) field(:last_refreshed_at, :naive_datetime_usec) + has_many(:bookmarks, Bookmark) has_many(:notifications, Notification) has_many(:registrations, Registration) embeds_one(:info, Pleroma.User.Info) @@ -269,6 +270,7 @@ defmodule Pleroma.User do def register(%Ecto.Changeset{} = changeset) do with {:ok, user} <- Repo.insert(changeset), {:ok, user} <- autofollow_users(user), + {:ok, user} <- set_cache(user), {:ok, _} <- Pleroma.User.WelcomeMessage.post_welcome_message_to_user(user), {:ok, _} <- try_send_confirmation_email(user) do {:ok, user} @@ -281,6 +283,8 @@ defmodule Pleroma.User do user |> Pleroma.Emails.UserEmail.account_confirmation_email() |> Pleroma.Emails.Mailer.deliver_async() + + {:ok, :enqueued} else {:ok, :noop} end @@ -419,7 +423,7 @@ defmodule Pleroma.User do Enum.map( followed_identifiers, fn followed_identifier -> - with %User{} = followed <- get_or_fetch(followed_identifier), + with {:ok, %User{} = followed} <- get_or_fetch(followed_identifier), {:ok, follower} <- maybe_direct_follow(follower, followed), {:ok, _} <- ActivityPub.follow(follower, followed) do followed @@ -451,10 +455,13 @@ defmodule Pleroma.User do name = List.last(String.split(ap_id, "/")) nickname = "#{name}@#{domain}" - get_by_nickname(nickname) + get_cached_by_nickname(nickname) end - def set_cache(user) do + def set_cache({:ok, user}), do: set_cache(user) + def set_cache({:error, err}), do: {:error, err} + + def set_cache(%User{} = user) do 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)) @@ -500,7 +507,15 @@ defmodule Pleroma.User do def get_cached_by_nickname(nickname) do key = "nickname:#{nickname}" - Cachex.fetch!(:user_cache, key, fn _ -> get_or_fetch_by_nickname(nickname) end) + + Cachex.fetch!(:user_cache, key, fn -> + user_result = get_or_fetch_by_nickname(nickname) + + case user_result do + {:ok, user} -> {:commit, user} + {:error, _error} -> {:ignore, nil} + end + end) end def get_cached_by_nickname_or_id(nickname_or_id) do @@ -536,18 +551,19 @@ defmodule Pleroma.User do def get_or_fetch_by_nickname(nickname) do with %User{} = user <- get_by_nickname(nickname) do - user + {:ok, user} else _e -> with [_nick, _domain] <- String.split(nickname, "@"), {:ok, user} <- fetch_by_nickname(nickname) do if Pleroma.Config.get([:fetch_initial_posts, :enabled]) do + # TODO turn into job {:ok, _} = Task.start(__MODULE__, :fetch_initial_posts, [user]) end - user + {:ok, user} else - _e -> nil + _e -> {:error, "not found " <> nickname} end end end @@ -894,7 +910,7 @@ defmodule Pleroma.User do Enum.map( blocked_identifiers, fn blocked_identifier -> - with %User{} = blocked <- get_or_fetch(blocked_identifier), + with {:ok, %User{} = blocked} <- get_or_fetch(blocked_identifier), {:ok, blocker} <- block(blocker, blocked), {:ok, _} <- ActivityPub.block(blocker, blocked) do blocked @@ -1000,7 +1016,7 @@ defmodule Pleroma.User do # helper to handle the block given only an actor's AP id def block(blocker, %{ap_id: ap_id}) do - block(blocker, User.get_by_ap_id(ap_id)) + block(blocker, get_cached_by_ap_id(ap_id)) end def unblock(blocker, %{ap_id: ap_id}) do @@ -1030,7 +1046,7 @@ defmodule Pleroma.User do end def subscribed_to?(user, %{ap_id: ap_id}) do - with %User{} = target <- User.get_by_ap_id(ap_id) do + with %User{} = target <- get_cached_by_ap_id(ap_id) do Enum.member?(target.info.subscribers, user.ap_id) end end @@ -1194,41 +1210,41 @@ defmodule Pleroma.User do case ap_try do {:ok, user} -> - user + {:ok, user} _ -> case OStatus.make_user(ap_id) do - {:ok, user} -> user + {:ok, user} -> {:ok, user} _ -> {:error, "Could not fetch by AP id"} end end end def get_or_fetch_by_ap_id(ap_id) do - user = get_by_ap_id(ap_id) + user = get_cached_by_ap_id(ap_id) if !is_nil(user) and !User.needs_update?(user) do - user + {:ok, user} else # Whether to fetch initial posts for the user (if it's a new user & the fetching is enabled) should_fetch_initial = is_nil(user) and Pleroma.Config.get([:fetch_initial_posts, :enabled]) - user = fetch_by_ap_id(ap_id) + resp = fetch_by_ap_id(ap_id) if should_fetch_initial do - with %User{} = user do + with {:ok, %User{} = user} = resp do {:ok, _} = Task.start(__MODULE__, :fetch_initial_posts, [user]) end end - user + resp end end def get_or_create_instance_user do relay_uri = "#{Pleroma.Web.Endpoint.url()}/relay" - if user = get_by_ap_id(relay_uri) do + if user = get_cached_by_ap_id(relay_uri) do user else changes = @@ -1263,7 +1279,7 @@ defmodule Pleroma.User do end def get_public_key_for_ap_id(ap_id) do - with %User{} = user <- get_or_fetch_by_ap_id(ap_id), + with {:ok, %User{} = user} <- get_or_fetch_by_ap_id(ap_id), {:ok, public_key} <- public_key_from_info(user.info) do {:ok, public_key} else @@ -1275,13 +1291,11 @@ defmodule Pleroma.User do defp blank?(n), do: n def insert_or_update_user(data) do - data = - data - |> Map.put(:name, blank?(data[:name]) || data[:nickname]) - - cs = User.remote_user_creation(data) - - Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname) + data + |> Map.put(:name, blank?(data[:name]) || data[:nickname]) + |> remote_user_creation() + |> Repo.insert(on_conflict: :replace_all, conflict_target: :nickname) + |> set_cache() end def ap_enabled?(%User{local: true}), do: true @@ -1297,8 +1311,8 @@ defmodule Pleroma.User do # this is because we have synchronous follow APIs and need to simulate them # with an async handshake def wait_and_refresh(_, %User{local: true} = a, %User{local: true} = b) do - with %User{} = a <- User.get_by_id(a.id), - %User{} = b <- User.get_by_id(b.id) do + with %User{} = a <- User.get_cached_by_id(a.id), + %User{} = b <- User.get_cached_by_id(b.id) do {:ok, a, b} else _e -> @@ -1308,8 +1322,8 @@ defmodule Pleroma.User do def wait_and_refresh(timeout, %User{} = a, %User{} = b) do with :ok <- :timer.sleep(timeout), - %User{} = a <- User.get_by_id(a.id), - %User{} = b <- User.get_by_id(b.id) do + %User{} = a <- User.get_cached_by_id(a.id), + %User{} = b <- User.get_cached_by_id(b.id) do {:ok, a, b} else _e -> @@ -1348,7 +1362,7 @@ defmodule Pleroma.User do end def tag(nickname, tags) when is_binary(nickname), - do: tag(User.get_by_nickname(nickname), tags) + do: tag(get_by_nickname(nickname), tags) def tag(%User{} = user, tags), do: update_tags(user, Enum.uniq((user.tags || []) ++ normalize_tags(tags))) @@ -1360,7 +1374,7 @@ defmodule Pleroma.User do end def untag(nickname, tags) when is_binary(nickname), - do: untag(User.get_by_nickname(nickname), tags) + do: untag(get_by_nickname(nickname), tags) def untag(%User{} = user, tags), do: update_tags(user, (user.tags || []) -- normalize_tags(tags)) @@ -1374,22 +1388,6 @@ defmodule Pleroma.User do updated_user end - def bookmark(%User{} = user, status_id) do - bookmarks = Enum.uniq(user.bookmarks ++ [status_id]) - update_bookmarks(user, bookmarks) - end - - def unbookmark(%User{} = user, status_id) do - bookmarks = Enum.uniq(user.bookmarks -- [status_id]) - update_bookmarks(user, bookmarks) - end - - def update_bookmarks(%User{} = user, bookmarks) do - user - |> change(%{bookmarks: bookmarks}) - |> update_and_set_cache - end - defp normalize_tags(tags) do [tags] |> List.flatten()