discourse/app/controllers/admin/watched_words_controller.rb
Régis Hanol e7d0083dbe FIX: creating watched words...
... wasn't working because it wasn't storing the proper "action" value.

Issue was that we were using the "action" parameter which is being used by Rails to determine which controller action to call.

We need to use the "action_key" parameter instead.
2024-04-30 19:16:47 +02:00

124 lines
3.7 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
opts = watched_words_params
action = WatchedWord.actions[opts[:action_key].to_sym]
words = opts.delete(:words)
watched_word_group = WatchedWordGroup.new(action: action)
watched_word_group.create_or_update_members(words, opts)
if watched_word_group.valid?
StaffActionLogger.new(current_user).log_watched_words_creation(watched_word_group)
render_json_dump WatchedWordListSerializer.new(
watched_word_group.watched_words,
scope: guardian,
root: false,
)
else
render_json_error(watched_word_group)
end
end
def destroy
watched_word = WatchedWord.find_by(id: params[:id])
raise Discourse::InvalidParameters.new(:id) unless watched_word
watched_word_group = watched_word.watched_word_group
if watched_word_group&.watched_words&.count == 1
watched_word_group.destroy!
else
watched_word.destroy!
end
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
@watched_words_params ||=
params.permit(:id, :replacement, :action_key, :case_sensitive, words: [])
end
end