mandate published on notes
[akkoma] / lib / mix / tasks / pleroma / refresh_counter_cache.ex
index bc2571efd8834e04dbba432c5e1c4d36515b601d..66eed86570d7e0a0ea1f6c38a8d1fbf34710934d 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Mix.Tasks.Pleroma.RefreshCounterCache do
@@ -17,30 +17,53 @@ defmodule Mix.Tasks.Pleroma.RefreshCounterCache do
   def run([]) do
     Mix.Pleroma.start_pleroma()
 
-    ["public", "unlisted", "private", "direct"]
-    |> Enum.each(fn visibility ->
-      count = status_visibility_count_query(visibility)
-      name = "status_visibility_#{visibility}"
-      CounterCache.set(name, count)
-      Mix.Pleroma.shell_info("Set #{name} to #{count}")
+    instances =
+      Activity
+      |> distinct([a], true)
+      |> select([a], fragment("split_part(?, '/', 3)", a.actor))
+      |> Repo.all()
+
+    instances
+    |> Enum.with_index(1)
+    |> Enum.each(fn {instance, i} ->
+      counters = instance_counters(instance)
+      CounterCache.set(instance, counters)
+
+      Mix.Pleroma.shell_info(
+        "[#{i}/#{length(instances)}] Setting #{instance} counters: #{inspect(counters)}"
+      )
     end)
 
     Mix.Pleroma.shell_info("Done")
   end
 
-  defp status_visibility_count_query(visibility) do
+  defp instance_counters(instance) do
+    counters = %{"public" => 0, "unlisted" => 0, "private" => 0, "direct" => 0}
+
     Activity
-    |> where(
+    |> where([a], fragment("(? ->> 'type'::text) = 'Create'", a.data))
+    |> where([a], fragment("split_part(?, '/', 3) = ?", a.actor, ^instance))
+    |> select(
+      [a],
+      {fragment(
+         "activity_visibility(?, ?, ?)",
+         a.actor,
+         a.recipients,
+         a.data
+       ), count(a.id)}
+    )
+    |> group_by(
       [a],
       fragment(
-        "activity_visibility(?, ?, ?) = ?",
+        "activity_visibility(?, ?, ?)",
         a.actor,
         a.recipients,
-        a.data,
-        ^visibility
+        a.data
       )
     )
-    |> where([a], fragment("(? ->> 'type'::text) = 'Create'", a.data))
-    |> Repo.aggregate(:count, :id, timeout: :timer.minutes(30))
+    |> Repo.all(timeout: :timer.minutes(30))
+    |> Enum.reduce(counters, fn {visibility, count}, acc ->
+      Map.put(acc, visibility, count)
+    end)
   end
 end