diff options
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/backup_service.rb | 24 | ||||
-rw-r--r-- | app/services/batched_remove_status_service.rb | 11 | ||||
-rw-r--r-- | app/services/fan_out_on_write_service.rb | 19 | ||||
-rw-r--r-- | app/services/post_status_service.rb | 14 | ||||
-rw-r--r-- | app/services/precompute_feed_service.rb | 1 | ||||
-rw-r--r-- | app/services/process_mentions_service.rb | 2 | ||||
-rw-r--r-- | app/services/reblog_service.rb | 2 | ||||
-rw-r--r-- | app/services/remove_status_service.rb | 8 |
8 files changed, 73 insertions, 8 deletions
diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb index 12e4fa8b4..cc9fb1f4e 100644 --- a/app/services/backup_service.rb +++ b/app/services/backup_service.rb @@ -45,6 +45,7 @@ class BackupService < BaseService dump_media_attachments!(tar) dump_outbox!(tar) dump_likes!(tar) + dump_bookmarks!(tar) dump_actor!(tar) end end @@ -85,6 +86,7 @@ class BackupService < BaseService actor[:image][:url] = 'header' + File.extname(actor[:image][:url]) if actor[:image] actor[:outbox] = 'outbox.json' actor[:likes] = 'likes.json' + actor[:bookmarks] = 'bookmarks.json' download_to_tar(tar, account.avatar, 'avatar' + File.extname(account.avatar.path)) if account.avatar.exists? download_to_tar(tar, account.header, 'header' + File.extname(account.header.path)) if account.header.exists? @@ -115,6 +117,25 @@ class BackupService < BaseService end end + def dump_bookmarks!(tar) + collection = serialize(ActivityPub::CollectionPresenter.new(id: 'bookmarks.json', type: :ordered, size: 0, items: []), ActivityPub::CollectionSerializer) + + Status.reorder(nil).joins(:bookmarks).includes(:account).merge(account.bookmarks).find_in_batches do |statuses| + statuses.each do |status| + collection[:totalItems] += 1 + collection[:orderedItems] << ActivityPub::TagManager.instance.uri_for(status) + end + + GC.start + end + + json = Oj.dump(collection) + + tar.add_file_simple('bookmarks.json', 0o444, json.bytesize) do |io| + io.write(json) + end + end + def collection_presenter ActivityPub::CollectionPresenter.new( id: 'outbox.json', @@ -128,7 +149,8 @@ class BackupService < BaseService ActiveModelSerializers::SerializableResource.new( object, serializer: serializer, - adapter: ActivityPub::Adapter + adapter: ActivityPub::Adapter, + allow_local_only: true, ).as_json end diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index 3638134be..31237337a 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -40,6 +40,7 @@ class BatchedRemoveStatusService < BaseService # Cannot be batched statuses.each do |status| unpush_from_public_timelines(status) + unpush_from_direct_timelines(status) if status.direct_visibility? end end @@ -85,4 +86,14 @@ class BatchedRemoveStatusService < BaseService end end end + + def unpush_from_direct_timelines(status) + payload = @json_payloads[status.id] + redis.pipelined do + @mentions[status.id].each do |mention| + FeedManager.instance.unpush_from_direct(mention.account, status) if mention.account.local? + end + FeedManager.instance.unpush_from_direct(status.account, status) if status.account.local? + end + end end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 95336ef45..72f716dc5 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -6,23 +6,27 @@ class FanOutOnWriteService < BaseService def call(status) raise Mastodon::RaceConditionError if status.visibility.nil? + deliver_to_self(status) if status.account.local? + render_anonymous_payload(status) if status.direct_visibility? + deliver_to_mentioned_followers(status) + deliver_to_direct_timelines(status) deliver_to_own_conversation(status) elsif status.limited_visibility? deliver_to_mentioned_followers(status) else - deliver_to_self(status) if status.account.local? deliver_to_followers(status) deliver_to_lists(status) end - return if status.account.silenced? || !status.public_visibility? || status.reblog? + return if status.account.silenced? || !status.public_visibility? + return if status.reblog? && !Setting.show_reblogs_in_public_timelines deliver_to_hashtags(status) - return if status.reply? && status.in_reply_to_account_id != status.account_id + return if status.reply? && status.in_reply_to_account_id != status.account_id && !Setting.show_replies_in_public_timelines deliver_to_public(status) deliver_to_media(status) if status.media_attachments.any? @@ -33,6 +37,7 @@ class FanOutOnWriteService < BaseService def deliver_to_self(status) Rails.logger.debug "Delivering status #{status.id} to author" FeedManager.instance.push_to_home(status.account, status) + FeedManager.instance.push_to_direct(status.account, status) if status.direct_visibility? end def deliver_to_followers(status) @@ -91,6 +96,14 @@ class FanOutOnWriteService < BaseService Redis.current.publish('timeline:public:local:media', @payload) if status.local? end + def deliver_to_direct_timelines(status) + Rails.logger.debug "Delivering status #{status.id} to direct timelines" + + FeedInsertWorker.push_bulk(status.mentions.includes(:account).map(&:account).select { |mentioned_account| mentioned_account.local? }) do |account| + [status.id, account.id, :direct] + end + end + def deliver_to_own_conversation(status) AccountConversation.add_status(status.account, status) end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 34ec6d504..5d17f111b 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -47,7 +47,16 @@ class PostStatusService < BaseService private def preprocess_attributes! - @text = @options.delete(:spoiler_text) if @text.blank? && @options[:spoiler_text].present? + if @text.blank? && @options[:spoiler_text].present? + @text = '.' + if @media.find(&:video?) || @media.find(&:gifv?) + @text = '📹' + elsif @media.find(&:audio?) + @text = '🎵' + elsif @media.find(&:image?) + @text = '🖼' + end + end @visibility = @options[:visibility] || @account.user&.setting_default_privacy @visibility = :unlisted if @visibility == :public && @account.silenced? @scheduled_at = @options[:scheduled_at]&.to_datetime @@ -88,7 +97,7 @@ class PostStatusService < BaseService def postprocess_status! LinkCrawlWorker.perform_async(@status.id) unless @status.spoiler_text? DistributionWorker.perform_async(@status.id) - ActivityPub::DistributionWorker.perform_async(@status.id) + ActivityPub::DistributionWorker.perform_async(@status.id) unless @status.local_only? PollExpirationNotifyWorker.perform_at(@status.poll.expires_at, @status.poll.id) if @status.poll end @@ -160,6 +169,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], + content_type: @options[:content_type] || @account.user&.setting_default_content_type, }.compact end diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb index 076dedaca..029c2f6e5 100644 --- a/app/services/precompute_feed_service.rb +++ b/app/services/precompute_feed_service.rb @@ -3,6 +3,7 @@ class PrecomputeFeedService < BaseService def call(account) FeedManager.instance.populate_feed(account) + FeedManager.instance.populate_direct_feed(account) ensure Redis.current.del("account:#{account.id}:regeneration") end diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index 2f7a9e985..19de37717 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -49,7 +49,7 @@ class ProcessMentionsService < BaseService if mentioned_account.local? LocalNotificationWorker.perform_async(mentioned_account.id, mention.id, mention.class.name) - elsif mentioned_account.activitypub? + elsif mentioned_account.activitypub? && !@status.local_only? ActivityPub::DeliveryWorker.perform_async(activitypub_json, mention.status.account_id, mentioned_account.inbox_url) end end diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb index 3bb460fca..0b12f143c 100644 --- a/app/services/reblog_service.rb +++ b/app/services/reblog_service.rb @@ -23,7 +23,7 @@ class ReblogService < BaseService reblog = account.statuses.create!(reblog: reblogged_status, text: '', visibility: visibility) DistributionWorker.perform_async(reblog.id) - ActivityPub::DistributionWorker.perform_async(reblog.id) + ActivityPub::DistributionWorker.perform_async(reblog.id) unless reblogged_status.local_only? create_notification(reblog) bump_potential_friendship(account, reblog) diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index f9352ed3d..1ddce675c 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -29,6 +29,7 @@ class RemoveStatusService < BaseService remove_from_hashtags remove_from_public remove_from_media if status.media_attachments.any? + remove_from_direct if status.direct_visibility? remove_from_spam_check remove_media @@ -53,6 +54,7 @@ class RemoveStatusService < BaseService def remove_from_self FeedManager.instance.unpush_from_home(@account, @status) + FeedManager.instance.unpush_from_direct(@account, @status) if @status.direct_visibility? end def remove_from_followers @@ -150,6 +152,12 @@ class RemoveStatusService < BaseService redis.publish('timeline:public:local:media', @payload) if @status.local? end + def remove_from_direct + @mentions.each do |mention| + FeedManager.instance.unpush_from_direct(mention.account, @status) if mention.account.local? + end + end + def remove_media return if @options[:redraft] || (!@options[:immediate] && @status.reported?) |