2024-02-25 12:15:55 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-06-14 22:27:53 -04:00
|
|
|
class BulkUpdateRequest < ApplicationRecord
|
2020-07-17 04:34:12 -04:00
|
|
|
attr_accessor :reason, :skip_forum, :should_validate
|
2014-06-16 20:29:27 -04:00
|
|
|
|
2014-06-12 23:12:09 -04:00
|
|
|
belongs_to :user
|
2018-04-02 13:51:26 -04:00
|
|
|
belongs_to :forum_topic, optional: true
|
|
|
|
belongs_to :forum_post, optional: true
|
|
|
|
belongs_to :approver, optional: true, class_name: "User"
|
2014-06-12 23:12:09 -04:00
|
|
|
|
2019-09-05 08:59:51 -04:00
|
|
|
validates :user, presence: true
|
|
|
|
validates :script, presence: true
|
|
|
|
validates :title, presence: { if: ->(rec) {rec.forum_topic_id.blank?} }
|
|
|
|
validates :status, inclusion: { :in => %w(pending approved rejected) }
|
2014-06-17 13:19:40 -04:00
|
|
|
validate :script_formatted_correctly
|
2014-08-23 20:01:56 -04:00
|
|
|
validate :forum_topic_id_not_invalid
|
2020-07-13 01:53:02 -04:00
|
|
|
validate :validate_script, on: :create
|
|
|
|
validate :check_validate_script, on: :update
|
2022-05-22 12:59:45 -04:00
|
|
|
validates :reason, length: { minimum: 5 }, on: :create, unless: :skip_forum
|
|
|
|
before_validation :initialize_attributes, on: :create
|
2015-04-21 20:22:16 -04:00
|
|
|
before_validation :normalize_text
|
2014-06-16 20:29:27 -04:00
|
|
|
after_create :create_forum_topic
|
2014-06-12 23:12:09 -04:00
|
|
|
|
2018-05-10 14:18:02 -04:00
|
|
|
scope :pending_first, -> { order(Arel.sql("(case status when 'pending' then 0 when 'approved' then 1 else 2 end)")) }
|
|
|
|
scope :pending, -> {where(status: "pending")}
|
2017-05-14 13:47:57 -04:00
|
|
|
|
2021-07-19 11:48:23 -04:00
|
|
|
module ApiMethods
|
|
|
|
def hidden_attributes
|
|
|
|
super + [:user_ip_addr]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-06-17 13:20:29 -04:00
|
|
|
module SearchMethods
|
2020-07-10 07:20:24 -04:00
|
|
|
def for_creator(id)
|
|
|
|
where("user_id = ?", id)
|
|
|
|
end
|
|
|
|
|
2018-01-28 23:46:18 -05:00
|
|
|
def default_order
|
|
|
|
pending_first.order(id: :desc)
|
|
|
|
end
|
|
|
|
|
2023-06-02 10:15:17 -04:00
|
|
|
def search(params)
|
2017-12-17 17:58:34 -05:00
|
|
|
q = super
|
2014-06-17 13:20:29 -04:00
|
|
|
|
2023-08-03 16:01:53 -04:00
|
|
|
q = q.where_user(:user_id, :user, params)
|
|
|
|
q = q.where_user(:approver_id, :approver, params)
|
2017-05-14 13:47:57 -04:00
|
|
|
|
|
|
|
if params[:forum_topic_id].present?
|
|
|
|
q = q.where(forum_topic_id: params[:forum_topic_id].split(",").map(&:to_i))
|
|
|
|
end
|
|
|
|
|
|
|
|
if params[:forum_post_id].present?
|
|
|
|
q = q.where(forum_post_id: params[:forum_post_id].split(",").map(&:to_i))
|
|
|
|
end
|
|
|
|
|
|
|
|
if params[:status].present?
|
|
|
|
q = q.where(status: params[:status].split(","))
|
|
|
|
end
|
|
|
|
|
2018-08-31 20:23:25 -04:00
|
|
|
q = q.attribute_matches(:title, params[:title_matches])
|
|
|
|
q = q.attribute_matches(:script, params[:script_matches])
|
|
|
|
|
2017-05-14 13:47:57 -04:00
|
|
|
params[:order] ||= "status_desc"
|
|
|
|
case params[:order]
|
|
|
|
when "updated_at_desc"
|
|
|
|
q = q.order(updated_at: :desc)
|
|
|
|
when "updated_at_asc"
|
|
|
|
q = q.order(updated_at: :asc)
|
2018-01-28 23:46:18 -05:00
|
|
|
else
|
2023-07-07 08:32:57 -04:00
|
|
|
q = q.apply_basic_order(params)
|
2017-05-14 13:47:57 -04:00
|
|
|
end
|
|
|
|
|
2014-06-17 13:20:29 -04:00
|
|
|
q
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
module ApprovalMethods
|
|
|
|
def forum_updater
|
|
|
|
@forum_updater ||= begin
|
|
|
|
post = if forum_topic
|
|
|
|
forum_post || forum_topic.posts.first
|
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
ForumUpdater.new(
|
2019-06-29 15:58:28 -04:00
|
|
|
forum_topic,
|
|
|
|
forum_post: post,
|
2019-01-02 20:27:01 -05:00
|
|
|
expected_title: title,
|
|
|
|
skip_update: !TagRelationship::SUPPORT_HARD_CODED
|
2017-03-31 20:42:14 -04:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2014-06-19 03:06:36 -04:00
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
def approve!(approver)
|
2018-02-24 15:58:04 -05:00
|
|
|
transaction do
|
|
|
|
CurrentUser.scoped(approver) do
|
2022-12-26 14:36:53 -05:00
|
|
|
BulkUpdateRequestImporter.new(script, forum_topic_id, user_id, user_ip_addr).process!
|
2020-07-17 04:34:12 -04:00
|
|
|
update(status: "approved", approver: CurrentUser.user)
|
2020-03-14 22:51:41 -04:00
|
|
|
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post&.id}) has been approved by @#{approver.name}.", "APPROVED")
|
2018-02-24 15:58:04 -05:00
|
|
|
end
|
2017-03-31 20:42:14 -04:00
|
|
|
end
|
2016-10-26 19:40:58 -04:00
|
|
|
|
2022-12-26 14:21:33 -05:00
|
|
|
rescue BulkUpdateRequestImporter::Error => x
|
2017-03-31 20:42:14 -04:00
|
|
|
self.approver = approver
|
|
|
|
CurrentUser.scoped(approver) do
|
2020-03-14 22:51:41 -04:00
|
|
|
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post&.id}) has failed: #{x.to_s}", "FAILED")
|
2017-03-31 20:42:14 -04:00
|
|
|
end
|
2021-02-07 21:56:22 -05:00
|
|
|
self.errors.add(:base, x.to_s)
|
2017-03-31 20:42:14 -04:00
|
|
|
end
|
2015-04-21 21:39:42 -04:00
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
def create_forum_topic
|
2019-08-11 00:52:16 -04:00
|
|
|
return if skip_forum
|
2017-03-31 20:42:14 -04:00
|
|
|
if forum_topic_id
|
2017-04-12 20:09:09 -04:00
|
|
|
forum_post = forum_topic.posts.create(body: reason_with_link)
|
2018-04-02 13:51:26 -04:00
|
|
|
update(forum_post_id: forum_post.id)
|
2017-03-31 20:42:14 -04:00
|
|
|
else
|
2020-07-04 21:27:17 -04:00
|
|
|
forum_topic = ForumTopic.create(title: title, category_id: Danbooru.config.alias_implication_forum_category, original_post_attributes: {body: reason_with_link})
|
2018-04-02 13:51:26 -04:00
|
|
|
update(forum_topic_id: forum_topic.id, forum_post_id: forum_topic.posts.first.id)
|
2017-03-31 20:42:14 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-04-16 19:09:39 -04:00
|
|
|
def reject!(rejector = User.system)
|
2018-02-24 15:58:04 -05:00
|
|
|
transaction do
|
|
|
|
update(status: "rejected")
|
2019-11-09 13:54:33 -05:00
|
|
|
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post&.id}) has been rejected by @#{rejector.name}.", "REJECTED")
|
2018-02-24 15:58:04 -05:00
|
|
|
end
|
2017-03-31 20:42:14 -04:00
|
|
|
end
|
2017-11-15 13:50:15 -05:00
|
|
|
|
|
|
|
def bulk_update_request_link
|
2022-07-10 10:17:31 -04:00
|
|
|
%("bulk update request ##{id}":/bulk_update_requests/#{id})
|
2017-11-15 13:50:15 -05:00
|
|
|
end
|
2015-07-07 17:11:13 -04:00
|
|
|
end
|
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
module ValidationMethods
|
|
|
|
def script_formatted_correctly
|
2022-12-26 14:21:33 -05:00
|
|
|
BulkUpdateRequestImporter.tokenize(script)
|
2017-03-31 20:42:14 -04:00
|
|
|
return true
|
|
|
|
rescue StandardError => e
|
2021-02-07 21:56:22 -05:00
|
|
|
errors.add(:base, e.message)
|
2017-03-31 20:42:14 -04:00
|
|
|
return false
|
|
|
|
end
|
2015-04-21 21:39:42 -04:00
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
def forum_topic_id_not_invalid
|
|
|
|
if forum_topic_id && !forum_topic
|
2021-02-07 21:56:22 -05:00
|
|
|
errors.add(:base, "Forum topic ID is invalid")
|
2017-03-31 20:42:14 -04:00
|
|
|
end
|
2015-04-21 21:39:42 -04:00
|
|
|
end
|
|
|
|
|
2020-07-13 01:53:02 -04:00
|
|
|
def check_validate_script
|
|
|
|
validate_script if should_validate
|
|
|
|
end
|
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
def validate_script
|
2022-12-26 14:36:53 -05:00
|
|
|
errors, new_script = BulkUpdateRequestImporter.new(script, forum_topic_id).validate!(CurrentUser.user)
|
2022-04-09 07:43:51 -04:00
|
|
|
if errors.size > 0
|
|
|
|
errors.each { |err| self.errors.add(:base, err) }
|
|
|
|
end
|
|
|
|
self.script = new_script
|
2014-06-12 23:12:09 -04:00
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
errors.empty?
|
2022-12-26 14:21:33 -05:00
|
|
|
rescue BulkUpdateRequestImporter::Error => e
|
2020-07-25 20:29:11 -04:00
|
|
|
self.errors.add(:script, e)
|
2015-07-07 17:11:13 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-03-31 20:42:14 -04:00
|
|
|
extend SearchMethods
|
|
|
|
include ApprovalMethods
|
|
|
|
include ValidationMethods
|
2021-07-19 11:48:23 -04:00
|
|
|
include ApiMethods
|
2017-03-31 20:42:14 -04:00
|
|
|
|
2019-01-02 20:27:01 -05:00
|
|
|
concerning :EmbeddedText do
|
|
|
|
class_methods do
|
|
|
|
def embedded_pattern
|
|
|
|
/\[bur:(?<id>\d+)\]/m
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-06-17 21:06:28 -04:00
|
|
|
def editable?(user)
|
2022-12-26 10:30:38 -05:00
|
|
|
is_pending? && (user_id == user.id || user.is_admin?)
|
2014-06-17 21:06:28 -04:00
|
|
|
end
|
|
|
|
|
2019-01-15 22:07:48 -05:00
|
|
|
def approvable?(user)
|
2024-03-03 06:04:56 -05:00
|
|
|
is_pending? && user.is_admin?
|
2019-01-15 22:07:48 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def rejectable?(user)
|
|
|
|
is_pending? && editable?(user)
|
|
|
|
end
|
|
|
|
|
2014-06-16 20:29:27 -04:00
|
|
|
def reason_with_link
|
2019-01-02 20:27:01 -05:00
|
|
|
"[bur:#{id}]\n\nReason: #{reason}"
|
2014-06-17 13:36:33 -04:00
|
|
|
end
|
|
|
|
|
2014-06-12 23:12:09 -04:00
|
|
|
def initialize_attributes
|
|
|
|
self.user_id = CurrentUser.user.id unless self.user_id
|
2024-10-28 14:37:37 -04:00
|
|
|
self.user_ip_addr = CurrentUser.ip_addr unless self.user_ip_addr
|
2014-06-12 23:12:09 -04:00
|
|
|
self.status = "pending"
|
|
|
|
end
|
2014-06-17 13:19:40 -04:00
|
|
|
|
2015-04-21 20:22:16 -04:00
|
|
|
def normalize_text
|
|
|
|
self.script = script.downcase
|
|
|
|
end
|
2016-01-28 20:39:01 -05:00
|
|
|
|
2019-08-11 00:52:16 -04:00
|
|
|
def skip_forum=(v)
|
|
|
|
@skip_forum = v.to_s.truthy?
|
|
|
|
end
|
|
|
|
|
2018-05-15 17:47:14 -04:00
|
|
|
def is_pending?
|
|
|
|
status == "pending"
|
|
|
|
end
|
|
|
|
|
|
|
|
def is_approved?
|
|
|
|
status == "approved"
|
|
|
|
end
|
|
|
|
|
|
|
|
def is_rejected?
|
|
|
|
status == "rejected"
|
|
|
|
end
|
2019-01-09 18:54:55 -05:00
|
|
|
|
|
|
|
def estimate_update_count
|
2022-12-26 14:21:33 -05:00
|
|
|
BulkUpdateRequestImporter.new(script, nil).estimate_update_count
|
2019-01-09 18:54:55 -05:00
|
|
|
end
|
2014-06-12 23:12:09 -04:00
|
|
|
end
|