discourse/app/controllers/admin/watched_words_controller.rb
Bianca Nenciu fd07c943ad
DEV: Refactor watched words (#24163)
- Ignore only invalid words, not all words if one of them is invalid

- The naming scheme for methods was inconsistent

- Optimize regular expressions
2023-11-01 16:41:10 +02:00

106 lines
3.2 KiB
Ruby

# frozen_string_literal: true
require "csv"
class Admin::WatchedWordsController < Admin::StaffController
skip_before_action :check_xhr, only: [:download]
def index
watched_words = WatchedWord.order(:action, :word)
watched_words =
watched_words.where.not(action: WatchedWord.actions[:tag]) if !SiteSetting.tagging_enabled
render_json_dump WatchedWordListSerializer.new(watched_words, scope: guardian, root: false)
end
def create
watched_word = WatchedWord.create_or_update_word(watched_words_params)
if watched_word.valid?
StaffActionLogger.new(current_user).log_watched_words_creation(watched_word)
render json: watched_word, root: false
else
render_json_error(watched_word)
end
end
def destroy
watched_word = WatchedWord.find_by(id: params[:id])
raise Discourse::InvalidParameters.new(:id) unless watched_word
watched_word.destroy!
StaffActionLogger.new(current_user).log_watched_words_deletion(watched_word)
render json: success_json
end
def upload
file = params[:file] || params[:files].first
action_key = params[:action_key].to_sym
has_replacement = WatchedWord.has_replacement?(action_key)
Scheduler::Defer.later("Upload watched words") do
begin
CSV.foreach(file.tempfile, encoding: "bom|utf-8") do |row|
if row[0].present? && (!has_replacement || row[1].present?)
watched_word =
WatchedWord.create_or_update_word(
word: row[0],
replacement: has_replacement ? row[1] : nil,
action_key: action_key,
case_sensitive: "true" == row[2]&.strip&.downcase,
)
if watched_word.valid?
StaffActionLogger.new(current_user).log_watched_words_creation(watched_word)
end
end
end
data = { url: "/ok" }
rescue => e
data = failed_json.merge(errors: [e.message])
end
MessageBus.publish("/uploads/txt", data.as_json, client_ids: [params[:client_id]])
end
render json: success_json
end
def download
params.require(:id)
name = watched_words_params[:id].to_sym
action = WatchedWord.actions[name]
raise Discourse::NotFound if !action
content = WatchedWord.where(action: action)
if WatchedWord.has_replacement?(name)
content = content.pluck(:word, :replacement).map(&:to_csv).join
else
content = content.pluck(:word).join("\n")
end
headers["Content-Length"] = content.bytesize.to_s
send_data content,
filename: "#{Discourse.current_hostname}-watched-words-#{name}.csv",
content_type: "text/csv"
end
def clear_all
params.require(:id)
name = watched_words_params[:id].to_sym
action = WatchedWord.actions[name]
raise Discourse::NotFound if !action
WatchedWord
.where(action: action)
.find_each do |watched_word|
watched_word.destroy!
StaffActionLogger.new(current_user).log_watched_words_deletion(watched_word)
end
WordWatcher.clear_cache!
render json: success_json
end
private
def watched_words_params
params.permit(:id, :word, :replacement, :action_key, :case_sensitive)
end
end