Implement the ability for instances to define a list of disallowed hashtags (#7176)
The goal here isn't to prevent these hashtags from existing, but just to strongly curtail their usage; The hashtags may still exist in the database via federated status, or from being created prior to this feature.
This commit is contained in:
parent
495303d9b8
commit
60b871d56c
|
@ -59,6 +59,7 @@ class Status < ApplicationRecord
|
||||||
validates :uri, uniqueness: true, presence: true, unless: :local?
|
validates :uri, uniqueness: true, presence: true, unless: :local?
|
||||||
validates :text, presence: true, unless: -> { with_media? || reblog? }
|
validates :text, presence: true, unless: -> { with_media? || reblog? }
|
||||||
validates_with StatusLengthValidator
|
validates_with StatusLengthValidator
|
||||||
|
validates_with DisallowedHashtagsValidator
|
||||||
validates :reblog, uniqueness: { scope: :account }, if: :reblog?
|
validates :reblog, uniqueness: { scope: :account }, if: :reblog?
|
||||||
|
|
||||||
default_scope { recent }
|
default_scope { recent }
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class DisallowedHashtagsValidator < ActiveModel::Validator
|
||||||
|
def validate(status)
|
||||||
|
return unless status.local? && !status.reblog?
|
||||||
|
|
||||||
|
tags = Extractor.extract_hashtags(status.text)
|
||||||
|
tags.keep_if { |tag| disallowed_hashtags.include? tag.downcase }
|
||||||
|
|
||||||
|
status.errors.add(:text, I18n.t('statuses.disallowed_hashtags', tags: tags.join(', '), count: tags.size)) unless tags.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def disallowed_hashtags
|
||||||
|
return @disallowed_hashtags if @disallowed_hashtags
|
||||||
|
|
||||||
|
@disallowed_hashtags = Setting.disallowed_hashtags.nil? ? [] : Setting.disallowed_hashtags
|
||||||
|
@disallowed_hashtags = @disallowed_hashtags.split(' ') if @disallowed_hashtags.is_a? String
|
||||||
|
@disallowed_hashtags = @disallowed_hashtags.map(&:downcase)
|
||||||
|
end
|
||||||
|
end
|
|
@ -684,6 +684,9 @@ en:
|
||||||
one: "%{count} video"
|
one: "%{count} video"
|
||||||
other: "%{count} videos"
|
other: "%{count} videos"
|
||||||
content_warning: 'Content warning: %{warning}'
|
content_warning: 'Content warning: %{warning}'
|
||||||
|
disallowed_hashtags:
|
||||||
|
one: 'contained a disallowed hashtag: %{tags}'
|
||||||
|
other: 'contained the disallowed hashtags: %{tags}'
|
||||||
open_in_web: Open in web
|
open_in_web: Open in web
|
||||||
over_character_limit: character limit of %{max} exceeded
|
over_character_limit: character limit of %{max} exceeded
|
||||||
pin_errors:
|
pin_errors:
|
||||||
|
|
|
@ -47,6 +47,7 @@ defaults: &defaults
|
||||||
- root
|
- root
|
||||||
- webmaster
|
- webmaster
|
||||||
- administrator
|
- administrator
|
||||||
|
disallowed_hashtags: # space separated string or list of hashtags without the hash
|
||||||
bootstrap_timeline_accounts: ''
|
bootstrap_timeline_accounts: ''
|
||||||
activity_api_enabled: true
|
activity_api_enabled: true
|
||||||
peers_api_enabled: true
|
peers_api_enabled: true
|
||||||
|
|
Loading…
Reference in New Issue