diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/post_status_service.rb | 18 | ||||
-rw-r--r-- | app/services/reblog_service.rb | 7 | ||||
-rw-r--r-- | app/services/remove_status_service.rb | 32 | ||||
-rw-r--r-- | app/services/report_service.rb | 3 | ||||
-rw-r--r-- | app/services/suspend_account_service.rb | 2 |
5 files changed, 37 insertions, 25 deletions
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index b9952369d..820c553c9 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -29,7 +29,6 @@ class PostStatusService < BaseService return idempotency_duplicate if idempotency_given? && idempotency_duplicate? validate_media! - validate_poll! preprocess_attributes! if scheduled? @@ -74,6 +73,7 @@ class PostStatusService < BaseService def schedule_status! status_for_validation = @account.statuses.build(status_attributes) + if status_for_validation.valid? status_for_validation.destroy @@ -110,12 +110,6 @@ class PostStatusService < BaseService raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:video?) end - def validate_poll! - return if @options[:poll].blank? - - @poll = @account.polls.new(@options[:poll]) - end - def language_from_option(str) ISO_639.find(str)&.alpha2 end @@ -168,13 +162,13 @@ class PostStatusService < BaseService text: @text, media_attachments: @media || [], thread: @in_reply_to, - owned_poll: @poll, + owned_poll_attributes: poll_attributes, sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?, spoiler_text: @options[:spoiler_text] || '', visibility: @visibility, language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account), application: @options[:application], - } + }.compact end def scheduled_status_attributes @@ -185,6 +179,12 @@ class PostStatusService < BaseService } end + def poll_attributes + return if @options[:poll].blank? + + @options[:poll].merge(account: @account) + end + def scheduled_options @options.tap do |options_hash| options_hash[:in_reply_to_id] = options_hash.delete(:thread)&.id diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb index 03db27406..deaa0549e 100644 --- a/app/services/reblog_service.rb +++ b/app/services/reblog_service.rb @@ -7,8 +7,9 @@ class ReblogService < BaseService # Reblog a status and notify its remote author # @param [Account] account Account to reblog from # @param [Status] reblogged_status Status to be reblogged + # @param [Hash] options # @return [Status] - def call(account, reblogged_status) + def call(account, reblogged_status, options = {}) reblogged_status = reblogged_status.reblog if reblogged_status.reblog? authorize_with account, reblogged_status, :reblog? @@ -17,7 +18,7 @@ class ReblogService < BaseService return reblog unless reblog.nil? - reblog = account.statuses.create!(reblog: reblogged_status, text: '') + reblog = account.statuses.create!(reblog: reblogged_status, text: '', visibility: options[:visibility] || account.user&.setting_default_privacy) DistributionWorker.perform_async(reblog.id) @@ -38,7 +39,7 @@ class ReblogService < BaseService reblogged_status = reblog.reblog if reblogged_status.account.local? - NotifyService.new.call(reblogged_status.account, reblog) + LocalNotificationWorker.perform_async(reblogged_status.account_id, reblog.id, reblog.class.name) elsif reblogged_status.account.ostatus? NotificationWorker.perform_async(stream_entry_to_xml(reblog.stream_entry), reblog.account_id, reblogged_status.account_id) elsif reblogged_status.account.activitypub? && !reblogged_status.account.following?(reblog.account) diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index 7eec11ddf..6e4998e07 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -14,17 +14,23 @@ class RemoveStatusService < BaseService @stream_entry = status.stream_entry @options = options - remove_from_self if status.account.local? - remove_from_followers - remove_from_lists - remove_from_affected - remove_reblogs - remove_from_hashtags - remove_from_public - remove_from_media if status.media_attachments.any? - remove_from_direct if status.direct_visibility? - - @status.destroy! + RedisLock.acquire(lock_options) do |lock| + if lock.acquired? + remove_from_self if status.account.local? + remove_from_followers + remove_from_lists + remove_from_affected + remove_reblogs + remove_from_hashtags + remove_from_public + remove_from_media if status.media_attachments.any? + remove_from_direct if status.direct_visibility? + + @status.destroy! + else + raise Mastodon::RaceConditionError + end + end # There is no reason to send out Undo activities when the # cause is that the original object has been removed, since @@ -164,4 +170,8 @@ class RemoveStatusService < BaseService end Redis.current.publish("timeline:direct:#{@account.id}", @payload) if @account.local? end + + def lock_options + { redis: Redis.current, key: "distribute:#{@status.id}" } + end end diff --git a/app/services/report_service.rb b/app/services/report_service.rb index 1bcc1c0d5..73bd6694f 100644 --- a/app/services/report_service.rb +++ b/app/services/report_service.rb @@ -21,7 +21,8 @@ class ReportService < BaseService @report = @source_account.reports.create!( target_account: @target_account, status_ids: @status_ids, - comment: @comment + comment: @comment, + uri: @options[:uri] ) end diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb index 24fa1be69..6c2ecad30 100644 --- a/app/services/suspend_account_service.rb +++ b/app/services/suspend_account_service.rb @@ -68,7 +68,7 @@ class SuspendAccountService < BaseService end def purge_content! - distribute_delete_actor! if @account.local? + distribute_delete_actor! if @account.local? && !@options[:skip_distribution] @account.statuses.reorder(nil).find_in_batches do |statuses| BatchedRemoveStatusService.new.call(statuses, skip_side_effects: @options[:destroy]) |