about summary refs log tree commit diff
path: root/app/workers/scheduler/ambassador_scheduler.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/workers/scheduler/ambassador_scheduler.rb')
-rw-r--r--app/workers/scheduler/ambassador_scheduler.rb56
1 files changed, 56 insertions, 0 deletions
diff --git a/app/workers/scheduler/ambassador_scheduler.rb b/app/workers/scheduler/ambassador_scheduler.rb
new file mode 100644
index 000000000..f00d0912a
--- /dev/null
+++ b/app/workers/scheduler/ambassador_scheduler.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+class Scheduler::AmbassadorScheduler
+  include Sidekiq::Worker
+  sidekiq_options lock: :until_executed, retry: 0
+
+  def perform
+    @ambassador = find_ambassador_acct
+    return if @ambassador.nil?
+
+    status = next_boost
+    return if status.nil?
+
+    ReblogService.new.call(@ambassador, status)
+  end
+
+  private
+
+  def find_ambassador_acct
+    ambassador = ENV['AMBASSADOR_USER'].to_i
+    return Account.find_by(id: ambassador) unless ambassador.zero?
+
+    ambassador = ENV['AMBASSADOR_USER']
+    return if ambassador.blank?
+
+    Account.find_local(ambassador)
+  end
+
+  def next_boost
+    ambassador_boost_candidates.first
+  end
+
+  def ambassador_boost_candidates
+    ambassador_boostable.joins(:status_stat).where('favourites_count + reblogs_count >= ?', ENV.fetch('AMBASSADOR_THRESHOLD', 3).to_i)
+  end
+
+  def ambassador_boostable
+    ambassador_unboosted.excluding_silenced_accounts.not_excluded_by_account(@ambassador)
+  end
+
+  def ambassador_unboosted
+    locally_boostable.where.not(id: ambassador_boosts)
+  end
+
+  def ambassador_boosts
+    @ambassador.statuses.where('statuses.reblog_of_id IS NOT NULL').reorder(nil).select(:reblog_of_id)
+  end
+
+  def locally_boostable
+    Status.local
+          .public_visibility
+          .without_replies
+          .without_reblogs
+          .where('statuses.created_at > ?', ENV.fetch('AMBASSADOR_RANGE', 14).days.ago)
+  end
+end