diff options
author | feld <feld@feld.me> | 2019-12-20 16:30:26 +0000 |
---|---|---|
committer | feld <feld@feld.me> | 2019-12-20 16:30:26 +0000 |
commit | a54aa5af43bad062e7ab5ce946fa5add2fc4d48e (patch) | |
tree | 2b7c6fe32b9255e042a898544b66ab884797e999 /lib | |
parent | 60819fd973b811b4e079cdb31c2764e92753f4af (diff) | |
parent | 5fc84552d311efd606f66775c55862b3d11ad258 (diff) | |
download | pleroma-a54aa5af43bad062e7ab5ce946fa5add2fc4d48e.tar.gz |
Merge branch 'feature/status-counts-by-scope' into 'develop'
Stats: return status counts by scope
See merge request pleroma/pleroma!2076
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/stats.ex | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index 8154a09b7..97e8b1990 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -3,11 +3,15 @@ # 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 - use GenServer + require Pleroma.Constants @interval 1000 * 60 * 60 @@ -56,7 +60,7 @@ defmodule Pleroma.Stats do %{peers: [], stats: %{}} end - defp get_stat_data do + def get_stat_data do peers = from( u in User, @@ -68,13 +72,71 @@ 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 + %{ + 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) + } + 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 |