X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fstats.ex;h=cf590fb0158abedf9d2e80dda0db9d8262a61a65;hb=cf943492878c901cf2f0056ee2a8814e0322e9d8;hp=c90e8f4092b0b14fa30398dfd7dfef4b791196f4;hpb=404a9ccb9a220f3f52ee03bd69bd3746d95794cc;p=akkoma diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index c90e8f409..cf590fb01 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -3,32 +3,49 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Stats do - use GenServer - import Ecto.Query - - alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User - require Pleroma.Constants + use GenServer - @interval 1000 * 60 * 60 + @init_state %{ + peers: [], + stats: %{ + domain_count: 0, + status_count: 0, + user_count: 0 + } + } def start_link(_) do - GenServer.start_link(__MODULE__, initial_data(), name: __MODULE__) + GenServer.start_link( + __MODULE__, + @init_state, + name: __MODULE__ + ) end + @doc "Performs update stats" def force_update do GenServer.call(__MODULE__, :force_update) end + @doc "Performs collect stats" + def do_collect do + GenServer.cast(__MODULE__, :run_update) + end + + @doc "Returns stats data" + @spec get_stats() :: %{domain_count: integer(), status_count: integer(), user_count: integer()} def get_stats do %{stats: stats} = GenServer.call(__MODULE__, :get_state) stats end + @doc "Returns list peers" + @spec get_peers() :: list(String.t()) def get_peers do %{peers: peers} = GenServer.call(__MODULE__, :get_state) @@ -36,7 +53,6 @@ defmodule Pleroma.Stats do end def init(args) do - Process.send(self(), :run_update, []) {:ok, args} end @@ -49,18 +65,13 @@ defmodule Pleroma.Stats do {:reply, state, state} end - def handle_info(:run_update, _state) do + def handle_cast(:run_update, _state) do new_stats = get_stat_data() - Process.send_after(self(), :run_update, @interval) {:noreply, new_stats} end - defp initial_data do - %{peers: [], stats: %{}} - end - - def get_stat_data do + defp get_stat_data do peers = from( u in User, @@ -72,71 +83,17 @@ defmodule Pleroma.Stats do domain_count = Enum.count(peers) + status_count = Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count) + user_count = Repo.aggregate(User.Query.build(%{local: true, active: true}), :count, :id) %{ peers: peers, - stats: %{domain_count: domain_count, status_count: status_count(), user_count: user_count} - } - end - - defp status_count do - %{ - all: get_all_statuses_count(), - public: public_statuses_query() |> Repo.aggregate(:count, :id), - unlisted: unlisted_statuses_query() |> Repo.aggregate(:count, :id), - direct: direct_statuses_query() |> Repo.aggregate(:count, :id), - private: private_statuses_query() |> Repo.aggregate(:count, :id) + stats: %{ + domain_count: domain_count, + status_count: status_count, + user_count: user_count + } } end - - defp get_all_statuses_count do - Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count) - end - - def public_statuses_query do - from(o in Object, - where: fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()) - ) - end - - def unlisted_statuses_query do - from(o in Object, - where: not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()), - where: fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) - ) - end - - def direct_statuses_query do - private_statuses_ids = from(p in private_statuses_query(), select: p.id) |> Repo.all() - - from(o in Object, - where: - fragment( - "? \\? 'directMessage' AND (?->>'directMessage')::boolean = true", - o.data, - o.data - ) or - (not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()) and - not fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) and - o.id not in ^private_statuses_ids) - ) - end - - def private_statuses_query do - from(o in subquery(recipients_query()), - where: ilike(o.recipients, "%/followers%") - ) - end - - defp recipients_query do - from(o in Object, - select: %{ - id: o.id, - recipients: fragment("jsonb_array_elements_text((?)->'to')", o.data) - }, - where: not fragment("(?)->'to' \\? ?", o.data, ^Pleroma.Constants.as_public()), - where: not fragment("(?)->'cc' \\? ?", o.data, ^Pleroma.Constants.as_public()) - ) - end end