philomena/lib/philomena_web/controllers/stat_controller.ex
2020-01-10 23:20:19 -05:00

140 lines
3.8 KiB
Elixir

defmodule PhilomenaWeb.StatController do
use PhilomenaWeb, :controller
alias Philomena.Elasticsearch
alias Philomena.Servers.Config
alias Philomena.Images.Image
alias Philomena.Comments.Comment
alias Philomena.Topics.Topic
alias Philomena.Forums.Forum
alias Philomena.Posts.Post
alias Philomena.Users.User
alias Philomena.Galleries.Gallery
alias Philomena.Galleries.Interaction
alias Philomena.Commissions.Commission
alias Philomena.Commissions.Item
alias Philomena.Reports.Report
alias Philomena.Repo
import Ecto.Query
def index(conn, _params) do
{gallery_count, gallery_size, distinct_creators, images_in_galleries} = galleries()
{open_reports, report_count, response_time} = moderation()
{open_commissions, commission_items} = commissions()
{image_aggs, comment_aggs} = aggregations()
{forums, topics, posts} = forums()
{users, users_24h} = users()
render(
conn,
"index.html",
image_aggs: image_aggs,
comment_aggs: comment_aggs,
forums_count: forums,
topics_count: topics,
posts_count: posts,
users_count: users,
users_24h: users_24h,
open_commissions: open_commissions,
commission_items: commission_items,
open_reports: open_reports,
report_stat_count: report_count,
response_time: response_time,
gallery_count: gallery_count,
gallery_size: gallery_size,
distinct_creators: distinct_creators,
images_in_galleries: images_in_galleries,
title: "Statistics"
)
end
defp aggregations do
data = Config.get(:aggregation)
{
Elasticsearch.search(Image, data["images"]),
Elasticsearch.search(Comment, data["comments"])
}
end
defp forums do
forums =
Forum
|> where(access_level: "normal")
|> Repo.aggregate(:count, :id)
first_topic = Repo.one(first(Topic))
last_topic = Repo.one(last(Topic))
first_post = Repo.one(first(Post))
last_post = Repo.one(last(Post))
{forums, diff(last_topic, first_topic), diff(last_post, first_post)}
end
defp users do
first_user = Repo.one(first(User))
last_user = Repo.one(last(User))
time = DateTime.utc_now() |> DateTime.add(-86400, :second)
last_24h =
User
|> where([u], u.created_at > ^time)
|> Repo.aggregate(:count, :id)
{diff(last_user, first_user), last_24h}
end
defp galleries do
gallery_count = Repo.aggregate(Gallery, :count, :id)
gallery_size =
Repo.aggregate(Gallery, :avg, :image_count)
|> Kernel.||(Decimal.new(0))
|> Decimal.to_float()
|> trunc()
distinct_creators =
Gallery
|> distinct(:creator_id)
|> Repo.aggregate(:count, :id)
first_gi = Repo.one(first(Interaction))
last_gi = Repo.one(last(Interaction))
{gallery_count, gallery_size, distinct_creators, diff(last_gi, first_gi)}
end
defp commissions do
open_commissions = Repo.aggregate(where(Commission, open: true), :count, :id)
commission_items = Repo.aggregate(Item, :count, :id)
{open_commissions, commission_items}
end
defp moderation do
open_reports = Repo.aggregate(where(Report, open: true), :count, :id)
first_report = Repo.one(first(Report))
last_report = Repo.one(last(Report))
closed_reports =
Report
|> where(open: false)
|> order_by(desc: :created_at)
|> limit(250)
|> Repo.all()
response_time =
closed_reports
|> Enum.reduce(0, &(&2 + NaiveDateTime.diff(&1.updated_at, &1.created_at, :second)))
|> Kernel./(safe_length(closed_reports) * 3600)
|> trunc()
{open_reports, diff(last_report, first_report), response_time}
end
defp diff(nil, nil), do: 0
defp diff(%{id: id2}, %{id: id1}), do: id2 - id1
defp safe_length([]), do: 1
defp safe_length(list), do: length(list)
end