# Pleroma: A lightweight social networking server # Copyright © 2017-2020 Pleroma Authors # 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