about summary refs log tree commit diff
path: root/app/models/admin
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/admin')
-rw-r--r--app/models/admin/account_action.rb28
-rw-r--r--app/models/admin/status_batch_action.rb92
-rw-r--r--app/models/admin/status_filter.rb41
3 files changed, 144 insertions, 17 deletions
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
index bf222391f..d3be4be3f 100644
--- a/app/models/admin/account_action.rb
+++ b/app/models/admin/account_action.rb
@@ -33,7 +33,7 @@ class Admin::AccountAction
   def save!
     ApplicationRecord.transaction do
       process_action!
-      process_warning!
+      process_strike!
     end
 
     process_email!
@@ -74,20 +74,14 @@ class Admin::AccountAction
     end
   end
 
-  def process_warning!
-    return unless warnable?
-
-    authorize(target_account, :warn?)
-
-    @warning = AccountWarning.create!(target_account: target_account,
-                                      account: current_account,
-                                      action: type,
-                                      text: text_for_warning)
-
-    # A log entry is only interesting if the warning contains
-    # custom text from someone. Otherwise it's just noise.
-
-    log_action(:create, warning) if warning.text.present?
+  def process_strike!
+    @warning = target_account.strikes.create!(
+      account: current_account,
+      report: report,
+      action: type,
+      text: text_for_warning,
+      status_ids: status_ids
+    )
   end
 
   def process_reports!
@@ -143,7 +137,7 @@ class Admin::AccountAction
   end
 
   def process_email!
-    UserMailer.warning(target_account.user, warning, status_ids).deliver_later! if warnable?
+    UserMailer.warning(target_account.user, warning).deliver_later! if warnable?
   end
 
   def warnable?
@@ -151,7 +145,7 @@ class Admin::AccountAction
   end
 
   def status_ids
-    report.status_ids if report && include_statuses
+    report.status_ids if with_report? && include_statuses
   end
 
   def reports
diff --git a/app/models/admin/status_batch_action.rb b/app/models/admin/status_batch_action.rb
new file mode 100644
index 000000000..319deff98
--- /dev/null
+++ b/app/models/admin/status_batch_action.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+class Admin::StatusBatchAction
+  include ActiveModel::Model
+  include AccountableConcern
+  include Authorization
+
+  attr_accessor :current_account, :type,
+                :status_ids, :report_id
+
+  def save!
+    process_action!
+  end
+
+  private
+
+  def statuses
+    Status.with_discarded.where(id: status_ids)
+  end
+
+  def process_action!
+    return if status_ids.empty?
+
+    case type
+    when 'delete'
+      handle_delete!
+    when 'report'
+      handle_report!
+    when 'remove_from_report'
+      handle_remove_from_report!
+    end
+  end
+
+  def handle_delete!
+    statuses.each { |status| authorize(status, :destroy?) }
+
+    ApplicationRecord.transaction do
+      statuses.each do |status|
+        status.discard
+        log_action(:destroy, status)
+      end
+
+      if with_report?
+        report.resolve!(current_account)
+        log_action(:resolve, report)
+      end
+
+      @warning = target_account.strikes.create!(
+        action: :delete_statuses,
+        account: current_account,
+        report: report,
+        status_ids: status_ids
+      )
+
+      statuses.each { |status| Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true) } unless target_account.local?
+    end
+
+    UserMailer.warning(target_account.user, @warning).deliver_later! if target_account.local?
+    RemovalWorker.push_bulk(status_ids) { |status_id| [status_id, preserve: target_account.local?, immediate: !target_account.local?] }
+  end
+
+  def handle_report!
+    @report = Report.new(report_params) unless with_report?
+    @report.status_ids = (@report.status_ids + status_ids.map(&:to_i)).uniq
+    @report.save!
+
+    @report_id = @report.id
+  end
+
+  def handle_remove_from_report!
+    return unless with_report?
+
+    report.status_ids -= status_ids.map(&:to_i)
+    report.save!
+  end
+
+  def report
+    @report ||= Report.find(report_id) if report_id.present?
+  end
+
+  def with_report?
+    !report.nil?
+  end
+
+  def target_account
+    @target_account ||= statuses.first.account
+  end
+
+  def report_params
+    { account: current_account, target_account: target_account }
+  end
+end
diff --git a/app/models/admin/status_filter.rb b/app/models/admin/status_filter.rb
new file mode 100644
index 000000000..ce5bb5f46
--- /dev/null
+++ b/app/models/admin/status_filter.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class Admin::StatusFilter
+  KEYS = %i(
+    media
+    id
+    report_id
+  ).freeze
+
+  attr_reader :params
+
+  def initialize(account, params)
+    @account = account
+    @params  = params
+  end
+
+  def results
+    scope = @account.statuses.where(visibility: [:public, :unlisted])
+
+    params.each do |key, value|
+      next if %w(page report_id).include?(key.to_s)
+
+      scope.merge!(scope_for(key, value.to_s.strip)) if value.present?
+    end
+
+    scope
+  end
+
+  private
+
+  def scope_for(key, value)
+    case key.to_s
+    when 'media'
+      Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
+    when 'id'
+      Status.where(id: value)
+    else
+      raise "Unknown filter: #{key}"
+    end
+  end
+end