FEATURE: adds a most disagreed flaggers report

This commit is contained in:
Joffrey JAFFEUX 2018-10-26 15:59:04 +02:00 committed by GitHub
parent e955a1f24b
commit b2585524a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 127 additions and 1 deletions

View File

@ -12,6 +12,16 @@ export default Ember.Controller.extend(PeriodComputationMixin, {
};
},
@computed
mostDisagreedFlaggersOptions() {
return {
table: {
total: false,
perPage: 10
}
};
},
@computed("startDate", "endDate")
filters(startDate, endDate) {
return { startDate, endDate };

View File

@ -33,6 +33,11 @@
dataSourceName="post_edits"
filters=lastWeekfilters}}
{{admin-report
dataSourceName="most_disagreed_flaggers"
filters=lastWeekfilters
reportOptions=mostDisagreedFlaggersOptions}}
{{plugin-outlet name="admin-dashboard-moderation-bottom"}}
</div>
</div>

View File

@ -1170,6 +1170,72 @@ class Report
end
end
def self.report_most_disagreed_flaggers(report)
report.data = []
report.modes = [:table]
report.labels = [
{
type: :user,
properties: {
username: :username,
id: :user_id,
avatar: :avatar_template,
},
title: I18n.t("reports.most_disagreed_flaggers.labels.user")
},
{
type: :number,
property: :disagreed_flags,
title: I18n.t("reports.most_disagreed_flaggers.labels.disagreed_flags")
},
{
type: :number,
property: :agreed_flags,
title: I18n.t("reports.most_disagreed_flaggers.labels.agreed_flags")
},
{
type: :number,
property: :score,
title: I18n.t("reports.most_disagreed_flaggers.labels.score")
},
]
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,
SUM(CASE WHEN pa.disagreed_at IS NOT NULL THEN 1 ELSE 0 END) as disagreed_flags,
SUM(CASE WHEN pa.agreed_at IS NOT NULL THEN 1 ELSE 0 END) as agreed_flags,
ROUND(SUM(CASE WHEN pa.agreed_at IS NOT NULL THEN 1 ELSE 0 END)::numeric / SUM(CASE WHEN pa.disagreed_at IS NOT NULL THEN 1 ELSE 0 END)::numeric, 2) as ratio,
SUM(CASE WHEN pa.disagreed_at IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN pa.agreed_at IS NOT NULL THEN 1 ELSE 0 END) spread,
ROUND((1-(SUM(CASE WHEN pa.agreed_at IS NOT NULL THEN 1 ELSE 0 END)::numeric / SUM(CASE WHEN pa.disagreed_at IS NOT NULL THEN 1 ELSE 0 END)::numeric)) *
(SUM(CASE WHEN pa.disagreed_at IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN pa.agreed_at IS NOT NULL THEN 1 ELSE 0 END)), 2) as score
FROM post_actions AS pa
INNER JOIN users AS u ON u.id = pa.user_id
WHERE pa.post_action_type_id IN (#{PostActionType.flag_types.values.join(', ')})
AND pa.user_id <> -1
GROUP BY u.id, u.username, u.silenced_till
HAVING SUM(CASE WHEN pa.disagreed_at IS NOT NULL THEN 1 ELSE 0 END) > SUM(CASE WHEN pa.agreed_at IS NOT NULL THEN 1 ELSE 0 END)
ORDER BY score DESC
LIMIT 20
SQL
DB.query(sql).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[:agreed_flags] = row.agreed_flags
flagger[:score] = row.score
report.data << flagger
end
end
private
def hex_to_rgbs(hex_color)

View File

@ -898,6 +898,13 @@ en:
editor: Editor
author: Author
edit_reason: Reason
most_disagreed_flaggers:
title: "Most disagreed flaggers"
labels:
user: User
agreed_flags: Agreed flags
disagreed_flags: Disagreed flags
score: Score
moderators_activity:
title: "Moderators activity"
labels:
@ -2725,7 +2732,7 @@ en:
This is an automated message.
The new user [%{username}](%{user_url}) tried to create multiple posts with links to %{domains}, but those posts were blocked to avoid spam. The user is still able to create new posts that do not link to %{domains}.
Please [review the user](%{user_url}).
This can be modified via the `newuser_spam_host_threshold` and `white_listed_spam_host_domains` site settings. Consider adding %{domains} to the whitelist if they should be exempt.

View File

@ -935,4 +935,42 @@ describe Report do
end
end
end
describe 'most_disagreed_flaggers' do
let(:joffrey) { Fabricate(:user, username: "joffrey") }
let(:robin) { Fabricate(:user, username: "robin") }
let(:moderator) { Fabricate(:moderator) }
context 'with data' do
it "it works" do
10.times do
post_disagreed = Fabricate(:post)
PostAction.act(joffrey, post_disagreed, PostActionType.types[:spam])
PostAction.clear_flags!(post_disagreed, moderator)
end
3.times do
post_disagreed = Fabricate(:post)
PostAction.act(robin, post_disagreed, PostActionType.types[:spam])
PostAction.clear_flags!(post_disagreed, moderator)
end
post_agreed = Fabricate(:post)
PostAction.act(robin, post_agreed, PostActionType.types[:off_topic])
PostAction.agree_flags!(post_agreed, moderator)
report = Report.find('most_disagreed_flaggers')
first = report.data[0]
expect(first[:username]).to eq("joffrey")
expect(first[:score]).to eq(10)
expect(first[:agreed_flags]).to eq(0)
expect(first[:disagreed_flags]).to eq(10)
second = report.data[1]
expect(second[:username]).to eq("robin")
expect(second[:agreed_flags]).to eq(1)
expect(second[:disagreed_flags]).to eq(3)
end
end
end
end