Files
danbooru/app/models/post_flag.rb
evazion 3210da1a23 flags: raise flag limits.
The old flag limits were:

* 1 flag per day for regular members.
* 10 flags per day for Gold users.
* Unlimited flags for approvers.

The new flag limits are:

* 10 flags in the modqueue at once for regular users.
* Unlimited flags for approvers.
* Unlimited flags for users with a high enough flag success rate. If you
  have at least 30 flags in the last 3 months, and you have at least a
  70% flag success rate, then you get unlimited flags.

10 flags at once means you can have up to 10 flagged posts in the
modqueue at the same time. Because flags stay in the modqueue for 3
days, this means you can flag on average 10 posts every 3 days, or just
over 3 posts per day.
2020-08-08 15:22:13 -05:00

121 lines
3.4 KiB
Ruby

class PostFlag < ApplicationRecord
class Error < StandardError; end
module Reasons
UNAPPROVED = "Unapproved in three days"
REJECTED = "Unapproved in three days after returning to moderation queue%"
end
COOLDOWN_PERIOD = 3.days
belongs_to :creator, class_name: "User"
belongs_to :post
validates :reason, presence: true, length: { in: 1..140 }
validate :validate_creator_is_not_limited, on: :create
validate :validate_post, on: :create
validates_uniqueness_of :creator_id, scope: :post_id, on: :create, unless: :is_deletion, message: "have already flagged this post"
before_save :update_post
attr_accessor :is_deletion
enum status: {
pending: 0,
succeeded: 1,
rejected: 2
}
scope :by_users, -> { where.not(creator: User.system) }
scope :by_system, -> { where(creator: User.system) }
scope :in_cooldown, -> { by_users.where("created_at >= ?", COOLDOWN_PERIOD.ago) }
scope :expired, -> { pending.where("post_flags.created_at <= ?", 3.days.ago) }
module SearchMethods
def creator_matches(creator, searcher)
return none if creator.nil?
policy = Pundit.policy!([searcher, nil], PostFlag.new(creator: creator))
if policy.can_view_flagger?
where(creator: creator).where.not(post: searcher.posts)
else
none
end
end
def category_matches(category)
case category
when "normal"
where("reason NOT IN (?) AND reason NOT LIKE ?", [Reasons::UNAPPROVED], Reasons::REJECTED)
when "unapproved"
where(reason: Reasons::UNAPPROVED)
when "rejected"
where("reason LIKE ?", Reasons::REJECTED)
when "deleted"
where("reason = ? OR reason LIKE ?", Reasons::UNAPPROVED, Reasons::REJECTED)
else
none
end
end
def search(params)
q = super
q = q.search_attributes(params, :post, :reason, :status)
q = q.text_attribute_matches(:reason, params[:reason_matches])
if params[:creator_id].present?
flagger = User.find(params[:creator_id])
q = q.creator_matches(flagger, CurrentUser.user)
elsif params[:creator_name].present?
flagger = User.find_by_name(params[:creator_name])
q = q.creator_matches(flagger, CurrentUser.user)
end
if params[:category]
q = q.category_matches(params[:category])
end
q.apply_default_order(params)
end
end
extend SearchMethods
def category
case reason
when Reasons::UNAPPROVED
:unapproved
when /#{Reasons::REJECTED.gsub("%", ".*")}/
:rejected
else
:normal
end
end
def update_post
post.update_column(:is_flagged, true) unless post.is_flagged?
end
def validate_creator_is_not_limited
errors[:creator] << "have reached your flag limit" if creator.is_flag_limited? && !is_deletion
end
def validate_post
errors[:post] << "is pending and cannot be flagged" if post.is_pending? && !is_deletion
errors[:post] << "is deleted and cannot be flagged" if post.is_deleted? && !is_deletion
errors[:post] << "is locked and cannot be flagged" if post.is_status_locked?
flag = post.flags.in_cooldown.last
if flag.present?
errors[:post] << "cannot be flagged more than once every #{COOLDOWN_PERIOD.inspect} (last flagged: #{flag.created_at.to_s(:long)})"
end
end
def uploader_id
post.uploader_id
end
def self.available_includes
[:post]
end
end