Fix #4491: Have tag rename option for bulk update requests.

* Add a `rename A -> B` command for bulk update requests.
* Change mass updates to only retag the posts, not to move saved
  searches or blacklists.

A tag rename does the same thing an alias does, except it doesn't
create a permanent alias. More precisely, a tag rename:

* Moves the wiki.
* Moves the artist entry.
* Moves saved searches.
* Moves blacklists.
* Merges the wikis, if both tags have wiki pages.
* Merges the artist entries, if both tags have artist pages.
* Fixes links in wiki pages to point to the new tag.
* Retags the posts.
This commit is contained in:
evazion
2020-08-26 19:25:14 -05:00
parent bbf2b53d83
commit 23944a1794
6 changed files with 61 additions and 92 deletions

View File

@@ -1,19 +1,12 @@
class TagBatchChangeJob < ApplicationJob
class Error < StandardError; end
queue_as :bulk_update
def perform(antecedent, consequent, updater, updater_ip_addr)
raise Error.new("antecedent is missing") if antecedent.blank?
def perform(antecedent, consequent)
normalized_antecedent = PostQueryBuilder.new(antecedent).split_query
normalized_consequent = PostQueryBuilder.new(consequent).parse_tag_edit
CurrentUser.scoped(updater, updater_ip_addr) do
CurrentUser.scoped(User.system) do
migrate_posts(normalized_antecedent, normalized_consequent)
migrate_saved_searches(normalized_antecedent, normalized_consequent)
migrate_blacklists(normalized_antecedent, normalized_consequent)
ModAction.log("processed mass update: #{antecedent} -> #{consequent}", :mass_update)
end
end
@@ -26,47 +19,4 @@ class TagBatchChangeJob < ApplicationJob
end
end
end
def migrate_saved_searches(normalized_antecedent, normalized_consequent)
tags = PostQueryBuilder.new(normalized_antecedent.join(" ")).split_query
# 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
# 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_like(:blacklisted_tags, "*#{x}*"))
end
arel.find_each do |user|
changed = false
begin
repl = user.blacklisted_tags.split(/\r\n|\r|\n/).map do |line|
list = PostQueryBuilder.new(line).split_query
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
DanbooruLogger.log(e)
end
end
end
end

View File

@@ -0,0 +1,7 @@
class TagRenameJob < ApplicationJob
queue_as :bulk_update
def perform(old_tag_name, new_tag_name)
TagMover.new(old_tag_name, new_tag_name, user: User.system).move!
end
end