mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
prevent users with a tiny number of posts to dominate the 'new user of the month' leaderboard
This commit is contained in:
parent
52fbf9d3ae
commit
77ac14d475
@ -33,8 +33,6 @@ module Jobs
|
||||
end
|
||||
|
||||
def scores
|
||||
scores = {}
|
||||
|
||||
current_owners = UserBadge.where(badge_id: Badge::NewUserOfTheMonth).pluck(:user_id)
|
||||
current_owners = [-1] if current_owners.blank?
|
||||
|
||||
@ -44,49 +42,43 @@ module Jobs
|
||||
sql = <<~SQL
|
||||
SELECT u.id,
|
||||
SUM(CASE
|
||||
WHEN pa.id IS NOT NULL THEN
|
||||
CASE
|
||||
WHEN liked_by.id <= 0 THEN 0.0
|
||||
WHEN liked_by.admin OR liked_by.moderator THEN 2.0
|
||||
WHEN liked_by.trust_level = 0 THEN 0.1
|
||||
WHEN liked_by.trust_level = 1 THEN 0.25
|
||||
WHEN liked_by.trust_level = 2 THEN 1.0
|
||||
WHEN liked_by.trust_level = 3 THEN 1.5
|
||||
WHEN liked_by.trust_level = 4 THEN 2.0
|
||||
ELSE 1.0
|
||||
END
|
||||
ELSE 0
|
||||
END) / COUNT(DISTINCT p.id) AS score
|
||||
WHEN pa.id IS NOT NULL THEN
|
||||
CASE
|
||||
WHEN liked_by.id <= 0 THEN 0.0
|
||||
WHEN liked_by.admin THEN 3.0
|
||||
WHEN liked_by.moderator THEN 3.0
|
||||
WHEN liked_by.trust_level = 4 THEN 2.0
|
||||
WHEN liked_by.trust_level = 3 THEN 1.5
|
||||
WHEN liked_by.trust_level = 2 THEN 1.0
|
||||
WHEN liked_by.trust_level = 1 THEN 0.25
|
||||
WHEN liked_by.trust_level = 0 THEN 0.1
|
||||
ELSE 1.0
|
||||
END
|
||||
ELSE 0
|
||||
END) / (5 + COUNT(DISTINCT p.id)) AS score
|
||||
FROM users AS u
|
||||
INNER JOIN user_stats AS us ON u.id = us.user_id
|
||||
LEFT OUTER JOIN posts AS p ON p.user_id = u.id
|
||||
LEFT OUTER JOIN post_actions AS pa ON
|
||||
pa.post_id = p.id AND pa.post_action_type_id = :like
|
||||
LEFT OUTER JOIN users AS liked_by ON liked_by.id = pa.user_id
|
||||
LEFT OUTER JOIN topics AS t ON t.id = p.topic_id
|
||||
WHERE u.active AND
|
||||
u.id > 0 AND
|
||||
NOT(u.admin) AND
|
||||
NOT(u.moderator) AND
|
||||
t.archetype <> '#{Archetype.private_message}' AND
|
||||
u.created_at >= CURRENT_TIMESTAMP - '1 month'::INTERVAL AND
|
||||
u.id NOT IN (#{current_owners.join(',')})
|
||||
INNER JOIN user_stats AS us ON u.id = us.user_id
|
||||
LEFT OUTER JOIN posts AS p ON p.user_id = u.id
|
||||
LEFT OUTER JOIN post_actions AS pa ON pa.post_id = p.id AND pa.post_action_type_id = #{PostActionType.types[:like]}
|
||||
LEFT OUTER JOIN users AS liked_by ON liked_by.id = pa.user_id
|
||||
LEFT OUTER JOIN topics AS t ON t.id = p.topic_id
|
||||
WHERE u.active
|
||||
AND u.id > 0
|
||||
AND NOT u.staged
|
||||
AND NOT u.admin
|
||||
AND NOT u.moderator
|
||||
AND t.archetype <> '#{Archetype.private_message}'
|
||||
AND u.created_at >= CURRENT_TIMESTAMP - '1 month'::INTERVAL
|
||||
AND u.id NOT IN (#{current_owners.join(',')})
|
||||
GROUP BY u.id
|
||||
HAVING COUNT(DISTINCT p.id) > 1
|
||||
AND COUNT(DISTINCT p.topic_id) > 1
|
||||
AND COUNT(pa.id) > 1
|
||||
AND COUNT(DISTINCT p.topic_id) > 1
|
||||
AND COUNT(pa.id) > 1
|
||||
ORDER BY score DESC
|
||||
LIMIT :max_awarded
|
||||
LIMIT #{MAX_AWARDED}
|
||||
SQL
|
||||
|
||||
User.exec_sql(
|
||||
sql,
|
||||
like: PostActionType.types[:like],
|
||||
max_awarded: MAX_AWARDED
|
||||
).each do |row|
|
||||
scores[row['id'].to_i] = row['score'].to_f
|
||||
end
|
||||
scores
|
||||
User.exec_sql(sql).map { |r| [r['id'].to_i, r['score'].to_f] }.to_h
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -162,11 +162,11 @@ describe Jobs::GrantNewUserOfTheMonthBadges do
|
||||
PostAction.act(um, p, PostActionType.types[:like])
|
||||
PostAction.act(ua, p, PostActionType.types[:like])
|
||||
PostAction.act(Discourse.system_user, p, PostActionType.types[:like])
|
||||
expect(granter.scores[user.id]).to eq(4.425)
|
||||
expect(granter.scores[user.id]).to eq(1.55)
|
||||
|
||||
# It goes down the more they post
|
||||
Fabricate(:post, user: user)
|
||||
expect(granter.scores[user.id]).to eq(2.95)
|
||||
expect(granter.scores[user.id]).to eq(1.35625)
|
||||
end
|
||||
|
||||
it "is limited to two accounts" do
|
||||
|
Loading…
Reference in New Issue
Block a user