status_batch_action.rb 3.7 KB

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