Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.5KB

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