update counter_cache logic
[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 Activity
21 |> distinct([a], true)
22 |> select([a], fragment("split_part(?, '/', 3)", a.actor))
23 |> Repo.all()
24 |> Enum.each(fn instance ->
25 counters = instance_counters(instance)
26 CounterCache.set(instance, counters)
27 Mix.Pleroma.shell_info("Setting #{instance} counters: #{inspect(counters)}")
28 end)
29
30 Mix.Pleroma.shell_info("Done")
31 end
32
33 defp instance_counters(instance) do
34 counters = %{"public" => 0, "unlisted" => 0, "private" => 0, "direct" => 0}
35
36 Activity
37 |> where([a], fragment("(? ->> 'type'::text) = 'Create'", a.data))
38 |> where([a], like(a.actor, ^"%#{instance}%"))
39 |> select(
40 [a],
41 {fragment(
42 "activity_visibility(?, ?, ?)",
43 a.actor,
44 a.recipients,
45 a.data
46 ), count(a.id)}
47 )
48 |> group_by(
49 [a],
50 fragment(
51 "activity_visibility(?, ?, ?)",
52 a.actor,
53 a.recipients,
54 a.data
55 )
56 )
57 |> Repo.all(timeout: :timer.minutes(30))
58 |> Enum.reduce(counters, fn {visibility, count}, acc ->
59 Map.put(acc, visibility, count)
60 end)
61 end
62 end