1 # frozen_string_literal: true
3 class RemoveStatusService
< BaseService
4 include StreamEntryRenderer
6 def call(status
, **options
)
7 @payload = Oj
.dump(event
: :delete, payload
: status
.id
.to_s
)
9 @account = status
.account
10 @tags = status
.tags
.pluck(:name).to_a
11 @mentions = status
.active_mentions
.includes(:account).to_a
12 @reblogs = status
.reblogs
.to_a
13 @stream_entry = status
.stream_entry
16 remove_from_self
if status
.account
.local
?
23 remove_from_media
if status
.media_attachments
.any
?
24 remove_from_direct
if status
.direct_visibility
?
28 # There is no reason to send out Undo activities when the
29 # cause is that the original object has been removed, since
30 # original object being removed implicitly removes reblogs
31 # of it. The Delete activity of the original is forwarded
33 return if !
@account.local
? || @options[:original_removed]
35 remove_from_remote_followers
36 remove_from_remote_affected
42 FeedManager
.instance
.unpush_from_home(@account, @status)
45 def remove_from_followers
46 @account.followers_for_local_distribution
.reorder(nil).find_each
do |follower
|
47 FeedManager
.instance
.unpush_from_home(follower
, @status)
52 @account.lists_for_local_distribution
.select(:id, :account_id).reorder(nil).find_each
do |list
|
53 FeedManager
.instance
.unpush_from_list(list
, @status)
57 def remove_from_affected
58 @mentions.map(&:account).select(&:local?).each
do |account
|
59 Redis
.current
.publish("timeline:#{account.id}", @payload)
63 def remove_from_remote_affected
64 # People who got mentioned in the status, or who
65 # reblogged it from someone else might not follow
66 # the author and wouldn't normally receive the
67 # delete notification - so here, we explicitly
70 target_accounts
= (@mentions.map(&:account).reject(&:local?) +
@reblogs.map(&:account).reject(&:local?))
71 target_accounts
<< @status.reblog
.account
if @status.reblog
? && !
@status.reblog
.account
.local
?
72 target_accounts
.uniq!
(&:id)
75 NotificationWorker
.push_bulk(target_accounts
.select(&:ostatus?).uniq(&:domain)) do |target_account
|
76 [salmon_xml
, @account.id
, target_account
.id
]
80 ActivityPub
::DeliveryWorker.push_bulk(target_accounts
.select(&:activitypub?).uniq(&:inbox_url)) do |target_account
|
81 [signed_activity_json
, @account.id
, target_account
.inbox_url
]
85 def remove_from_remote_followers
87 Pubsubhubbub
::RawDistributionWorker.perform_async(salmon_xml
, @account.id
)
90 ActivityPub
::DeliveryWorker.push_bulk(@account.followers
.inboxes
) do |inbox_url
|
91 [signed_activity_json
, @account.id
, inbox_url
]
98 @status.public_visibility
?
102 ActivityPub
::DeliveryWorker.push_bulk(Relay
.enabled
.pluck(:inbox_url)) do |inbox_url
|
103 [signed_activity_json
, @account.id
, inbox_url
]
108 @salmon_xml ||= stream_entry_to_xml(@stream_entry)
111 def signed_activity_json
112 @signed_activity_json ||= Oj
.dump(ActivityPub
::LinkedDataSignature.new(activity_json
).sign!
(@account))
116 @activity_json ||= ActiveModelSerializers
::SerializableResource.new(
118 serializer
: @status.reblog
? ? ActivityPub
::UndoAnnounceSerializer : ActivityPub
::DeleteSerializer,
119 adapter
: ActivityPub
::Adapter
124 # We delete reblogs of the status before the original status,
125 # because once original status is gone, reblogs will disappear
126 # without us being able to do all the fancy stuff
128 @reblogs.each
do |reblog
|
129 RemoveStatusService
.new
.call(reblog
, original_removed
: true)
133 def remove_from_hashtags
134 return unless @status.public_visibility
?
136 @tags.each
do |hashtag
|
137 Redis
.current
.publish("timeline:hashtag:#{hashtag}", @payload)
138 Redis
.current
.publish("timeline:hashtag:#{hashtag}:local", @payload) if @status.local
?
142 def remove_from_public
143 return unless @status.public_visibility
?
145 Redis
.current
.publish('timeline:public', @payload)
146 Redis
.current
.publish('timeline:public:local', @payload) if @status.local
?
149 def remove_from_media
150 return unless @status.public_visibility
?
152 Redis
.current
.publish('timeline:public:media', @payload)
153 Redis
.current
.publish('timeline:public:local:media', @payload) if @status.local
?
156 def remove_from_direct
157 @mentions.each
do |mention
|
158 Redis
.current
.publish("timeline:direct:#{mention.account.id}", @payload) if mention
.account
.local
?
160 Redis
.current
.publish("timeline:direct:#{@account.id}", @payload) if @account.local
?