diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8a09c8fbe..99846d6dd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -75,9 +75,13 @@ class ApplicationController < ActionController::Base render 'default/empty' end + def render_rate_limit_error(e) + render_json_error e.description, type: :rate_limit, status: 429 + end + # If they hit the rate limiter rescue_from RateLimiter::LimitExceeded do |e| - render_json_error e.description, type: :rate_limit, status: 429 + render_rate_limit_error(e) end rescue_from PG::ReadOnlySqlTransaction do |e| diff --git a/app/controllers/post_actions_controller.rb b/app/controllers/post_actions_controller.rb index 4a7585890..f707c57e6 100644 --- a/app/controllers/post_actions_controller.rb +++ b/app/controllers/post_actions_controller.rb @@ -23,6 +23,15 @@ class PostActionsController < ApplicationController @post.reload render_post_json(@post, _add_raw = false) end + rescue RateLimiter::LimitExceeded => e + # Special case: if we hit the create like rate limit, record it in user history + # so we can award a badge + if e.type == "create_like" + UserHistory.create!(action: UserHistory.actions[:rate_limited_like], + target_user_id: current_user.id, + post_id: @post.id) + end + render_rate_limit_error(e) end def destroy diff --git a/app/models/badge.rb b/app/models/badge.rb index dd01145ef..467a72157 100644 --- a/app/models/badge.rb +++ b/app/models/badge.rb @@ -28,6 +28,7 @@ class Badge < ActiveRecord::Base FamousLink = 30 Admired = 31 GivesBack = 32 + Generous = 33 # other consts AutobiographerMinBioLength = 10 @@ -218,6 +219,14 @@ SQL HAVING us.likes_given::float / count(*) > 5.0 SQL + Generous = <<-SQL + SELECT uh.target_user_id AS user_id, MIN(uh.created_at) AS granted_at + FROM user_histories AS uh + WHERE uh.action = #{UserHistory.actions[:rate_limited_like]} + AND (:backfill OR uh.target_user_id IN (:user_ids)) + GROUP BY uh.target_user_id +SQL + def self.invite_badge(count,trust_level) " SELECT u.id user_id, current_timestamp granted_at diff --git a/app/models/user_history.rb b/app/models/user_history.rb index e142d9f5a..ccabc8ce6 100644 --- a/app/models/user_history.rb +++ b/app/models/user_history.rb @@ -51,7 +51,8 @@ class UserHistory < ActiveRecord::Base revoke_admin: 33, grant_moderation: 34, revoke_moderation: 35, - backup_operation: 36) + backup_operation: 36, + rate_limited_like: 37) end # Staff actions is a subset of all actions, used to audit actions taken by staff users. diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 736e318b2..ac91569ce 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -2970,6 +2970,9 @@ en: gives_back: name: Gives Back description: Has a high ratio of likes given to likes received + generous: + name: Generous + description: Used the maximum amount of likes in a day google_search: |