BURs: rename AliasAndImplicationImporter to BulkUpdateRequestProcessor.

The name AliasAndImplicationImporter is a holdover from the time before
bulk update requests existed. This was a bad name because it doesn't do
any actual importing, instead it's used for parsing and executing bulk
update requests.
This commit is contained in:
evazion
2020-05-10 22:07:27 -05:00
parent 54bae4017d
commit 49383d393a
8 changed files with 105 additions and 129 deletions

View File

@@ -1,65 +1,50 @@
class AliasAndImplicationImporter
class Error < RuntimeError; end
attr_accessor :text, :commands, :forum_id, :skip_secondary_validations
class BulkUpdateRequestProcessor
extend Memoist
def initialize(text, forum_id, skip_secondary_validations = true)
@forum_id = forum_id
class Error < StandardError; end
attr_accessor :text, :forum_topic_id, :skip_secondary_validations
def initialize(text, forum_topic_id: nil, skip_secondary_validations: true)
@forum_topic_id = forum_topic_id
@text = text
@skip_secondary_validations = skip_secondary_validations
end
def process!(approver = CurrentUser.user)
tokens = AliasAndImplicationImporter.tokenize(text)
parse(tokens, approver)
end
def validate!
tokens = AliasAndImplicationImporter.tokenize(text)
validate(tokens)
end
def self.tokenize(text)
def tokens
text.split(/\r\n|\r|\n/).reject(&:blank?).map do |line|
line = line.gsub(/[[:space:]]+/, " ").strip
if line =~ /^(?:create alias|aliasing|alias) (\S+) -> (\S+)$/i
[:create_alias, $1, $2]
elsif line =~ /^(?:create implication|implicating|implicate|imply) (\S+) -> (\S+)$/i
[:create_implication, $1, $2]
elsif line =~ /^(?:remove alias|unaliasing|unalias) (\S+) -> (\S+)$/i
[:remove_alias, $1, $2]
elsif line =~ /^(?:remove implication|unimplicating|unimplicate|unimply) (\S+) -> (\S+)$/i
[:remove_implication, $1, $2]
elsif line =~ /^(?:mass update|updating|update|change) (.+?) -> (.*)$/i
[:mass_update, $1, $2]
elsif line =~ /^category (\S+) -> (#{Tag.categories.regexp})/
[:change_category, $1, $2]
elsif line.strip.empty?
# do nothing
else
raise Error, "Unparseable line: #{line}"
end
end
end
def validate(tokens)
def validate!
tokens.map do |token|
case token[0]
when :create_alias
tag_alias = TagAlias.new(creator: User.system, forum_topic_id: forum_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
tag_alias = TagAlias.new(creator: User.system, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
unless tag_alias.valid?
raise Error, "Error: #{tag_alias.errors.full_messages.join("; ")} (create alias #{tag_alias.antecedent_name} -> #{tag_alias.consequent_name})"
end
when :create_implication
tag_implication = TagImplication.new(creator: User.system, forum_topic_id: forum_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
tag_implication = TagImplication.new(creator: User.system, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
unless tag_implication.valid?
raise Error, "Error: #{tag_implication.errors.full_messages.join("; ")} (create implication #{tag_implication.antecedent_name} -> #{tag_implication.consequent_name})"
end
@@ -73,37 +58,19 @@ class AliasAndImplicationImporter
end
end
def affected_tags
AliasAndImplicationImporter.tokenize(text).flat_map do |type, *args|
case type
when :create_alias, :remove_alias, :create_implication, :remove_implication
[args[0], args[1]]
when :mass_update
tags = PostQueryBuilder.new(args[0]).tags + PostQueryBuilder.new(args[1]).tags
tags.reject(&:negated).reject(&:optional).reject(&:wildcard).map(&:name)
when :change_category
args[0]
end
end.sort.uniq
rescue Error
[]
end
private
def parse(tokens, approver)
def process!(approver)
ActiveRecord::Base.transaction do
tokens.map do |token|
case token[0]
when :create_alias
tag_alias = TagAlias.create(creator: approver, forum_topic_id: forum_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
tag_alias = TagAlias.create(creator: approver, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
unless tag_alias.valid?
raise Error, "Error: #{tag_alias.errors.full_messages.join("; ")} (create alias #{tag_alias.antecedent_name} -> #{tag_alias.consequent_name})"
end
tag_alias.approve!(approver: approver)
when :create_implication
tag_implication = TagImplication.create(creator: approver, forum_topic_id: forum_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
tag_implication = TagImplication.create(creator: approver, forum_topic_id: forum_topic_id, status: "pending", antecedent_name: token[1], consequent_name: token[2], skip_secondary_validations: skip_secondary_validations)
unless tag_implication.valid?
raise Error, "Error: #{tag_implication.errors.full_messages.join("; ")} (create implication #{tag_implication.antecedent_name} -> #{tag_implication.consequent_name})"
end
@@ -133,4 +100,37 @@ class AliasAndImplicationImporter
end
end
end
def affected_tags
tokens.flat_map do |type, *args|
case type
when :create_alias, :remove_alias, :create_implication, :remove_implication
[args[0], args[1]]
when :mass_update
tags = PostQueryBuilder.new(args[0]).tags + PostQueryBuilder.new(args[1]).tags
tags.reject(&:negated).reject(&:optional).reject(&:wildcard).map(&:name)
when :change_category
args[0]
end
end.sort.uniq
rescue Error
[]
end
def to_dtext
tokens.map do |token|
case token[0]
when :create_alias, :create_implication, :remove_alias, :remove_implication
"#{token[0].to_s.tr("_", " ")} [[#{token[1]}]] -> [[#{token[2]}]]"
when :mass_update
"mass update {{#{token[1]}}} -> #{token[2]}"
when :change_category
"category [[#{token[1]}]] -> #{token[2]}"
else
raise "Unknown token: #{token[0]}"
end
end.join("\n")
end
memoize :tokens
end

View File

@@ -105,9 +105,9 @@ class DText
end
elsif obj.is_a?(BulkUpdateRequest)
if obj.script.size < 700
embedded_script = obj.script_with_links
embedded_script = obj.processor.to_dtext
else
embedded_script = "[expand]#{obj.script_with_links}[/expand]"
embedded_script = "[expand]#{obj.processor.to_dtext}[/expand]"
end
if obj.is_approved?

View File

@@ -75,12 +75,12 @@ class BulkUpdateRequest < ApplicationRecord
def approve!(approver)
transaction do
CurrentUser.scoped(approver) do
AliasAndImplicationImporter.new(script, forum_topic_id, true).process!
processor.process!(approver)
update!(status: "approved", approver: approver, skip_secondary_validations: true)
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post.id}) has been approved by @#{approver.name}.")
end
end
rescue AliasAndImplicationImporter::Error => x
rescue BulkUpdateRequestProcessor::Error => x
self.approver = approver
CurrentUser.scoped(approver) do
forum_updater.update("The #{bulk_update_request_link} (forum ##{forum_post.id}) has failed: #{x}")
@@ -110,8 +110,8 @@ class BulkUpdateRequest < ApplicationRecord
module ValidationMethods
def validate_script
AliasAndImplicationImporter.new(script, forum_topic_id, skip_secondary_validations).validate!
rescue AliasAndImplicationImporter::Error => e
processor.validate!
rescue BulkUpdateRequestProcessor::Error => e
errors[:base] << e.message
end
end
@@ -120,38 +120,22 @@ class BulkUpdateRequest < ApplicationRecord
include ApprovalMethods
include ValidationMethods
def script_with_links
tokens = AliasAndImplicationImporter.tokenize(script)
lines = tokens.map do |token|
case token[0]
when :create_alias, :create_implication, :remove_alias, :remove_implication
"#{token[0].to_s.tr("_", " ")} [[#{token[1]}]] -> [[#{token[2]}]]"
when :mass_update
"mass update {{#{token[1]}}} -> #{token[2]}"
when :change_category
"category [[#{token[1]}]] -> #{token[2]}"
else
raise "Unknown token: #{token[0]}"
end
end
lines.join("\n")
end
def normalize_text
self.script = script.downcase
end
def update_tags
self.tags = AliasAndImplicationImporter.new(script, nil).affected_tags
self.tags = processor.affected_tags
end
def skip_secondary_validations=(v)
@skip_secondary_validations = v.to_s.truthy?
end
def processor
@processor ||= BulkUpdateRequestProcessor.new(script, forum_topic_id: forum_topic_id, skip_secondary_validations: skip_secondary_validations)
end
def is_pending?
status == "pending"
end

View File

@@ -1,4 +1,4 @@
<% dtext_data = DText.preprocess(bulk_update_requests.map(&:script_with_links)) %>
<% dtext_data = DText.preprocess(bulk_update_requests.map(&:processor).map(&:to_dtext)) %>
<%= table_for bulk_update_requests, width: "100%" do |t| %>
<% t.column "Request" do |request| %>
@@ -9,7 +9,7 @@
<% end %>
<div class="prose">
<%= format_text(request.script_with_links, data: dtext_data) %>
<%= format_text(request.processor.to_dtext, data: dtext_data) %>
</div>
<% end %>
<% t.column "Votes" do |request| %>

View File

@@ -14,7 +14,7 @@
<div style="margin: 1em 0;">
<h2>Script</h2>
<div class="prose">
<%= format_text @bulk_update_request.script_with_links %>
<%= format_text @bulk_update_request.processor.to_dtext %>
</div>
<%= render "bur_edit_links", bur: @bulk_update_request %>