logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

stats.ex (3094B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Stats do
  5. use GenServer
  6. import Ecto.Query
  7. alias Pleroma.CounterCache
  8. alias Pleroma.Repo
  9. alias Pleroma.User
  10. @interval :timer.seconds(60)
  11. def start_link(_) do
  12. GenServer.start_link(
  13. __MODULE__,
  14. nil,
  15. name: __MODULE__
  16. )
  17. end
  18. @impl true
  19. def init(_args) do
  20. if Pleroma.Config.get(:env) != :test do
  21. {:ok, nil, {:continue, :calculate_stats}}
  22. else
  23. {:ok, calculate_stat_data()}
  24. end
  25. end
  26. @doc "Performs update stats"
  27. def force_update do
  28. GenServer.call(__MODULE__, :force_update)
  29. end
  30. @doc "Returns stats data"
  31. @spec get_stats() :: %{
  32. domain_count: non_neg_integer(),
  33. status_count: non_neg_integer(),
  34. user_count: non_neg_integer()
  35. }
  36. def get_stats do
  37. %{stats: stats} = GenServer.call(__MODULE__, :get_state)
  38. stats
  39. end
  40. @doc "Returns list peers"
  41. @spec get_peers() :: list(String.t())
  42. def get_peers do
  43. %{peers: peers} = GenServer.call(__MODULE__, :get_state)
  44. peers
  45. end
  46. @spec calculate_stat_data() :: %{
  47. peers: list(),
  48. stats: %{
  49. domain_count: non_neg_integer(),
  50. status_count: non_neg_integer(),
  51. user_count: non_neg_integer()
  52. }
  53. }
  54. def calculate_stat_data do
  55. peers =
  56. from(
  57. u in User,
  58. select: fragment("distinct split_part(?, '@', 2)", u.nickname),
  59. where: u.local != ^true
  60. )
  61. |> Repo.all()
  62. |> Enum.filter(& &1)
  63. domain_count = Enum.count(peers)
  64. status_count = Repo.aggregate(User.Query.build(%{local: true}), :sum, :note_count)
  65. users_query =
  66. from(u in User,
  67. where: u.is_active == true,
  68. where: u.local == true,
  69. where: not is_nil(u.nickname),
  70. where: not u.invisible
  71. )
  72. user_count = Repo.aggregate(users_query, :count, :id)
  73. %{
  74. peers: peers,
  75. stats: %{
  76. domain_count: domain_count,
  77. status_count: status_count || 0,
  78. user_count: user_count
  79. }
  80. }
  81. end
  82. @spec get_status_visibility_count(String.t() | nil) :: map()
  83. def get_status_visibility_count(instance \\ nil) do
  84. if is_nil(instance) do
  85. CounterCache.get_sum()
  86. else
  87. CounterCache.get_by_instance(instance)
  88. end
  89. end
  90. @impl true
  91. def handle_continue(:calculate_stats, _) do
  92. stats = calculate_stat_data()
  93. unless Pleroma.Config.get(:env) == :test do
  94. Process.send_after(self(), :run_update, @interval)
  95. end
  96. {:noreply, stats}
  97. end
  98. @impl true
  99. def handle_call(:force_update, _from, _state) do
  100. new_stats = calculate_stat_data()
  101. {:reply, new_stats, new_stats}
  102. end
  103. @impl true
  104. def handle_call(:get_state, _from, state) do
  105. {:reply, state, state}
  106. end
  107. @impl true
  108. def handle_info(:run_update, _) do
  109. new_stats = calculate_stat_data()
  110. Process.send_after(self(), :run_update, @interval)
  111. {:noreply, new_stats}
  112. end
  113. end