forked from e621ng/e621ng
Add tag alias undo support
This commit is contained in:
parent
28346368dc
commit
fa4a51d81b
8
app/jobs/tag_alias_undo_job.rb
Normal file
8
app/jobs/tag_alias_undo_job.rb
Normal file
@ -0,0 +1,8 @@
|
||||
class TagAliasJob < ApplicationJob
|
||||
queue_as :tags
|
||||
|
||||
def perform(*args)
|
||||
ta = TagAlias.find(args[0])
|
||||
ta.process_undo!(update_topic: args[1])
|
||||
end
|
||||
end
|
@ -1,9 +0,0 @@
|
||||
class TagAliasUpdatePostsJob < ApplicationJob
|
||||
queue_as :tags
|
||||
|
||||
def perform(*args)
|
||||
ta = TagAlias.find(args[0])
|
||||
|
||||
ta.update_posts
|
||||
end
|
||||
end
|
@ -1,4 +1,6 @@
|
||||
class TagAlias < TagRelationship
|
||||
has_many :tag_rel_undos, as: :tag_rel
|
||||
|
||||
after_save :create_mod_action
|
||||
validates :antecedent_name, uniqueness: true
|
||||
validate :absence_of_transitive_relation
|
||||
@ -9,9 +11,16 @@ class TagAlias < TagRelationship
|
||||
def approve!(update_topic: true, approver: CurrentUser.user)
|
||||
CurrentUser.scoped(approver) do
|
||||
update(status: "queued", approver_id: approver.id)
|
||||
create_undo_information
|
||||
TagAliasJob.perform_later(id, update_topic)
|
||||
end
|
||||
end
|
||||
|
||||
def undo!(approver: CurrentUser.user)
|
||||
CurrentUser.scoped(approver) do
|
||||
TagAliaseUndoJob.perform_later(id, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ForumMethods
|
||||
@ -54,7 +63,7 @@ class TagAlias < TagRelationship
|
||||
TagAlias.to_aliased_with_originals(names).values
|
||||
end
|
||||
|
||||
def self.to_aliased_query(query)
|
||||
def self.to_aliased_query(query, overrides: nil)
|
||||
# Remove tag types (newline syntax)
|
||||
query.gsub!(/(^| )(-)?(#{TagCategory.mapping.keys.sort_by { |x| -x.size }.join("|")}):([\S])/i, '\1\2\4')
|
||||
# Remove tag types (comma syntax)
|
||||
@ -66,11 +75,85 @@ class TagAlias < TagRelationship
|
||||
[negated ? x[1..-1] : x, negated]
|
||||
end
|
||||
aliased = to_aliased_with_originals(tags.map { |t| t[0] })
|
||||
aliased.merge!(overrides) if overrides
|
||||
tags.map { |t| "#{t[1] ? '-' : ''}#{aliased[t[0]]}" }.join(" ")
|
||||
end
|
||||
lines.uniq.join("\n")
|
||||
end
|
||||
|
||||
def process_undo!(update_topic: true)
|
||||
unless valid?
|
||||
raise errors.full_messages.join("; ")
|
||||
end
|
||||
|
||||
CurrentUser.scoped(approver) do
|
||||
update(status: "pending")
|
||||
update_posts_locked_tags_undo
|
||||
update_blacklists_undo
|
||||
update_posts_undo
|
||||
forum_updater.update(retirement_message, "UNDONE") if update_topic
|
||||
rename_wiki_and_artist_undo
|
||||
end
|
||||
tag_rel_undos.update_all(applied: true)
|
||||
end
|
||||
|
||||
def update_posts_locked_tags_undo
|
||||
Post.without_timeout do
|
||||
Post.where_ilike(:locked_tags, "*#{consequent_name}*").find_each(batch_size: 50) do |post|
|
||||
fixed_tags = TagAlias.to_aliased_query(post.locked_tags, overrides: {consequent_name => antecedent_name})
|
||||
CurrentUser.scoped(creator, creator_ip_addr) do
|
||||
post.update_column(:locked_tags, fixed_tags)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_blacklists_undo
|
||||
User.without_timeout do
|
||||
User.where_ilike(:blacklisted_tags, "*#{consequent_name}*").find_each(batch_size: 50) do |user|
|
||||
fixed_blacklist = TagAlias.to_aliased_query(user.blacklisted_tags, overrides: {consequent_name => antecedent_name})
|
||||
user.update_column(:blacklisted_tags, fixed_blacklist)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_posts_undo
|
||||
Post.without_timeout do
|
||||
tag_rel_undos.where(applied: false).each do |tu|
|
||||
Post.where(id: tu.undo_data).find_each do |post|
|
||||
post.do_not_version_changes = true
|
||||
post.tag_string_diff = "-#{consequent_name} #{antecedent_name}"
|
||||
post.save
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: Race condition with indexing jobs here.
|
||||
antecedent_tag.fix_post_count if antecedent_tag
|
||||
consequent_tag.fix_post_count if consequent_tag
|
||||
end
|
||||
end
|
||||
|
||||
def rename_wiki_and_artist_undo
|
||||
consequent_wiki = WikiPage.titled(consequent_name).first
|
||||
if consequent_wiki.present?
|
||||
if WikiPage.titled(antecedent_name).blank?
|
||||
CurrentUser.scoped(creator, creator_ip_addr) do
|
||||
consequent_wiki.update(title: antecedent_name, skip_secondary_validations: true)
|
||||
end
|
||||
else
|
||||
forum_updater.update(conflict_message)
|
||||
end
|
||||
end
|
||||
|
||||
if consequent_tag.category == Tag.categories.artist
|
||||
if consequent_tag.artist.present? && antecedent_tag.artist.blank?
|
||||
CurrentUser.scoped(creator, creator_ip_addr) do
|
||||
consequent_tag.artist.update!(name: antecedent_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process!(update_topic: true)
|
||||
unless valid?
|
||||
raise errors.full_messages.join("; ")
|
||||
@ -82,14 +165,13 @@ class TagAlias < TagRelationship
|
||||
CurrentUser.scoped(approver) do
|
||||
update(status: "processing")
|
||||
move_aliases_and_implications
|
||||
move_saved_searches
|
||||
ensure_category_consistency
|
||||
update_posts_locked_tags
|
||||
update_blacklists
|
||||
update_posts
|
||||
forum_updater.update(approval_message(approver), "APPROVED") if update_topic
|
||||
rename_wiki_and_artist
|
||||
update(status: "active", post_count: consequent_tag.post_count)
|
||||
update(status: 'active', post_count: consequent_tag.post_count)
|
||||
end
|
||||
rescue Exception => e
|
||||
Rails.logger.error("[TA] #{e.message}\n#{e.backtrace}")
|
||||
@ -116,17 +198,6 @@ class TagAlias < TagRelationship
|
||||
end
|
||||
end
|
||||
|
||||
def move_saved_searches
|
||||
escaped = Regexp.escape(antecedent_name)
|
||||
|
||||
if SavedSearch.enabled?
|
||||
SavedSearch.where("query like ?", "%#{antecedent_name}%").find_each do |ss|
|
||||
ss.query = ss.query.sub(/(?:^| )#{escaped}(?:$| )/, " #{consequent_name} ").strip.gsub(/ /, " ")
|
||||
ss.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def move_aliases_and_implications
|
||||
aliases = TagAlias.where(["consequent_name = ?", antecedent_name])
|
||||
aliases.each do |ta|
|
||||
@ -182,6 +253,18 @@ class TagAlias < TagRelationship
|
||||
end
|
||||
end
|
||||
|
||||
def create_undo_information
|
||||
post_ids = []
|
||||
Post.transaction do
|
||||
Post.without_timeout do
|
||||
Post.sql_raw_tag_match(antecedent_name).find_each do |post|
|
||||
post_ids << post.id
|
||||
end
|
||||
tag_rel_undos.create!(undo_data: post_ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_posts
|
||||
Post.without_timeout do
|
||||
Post.sql_raw_tag_match(antecedent_name).find_each do |post|
|
||||
|
@ -1,6 +1,8 @@
|
||||
class TagImplication < TagRelationship
|
||||
extend Memoist
|
||||
|
||||
has_many :tag_rel_undos, as: :tag_rel
|
||||
|
||||
array_attribute :descendant_names
|
||||
|
||||
before_save :update_descendant_names
|
||||
@ -150,6 +152,19 @@ class TagImplication < TagRelationship
|
||||
end
|
||||
end
|
||||
|
||||
def create_undo_information
|
||||
Post.without_timeout do
|
||||
Post.sql_raw_tag_match(antecedent_name).find_in_batches do |posts|
|
||||
post_info = Hash.new
|
||||
posts.each do |p|
|
||||
post_info[p.id] = p.tag_string
|
||||
end
|
||||
tag_rel_undos.create!(undo_data: post_info)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def update_posts
|
||||
Post.without_timeout do
|
||||
Post.sql_raw_tag_match(antecedent_name).find_each do |post|
|
||||
@ -165,6 +180,7 @@ class TagImplication < TagRelationship
|
||||
|
||||
def approve!(approver: CurrentUser.user, update_topic: true)
|
||||
update(status: "queued", approver_id: approver.id)
|
||||
create_undo_information
|
||||
TagImplicationJob.perform_later(id, update_topic)
|
||||
end
|
||||
|
||||
|
3
app/models/tag_rel_undo.rb
Normal file
3
app/models/tag_rel_undo.rb
Normal file
@ -0,0 +1,3 @@
|
||||
class TagRelUndo < ApplicationRecord
|
||||
belongs_to :tag_rel, polymorphic: true
|
||||
end
|
10
db/migrate/20191003070653_create_tag_relationship_undos.rb
Normal file
10
db/migrate/20191003070653_create_tag_relationship_undos.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class CreateTagRelationshipUndos < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :tag_rel_undos do |t|
|
||||
t.references :tag_rel, polymorphic: true
|
||||
t.json :undo_data
|
||||
t.boolean :applied, default: false
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
@ -2185,6 +2185,40 @@ CREATE SEQUENCE public.tag_implications_id_seq
|
||||
ALTER SEQUENCE public.tag_implications_id_seq OWNED BY public.tag_implications.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_rel_undos; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.tag_rel_undos (
|
||||
id bigint NOT NULL,
|
||||
tag_rel_type character varying,
|
||||
tag_rel_id bigint,
|
||||
undo_data json,
|
||||
applied boolean DEFAULT false,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_rel_undos_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.tag_rel_undos_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_rel_undos_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.tag_rel_undos_id_seq OWNED BY public.tag_rel_undos.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_subscriptions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
@ -3162,6 +3196,13 @@ ALTER TABLE ONLY public.tag_aliases ALTER COLUMN id SET DEFAULT nextval('public.
|
||||
ALTER TABLE ONLY public.tag_implications ALTER COLUMN id SET DEFAULT nextval('public.tag_implications_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_rel_undos id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.tag_rel_undos ALTER COLUMN id SET DEFAULT nextval('public.tag_rel_undos_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_subscriptions id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
@ -3708,6 +3749,14 @@ ALTER TABLE ONLY public.tag_implications
|
||||
ADD CONSTRAINT tag_implications_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_rel_undos tag_rel_undos_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.tag_rel_undos
|
||||
ADD CONSTRAINT tag_rel_undos_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: tag_subscriptions tag_subscriptions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
@ -4744,6 +4793,13 @@ CREATE INDEX index_tag_implications_on_consequent_name ON public.tag_implication
|
||||
CREATE INDEX index_tag_implications_on_forum_post_id ON public.tag_implications USING btree (forum_post_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_tag_rel_undos_on_tag_rel_type_and_tag_rel_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_tag_rel_undos_on_tag_rel_type_and_tag_rel_id ON public.tag_rel_undos USING btree (tag_rel_type, tag_rel_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_tag_subscriptions_on_creator_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
@ -5268,6 +5324,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||
('20190905111159'),
|
||||
('20190916204908'),
|
||||
('20190919213915'),
|
||||
('20190924233432');
|
||||
('20190924233432'),
|
||||
('20191003070653');
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user