mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 17:06:31 -06:00
Migrate score settings to use sensitivities
We hide scores so these settings no longer made sense.
This commit is contained in:
parent
fad5d9c49b
commit
89b84651c3
@ -41,7 +41,7 @@ class Reviewable < ActiveRecord::Base
|
||||
Jobs.enqueue(:notify_reviewable, reviewable_id: self.id) if pending?
|
||||
end
|
||||
|
||||
# The gaps are in case we want more accuracy in the future
|
||||
# The gaps are in case we want more precision in the future
|
||||
def self.priorities
|
||||
@priorities ||= Enum.new(
|
||||
low: 0,
|
||||
@ -50,6 +50,16 @@ class Reviewable < ActiveRecord::Base
|
||||
)
|
||||
end
|
||||
|
||||
# The gaps are in case we want more precision in the future
|
||||
def self.sensitivity
|
||||
@sensitivity ||= Enum.new(
|
||||
disabled: 0,
|
||||
low: 9,
|
||||
medium: 6,
|
||||
high: 3
|
||||
)
|
||||
end
|
||||
|
||||
def self.statuses
|
||||
@statuses ||= Enum.new(
|
||||
pending: 0,
|
||||
@ -173,6 +183,29 @@ class Reviewable < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def self.sensitivity_score(sensitivity, scale: 1.0)
|
||||
return Float::MAX if sensitivity == 0
|
||||
|
||||
ratio = sensitivity / Reviewable.sensitivity[:low].to_f
|
||||
high = PluginStore.get('reviewables', "priority_#{Reviewable.priorities[:high]}")
|
||||
return (10.0 * scale) if high.nil?
|
||||
|
||||
# We want this to be hard to reach
|
||||
(high.to_f * ratio) * scale
|
||||
end
|
||||
|
||||
def self.score_to_auto_close_topic
|
||||
sensitivity_score(SiteSetting.auto_close_topic_sensitivity, scale: 2.5)
|
||||
end
|
||||
|
||||
def self.spam_score_to_silence_new_user
|
||||
sensitivity_score(SiteSetting.silence_new_user_sensitivity, scale: 0.6)
|
||||
end
|
||||
|
||||
def self.score_required_to_hide_post
|
||||
sensitivity_score(SiteSetting.hide_post_sensitivity)
|
||||
end
|
||||
|
||||
def self.min_score_for_priority(priority = nil)
|
||||
priority ||= SiteSetting.reviewable_default_visibility
|
||||
id = Reviewable.priorities[priority.to_sym]
|
||||
|
22
app/models/reviewable_sensitivity_setting.rb
Normal file
22
app/models/reviewable_sensitivity_setting.rb
Normal file
@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_dependency 'enum_site_setting'
|
||||
|
||||
class ReviewableSensitivitySetting < EnumSiteSetting
|
||||
|
||||
def self.valid_value?(val)
|
||||
values.any? { |v| v[:value].to_s == val.to_s }
|
||||
end
|
||||
|
||||
def self.values
|
||||
Reviewable.sensitivity.map do |p|
|
||||
{ name: I18n.t("reviewables.sensitivity.#{p[0]}"), value: p[1] }
|
||||
end
|
||||
end
|
||||
|
||||
def self.translate_names?
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1373,7 +1373,7 @@ class Topic < ActiveRecord::Base
|
||||
.pluck("COUNT(DISTINCT reviewable_scores.user_id), COALESCE(SUM(reviewable_scores.score), 0.0)")
|
||||
.first
|
||||
|
||||
scores[0] >= SiteSetting.num_flaggers_to_close_topic && scores[1] >= SiteSetting.score_to_auto_close_topic
|
||||
scores[0] >= SiteSetting.num_flaggers_to_close_topic && scores[1] >= Reviewable.score_to_auto_close_topic
|
||||
end
|
||||
|
||||
def update_category_topic_count_by(num)
|
||||
|
@ -24,14 +24,9 @@ class SpamRule::AutoSilence
|
||||
return false if @user.staged?
|
||||
return false if @user.has_trust_level?(TrustLevel[1])
|
||||
|
||||
if SiteSetting.spam_score_to_silence_new_user > 0 &&
|
||||
SiteSetting.num_users_to_silence_new_user > 0 &&
|
||||
user_spam_stats.total_spam_score >= SiteSetting.spam_score_to_silence_new_user &&
|
||||
user_spam_stats.spam_user_count >= SiteSetting.num_users_to_silence_new_user
|
||||
return true
|
||||
end
|
||||
|
||||
false
|
||||
SiteSetting.num_users_to_silence_new_user > 0 &&
|
||||
user_spam_stats.total_spam_score >= Reviewable.spam_score_to_silence_new_user &&
|
||||
user_spam_stats.spam_user_count >= SiteSetting.num_users_to_silence_new_user
|
||||
end
|
||||
|
||||
def user_spam_stats
|
||||
|
@ -1388,7 +1388,10 @@ en:
|
||||
anon_polling_interval: "How often should anonymous clients poll in milliseconds"
|
||||
background_polling_interval: "How often should the clients poll in milliseconds (when the window is in the background)"
|
||||
|
||||
score_required_to_hide_post: "Score threshold that causes a post to be automatically hidden and message sent to the user (0 to disable)"
|
||||
hide_post_sensitivity: "The likelyhood that a flagged post will be hidden"
|
||||
silence_new_user_sensitivity: "The likelyhood that a new user will be silenced based on spam flags"
|
||||
auto_close_topic_sensitivity: "The likelyhood that a flagged topic will be automatically closed"
|
||||
|
||||
cooldown_minutes_after_hiding_posts: "Number of minutes a user must wait before they can edit a post hidden via community flagging"
|
||||
|
||||
max_topics_in_first_day: "The maximum number of topics a user is allowed to create in the 24 hour period after creating their first post"
|
||||
@ -1397,8 +1400,6 @@ en:
|
||||
tl2_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl2 (member) by multiplying with this number"
|
||||
tl3_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl3 (regular) by multiplying with this number"
|
||||
tl4_additional_likes_per_day_multiplier: "Increase limit of likes per day for tl4 (leader) by multiplying with this number"
|
||||
|
||||
spam_score_to_silence_new_user: "If a new user's posts receive this score from num_users_to_silence_new_user different users, hide all their posts and prevent future posting. 0 to disable."
|
||||
num_users_to_silence_new_user: "If a new user's posts get num_spam_flags_to_silence_new_user spam flags from this many different users, hide all their posts and prevent future posting. 0 to disable."
|
||||
num_tl3_flags_to_silence_new_user: "If a new user's posts get this many flags from num_tl3_users_to_silence_new_user different trust level 3 users, hide all their posts and prevent future posting. 0 to disable."
|
||||
num_tl3_users_to_silence_new_user: "If a new user's posts get num_tl3_flags_to_silence_new_user flags from this many different trust level 3 users, hide all their posts and prevent future posting. 0 to disable."
|
||||
@ -1745,7 +1746,6 @@ en:
|
||||
max_age_unmatched_ips: "Delete unmatched screened IP entries after (N) days."
|
||||
|
||||
num_flaggers_to_close_topic: "Minimum number of unique flaggers that is required to automatically pause a topic for intervention"
|
||||
score_to_auto_close_topic: "The total flag score of that is required to automatically pause a topic for intervention"
|
||||
num_hours_to_close_topic: "Number of hours to pause a topic for intervention."
|
||||
|
||||
auto_respond_to_flag_actions: "Enable automatic reply when disposing a flag."
|
||||
@ -4418,7 +4418,11 @@ en:
|
||||
low: "Low"
|
||||
medium: "Medium"
|
||||
high: "High"
|
||||
|
||||
sensitivity:
|
||||
disabled: "Disabled"
|
||||
low: "Low"
|
||||
medium: "Medium"
|
||||
high: "High"
|
||||
must_claim: "You must claim items before acting on them."
|
||||
user_claimed: "This item has been claimed by another user."
|
||||
missing_version: "You must supply a version parameter"
|
||||
|
@ -1366,9 +1366,15 @@ onebox:
|
||||
|
||||
spam:
|
||||
add_rel_nofollow_to_user_content: true
|
||||
score_required_to_hide_post: 10
|
||||
hide_post_sensitivity:
|
||||
type: enum
|
||||
enum: "ReviewableSensitivitySetting"
|
||||
default: 6
|
||||
cooldown_minutes_after_hiding_posts: 10
|
||||
spam_score_to_silence_new_user: 6.0
|
||||
silence_new_user_sensitivity:
|
||||
type: enum
|
||||
enum: "ReviewableSensitivitySetting"
|
||||
default: 9
|
||||
num_users_to_silence_new_user: 3
|
||||
notify_mods_when_user_silenced: false
|
||||
flag_sockpuppets: false
|
||||
@ -1384,7 +1390,10 @@ spam:
|
||||
max_age_unmatched_emails: 365
|
||||
max_age_unmatched_ips: 365
|
||||
num_flaggers_to_close_topic: 5
|
||||
score_to_auto_close_topic: 25.0
|
||||
auto_close_topic_sensitivity:
|
||||
type: enum
|
||||
enum: "ReviewableSensitivitySetting"
|
||||
default: 3
|
||||
num_hours_to_close_topic:
|
||||
default: 4
|
||||
min: 1
|
||||
|
@ -166,9 +166,9 @@ private
|
||||
@post.user&.trust_level != TrustLevel[4]
|
||||
|
||||
@post.hide!(@post_action_type_id, Post.hidden_reasons[:flagged_by_tl4_user])
|
||||
elsif SiteSetting.score_required_to_hide_post > 0
|
||||
else
|
||||
score = ReviewableFlaggedPost.find_by(target: @post)&.score || 0
|
||||
if score >= SiteSetting.score_required_to_hide_post
|
||||
if score >= Reviewable.score_required_to_hide_post
|
||||
@post.hide!(@post_action_type_id)
|
||||
end
|
||||
end
|
||||
|
@ -12,8 +12,9 @@ describe "spam rules for users" do
|
||||
fab!(:user2) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
SiteSetting.score_required_to_hide_post = 0
|
||||
SiteSetting.spam_score_to_silence_new_user = 4.0
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled]
|
||||
Reviewable.set_priorities(high: 4.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
|
||||
SiteSetting.num_users_to_silence_new_user = 2
|
||||
end
|
||||
|
||||
@ -73,9 +74,10 @@ describe "spam rules for users" do
|
||||
end
|
||||
end
|
||||
|
||||
context 'score_required_to_hide_post takes effect too' do
|
||||
context 'hide_post_sensitivity' do
|
||||
it 'should silence the spammer' do
|
||||
SiteSetting.score_required_to_hide_post = 2.0
|
||||
Reviewable.set_priorities(high: 2.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
|
||||
PostActionCreator.create(user2, spam_post, :spam)
|
||||
expect(spammer.reload).to be_silenced
|
||||
expect(Guardian.new(spammer).can_create_topic?(nil)).to be false
|
||||
|
@ -517,7 +517,8 @@ describe PostAction do
|
||||
mod = Fabricate(:moderator)
|
||||
post = Fabricate(:post, user: mod)
|
||||
|
||||
SiteSetting.score_required_to_hide_post = 2.0
|
||||
Reviewable.set_priorities(high: 2.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
|
||||
Discourse.stubs(:site_contact_user).returns(admin)
|
||||
|
||||
PostActionCreator.spam(eviltrout, post)
|
||||
@ -531,7 +532,8 @@ describe PostAction do
|
||||
mod = Fabricate(:moderator)
|
||||
post = Fabricate(:post, user: mod)
|
||||
|
||||
SiteSetting.score_required_to_hide_post = 8.0
|
||||
Reviewable.set_priorities(high: 8.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
|
||||
Discourse.stubs(:site_contact_user).returns(admin)
|
||||
|
||||
PostActionCreator.spam(eviltrout, post)
|
||||
@ -547,7 +549,8 @@ describe PostAction do
|
||||
post = create_post
|
||||
walterwhite = Fabricate(:walter_white)
|
||||
|
||||
SiteSetting.score_required_to_hide_post = 3.0
|
||||
Reviewable.set_priorities(high: 3.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
|
||||
Discourse.stubs(:site_contact_user).returns(admin)
|
||||
|
||||
PostActionCreator.spam(eviltrout, post)
|
||||
@ -707,8 +710,9 @@ describe PostAction do
|
||||
fab!(:flagger2) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
SiteSetting.score_required_to_hide_post = 0
|
||||
SiteSetting.score_to_auto_close_topic = 12.0
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled]
|
||||
Reviewable.set_priorities(high: 4.5)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low]
|
||||
SiteSetting.num_flaggers_to_close_topic = 2
|
||||
SiteSetting.num_hours_to_close_topic = 1
|
||||
end
|
||||
@ -769,7 +773,8 @@ describe PostAction do
|
||||
freeze_time
|
||||
|
||||
SiteSetting.num_flaggers_to_close_topic = 1
|
||||
SiteSetting.score_to_auto_close_topic = 2.0
|
||||
Reviewable.set_priorities(high: 0.5)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low]
|
||||
|
||||
post = Fabricate(:post, topic: topic)
|
||||
PostActionCreator.spam(flagger1, post)
|
||||
@ -792,7 +797,8 @@ describe PostAction do
|
||||
|
||||
freeze_time timer.execute_at
|
||||
SiteSetting.num_flaggers_to_close_topic = 10
|
||||
SiteSetting.score_to_auto_close_topic = 20.0
|
||||
Reviewable.set_priorities(high: 10.0)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low]
|
||||
|
||||
Jobs::ToggleTopicClosed.new.execute(topic_timer_id: timer.id, state: false)
|
||||
|
||||
|
@ -87,7 +87,8 @@ RSpec.describe ReviewableQueuedPost, type: :model do
|
||||
newuser.update!(trust_level: 0)
|
||||
post = Fabricate(:post, user: newuser)
|
||||
PostActionCreator.spam(moderator, post)
|
||||
SiteSetting.spam_score_to_silence_new_user = 1
|
||||
Reviewable.set_priorities(high: 1.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
|
||||
SiteSetting.num_users_to_silence_new_user = 1
|
||||
expect(Guardian.new(newuser).can_create_post?(topic)).to eq(false)
|
||||
|
||||
|
@ -282,6 +282,73 @@ RSpec.describe Reviewable, type: :model do
|
||||
end
|
||||
end
|
||||
|
||||
context ".score_required_to_hide_post" do
|
||||
it "returns 10 if we can't calculated any percentiles" do
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
|
||||
expect(Reviewable.score_required_to_hide_post).to eq(10.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium]
|
||||
expect(Reviewable.score_required_to_hide_post).to eq(10.0)
|
||||
end
|
||||
|
||||
it "returns a fraction of the high percentile" do
|
||||
Reviewable.set_priorities(high: 100.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled]
|
||||
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(Float::MAX)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
|
||||
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(100.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:medium]
|
||||
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(66.66)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:high]
|
||||
expect(Reviewable.score_required_to_hide_post.to_f.truncate(2)).to eq(33.33)
|
||||
end
|
||||
end
|
||||
|
||||
context ".spam_score_to_silence_new_user" do
|
||||
it "returns 6 if we can't calculated any percentiles" do
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
|
||||
expect(Reviewable.spam_score_to_silence_new_user).to eq(6.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium]
|
||||
expect(Reviewable.spam_score_to_silence_new_user).to eq(6.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high]
|
||||
expect(Reviewable.spam_score_to_silence_new_user).to eq(6.0)
|
||||
end
|
||||
|
||||
it "returns a fraction of the high percentile" do
|
||||
Reviewable.set_priorities(high: 100.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:disabled]
|
||||
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(Float::MAX)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
|
||||
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(60.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:medium]
|
||||
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(39.99)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:high]
|
||||
expect(Reviewable.spam_score_to_silence_new_user.to_f.truncate(2)).to eq(19.99)
|
||||
end
|
||||
end
|
||||
|
||||
context ".score_to_auto_close_topic" do
|
||||
it "returns 25 if we can't calculated any percentiles" do
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low]
|
||||
expect(Reviewable.score_to_auto_close_topic).to eq(25.0)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium]
|
||||
expect(Reviewable.score_to_auto_close_topic).to eq(25.0)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high]
|
||||
expect(Reviewable.score_to_auto_close_topic).to eq(25.0)
|
||||
end
|
||||
|
||||
it "returns a fraction of the high percentile" do
|
||||
Reviewable.set_priorities(high: 100.0)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:disabled]
|
||||
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(Float::MAX)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:low]
|
||||
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(250.0)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:medium]
|
||||
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(166.66)
|
||||
SiteSetting.auto_close_topic_sensitivity = Reviewable.sensitivity[:high]
|
||||
expect(Reviewable.score_to_auto_close_topic.to_f.truncate(2)).to eq(83.33)
|
||||
end
|
||||
end
|
||||
|
||||
context "priorities" do
|
||||
it "returns 0 for unknown priorities" do
|
||||
expect(Reviewable.min_score_for_priority(:wat)).to eq(0.0)
|
||||
|
@ -115,7 +115,8 @@ RSpec.describe Admin::FlagsController do
|
||||
|
||||
context '#disagree' do
|
||||
it "unhides the post and unsilences the user if disagreed" do
|
||||
SiteSetting.spam_score_to_silence_new_user = 1.0
|
||||
Reviewable.set_priorities(high: 1.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
|
||||
SiteSetting.num_users_to_silence_new_user = 1
|
||||
|
||||
new_user = Fabricate(:newuser)
|
||||
|
@ -5,8 +5,9 @@ require 'rails_helper'
|
||||
describe SpamRule::AutoSilence do
|
||||
|
||||
before do
|
||||
SiteSetting.score_required_to_hide_post = 0 # never
|
||||
SiteSetting.spam_score_to_silence_new_user = 4.0
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:disabled]
|
||||
Reviewable.set_priorities(high: 4.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
|
||||
SiteSetting.num_users_to_silence_new_user = 2
|
||||
end
|
||||
|
||||
@ -21,7 +22,8 @@ describe SpamRule::AutoSilence do
|
||||
end
|
||||
|
||||
it 'delivers punishment when user should be silenced' do
|
||||
SiteSetting.spam_score_to_silence_new_user = 2.0
|
||||
Reviewable.set_priorities(high: 2.0)
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:low]
|
||||
SiteSetting.num_users_to_silence_new_user = 1
|
||||
PostActionCreator.spam(Discourse.system_user, post)
|
||||
subject.perform
|
||||
@ -194,8 +196,8 @@ describe SpamRule::AutoSilence do
|
||||
expect(subject.should_autosilence?).to eq(false)
|
||||
end
|
||||
|
||||
it 'returns false if spam_score_to_silence_new_user is 0' do
|
||||
SiteSetting.spam_score_to_silence_new_user = 0
|
||||
it 'returns false if silence_new_user_sensitivity is disabled' do
|
||||
SiteSetting.silence_new_user_sensitivity = Reviewable.sensitivity[:disabled]
|
||||
PostActionCreator.spam(flagger, post)
|
||||
PostActionCreator.spam(flagger2, post)
|
||||
expect(subject.should_autosilence?).to eq(false)
|
||||
|
@ -128,7 +128,8 @@ describe PostAlerter do
|
||||
coding_horror = Fabricate(:coding_horror)
|
||||
|
||||
PostActionNotifier.enable
|
||||
SiteSetting.score_required_to_hide_post = 4.0
|
||||
Reviewable.set_priorities(high: 4.0)
|
||||
SiteSetting.hide_post_sensitivity = Reviewable.sensitivity[:low]
|
||||
|
||||
PostActionCreator.spam(evil_trout, post)
|
||||
PostActionCreator.spam(walterwhite, post)
|
||||
|
Loading…
Reference in New Issue
Block a user