diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/concerns/account_interactions.rb | 16 | ||||
-rw-r--r-- | app/models/concerns/rate_limitable.rb | 36 | ||||
-rw-r--r-- | app/models/follow.rb | 3 | ||||
-rw-r--r-- | app/models/follow_request.rb | 3 | ||||
-rw-r--r-- | app/models/status.rb | 3 |
5 files changed, 59 insertions, 2 deletions
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb index 14bcf7bb1..32fcb5397 100644 --- a/app/models/concerns/account_interactions.rb +++ b/app/models/concerns/account_interactions.rb @@ -87,10 +87,10 @@ module AccountInteractions has_many :announcement_mutes, dependent: :destroy end - def follow!(other_account, reblogs: nil, uri: nil) + def follow!(other_account, reblogs: nil, uri: nil, rate_limit: false) reblogs = true if reblogs.nil? - rel = active_relationships.create_with(show_reblogs: reblogs, uri: uri) + rel = active_relationships.create_with(show_reblogs: reblogs, uri: uri, rate_limit: rate_limit) .find_or_create_by!(target_account: other_account) rel.update!(show_reblogs: reblogs) @@ -99,6 +99,18 @@ module AccountInteractions rel end + def request_follow!(other_account, reblogs: nil, uri: nil, rate_limit: false) + reblogs = true if reblogs.nil? + + rel = follow_requests.create_with(show_reblogs: reblogs, uri: uri, rate_limit: rate_limit) + .find_or_create_by!(target_account: other_account) + + rel.update!(show_reblogs: reblogs) + remove_potential_friendship(other_account) + + rel + end + def block!(other_account, uri: nil) remove_potential_friendship(other_account) block_relationships.create_with(uri: uri) diff --git a/app/models/concerns/rate_limitable.rb b/app/models/concerns/rate_limitable.rb new file mode 100644 index 000000000..ad1b5e44e --- /dev/null +++ b/app/models/concerns/rate_limitable.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module RateLimitable + extend ActiveSupport::Concern + + def rate_limit=(value) + @rate_limit = value + end + + def rate_limit? + @rate_limit + end + + def rate_limiter(by, options = {}) + return @rate_limiter if defined?(@rate_limiter) + + @rate_limiter = RateLimiter.new(by, options) + end + + class_methods do + def rate_limit(options = {}) + after_create do + by = public_send(options[:by]) + + if rate_limit? && by&.local? + rate_limiter(by, options).record! + @rate_limit_recorded = true + end + end + + after_rollback do + rate_limiter(public_send(options[:by]), options).rollback! if @rate_limit_recorded + end + end + end +end diff --git a/app/models/follow.rb b/app/models/follow.rb index 87fa11425..f3e48a2ed 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -15,6 +15,9 @@ class Follow < ApplicationRecord include Paginable include RelationshipCacheable + include RateLimitable + + rate_limit by: :account, family: :follows belongs_to :account belongs_to :target_account, class_name: 'Account' diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb index 96ac7eaa5..3325e264c 100644 --- a/app/models/follow_request.rb +++ b/app/models/follow_request.rb @@ -15,6 +15,9 @@ class FollowRequest < ApplicationRecord include Paginable include RelationshipCacheable + include RateLimitable + + rate_limit by: :account, family: :follows belongs_to :account belongs_to :target_account, class_name: 'Account' diff --git a/app/models/status.rb b/app/models/status.rb index 1e630196b..1610da245 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -32,6 +32,9 @@ class Status < ApplicationRecord include Paginable include Cacheable include StatusThreadingConcern + include RateLimitable + + rate_limit by: :account, family: :statuses self.discard_column = :deleted_at |