status_reach_finder.rb 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # frozen_string_literal: true
  2. class StatusReachFinder
  3. # @param [Status] status
  4. # @param [Hash] options
  5. # @option options [Boolean] :unsafe
  6. def initialize(status, options = {})
  7. @status = status
  8. @options = options
  9. end
  10. def inboxes
  11. (reached_account_inboxes + followers_inboxes + relay_inboxes).uniq
  12. end
  13. private
  14. def reached_account_inboxes
  15. # When the status is a reblog, there are no interactions with it
  16. # directly, we assume all interactions are with the original one
  17. if @status.reblog?
  18. []
  19. else
  20. Account.where(id: reached_account_ids).inboxes
  21. end
  22. end
  23. def reached_account_ids
  24. [
  25. replied_to_account_id,
  26. reblog_of_account_id,
  27. mentioned_account_ids,
  28. reblogs_account_ids,
  29. favourites_account_ids,
  30. replies_account_ids,
  31. ].tap do |arr|
  32. arr.flatten!
  33. arr.compact!
  34. arr.uniq!
  35. end
  36. end
  37. def replied_to_account_id
  38. @status.in_reply_to_account_id if distributable?
  39. end
  40. def reblog_of_account_id
  41. @status.reblog.account_id if @status.reblog?
  42. end
  43. def mentioned_account_ids
  44. @status.mentions.pluck(:account_id)
  45. end
  46. # Beware: Reblogs can be created without the author having had access to the status
  47. def reblogs_account_ids
  48. @status.reblogs.rewhere(deleted_at: [nil, @status.deleted_at]).pluck(:account_id) if distributable? || unsafe?
  49. end
  50. # Beware: Favourites can be created without the author having had access to the status
  51. def favourites_account_ids
  52. @status.favourites.pluck(:account_id) if distributable? || unsafe?
  53. end
  54. # Beware: Replies can be created without the author having had access to the status
  55. def replies_account_ids
  56. @status.replies.pluck(:account_id) if distributable? || unsafe?
  57. end
  58. def followers_inboxes
  59. if @status.in_reply_to_local_account? && distributable?
  60. @status.account.followers.or(@status.thread.account.followers.not_domain_blocked_by_account(@status.account)).inboxes
  61. elsif @status.direct_visibility? || @status.limited_visibility?
  62. []
  63. else
  64. @status.account.followers.inboxes
  65. end
  66. end
  67. def relay_inboxes
  68. if @status.public_visibility?
  69. Relay.enabled.pluck(:inbox_url)
  70. else
  71. []
  72. end
  73. end
  74. def distributable?
  75. @status.public_visibility? || @status.unlisted_visibility?
  76. end
  77. def unsafe?
  78. @options[:unsafe]
  79. end
  80. end