status_batch_action.rb 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. # frozen_string_literal: true
  2. class Admin::StatusBatchAction
  3. include ActiveModel::Model
  4. include AccountableConcern
  5. include Authorization
  6. attr_accessor :current_account, :type,
  7. :status_ids, :report_id
  8. attr_reader :send_email_notification
  9. def send_email_notification=(value)
  10. @send_email_notification = ActiveModel::Type::Boolean.new.cast(value)
  11. end
  12. def save!
  13. process_action!
  14. end
  15. private
  16. def statuses
  17. Status.with_discarded.where(id: status_ids)
  18. end
  19. def process_action!
  20. return if status_ids.empty?
  21. case type
  22. when 'delete'
  23. handle_delete!
  24. when 'mark_as_sensitive'
  25. handle_mark_as_sensitive!
  26. when 'report'
  27. handle_report!
  28. when 'remove_from_report'
  29. handle_remove_from_report!
  30. end
  31. end
  32. def handle_delete!
  33. statuses.each { |status| authorize(status, :destroy?) }
  34. ApplicationRecord.transaction do
  35. statuses.each do |status|
  36. status.discard
  37. log_action(:destroy, status)
  38. end
  39. if with_report?
  40. report.resolve!(current_account)
  41. log_action(:resolve, report)
  42. end
  43. @warning = target_account.strikes.create!(
  44. action: :delete_statuses,
  45. account: current_account,
  46. report: report,
  47. status_ids: status_ids
  48. )
  49. statuses.each { |status| Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true) } unless target_account.local?
  50. end
  51. UserMailer.warning(target_account.user, @warning).deliver_later! if warnable?
  52. RemovalWorker.push_bulk(status_ids) { |status_id| [status_id, { 'preserve' => target_account.local?, 'immediate' => !target_account.local? }] }
  53. end
  54. def handle_mark_as_sensitive!
  55. representative_account = Account.representative
  56. # Can't use a transaction here because UpdateStatusService queues
  57. # Sidekiq jobs
  58. statuses.includes(:media_attachments, :preview_cards).find_each do |status|
  59. next if status.discarded? || !(status.with_media? || status.with_preview_card?)
  60. authorize(status, :update?)
  61. if target_account.local?
  62. UpdateStatusService.new.call(status, representative_account.id, sensitive: true)
  63. else
  64. status.update(sensitive: true)
  65. end
  66. log_action(:update, status)
  67. if with_report?
  68. report.resolve!(current_account)
  69. log_action(:resolve, report)
  70. end
  71. end
  72. @warning = target_account.strikes.create!(
  73. action: :mark_statuses_as_sensitive,
  74. account: current_account,
  75. report: report,
  76. status_ids: status_ids
  77. )
  78. UserMailer.warning(target_account.user, @warning).deliver_later! if warnable?
  79. end
  80. def handle_report!
  81. @report = Report.new(report_params) unless with_report?
  82. @report.status_ids = (@report.status_ids + allowed_status_ids).uniq
  83. @report.save!
  84. @report_id = @report.id
  85. end
  86. def handle_remove_from_report!
  87. return unless with_report?
  88. report.status_ids -= status_ids.map(&:to_i)
  89. report.save!
  90. end
  91. def report
  92. @report ||= Report.find(report_id) if report_id.present?
  93. end
  94. def with_report?
  95. !report.nil?
  96. end
  97. def warnable?
  98. send_email_notification && target_account.local?
  99. end
  100. def target_account
  101. @target_account ||= statuses.first.account
  102. end
  103. def report_params
  104. { account: current_account, target_account: target_account }
  105. end
  106. def allowed_status_ids
  107. Admin::AccountStatusesFilter.new(@report.target_account, current_account).results.with_discarded.where(id: status_ids).pluck(:id)
  108. end
  109. end