diff options
author | David Yip <yipdw@member.fsf.org> | 2017-10-14 20:36:53 -0500 |
---|---|---|
committer | David Yip <yipdw@member.fsf.org> | 2017-10-21 14:54:36 -0500 |
commit | 603cf02b703a2df2ae6690077a3e21a5ce64b548 (patch) | |
tree | e20a1b4f6e6742660cc556a93174b19e2fc56585 /app | |
parent | 4745d6eeca3a422f41775ee5f31989fc036da7d6 (diff) |
Rework KeywordMute interface to use a matcher object; spec out matcher. #164.
A matcher object that builds a match from KeywordMute data and runs it over text is, in my view, one of the easier ways to write examples for this sort of thing.
Diffstat (limited to 'app')
-rw-r--r-- | app/lib/feed_manager.rb | 2 | ||||
-rw-r--r-- | app/models/keyword_mute.rb | 31 |
2 files changed, 31 insertions, 2 deletions
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index baaa09e86..516bd81af 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -138,7 +138,7 @@ class FeedManager end def filter_from_home?(status, receiver_id) - return true if KeywordMute.where(account_id: receiver_id).matches?(status.text) + return true if KeywordMute.matcher_for(receiver_id) =~ status.text return false if receiver_id == status.account_id return true if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?) diff --git a/app/models/keyword_mute.rb b/app/models/keyword_mute.rb index d397a1f41..d80fcaa60 100644 --- a/app/models/keyword_mute.rb +++ b/app/models/keyword_mute.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # == Schema Information # # Table name: keyword_mutes @@ -10,6 +11,34 @@ # class KeywordMute < ApplicationRecord - def self.matches?(text) + belongs_to :account, required: true + + validates_presence_of :keyword + + def self.matcher_for(account) + Rails.cache.fetch("keyword_mutes:matcher:#{account}") { Matcher.new(account) } + end + + class Matcher + attr_reader :regex + + def initialize(account) + re = String.new.tap do |str| + scoped = KeywordMute.where(account: account) + keywords = scoped.select(:id, :keyword) + count = scoped.count + + keywords.find_each.with_index do |kw, index| + str << Regexp.escape(kw.keyword.strip) + str << '|' if index < count - 1 + end + end + + @regex = /\b(?:#{re})\b/i unless re.empty? + end + + def =~(str) + @regex ? @regex =~ str : false + end end end |