summaryrefslogtreecommitdiff
path: root/lib/mix/tasks/pleroma/refresh_counter_cache.ex
blob: 280201befcfd0ad0fbeabe6bac4aa51afaeeb8ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Mix.Tasks.Pleroma.RefreshCounterCache do
  @shortdoc "Refreshes counter cache"

  use Mix.Task

  alias Pleroma.Activity
  alias Pleroma.CounterCache
  alias Pleroma.Repo

  require Logger
  import Ecto.Query

  def run([]) do
    Mix.Pleroma.start_pleroma()

    Activity
    |> distinct([a], true)
    |> select([a], fragment("split_part(?, '/', 3)", a.actor))
    |> Repo.all()
    |> Enum.each(fn instance ->
      counters = instance_counters(instance)
      CounterCache.set(instance, counters)
      Mix.Pleroma.shell_info("Setting #{instance} counters: #{inspect(counters)}")
    end)

    Mix.Pleroma.shell_info("Done")
  end

  defp instance_counters(instance) do
    counters = %{"public" => 0, "unlisted" => 0, "private" => 0, "direct" => 0}

    Activity
    |> where([a], fragment("(? ->> 'type'::text) = 'Create'", a.data))
    |> where([a], like(a.actor, ^"%#{instance}%"))
    |> select(
      [a],
      {fragment(
         "activity_visibility(?, ?, ?)",
         a.actor,
         a.recipients,
         a.data
       ), count(a.id)}
    )
    |> group_by(
      [a],
      fragment(
        "activity_visibility(?, ?, ?)",
        a.actor,
        a.recipients,
        a.data
      )
    )
    |> Repo.all(timeout: :timer.minutes(30))
    |> Enum.reduce(counters, fn {visibility, count}, acc ->
      Map.put(acc, visibility, count)
    end)
  end
end