discourse/app/jobs/regular/process_post.rb
Gary Pendergast 9abeff460c
FEATURE: Display the Watched Words that caused a post to be flagged. (#31435)
When a post is flagged due to matching watched words, it can be difficult to know what you're looking for, particularly if you have a lot of watched words built up over a long period of time.

This change stores the list of matched words, and later displays them in the review queue, listing which Watched Words were responsible for the flag. Because watched words can change, this is recorded at the time the post is flagged. For posts that were flagged prior to this feature landing, it tries to guess the relevant words based on the current Watched Words set.
2025-03-04 17:22:12 +11:00

78 lines
2.6 KiB
Ruby

# frozen_string_literal: true
require "image_sizer"
module Jobs
class ProcessPost < ::Jobs::Base
def execute(args)
DistributedMutex.synchronize("process_post_#{args[:post_id]}", validity: 10.minutes) do
post = Post.find_by(id: args[:post_id])
# two levels of deletion
return if post.blank? || post.topic.blank?
orig_cooked = post.cooked
recooked = nil
if args[:cook].present?
cooking_options = args[:cooking_options] || {}
cooking_options[:topic_id] = post.topic_id
recooked = post.cook(post.raw, cooking_options.symbolize_keys)
post.update_columns(
cooked: recooked,
baked_at: Time.zone.now,
baked_version: Post::BAKED_VERSION,
)
end
cp = CookedPostProcessor.new(post, args)
cp.post_process(new_post: args[:new_post])
# If we changed the document, save it
cooked = cp.html
if cooked != (recooked || orig_cooked)
if orig_cooked.present? && cooked.blank?
# TODO stop/restart the worker if needed, let's gather a few here first
Rails.logger.warn(
"Cooked post processor in FATAL state, bypassing. You need to urgently restart sidekiq\norig: #{orig_cooked}\nrecooked: #{recooked}\ncooked: #{cooked}\npost id: #{post.id}",
)
else
post.update_column(:cooked, cp.html)
post.topic.update_excerpt(post.excerpt_for_topic) if post.is_first_post?
extract_links(post)
post.publish_change_to_clients! :revised
end
end
enqueue_pull_hotlinked_images(post) unless args[:skip_pull_hotlinked_images]
if !post.user&.staff? && !post.user&.staged?
s = post.raw
s << " #{post.topic.title}" if post.post_number == 1
word_watcher = WordWatcher.new(s)
if !args[:bypass_bump] && word_watcher.should_flag?
words = word_watcher.word_matches_for_action?(:flag, all_matches: true)
PostActionCreator.create(
Discourse.system_user,
post,
:inappropriate,
reason: :watched_word,
context: words.join(","),
)
end
end
end
end
# onebox may have added some links, so extract them now
def extract_links(post)
TopicLink.extract_from(post)
QuotedPost.extract_from(post)
end
def enqueue_pull_hotlinked_images(post)
Jobs.cancel_scheduled_job(:pull_hotlinked_images, post_id: post.id)
Jobs.enqueue(:pull_hotlinked_images, post_id: post.id)
end
end
end