闭社主体 forked from https://github.com/tootsuite/mastodon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.4 KiB

  1. # frozen_string_literal: true
  2. class RemoveStatusService < BaseService
  3. include StreamEntryRenderer
  4. def call(status)
  5. @payload = Oj.dump(event: :delete, payload: status.id)
  6. @status = status
  7. @account = status.account
  8. @tags = status.tags.pluck(:name).to_a
  9. @mentions = status.mentions.includes(:account).to_a
  10. @reblogs = status.reblogs.to_a
  11. @stream_entry = status.stream_entry
  12. remove_from_self if status.account.local?
  13. remove_from_followers
  14. remove_reblogs
  15. remove_from_hashtags
  16. remove_from_public
  17. @status.destroy!
  18. return unless @account.local?
  19. remove_from_mentioned(@stream_entry.reload)
  20. Pubsubhubbub::DistributionWorker.perform_async(@stream_entry.id)
  21. end
  22. private
  23. def remove_from_self
  24. unpush(:home, @account, @status)
  25. end
  26. def remove_from_followers
  27. @account.followers.local.find_each do |follower|
  28. unpush(:home, follower, @status)
  29. end
  30. end
  31. def remove_from_mentioned(stream_entry)
  32. salmon_xml = stream_entry_to_xml(stream_entry)
  33. target_accounts = @mentions.map(&:account).reject(&:local?).uniq(&:domain)
  34. NotificationWorker.push_bulk(target_accounts) do |target_account|
  35. [salmon_xml, stream_entry.account_id, target_account.id]
  36. end
  37. end
  38. def remove_reblogs
  39. # We delete reblogs of the status before the original status,
  40. # because once original status is gone, reblogs will disappear
  41. # without us being able to do all the fancy stuff
  42. @reblogs.each do |reblog|
  43. RemoveStatusService.new.call(reblog)
  44. end
  45. end
  46. def unpush(type, receiver, status)
  47. if status.reblog? && !redis.zscore(FeedManager.instance.key(type, receiver.id), status.reblog_of_id).nil?
  48. redis.zadd(FeedManager.instance.key(type, receiver.id), status.reblog_of_id, status.reblog_of_id)
  49. else
  50. redis.zremrangebyscore(FeedManager.instance.key(type, receiver.id), status.id, status.id)
  51. end
  52. Redis.current.publish("timeline:#{receiver.id}", @payload)
  53. end
  54. def remove_from_hashtags
  55. @tags.each do |hashtag|
  56. Redis.current.publish("timeline:hashtag:#{hashtag}", @payload)
  57. Redis.current.publish("timeline:hashtag:#{hashtag}:local", @payload) if @status.local?
  58. end
  59. end
  60. def remove_from_public
  61. Redis.current.publish('timeline:public', @payload)
  62. Redis.current.publish('timeline:public:local', @payload) if @status.local?
  63. end
  64. def redis
  65. Redis.current
  66. end
  67. end