about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-07-19 18:50:24 -0500
committerFire Demon <firedemon@creature.cafe>2020-08-30 05:43:59 -0500
commit21438b54bdaf3c557ec9ebbc482a2c418d8c64f8 (patch)
treee577d047af196823227e675dea52b2fc2fa842c6 /app/services
parent8c8ad0ac0ed0d3e67f3e521068b59edd4054f1e9 (diff)
[Feature] Add manual publishing option
Diffstat (limited to 'app/services')
-rw-r--r--app/services/fan_out_on_write_service.rb3
-rw-r--r--app/services/post_status_service.rb11
-rw-r--r--app/services/process_mentions_service.rb5
-rw-r--r--app/services/update_status_service.rb8
4 files changed, 21 insertions, 6 deletions
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index dd9c1264d..f16b799bd 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -3,10 +3,11 @@
 class FanOutOnWriteService < BaseService
   # Push a status into home and mentions feeds
   # @param [Status] status
-  def call(status)
+  def call(status, only_to_self: false)
     raise Mastodon::RaceConditionError if status.visibility.nil?
 
     deliver_to_self(status) if status.account.local?
+    return if only_to_self
 
     render_anonymous_payload(status)
 
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index c52ca4a9b..5ddc1aeeb 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -23,6 +23,7 @@ class PostStatusService < BaseService
   # @option [Status] :status Edit an existing status
   # @option [Enumerable] :mentions Optional array of Mentions to include
   # @option [Enumerable] :tags Option array of tag names to include
+  # @option [Boolean] :publish If true, status will be published
   # @return [Status]
   def call(account, options = {})
     @account     = account
@@ -30,6 +31,8 @@ class PostStatusService < BaseService
     @text        = @options[:text] || ''
     @in_reply_to = @options[:thread]
 
+    @options[:publish] ||= !account.user&.setting_manual_publish
+
     raise Mastodon::NotPermittedError if different_author?
 
     @tag_names   = (@options[:tags] || []).select { |tag| tag =~ /\A(#{Tag::HASHTAG_NAME_RE})\z/i }
@@ -47,7 +50,7 @@ class PostStatusService < BaseService
     else
       process_status!
       postprocess_status!
-      bump_potential_friendship!
+      bump_potential_friendship! if @options[:publish]
     end
 
     redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
@@ -86,7 +89,7 @@ class PostStatusService < BaseService
     end
 
     process_hashtags_service.call(@status, nil, @tag_names)
-    process_mentions_service.call(@status, mentions: @mentions)
+    process_mentions_service.call(@status, mentions: @mentions, deliver: @options[:publish])
   end
 
   def schedule_status!
@@ -109,6 +112,9 @@ class PostStatusService < BaseService
   def postprocess_status!
     LinkCrawlWorker.perform_async(@status.id) unless @status.spoiler_text?
     DistributionWorker.perform_async(@status.id)
+
+    return unless @options[:publish]
+
     ActivityPub::DistributionWorker.perform_async(@status.id) unless @status.local_only?
     PollExpirationNotifyWorker.perform_at(@status.poll.expires_at, @status.poll.id) if @status.poll
   end
@@ -188,6 +194,7 @@ class PostStatusService < BaseService
       visibility: @visibility,
       language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account),
       application: @options[:application],
+      published: @options[:publish],
       content_type: @options[:content_type] || @account.user&.setting_default_content_type,
       rate_limit: @options[:with_rate_limit],
     }.compact
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 2cc376a75..8b4b11617 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -9,13 +9,16 @@ class ProcessMentionsService < BaseService
   # @param [Status] status
   # @option [Enumerable] :mentions Mentions to include
   # @option [Boolean] :reveal_implicit_mentions Append implicit mentions to text
-  def call(status, mentions: [], reveal_implicit_mentions: true)
+  # @option [Boolean] :deliver Deliver mention notifications
+  def call(status, mentions: [], reveal_implicit_mentions: true, deliver: true)
     return unless status.local?
 
     @status = status
     @status.text, mentions = ResolveMentionsService.new.call(@status, mentions: mentions, reveal_implicit_mentions: reveal_implicit_mentions)
     @status.save!
 
+    return unless deliver
+
     check_for_spam(status)
 
     mentions.each { |mention| create_notification(mention) }
diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb
index b393f13bb..440b99ce7 100644
--- a/app/services/update_status_service.rb
+++ b/app/services/update_status_service.rb
@@ -32,7 +32,8 @@ class UpdateStatusService < BaseService
     @tags                   = (tags.nil? ? @status.tags : (tags || [])).to_set
 
     @params[:text]        ||= ''
-    @params[:edited]      ||= 1 + @status.edited
+    @params[:published]     = true if @status.published?
+    (@params[:edited]     ||= 1 + @status.edited) if @params[:published].presence || @status.published?
 
     update_tags if @status.local?
     filter_tags
@@ -54,7 +55,7 @@ class UpdateStatusService < BaseService
     prune_attachments
     reset_status_caches
 
-    SpamCheck.perform(@status)
+    SpamCheck.perform(@status) if @status.published?
     distribute
 
     @status
@@ -132,6 +133,9 @@ class UpdateStatusService < BaseService
   def distribute
     LinkCrawlWorker.perform_in(rand(1..30).seconds, @status.id) unless @status.spoiler_text?
     DistributionWorker.perform_async(@status.id)
+
+    return unless @status.published?
+
     ActivityPub::DistributionWorker.perform_async(@status.id) if @status.local? && !@status.local_only?
 
     mentions = @status.active_mentions.includes(:account).where(id: @new_mention_ids, accounts: { domain: nil })