From 4bb1bdbe10fa678d0487783bd54375bafdeefebc Mon Sep 17 00:00:00 2001 From: evazion Date: Mon, 28 Oct 2019 16:40:38 -0500 Subject: [PATCH] dtext: handle [bur:] tags in main parser. Move the parsing for the [bur:], [ta:], [ti:] pseudo tags to the main parser in `DText.format_text`. This fixes a bug where wiki links inside bulk update requests on the forum weren't properly colorized because the text of the BUR was embedded after we scanned for wiki links, not before. This also ensures that tags inside bulk update requests will be recorded in the dtext_links table, meaning that forum posts can be properly searched by tags. This incidentally means that these request pseudo tags can now be used outside the forum. --- app/helpers/forum_topics_helper.rb | 50 --------------------- app/logical/d_text.rb | 51 ++++++++++++++++++++++ app/views/forum_posts/_forum_post.html.erb | 2 +- test/unit/d_text_test.rb | 20 +++++++++ 4 files changed, 72 insertions(+), 51 deletions(-) diff --git a/app/helpers/forum_topics_helper.rb b/app/helpers/forum_topics_helper.rb index 2fc818be6..98b9ad8ed 100644 --- a/app/helpers/forum_topics_helper.rb +++ b/app/helpers/forum_topics_helper.rb @@ -6,54 +6,4 @@ module ForumTopicsHelper def available_min_user_levels ForumTopic::MIN_LEVELS.select { |name, level| level <= CurrentUser.level }.to_a end - - def tag_request_message(obj) - if obj.is_a?(TagRelationship) - if obj.is_approved? - return "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has been approved." - elsif obj.is_retired? - return "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has been retired." - elsif obj.is_deleted? - return "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has been rejected." - elsif obj.is_pending? - return "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] is pending approval." - elsif obj.is_errored? - return "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] (#{relationship} failed during processing." - else # should never happen - return "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has an unknown status." - end - end - - if obj.is_a?(BulkUpdateRequest) - if obj.script.size < 700 - embedded_script = obj.script_with_links - else - embedded_script = "[expand]#{obj.script_with_links}[/expand]" - end - - if obj.is_approved? - return "The bulk update request ##{obj.id} is active.\n\n#{embedded_script}" - elsif obj.is_pending? - return "The \"bulk update request ##{obj.id}\":/bulk_update_requests/#{obj.id} is pending approval.\n\n#{embedded_script}" - elsif obj.is_rejected? - return "The bulk update request ##{obj.id} has been rejected.\n\n#{embedded_script}" - end - end - end - - def parse_embedded_tag_request_text(text) - [TagAlias, TagImplication, BulkUpdateRequest].each do |tag_request| - text = text.gsub(tag_request.embedded_pattern) do |match| - begin - obj = tag_request.find($~[:id]) - tag_request_message(obj) || match - - rescue ActiveRecord::RecordNotFound - match - end - end - end - - text - end end diff --git a/app/logical/d_text.rb b/app/logical/d_text.rb index 25ef24dc7..ef66503c6 100644 --- a/app/logical/d_text.rb +++ b/app/logical/d_text.rb @@ -5,7 +5,9 @@ class DText MENTION_REGEXP = /(?<=^| )@\S+/ def self.format_text(text, data: nil, **options) + return nil if text.nil? data = preprocess([text]) if data.nil? + text = parse_embedded_tag_request_text(text) html = DTextRagel.parse(text, **options) html = postprocess(html, *data) html @@ -14,6 +16,7 @@ class DText end def self.preprocess(dtext_messages) + dtext_messages = dtext_messages.map { |message| parse_embedded_tag_request_text(message) } names = dtext_messages.map { |message| parse_wiki_titles(message) }.flatten.uniq wiki_pages = WikiPage.where(title: names) tags = Tag.where(name: names) @@ -57,6 +60,54 @@ class DText "[quote]\n#{creator_name} said:\n\n#{stripped_body}\n[/quote]\n\n" end + def self.parse_embedded_tag_request_text(text) + [TagAlias, TagImplication, BulkUpdateRequest].each do |tag_request| + text = text.gsub(tag_request.embedded_pattern) do |match| + begin + obj = tag_request.find($~[:id]) + tag_request_message(obj) || match + + rescue ActiveRecord::RecordNotFound + match + end + end + end + + text + end + + def self.tag_request_message(obj) + if obj.is_a?(TagRelationship) + if obj.is_approved? + "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has been approved." + elsif obj.is_retired? + "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has been retired." + elsif obj.is_deleted? + "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has been rejected." + elsif obj.is_pending? + "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] is pending approval." + elsif obj.is_errored? + "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] (#{relationship} failed during processing." + else # should never happen + "The #{obj.relationship} ##{obj.id} [[#{obj.antecedent_name}]] -> [[#{obj.consequent_name}]] has an unknown status." + end + elsif obj.is_a?(BulkUpdateRequest) + if obj.script.size < 700 + embedded_script = obj.script_with_links + else + embedded_script = "[expand]#{obj.script_with_links}[/expand]" + end + + if obj.is_approved? + "The bulk update request ##{obj.id} is active.\n\n#{embedded_script}" + elsif obj.is_pending? + "The \"bulk update request ##{obj.id}\":/bulk_update_requests/#{obj.id} is pending approval.\n\n#{embedded_script}" + elsif obj.is_rejected? + "The bulk update request ##{obj.id} has been rejected.\n\n#{embedded_script}" + end + end + end + def self.parse_mentions(text) text = strip_blocks(text.to_s, "quote") diff --git a/app/views/forum_posts/_forum_post.html.erb b/app/views/forum_posts/_forum_post.html.erb index f7cc58ac0..88cacfef8 100644 --- a/app/views/forum_posts/_forum_post.html.erb +++ b/app/views/forum_posts/_forum_post.html.erb @@ -11,7 +11,7 @@
- <%= format_text(parse_embedded_tag_request_text(forum_post.body), data: dtext_data) %> + <%= format_text(forum_post.body, data: dtext_data) %>
<%= render "application/update_notice", record: forum_post %> diff --git a/test/unit/d_text_test.rb b/test/unit/d_text_test.rb index c59b1f8d6..09769b09e 100644 --- a/test/unit/d_text_test.rb +++ b/test/unit/d_text_test.rb @@ -40,6 +40,16 @@ class DTextTest < ActiveSupport::TestCase end context "#format_text" do + setup do + CurrentUser.user = create(:user) + CurrentUser.ip_addr = "127.0.0.1" + end + + teardown do + CurrentUser.user = nil + CurrentUser.ip_addr = nil + end + should "add tag types to wiki links" do create(:tag, name: "bkub", category: Tag.categories.artist, post_count: 42) assert_match(/tag-type-#{Tag.categories.artist}/, DText.format_text("[[bkub]]")) @@ -55,6 +65,16 @@ class DTextTest < ActiveSupport::TestCase refute_match(/dtext-tag-does-not-exist/, DText.format_text("[[help:nothing]]")) end + + should "parse [ta:], [ti:], [bur:] pseudo tags" do + @bur = create(:bulk_update_request) + @ti = create(:tag_implication) + @ta = create(:tag_alias) + + assert_match(/bulk update request/, DText.format_text("[bur:#{@bur.id}]")) + assert_match(/implication ##{@ti.id}/, DText.format_text("[ti:#{@ti.id}]")) + assert_match(/alias ##{@ta.id}/, DText.format_text("[ta:#{@ta.id}]")) + end end context "#parse_wiki_titles" do