From bc81d32c2caa5a53b3326421bd8ffdb2fd4a3491 Mon Sep 17 00:00:00 2001 From: multiple creatures Date: Tue, 3 Dec 2019 17:04:32 -0600 Subject: when someone adds/changes a filter retroactively apply it to their home & list timelines --- app/models/custom_filter.rb | 15 +++++++++++++ app/workers/filter_feeds_worker.rb | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 app/workers/filter_feeds_worker.rb (limited to 'app') diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index a90b99c48..67d1a0bea 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -18,4 +18,19 @@ class CustomFilter < ApplicationRecord belongs_to :account validates :phrase, presence: true + + after_save :update_feeds + after_save :remove_cache + + private + + def update_feeds + FilterFeedsWorker.perform_async(account_id) + end + + private + + def remove_cache + redis.del("filtered_statuses:#{account_id}") + end end diff --git a/app/workers/filter_feeds_worker.rb b/app/workers/filter_feeds_worker.rb new file mode 100644 index 000000000..ced9e707b --- /dev/null +++ b/app/workers/filter_feeds_worker.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +class FilterFeedsWorker + include Sidekiq::Worker + include FilterHelper + + def perform(account_id) + @account = Account.find(account_id) + + statuses = HomeFeed.new(@account).all + filtered_statuses(statuses).each do |status| + FeedManager.instance.unpush_from_home(@account, status) + end + + @account.lists.find_each do |list| + statuses = ListFeed.new(list).all + filtered_statuses(statuses).each do |status| + FeedManager.instance.unpush_from_list(list, status) + end + end + rescue ActiveRecord::RecordNotFound + true + end + + private + + def filtered_statuses(statuses) + account_ids = statuses.map(&:account_id).uniq + domains = statuses.map(&:account_domain).compact.uniq + relations = relations_map_for_account(@account, account_ids, domains) + + statuses.select { |status| StatusFilter.new(status, @account, relations).filtered? } + end + + def relations_map_for_account(account, account_ids, domains) + return {} if account.nil? + + { + blocking: Account.blocking_map(account_ids, account.id), + blocked_by: Account.blocked_by_map(account_ids, account.id), + muting: Account.muting_map(account_ids, account.id), + following: Account.following_map(account_ids, account.id), + domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, account.id), + } + end +end -- cgit