diff options
Diffstat (limited to 'app/models/custom_filter.rb')
-rw-r--r-- | app/models/custom_filter.rb | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index 985eab125..da2a91493 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -34,6 +34,7 @@ class CustomFilter < ApplicationRecord belongs_to :account has_many :keywords, class_name: 'CustomFilterKeyword', foreign_key: :custom_filter_id, inverse_of: :custom_filter, dependent: :destroy + has_many :statuses, class_name: 'CustomFilterStatus', foreign_key: :custom_filter_id, inverse_of: :custom_filter, dependent: :destroy accepts_nested_attributes_for :keywords, reject_if: :all_blank, allow_destroy: true validates :title, :context, presence: true @@ -62,8 +63,10 @@ class CustomFilter < ApplicationRecord def self.cached_filters_for(account_id) active_filters = Rails.cache.fetch("filters:v3:#{account_id}") do + filters_hash = {} + scope = CustomFilterKeyword.includes(:custom_filter).where(custom_filter: { account_id: account_id }).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) - scope.to_a.group_by(&:custom_filter).map do |filter, keywords| + scope.to_a.group_by(&:custom_filter).each do |filter, keywords| keywords.map! do |keyword| if keyword.whole_word sb = /\A[[:word:]]/.match?(keyword.keyword) ? '\b' : '' @@ -74,13 +77,34 @@ class CustomFilter < ApplicationRecord /#{Regexp.escape(keyword.keyword)}/i end end - [filter, { keywords: Regexp.union(keywords) }] + + filters_hash[filter.id] = { keywords: Regexp.union(keywords), filter: filter } + end.to_h + + scope = CustomFilterStatus.includes(:custom_filter).where(custom_filter: { account_id: account_id }).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) + scope.to_a.group_by(&:custom_filter).each do |filter, statuses| + filters_hash[filter.id] ||= { filter: filter } + filters_hash[filter.id].merge!(status_ids: statuses.map(&:status_id)) end + + filters_hash.values.map { |cache| [cache.delete(:filter), cache] } end.to_a active_filters.select { |custom_filter, _| !custom_filter.expired? } end + def self.apply_cached_filters(cached_filters, status) + cached_filters.filter_map do |filter, rules| + match = rules[:keywords].match(status.proper.searchable_text) if rules[:keywords].present? + keyword_matches = [match.to_s] unless match.nil? + + status_matches = [status.id, status.reblog_of_id].compact & rules[:status_ids] if rules[:status_ids].present? + + next if keyword_matches.blank? && status_matches.blank? + FilterResultPresenter.new(filter: filter, keyword_matches: keyword_matches, status_matches: status_matches) + end + end + def prepare_cache_invalidation! @should_invalidate_cache = true end |