From 29cdaddd8606a76e2eb6d6bbf4fdcf06fe8037ad Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 20 Sep 2018 14:42:10 -0500 Subject: [PATCH] PostSetPresenters::Post#related_posts: clean up metatag parsing (#2894). * Fix `#related_tags` to use `Tag.has_metatag?`. * Fix Tag::SUBQUERY_METATAGS and Tag::METATAGS to be arrays instead of regexes. --- .../src/javascripts/autocomplete.js.erb | 2 +- app/logical/tag_name_validator.rb | 2 +- app/models/tag.rb | 18 +++++++++++++----- app/presenters/post_set_presenters/post.rb | 2 +- test/unit/tag_test.rb | 4 ++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/javascript/src/javascripts/autocomplete.js.erb b/app/javascript/src/javascripts/autocomplete.js.erb index a9e9a3f09..04c1d1353 100644 --- a/app/javascript/src/javascripts/autocomplete.js.erb +++ b/app/javascript/src/javascripts/autocomplete.js.erb @@ -8,7 +8,7 @@ Autocomplete.TAG_CATEGORIES = <%= TagCategory.mapping.to_json.html_safe %>; Autocomplete.TAG_PREFIXES = "-|~|" + Object.keys(Autocomplete.TAG_CATEGORIES).map(category => category + ":").join("|"); Autocomplete.TAG_PREFIXES_REGEX = new RegExp("^(" + Autocomplete.TAG_PREFIXES + ")(.*)$", "i"); -Autocomplete.METATAGS_REGEX = new RegExp("^(" + Autocomplete.METATAGS + "):(.*)$", "i"); +Autocomplete.METATAGS_REGEX = new RegExp("^(" + Autocomplete.METATAGS.join("|") + "):(.*)$", "i"); Autocomplete.initialize_all = function() { if (Utility.meta("enable-auto-complete") === "true") { diff --git a/app/logical/tag_name_validator.rb b/app/logical/tag_name_validator.rb index 872b9861d..d97351e34 100644 --- a/app/logical/tag_name_validator.rb +++ b/app/logical/tag_name_validator.rb @@ -21,7 +21,7 @@ class TagNameValidator < ActiveModel::EachValidator record.errors[attribute] << "'#{value}' cannot contain non-printable characters" when /[^[[:ascii:]]]/ record.errors[attribute] << "'#{value}' must consist of only ASCII characters" - when /\A(#{Tag::METATAGS}|#{Tag::SUBQUERY_METATAGS}):(.+)\z/i + when /\A(#{Regexp.union(Tag::METATAGS)}):(.+)\z/i record.errors[attribute] << "'#{value}' cannot begin with '#{$1}:'" when /\A(#{Tag.categories.regexp}):(.+)\z/i record.errors[attribute] << "'#{value}' cannot begin with '#{$1}:'" diff --git a/app/models/tag.rb b/app/models/tag.rb index c563c8549..179acfc7d 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -1,8 +1,16 @@ class Tag < ApplicationRecord COSINE_SIMILARITY_RELATED_TAG_THRESHOLD = 300 - METATAGS = "-user|user|-approver|approver|commenter|comm|noter|noteupdater|artcomm|-pool|pool|ordpool|-favgroup|favgroup|-fav|fav|ordfav|md5|-rating|rating|-locked|locked|width|height|mpixels|ratio|score|favcount|filesize|source|-source|id|-id|date|age|order|limit|-status|status|tagcount|parent|-parent|child|pixiv_id|pixiv|search|upvote|downvote|filetype|-filetype|flagger|-flagger|appealer|-appealer|disapproval|-disapproval|" + - TagCategory.short_name_list.map {|x| "#{x}tags"}.join("|") - SUBQUERY_METATAGS = "commenter|comm|noter|noteupdater|artcomm|flagger|-flagger|appealer|-appealer" + METATAGS = %w[ + -user user -approver approver commenter comm noter noteupdater artcomm + -pool pool ordpool -favgroup favgroup -fav fav ordfav md5 -rating rating + -locked locked width height mpixels ratio score favcount filesize source + -source id -id date age order limit -status status tagcount parent -parent + child pixiv_id pixiv search upvote downvote filetype -filetype flagger + -flagger appealer -appealer disapproval -disapproval + ] + TagCategory.short_name_list.map {|x| "#{x}tags"} + + SUBQUERY_METATAGS = %w[commenter comm noter noteupdater artcomm flagger -flagger appealer -appealer] + has_one :wiki_page, :foreign_key => "title", :primary_key => "name" has_one :artist, :foreign_key => "name", :primary_key => "name" has_one :antecedent_alias, -> {active}, :class_name => "TagAlias", :foreign_key => "antecedent_name", :primary_key => "name" @@ -430,7 +438,7 @@ class Tag < ApplicationRecord end def is_metatag?(tag) - !!(tag =~ /\A(#{METATAGS}):(.+)\Z/i) + tag.match?(/\A(#{Regexp.union(METATAGS)}):(.+)\z/i) end def is_negated_tag?(tag) @@ -466,7 +474,7 @@ class Tag < ApplicationRecord scan_query(query).each do |token| q[:tag_count] += 1 unless Danbooru.config.is_unlimited_tag?(token) - if token =~ /\A(#{METATAGS}):(.+)\Z/i + if token =~ /\A(#{Regexp.union(METATAGS)}):(.+)\z/i g1 = $1.downcase g2 = $2 case g1 diff --git a/app/presenters/post_set_presenters/post.rb b/app/presenters/post_set_presenters/post.rb index 9bfd6b9aa..fbb7b473d 100644 --- a/app/presenters/post_set_presenters/post.rb +++ b/app/presenters/post_set_presenters/post.rb @@ -24,7 +24,7 @@ module PostSetPresenters related_tags_for_single(post_set.tag_string) elsif post_set.unordered_tag_array.size == 1 related_tags_for_single(post_set.unordered_tag_array.first) - elsif post_set.tag_string =~ /(?:^|\s)(?:#{Tag::SUBQUERY_METATAGS}):\S+/ + elsif Tag.has_metatag?(post_set.tag_array, *Tag::SUBQUERY_METATAGS) calculate_related_tags_from_post_set elsif post_set.is_empty_tag? popular_tags diff --git a/test/unit/tag_test.rb b/test/unit/tag_test.rb index 6565957e0..0cffd4843 100644 --- a/test/unit/tag_test.rb +++ b/test/unit/tag_test.rb @@ -242,8 +242,8 @@ class TagTest < ActiveSupport::TestCase should_not allow_value("café").for(:name).on(:create) should_not allow_value("東方").for(:name).on(:create) - metatags = Tag::METATAGS.split("|") + Tag::SUBQUERY_METATAGS.split("|") + TagCategory.mapping.keys - metatags.split("|").each do |metatag| + metatags = Tag::METATAGS + TagCategory.mapping.keys + metatags.each do |metatag| should_not allow_value("#{metatag}:foo").for(:name).on(:create) end end