X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fstats.ex;h=33f50dda89825f1e0d12b897a64aad430fc3bc59;hb=8854770fc4e9079131a0897d5fb6c0ccccf98bc6;hp=97e8b199010b86a5f357233804417409cfc2777f;hpb=5fc84552d311efd606f66775c55862b3d11ad258;p=akkoma
diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex
index 97e8b1990..33f50dda8 100644
--- a/lib/pleroma/stats.ex
+++ b/lib/pleroma/stats.ex
@@ -1,34 +1,52 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors
+# Copyright © 2017-2020 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Stats do
- use GenServer
-
import Ecto.Query
-
- alias Pleroma.Object
+ alias Pleroma.CounterCache
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 +54,6 @@ defmodule Pleroma.Stats do
end
def init(args) do
- Process.send(self(), :run_update, [])
{:ok, args}
end
@@ -49,18 +66,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 +84,34 @@ 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}
+ stats: %{
+ domain_count: domain_count,
+ status_count: status_count,
+ user_count: user_count
+ }
}
end
- defp status_count do
+ def get_status_visibility_count do
+ counter_cache =
+ CounterCache.get_as_map([
+ "status_visibility_public",
+ "status_visibility_private",
+ "status_visibility_unlisted",
+ "status_visibility_direct"
+ ])
+
%{
- all: all_statuses_query() |> Repo.aggregate(:count, :id),
- 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)
+ public: counter_cache["status_visibility_public"] || 0,
+ unlisted: counter_cache["status_visibility_unlisted"] || 0,
+ private: counter_cache["status_visibility_private"] || 0,
+ direct: counter_cache["status_visibility_direct"] || 0
}
end
-
- defp all_statuses_query do
- from(o in Object, where: fragment("(?)->>'type' = 'Note'", o.data))
- 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