Merge branch 'user-search-experiments' into 'develop'
[akkoma] / lib / pleroma / user.ex
index 494a67f2237729f22a5f17d11f35fbdb82de6bd4..917bcf2ef0a99053b264670657886b6184b79d1a 100644 (file)
@@ -51,6 +51,7 @@ defmodule Pleroma.User do
     field(:password_hash, :string)
     field(:password, :string, virtual: true)
     field(:password_confirmation, :string, virtual: true)
+    field(:keys, :string)
     field(:following, {:array, :string}, default: [])
     field(:ap_id, :string)
     field(:avatar, :map)
@@ -436,7 +437,9 @@ defmodule Pleroma.User do
         {:error, "Could not follow user: #{followed.nickname} blocked you."}
 
       true ->
-        if !followed.local && follower.local && !ap_enabled?(followed) do
+        benchmark? = Pleroma.Config.get([:env]) == :benchmark
+
+        if !followed.local && follower.local && !ap_enabled?(followed) && !benchmark? do
           Websub.subscribe(follower, followed)
         end
 
@@ -847,7 +850,6 @@ defmodule Pleroma.User do
     unread_query = Participation.unread_conversation_count_for_user(user)
 
     User
-    |> where([u], u.id == ^user.id)
     |> join(:inner, [u], p in subquery(unread_query))
     |> update([u, p],
       set: [
@@ -859,10 +861,11 @@ defmodule Pleroma.User do
           )
       ]
     )
+    |> where([u], u.id == ^user.id)
     |> select([u], u)
     |> Repo.update_all([])
     |> case do
-      {1, [%{info: %User.Info{}} = user]} -> set_cache(user)
+      {1, [user]} -> set_cache(user)
       _ -> {:error, user}
     end
   end
@@ -880,7 +883,7 @@ defmodule Pleroma.User do
       set: [
         info:
           fragment(
-            "jsonb_set(?, '{unread_conversation_count}', ((?->>'unread_conversation_count')::int + 1)::varchar::jsonb, true)",
+            "jsonb_set(?, '{unread_conversation_count}', (coalesce((?->>'unread_conversation_count')::int, 0) + 1)::varchar::jsonb, true)",
             u.info,
             u.info
           )
@@ -891,7 +894,7 @@ defmodule Pleroma.User do
     |> select([u], u)
     |> Repo.update_all([])
     |> case do
-      {1, [%{info: %User.Info{}} = user]} -> set_cache(user)
+      {1, [user]} -> set_cache(user)
       _ -> {:error, user}
     end
   end
@@ -1058,7 +1061,15 @@ defmodule Pleroma.User do
     BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status})
   end
 
-  def deactivate(%User{} = user, status \\ true) do
+  def deactivate(user, status \\ true)
+
+  def deactivate(users, status) when is_list(users) do
+    Repo.transaction(fn ->
+      for user <- users, do: deactivate(user, status)
+    end)
+  end
+
+  def deactivate(%User{} = user, status) do
     with {:ok, user} <- update_info(user, &User.Info.set_activation_status(&1, status)) do
       Enum.each(get_followers(user), &invalidate_cache/1)
       Enum.each(get_friends(user), &update_follower_count/1)
@@ -1071,6 +1082,10 @@ defmodule Pleroma.User do
     update_info(user, &User.Info.update_notification_settings(&1, settings))
   end
 
+  def delete(users) when is_list(users) do
+    for user <- users, do: delete(user)
+  end
+
   def delete(%User{} = user) do
     BackgroundWorker.enqueue("delete_user", %{"user_id" => user.id})
   end
@@ -1554,11 +1569,14 @@ defmodule Pleroma.User do
     }
   end
 
-  def ensure_keys_present(%{info: %{keys: keys}} = user) when not is_nil(keys), do: {:ok, user}
+  def ensure_keys_present(%{keys: keys} = user) when not is_nil(keys), do: {:ok, user}
 
   def ensure_keys_present(%User{} = user) do
     with {:ok, pem} <- Keys.generate_rsa_pem() do
-      update_info(user, &User.Info.set_keys(&1, pem))
+      user
+      |> cast(%{keys: pem}, [:keys])
+      |> validate_required([:keys])
+      |> update_and_set_cache()
     end
   end
 
@@ -1621,6 +1639,12 @@ defmodule Pleroma.User do
 
   `fun` is called with the `user.info`.
   """
+  def update_info(users, fun) when is_list(users) do
+    Repo.transaction(fn ->
+      for user <- users, do: update_info(user, fun)
+    end)
+  end
+
   def update_info(user, fun) do
     user
     |> change_info(fun)