forked from fedi/mastodon
Spawn FeedInsertWorker to deliver status into personal feed
This commit is contained in:
parent
5f54981846
commit
6fd865c000
|
@ -11,11 +11,11 @@ class FeedManager
|
||||||
"feed:#{type}:#{id}"
|
"feed:#{type}:#{id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter?(timeline_type, status, receiver)
|
def filter?(timeline_type, status, receiver_id)
|
||||||
if timeline_type == :home
|
if timeline_type == :home
|
||||||
filter_from_home?(status, receiver)
|
filter_from_home?(status, receiver_id)
|
||||||
elsif timeline_type == :mentions
|
elsif timeline_type == :mentions
|
||||||
filter_from_mentions?(status, receiver)
|
filter_from_mentions?(status, receiver_id)
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -91,39 +91,39 @@ class FeedManager
|
||||||
Redis.current
|
Redis.current
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_from_home?(status, receiver)
|
def filter_from_home?(status, receiver_id)
|
||||||
return true if status.reply? && status.in_reply_to_id.nil?
|
return true if status.reply? && status.in_reply_to_id.nil?
|
||||||
|
|
||||||
check_for_mutes = [status.account_id]
|
check_for_mutes = [status.account_id]
|
||||||
check_for_mutes.concat([status.reblog.account_id]) if status.reblog?
|
check_for_mutes.concat([status.reblog.account_id]) if status.reblog?
|
||||||
|
|
||||||
return true if receiver.muting?(check_for_mutes)
|
return true if Mute.where(account_id: receiver_id, target_account_id: check_for_mutes).any?
|
||||||
|
|
||||||
check_for_blocks = status.mentions.map(&:account_id)
|
check_for_blocks = status.mentions.map(&:account_id)
|
||||||
check_for_blocks.concat([status.reblog.account_id]) if status.reblog?
|
check_for_blocks.concat([status.reblog.account_id]) if status.reblog?
|
||||||
|
|
||||||
return true if receiver.blocking?(check_for_blocks)
|
return true if Block.where(account_id: receiver_id, target_account_id: check_for_blocks).any?
|
||||||
|
|
||||||
if status.reply? && !status.in_reply_to_account_id.nil? # Filter out if it's a reply
|
if status.reply? && !status.in_reply_to_account_id.nil? # Filter out if it's a reply
|
||||||
should_filter = !receiver.following?(status.in_reply_to_account) # and I'm not following the person it's a reply to
|
should_filter = !Follow.where(account_id: receiver_id, target_account_id: status.in_reply_to_account_id).exists? # and I'm not following the person it's a reply to
|
||||||
should_filter &&= !(receiver.id == status.in_reply_to_account_id) # and it's not a reply to me
|
should_filter &&= !(receiver_id == status.in_reply_to_account_id) # and it's not a reply to me
|
||||||
should_filter &&= !(status.account_id == status.in_reply_to_account_id) # and it's not a self-reply
|
should_filter &&= !(status.account_id == status.in_reply_to_account_id) # and it's not a self-reply
|
||||||
return should_filter
|
return should_filter
|
||||||
elsif status.reblog? # Filter out a reblog
|
elsif status.reblog? # Filter out a reblog
|
||||||
return status.reblog.account.blocking?(receiver) # or if the author of the reblogged status is blocking me
|
return Block.where(account_id: status.reblog.account_id, target_account_id: receiver_id).exists? # or if the author of the reblogged status is blocking me
|
||||||
end
|
end
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_from_mentions?(status, receiver)
|
def filter_from_mentions?(status, receiver_id)
|
||||||
check_for_blocks = [status.account_id]
|
check_for_blocks = [status.account_id]
|
||||||
check_for_blocks.concat(status.mentions.select('account_id').map(&:account_id))
|
check_for_blocks.concat(status.mentions.select('account_id').map(&:account_id))
|
||||||
check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil?
|
check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil?
|
||||||
|
|
||||||
should_filter = receiver.id == status.account_id # Filter if I'm mentioning myself
|
should_filter = receiver_id == status.account_id # Filter if I'm mentioning myself
|
||||||
should_filter ||= receiver.blocking?(check_for_blocks) # or it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked
|
should_filter ||= Block.where(account_id: receiver_id, target_account_id: check_for_blocks).any? # or it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked
|
||||||
should_filter ||= (status.account.silenced? && !receiver.following?(status.account)) # of if the account is silenced and I'm not following them
|
should_filter ||= (status.account.silenced? && !Follow.where(account_id: receiver_id, target_account_id: status.account_id).exists?) # of if the account is silenced and I'm not following them
|
||||||
|
|
||||||
should_filter
|
should_filter
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,9 +33,8 @@ class FanOutOnWriteService < BaseService
|
||||||
def deliver_to_followers(status)
|
def deliver_to_followers(status)
|
||||||
Rails.logger.debug "Delivering status #{status.id} to followers"
|
Rails.logger.debug "Delivering status #{status.id} to followers"
|
||||||
|
|
||||||
status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).find_each do |follower|
|
status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).select(:id).find_each do |follower|
|
||||||
next if FeedManager.instance.filter?(:home, status, follower)
|
FeedInsertWorker.perform_async(status.id, follower.id)
|
||||||
FeedManager.instance.push(:home, follower, status)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ class FanOutOnWriteService < BaseService
|
||||||
|
|
||||||
status.mentions.includes(:account).each do |mention|
|
status.mentions.includes(:account).each do |mention|
|
||||||
mentioned_account = mention.account
|
mentioned_account = mention.account
|
||||||
next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mentioned_account)
|
next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mention.account_id)
|
||||||
FeedManager.instance.push(:home, mentioned_account, status)
|
FeedManager.instance.push(:home, mentioned_account, status)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -54,9 +53,9 @@ class FanOutOnWriteService < BaseService
|
||||||
|
|
||||||
payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status)
|
payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status)
|
||||||
|
|
||||||
status.tags.find_each do |tag|
|
status.tags.pluck(:name).each do |hashtag|
|
||||||
FeedManager.instance.broadcast("hashtag:#{tag.name}", event: 'update', payload: payload)
|
FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: payload)
|
||||||
FeedManager.instance.broadcast("hashtag:#{tag.name}:local", event: 'update', payload: payload) if status.account.local?
|
FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: payload) if status.account.local?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ class NotifyService < BaseService
|
||||||
private
|
private
|
||||||
|
|
||||||
def blocked_mention?
|
def blocked_mention?
|
||||||
FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient)
|
FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def blocked_favourite?
|
def blocked_favourite?
|
||||||
|
|
|
@ -7,7 +7,7 @@ class PrecomputeFeedService < BaseService
|
||||||
def call(_, account)
|
def call(_, account)
|
||||||
redis.pipelined do
|
redis.pipelined do
|
||||||
Status.as_home_timeline(account).limit(FeedManager::MAX_ITEMS / 4).each do |status|
|
Status.as_home_timeline(account).limit(FeedManager::MAX_ITEMS / 4).each do |status|
|
||||||
next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account)
|
next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account.id)
|
||||||
redis.zadd(FeedManager.instance.key(:home, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id)
|
redis.zadd(FeedManager.instance.key(:home, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
15
app/workers/feed_insert_worker.rb
Normal file
15
app/workers/feed_insert_worker.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class FeedInsertWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
|
||||||
|
def perform(status_id, follower_id)
|
||||||
|
status = Status.find(status_id)
|
||||||
|
follower = Account.find(follower_id)
|
||||||
|
|
||||||
|
return if FeedManager.instance.filter?(:home, status, follower.id)
|
||||||
|
FeedManager.instance.push(:home, follower, status)
|
||||||
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue