Files
danbooru/app/controllers/reports_controller.rb
evazion 0d835983ce reports: fix error when report is empty.
Fix an exception when a report is empty, for example when performing a
tag search that returns no results:

* https://betabooru.donmai.us/reports/posts?search[group]=uploader&search[tags]=does_not_exist
2022-10-23 21:55:06 -05:00

158 lines
6.5 KiB
Ruby

# frozen_string_literal: true
class ReportsController < ApplicationController
respond_to :html, :json, :xml
rate_limit :show, rate: 1.0/3.seconds, burst: 15
def index
end
def show
@report = params[:id]
@mode = params.dig(:search, :mode) || "chart"
@period = params.dig(:search, :period)&.downcase
@from = params.dig(:search, :from) || 1.month.ago
@to = params.dig(:search, :to) || Time.zone.now
@columns = params.dig(:search, :columns).to_s.split(/[[:space:],]/).map(&:to_sym)
@group = params.dig(:search, :group)&.downcase&.tr(" ", "_")
@group_limit = params.dig(:search, :group_limit)&.to_i || 10
case @report
when "posts"
@model = Post
@title = "Posts Report"
@available_columns = { posts: "COUNT(*)", uploaders: "COUNT(distinct uploader_id)" }
@available_groups = %w[uploader approver rating is_deleted]
when "post_approvals"
@model = PostApproval
@title = "Post Approvals Report"
@available_columns = { approvals: "COUNT(*)", approvers: "COUNT(distinct user_id)" }
@available_groups = %w[user]
when "post_appeals"
@model = PostAppeal
@title = "Post Appeals Report"
@available_columns = { appeals: "COUNT(*)", appealers: "COUNT(distinct creator_id)" }
@available_groups = %w[creator status]
when "post_flags"
@model = PostFlag
@title = "Post Flags Report"
@available_columns = { flags: "COUNT(*)", flaggers: "COUNT(distinct creator_id)" }
@available_groups = %w[status]
when "post_replacements"
@model = PostReplacement
@title = "Post Replacements Report"
@available_columns = { replacements: "COUNT(*)", replacers: "COUNT(distinct creator_id)" }
@available_groups = %w[creator]
when "post_votes"
@model = PostVote
@title = "Post Votes Report"
@available_columns = { votes: "COUNT(*)", posts: "COUNT(distinct post_id)", voters: "COUNT(distinct user_id)" }
@available_groups = %w[]
when "media_assets"
@model = MediaAsset
@title = "Media Assets Report"
@available_columns = { assets: "COUNT(*)", size: "SUM(file_size)", duration: "SUM(duration)" }
@available_groups = %w[file_ext status]
when "pools"
@model = Pool
@title = "Pools Report"
@available_columns = { pools: "COUNT(*)" }
@available_groups = %w[category is_deleted]
when "comments"
@model = Comment
@title = "Comments Report"
@available_columns = { comments: "COUNT(*)", commenters: "COUNT(distinct creator_id)" }
@available_groups = %w[creator do_not_bump_post is_deleted is_sticky]
when "comment_votes"
@model = CommentVote
@title = "Comment Votes Report"
@available_columns = { votes: "COUNT(*)", comments: "COUNT(distinct comment_id)", voters: "COUNT(distinct user_id)" }
@available_groups = %w[]
when "forum_posts"
@model = ForumPost
@title = "Forum Posts Report"
@available_columns = { forum_posts: "COUNT(*)", posters: "COUNT(distinct creator_id)" }
@available_groups = %w[creator is_deleted]
when "bulk_update_requests"
@model = BulkUpdateRequest
@title = "Bulk Update Requests Report"
@available_columns = { requests: "COUNT(*)", requestors: "COUNT(distinct user_id)" }
@available_groups = %w[user approver status]
when "tag_aliases"
@model = TagAlias
@title = "Tag Aliases Report"
@available_columns = { aliases: "COUNT(*)" }
@available_groups = %w[status approver]
when "tag_implications"
@model = TagImplication
@title = "Tag Implications Report"
@available_columns = { aliases: "COUNT(*)" }
@available_groups = %w[status approver]
when "artist_versions"
@model = ArtistVersion
@title = "Artist Edits Report"
@available_columns = { artist_edits: "COUNT(*)", artists: "COUNT(distinct artist_id)", editors: "COUNT(distinct updater_id)" }
@available_groups = %w[updater]
when "artist_commentary_versions"
@model = ArtistCommentaryVersion
@title = "Artist Commentary Edits Report"
@available_columns = { commentary_edits: "COUNT(*)", editors: "COUNT(distinct updater_id)" }
@available_groups = %w[updater]
when "note_versions"
@model = NoteVersion
@title = "Note Edits Report"
@available_columns = { note_edits: "COUNT(*)", posts: "COUNT(distinct post_id)", editors: "COUNT(distinct updater_id)" }
@available_groups = %w[updater]
when "wiki_page_versions"
@model = WikiPageVersion
@title = "Wiki Edits Report"
@available_columns = { wiki_edits: "COUNT(*)", editors: "COUNT(distinct updater_id)" }
@available_groups = %w[updater]
when "mod_actions"
@model = ModAction
@title = "Mod Actions Report"
@available_columns = { mod_actions: "COUNT(*)", creators: "COUNT(distinct creator_id)" }
@available_groups = %w[creator category subject_type]
when "bans"
@model = Ban
@title = "Bans Report"
@available_columns = { bans: "COUNT(*)", banners: "COUNT(DISTINCT banner_id)" }
@available_groups = %w[banner duration]
when "users"
@model = User
@title = "New Users Report"
@available_columns = { users: "COUNT(*)" }
@available_groups = %w[level]
else
raise ActiveRecord::RecordNotFound
end
if CurrentUser.user.is_member? && CurrentUser.user.statement_timeout < 10_000
@statement_timeout = 10_000
else
@statement_timeout = CurrentUser.user.statement_timeout
end
ApplicationRecord.set_timeout(@statement_timeout) do
@group = nil unless @group&.in?(@available_groups)
@columns = @available_columns.slice(*@columns)
@columns = [@available_columns.first].to_h if @columns.blank?
if @period.present?
@dataframe = @model.search(params[:search], CurrentUser.user).timeseries(period: @period, from: @from, to: @to, groups: [@group].compact_blank, group_limit: @group_limit, columns: @columns)
@x_axis = "date"
else
@dataframe = @model.search(params[:search], CurrentUser.user).aggregate(from: @from, to: @to, groups: [@group].compact_blank, limit: @group_limit, columns: @columns)
@x_axis = @group
end
@dataframe[@group] = @dataframe[@group].map(&:pretty_name) if @group.in?(%w[creator updater uploader banner approver user]) && @dataframe.names.include?(@group)
@dataframe["date"] = @dataframe["date"].map(&:to_date) if @dataframe["date"]
@dataframe = @dataframe.crosstab("date", @group) if @group && @period.present?
end
respond_with(@dataframe)
end
end