Merge branch 'preload-data' into 'develop'
[akkoma] / lib / mix / tasks / pleroma / refresh_counter_cache.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Mix.Tasks.Pleroma.RefreshCounterCache do
6 @shortdoc "Refreshes counter cache"
7
8 use Mix.Task
9
10 alias Pleroma.Activity
11 alias Pleroma.CounterCache
12 alias Pleroma.Repo
13
14 require Logger
15 import Ecto.Query
16
17 def run([]) do
18 Mix.Pleroma.start_pleroma()
19
20 instances =
21 Activity
22 |> distinct([a], true)
23 |> select([a], fragment("split_part(?, '/', 3)", a.actor))
24 |> Repo.all()
25
26 instances
27 |> Enum.with_index(1)
28 |> Enum.each(fn {instance, i} ->
29 counters = instance_counters(instance)
30 CounterCache.set(instance, counters)
31
32 Mix.Pleroma.shell_info(
33 "[#{i}/#{length(instances)}] Setting #{instance} counters: #{inspect(counters)}"
34 )
35 end)
36
37 Mix.Pleroma.shell_info("Done")
38 end
39
40 defp instance_counters(instance) do
41 counters = %{"public" => 0, "unlisted" => 0, "private" => 0, "direct" => 0}
42
43 Activity
44 |> where([a], fragment("(? ->> 'type'::text) = 'Create'", a.data))
45 |> where([a], fragment("split_part(?, '/', 3) = ?", a.actor, ^instance))
46 |> select(
47 [a],
48 {fragment(
49 "activity_visibility(?, ?, ?)",
50 a.actor,
51 a.recipients,
52 a.data
53 ), count(a.id)}
54 )
55 |> group_by(
56 [a],
57 fragment(
58 "activity_visibility(?, ?, ?)",
59 a.actor,
60 a.recipients,
61 a.data
62 )
63 )
64 |> Repo.all(timeout: :timer.minutes(30))
65 |> Enum.reduce(counters, fn {visibility, count}, acc ->
66 Map.put(acc, visibility, count)
67 end)
68 end
69 end