From 9e1e73ec4c2a3427a0cf1894336369e97fc984a9 Mon Sep 17 00:00:00 2001 From: Albert Yi Date: Wed, 19 Sep 2018 15:50:19 -0700 Subject: [PATCH] migrate blacklists during mass updates (#2251) --- app/logical/moderator/tag_batch_change.rb | 73 +++++++++++++++----- app/models/user.rb | 4 -- test/unit/moderator/tag_batch_change_test.rb | 8 +++ 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/app/logical/moderator/tag_batch_change.rb b/app/logical/moderator/tag_batch_change.rb index f794a4c12..3afd088cb 100644 --- a/app/logical/moderator/tag_batch_change.rb +++ b/app/logical/moderator/tag_batch_change.rb @@ -7,31 +7,70 @@ module Moderator normalized_antecedent = TagAlias.to_aliased(::Tag.scan_tags(antecedent.mb_chars.downcase)) normalized_consequent = TagAlias.to_aliased(::Tag.scan_tags(consequent.mb_chars.downcase)) - updater = User.find(updater_id) CurrentUser.without_safe_mode do CurrentUser.scoped(updater, updater_ip_addr) do - ::Post.tag_match(antecedent).where("true /* Moderator::TagBatchChange#perform */").find_each do |post| - post.reload - tags = (post.tag_array - normalized_antecedent + normalized_consequent).join(" ") - post.update_attributes(:tag_string => tags) - end - - if SavedSearch.enabled? - tags = Tag.scan_tags(antecedent, :strip_metatags => true) - - # https://www.postgresql.org/docs/current/static/functions-array.html - saved_searches = SavedSearch.where("string_to_array(query, ' ') @> ARRAY[?]", tags) - saved_searches.find_each do |ss| - ss.query = (ss.query.split - tags + [consequent]).uniq.join(" ") - ss.save - end - end + migrate_posts(normalized_antecedent, normalized_consequent) + migrate_saved_searches(normalized_antecedent, normalized_consequent) + migrate_blacklists(normalized_antecedent, normalized_consequent) end end ModAction.log("processed mass update: #{antecedent} -> #{consequent}",:mass_update) end + + def migrate_posts(normalized_antecedent, normalized_consequent) + ::Post.tag_match(normalized_antecedent.join(" ")).find_each do |post| + post.reload + tags = (post.tag_array - normalized_antecedent + normalized_consequent).join(" ") + post.update(tag_string: tags) + end + end + + def migrate_saved_searches(normalized_antecedent, normalized_consequent) + if SavedSearch.enabled? + tags = Tag.scan_tags(normalized_antecedent.join(" "), strip_metatags: true) + + # https://www.postgresql.org/docs/current/static/functions-array.html + saved_searches = SavedSearch.where("string_to_array(query, ' ') @> ARRAY[?]", tags) + saved_searches.find_each do |ss| + ss.query = (ss.query.split - tags + normalized_consequent).uniq.join(" ") + ss.save + end + end + end + + # this can't handle negated tags or other special cases + def migrate_blacklists(normalized_antecedent, normalized_consequent) + query = normalized_antecedent + adds = normalized_consequent + arel = query.inject(User.none) do |scope, x| + scope.or(User.where("blacklisted_tags like ?", "%" + x.to_escaped_for_sql_like + "%")) + end + + arel.find_each do |user| + changed = false + + begin + repl = user.blacklisted_tags.split(/\r\n|\r|\n/).map do |line| + list = Tag.scan_tags(line) + + if (list & query).size != query.size + next line + end + + changed = true + (list - query + adds).join(" ") + end + + if changed + user.update(blacklisted_tags: repl.join("\n")) + end + rescue Exception => e + NewRelic::Agent.notice_error(e) + end + end + end end end diff --git a/app/models/user.rb b/app/models/user.rb index b24d74ac3..80adcdcf0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -447,10 +447,6 @@ class User < ApplicationRecord end module BlacklistMethods - def blacklisted_tag_array - Tag.scan_query(blacklisted_tags) - end - def normalize_blacklisted_tags self.blacklisted_tags = blacklisted_tags.downcase if blacklisted_tags.present? end diff --git a/test/unit/moderator/tag_batch_change_test.rb b/test/unit/moderator/tag_batch_change_test.rb index 35965f2ac..57b6bdd0b 100644 --- a/test/unit/moderator/tag_batch_change_test.rb +++ b/test/unit/moderator/tag_batch_change_test.rb @@ -35,6 +35,14 @@ module Moderator assert_equal("123 456 bbb", ss.reload.normalized_query) end + should "move blacklists" do + @user.update(blacklisted_tags: "123 456\n789\n") + tag_batch_change = TagBatchChange.new("456", "xxx", @user.id, "127.0.0.1") + tag_batch_change.perform + @user.reload + assert_equal("123 xxx\n789", @user.blacklisted_tags) + end + should "move only saved searches that match the mass update exactly" do ss = FactoryBot.create(:saved_search, :user => @user, :query => "123 ... 456") tag_batch_change = TagBatchChange.new("1", "bbb", @user.id, "127.0.0.1")