+
+ 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