Add option to not consider word boundaries when processing keyword filtering (#7975)

* Add option to not consider word boundaries when filtering phrases

* Add a few tests for keyword/phrase filtering
This commit is contained in:
ThibG
2018-07-09 02:22:09 +02:00
committed by Eugen Rochko
parent 451e585b97
commit 1ca4e51eb3
9 changed files with 61 additions and 11 deletions

View File

@ -43,6 +43,6 @@ class Api::V1::FiltersController < Api::BaseController
end
def resource_params
params.permit(:phrase, :expires_in, :irreversible, context: [])
params.permit(:phrase, :expires_in, :irreversible, :whole_word, context: [])
end
end

View File

@ -45,7 +45,10 @@ export const regexFromFilters = filters => {
return null;
}
return new RegExp(filters.map(filter => escapeRegExp(filter.get('phrase'))).map(expr => `\\b${expr}\\b`).join('|'), 'i');
return new RegExp(filters.map(filter => {
let expr = escapeRegExp(filter.get('phrase'));
return filter.get('whole_word') ? `\\b${expr}\\b` : expr;
}).join('|'), 'i');
};
export const makeGetStatus = () => {

View File

@ -200,7 +200,16 @@ class FeedManager
active_filters = Rails.cache.fetch("filters:#{receiver_id}") { CustomFilter.where(account_id: receiver_id).active_irreversible.to_a }.to_a
active_filters.select! { |filter| filter.context.include?(context.to_s) && !filter.expired? }
active_filters.map! { |filter| Regexp.new("\\b#{Regexp.escape(filter.phrase)}\\b", true) }
active_filters.map! do |filter|
if filter.whole_word
sb = filter.phrase =~ /\A[[:word:]]/ ? '\b' : ''
eb = filter.phrase =~ /[[:word:]]\Z/ ? '\b' : ''
/(?mix:#{sb}#{Regexp.escape(filter.phrase)}#{eb})/
else
/#{Regexp.escape(filter.phrase)}/i
end
end
return false if active_filters.empty?

View File

@ -8,6 +8,7 @@
# expires_at :datetime
# phrase :text default(""), not null
# context :string default([]), not null, is an Array
# whole_word :boolean default(TRUE), not null
# irreversible :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
class REST::FilterSerializer < ActiveModel::Serializer
attributes :id, :phrase, :context, :expires_at,
attributes :id, :phrase, :context, :whole_word, :expires_at,
:irreversible
end

View File

@ -7,5 +7,8 @@
.fields-group
= f.input :irreversible, wrapper: :with_label
.fields-group
= f.input :whole_word, wrapper: :with_label
.fields-group
= f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: lambda { |i| I18n.t("invites.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt')