diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2018-06-29 15:34:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-29 15:34:36 +0200 |
commit | cdb101340a20183a82889f811d9311c370c855e5 (patch) | |
tree | daacd56d1edbf359b0d97a926e90b999ba7f6129 /app/models/custom_filter.rb | |
parent | fbee9b5ac898e571e384792a92b40fa1524cf127 (diff) |
Keyword/phrase filtering (#7905)
* Add keyword filtering GET|POST /api/v1/filters GET|PUT|DELETE /api/v1/filters/:id - Irreversible filters can drop toots from home or notifications - Other filters can hide toots through the client app - Filters use a phrase valid in particular contexts, expiration * Make sure expired filters don't get applied client-side * Add missing API methods * Remove "regex filter" from column settings * Add tests * Add test for FeedManager * Add CustomFilter test * Add UI for managing filters * Add streaming API event to allow syncing filters * Fix tests
Diffstat (limited to 'app/models/custom_filter.rb')
-rw-r--r-- | app/models/custom_filter.rb | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb new file mode 100644 index 000000000..2c1a54375 --- /dev/null +++ b/app/models/custom_filter.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true +# == Schema Information +# +# Table name: custom_filters +# +# id :bigint(8) not null, primary key +# account_id :bigint(8) +# expires_at :datetime +# phrase :text default(""), not null +# context :string default([]), not null, is an Array +# irreversible :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class CustomFilter < ApplicationRecord + VALID_CONTEXTS = %w( + home + notifications + public + thread + ).freeze + + include Expireable + + belongs_to :account + + validates :phrase, :context, presence: true + validate :context_must_be_valid + validate :irreversible_must_be_within_context + + scope :active_irreversible, -> { where(irreversible: true).where(Arel.sql('expires_at IS NULL OR expires_at > NOW()')) } + + before_validation :clean_up_contexts + after_commit :remove_cache + + private + + def clean_up_contexts + self.context = Array(context).map(&:strip).map(&:presence).compact + end + + def remove_cache + Rails.cache.delete("filters:#{account_id}") + Redis.current.publish("timeline:#{account_id}", Oj.dump(event: :filters_changed)) + end + + def context_must_be_valid + errors.add(:context, I18n.t('filters.errors.invalid_context')) if context.empty? || context.any? { |c| !VALID_CONTEXTS.include?(c) } + end + + def irreversible_must_be_within_context + errors.add(:irreversible, I18n.t('filters.errors.invalid_irreversible')) if irreversible? && !context.include?('home') && !context.include?('notifications') + end +end |