Merge remote-tracking branch 'remotes/origin/develop' into 1505-threads-federation
[akkoma] / lib / pleroma / stats.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Stats do
6 import Ecto.Query
7 alias Pleroma.Repo
8 alias Pleroma.User
9
10 use GenServer
11
12 @init_state %{
13 peers: [],
14 stats: %{
15 domain_count: 0,
16 status_count: 0,
17 user_count: 0
18 }
19 }
20
21 def start_link(_) do
22 GenServer.start_link(
23 __MODULE__,
24 @init_state,
25 name: __MODULE__
26 )
27 end
28
29 @doc "Performs update stats"
30 def force_update do
31 GenServer.call(__MODULE__, :force_update)
32 end
33
34 @doc "Performs collect stats"
35 def do_collect do
36 GenServer.cast(__MODULE__, :run_update)
37 end
38
39 @doc "Returns stats data"
40 @spec get_stats() :: %{domain_count: integer(), status_count: integer(), user_count: integer()}
41 def get_stats do
42 %{stats: stats} = GenServer.call(__MODULE__, :get_state)
43
44 stats
45 end
46
47 @doc "Returns list peers"
48 @spec get_peers() :: list(String.t())
49 def get_peers do
50 %{peers: peers} = GenServer.call(__MODULE__, :get_state)
51
52 peers
53 end
54
55 def init(args) do
56 {:ok, args}
57 end
58
59 def handle_call(:force_update, _from, _state) do
60 new_stats = get_stat_data()
61 {:reply, new_stats, new_stats}
62 end
63
64 def handle_call(:get_state, _from, state) do
65 {:reply, state, state}
66 end
67
68 def handle_cast(:run_update, _state) do
69 new_stats = get_stat_data()
70
71 {:noreply, new_stats}
72 end
73
74 defp get_stat_data do
75 peers =
76 from(
77 u in User,
78 select: fragment("distinct split_part(?, '@', 2)", u.nickname),
79 where: u.local != ^true
80 )
81 |> Repo.all()
82 |> Enum.filter(& &1)
83
84 domain_count = Enum.count(peers)
85
86 status_count = Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count)
87
88 user_count = Repo.aggregate(User.Query.build(%{local: true, active: true}), :count, :id)
89
90 %{
91 peers: peers,
92 stats: %{
93 domain_count: domain_count,
94 status_count: status_count,
95 user_count: user_count
96 }
97 }
98 end
99 end