discourse/app/models/reports/user_flagging_ratio.rb
Sam Saffron 30990006a9 DEV: enable frozen string literal on all files
This reduces chances of errors where consumers of strings mutate inputs
and reduces memory usage of the app.

Test suite passes now, but there may be some stuff left, so we will run
a few sites on a branch prior to merging
2019-05-13 09:31:32 +08:00

84 lines
2.4 KiB
Ruby

# frozen_string_literal: true
Report.add_report("user_flagging_ratio") do |report|
report.data = []
report.modes = [:table]
report.dates_filtering = true
report.labels = [
{
type: :user,
properties: {
username: :username,
id: :user_id,
avatar: :avatar_template,
},
title: I18n.t("reports.user_flagging_ratio.labels.user")
},
{
type: :number,
property: :disagreed_flags,
title: I18n.t("reports.user_flagging_ratio.labels.disagreed_flags")
},
{
type: :number,
property: :agreed_flags,
title: I18n.t("reports.user_flagging_ratio.labels.agreed_flags")
},
{
type: :number,
property: :ignored_flags,
title: I18n.t("reports.user_flagging_ratio.labels.ignored_flags")
},
{
type: :number,
property: :score,
title: I18n.t("reports.user_flagging_ratio.labels.score")
},
]
statuses = ReviewableScore.statuses
agreed = "SUM(CASE WHEN rs.status = #{statuses[:agreed]} THEN 1 ELSE 0 END)::numeric"
disagreed = "SUM(CASE WHEN rs.status = #{statuses[:disagreed]} THEN 1 ELSE 0 END)::numeric"
ignored = "SUM(CASE WHEN rs.status = #{statuses[:ignored]} THEN 1 ELSE 0 END)::numeric"
sql = <<~SQL
SELECT u.id,
u.username,
u.uploaded_avatar_id as avatar_id,
CASE WHEN u.silenced_till IS NOT NULL THEN 't' ELSE 'f' END as silenced,
#{disagreed} AS disagreed_flags,
#{agreed} AS agreed_flags,
#{ignored} AS ignored_flags,
ROUND((1-(#{agreed} / #{disagreed})) * (#{disagreed} - #{agreed})) AS score
FROM users AS u
INNER JOIN reviewable_scores AS rs ON rs.user_id = u.id
WHERE u.id > 0
AND rs.created_at >= :start_date
AND rs.created_at <= :end_date
GROUP BY u.id,
u.username,
u.uploaded_avatar_id,
u.silenced_till
HAVING #{disagreed} > #{agreed}
ORDER BY score DESC
LIMIT 100
SQL
DB.query(sql, start_date: report.start_date, end_date: report.end_date).each do |row|
flagger = {}
flagger[:user_id] = row.id
flagger[:username] = row.username
flagger[:avatar_template] = User.avatar_template(row.username, row.avatar_id)
flagger[:disagreed_flags] = row.disagreed_flags
flagger[:ignored_flags] = row.ignored_flags
flagger[:agreed_flags] = row.agreed_flags
flagger[:score] = row.score
report.data << flagger
end
end