Fix #4406: Add "commentary:" metasearch.
Add: * commentary:true (posts with commentary) * commentary:false (posts without commentary) * commentary:translated (posts with translated commentary) * commentary:untranslated (posts with untranslated commentary) * commentary:"text" (posts where any commentary field matches "text") Known issues: * There's no way to escape the true, false, translated, or untranslated keywords to do a literal text search for commentaries containing one of these keywords. * Negated searches may be slow. Using a left outer join instead of a subquery would be faster in most cases, but negating it is harder.
This commit is contained in:
@@ -288,6 +288,9 @@ Autocomplete.static_metatags = {
|
|||||||
filetype: [
|
filetype: [
|
||||||
"jpg", "png", "gif", "swf", "zip", "webm", "mp4"
|
"jpg", "png", "gif", "swf", "zip", "webm", "mp4"
|
||||||
],
|
],
|
||||||
|
commentary: [
|
||||||
|
"true", "false", "translated", "untranslated"
|
||||||
|
],
|
||||||
disapproved: Autocomplete.DISAPPROVAL_REASONS
|
disapproved: Autocomplete.DISAPPROVAL_REASONS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class PostQueryBuilder
|
|||||||
-ordfav ordfav
|
-ordfav ordfav
|
||||||
-favgroup favgroup
|
-favgroup favgroup
|
||||||
-pool pool ordpool
|
-pool pool ordpool
|
||||||
|
-commentary commentary
|
||||||
-id id
|
-id id
|
||||||
-rating rating
|
-rating rating
|
||||||
-locked locked
|
-locked locked
|
||||||
@@ -186,6 +187,21 @@ class PostQueryBuilder
|
|||||||
relation
|
relation
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def commentary_matches(query)
|
||||||
|
case query
|
||||||
|
when "none", "false"
|
||||||
|
Post.where.not(artist_commentary: ArtistCommentary.all).or(Post.where(artist_commentary: ArtistCommentary.deleted))
|
||||||
|
when "any", "true"
|
||||||
|
Post.where(artist_commentary: ArtistCommentary.undeleted)
|
||||||
|
when "translated"
|
||||||
|
Post.where(artist_commentary: ArtistCommentary.translated)
|
||||||
|
when "untranslated"
|
||||||
|
Post.where(artist_commentary: ArtistCommentary.untranslated)
|
||||||
|
else
|
||||||
|
Post.where(artist_commentary: ArtistCommentary.text_matches(query))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def table_for_metatag(metatag)
|
def table_for_metatag(metatag)
|
||||||
if metatag.in?(COUNT_METATAGS)
|
if metatag.in?(COUNT_METATAGS)
|
||||||
metatag[/(?<table>[a-z]+)_count\z/i, :table]
|
metatag[/(?<table>[a-z]+)_count\z/i, :table]
|
||||||
@@ -346,6 +362,14 @@ class PostQueryBuilder
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
q[:commentary_neg].to_a.each do |query|
|
||||||
|
relation = relation.merge(commentary_matches(query).negate)
|
||||||
|
end
|
||||||
|
|
||||||
|
q[:commentary].to_a.each do |query|
|
||||||
|
relation = relation.merge(commentary_matches(query))
|
||||||
|
end
|
||||||
|
|
||||||
if q[:saved_searches]
|
if q[:saved_searches]
|
||||||
relation = add_saved_search_relation(q[:saved_searches], relation)
|
relation = add_saved_search_relation(q[:saved_searches], relation)
|
||||||
end
|
end
|
||||||
@@ -731,8 +755,8 @@ class PostQueryBuilder
|
|||||||
class_methods do
|
class_methods do
|
||||||
def scan_query(query, strip_metatags: false)
|
def scan_query(query, strip_metatags: false)
|
||||||
tagstr = query.to_s.gsub(/\u3000/, " ").strip
|
tagstr = query.to_s.gsub(/\u3000/, " ").strip
|
||||||
list = tagstr.scan(/-?source:".*?"/) || []
|
list = tagstr.scan(/-?(?:source|commentary):".*?"/) || []
|
||||||
list += tagstr.gsub(/-?source:".*?"/, "").scan(/[^[:space:]]+/).uniq
|
list += tagstr.gsub(/-?(?:source|commentary):".*?"/, "").scan(/[^[:space:]]+/).uniq
|
||||||
list = list.map { |tag| tag.sub(/^[-~]/, "") } if strip_metatags
|
list = list.map { |tag| tag.sub(/^[-~]/, "") } if strip_metatags
|
||||||
list
|
list
|
||||||
end
|
end
|
||||||
@@ -867,6 +891,14 @@ class PostQueryBuilder
|
|||||||
q[:ordfav] ||= []
|
q[:ordfav] ||= []
|
||||||
q[:ordfav] << g2
|
q[:ordfav] << g2
|
||||||
|
|
||||||
|
when "-commentary"
|
||||||
|
q[:commentary_neg] ||= []
|
||||||
|
q[:commentary_neg] << g2.gsub(/\A"(.*)"\Z/, '\1')
|
||||||
|
|
||||||
|
when "commentary"
|
||||||
|
q[:commentary] ||= []
|
||||||
|
q[:commentary] << g2.gsub(/\A"(.*)"\Z/, '\1')
|
||||||
|
|
||||||
when "search"
|
when "search"
|
||||||
q[:saved_searches] ||= []
|
q[:saved_searches] ||= []
|
||||||
q[:saved_searches] << g2
|
q[:saved_searches] << g2
|
||||||
|
|||||||
@@ -11,6 +11,15 @@ class ArtistCommentary < ApplicationRecord
|
|||||||
after_save :create_version
|
after_save :create_version
|
||||||
after_commit :tag_post
|
after_commit :tag_post
|
||||||
|
|
||||||
|
scope :original_absent, -> { where(original_title: "").where(original_description: "") }
|
||||||
|
scope :original_present, -> { where.not(original_title: "").or(where.not(original_description: "")) }
|
||||||
|
scope :translation_absent, -> { where(translated_title: "").where(translated_description: "") }
|
||||||
|
scope :translation_present, -> { where.not(translated_title: "").or(where.not(translated_description: "")) }
|
||||||
|
scope :translated, -> { original_present.translation_present }
|
||||||
|
scope :untranslated, -> { original_present.translation_absent }
|
||||||
|
scope :deleted, -> { original_absent.translation_absent }
|
||||||
|
scope :undeleted, -> { original_present.or(translation_present) }
|
||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
def text_matches(query)
|
def text_matches(query)
|
||||||
query = "*#{query}*" unless query =~ /\*/
|
query = "*#{query}*" unless query =~ /\*/
|
||||||
@@ -21,14 +30,6 @@ class ArtistCommentary < ApplicationRecord
|
|||||||
.or(where_ilike(:translated_description, query))
|
.or(where_ilike(:translated_description, query))
|
||||||
end
|
end
|
||||||
|
|
||||||
def deleted
|
|
||||||
where(original_title: "", original_description: "", translated_title: "", translated_description: "")
|
|
||||||
end
|
|
||||||
|
|
||||||
def undeleted
|
|
||||||
where("original_title != '' OR original_description != '' OR translated_title != '' OR translated_description != ''")
|
|
||||||
end
|
|
||||||
|
|
||||||
def search(params)
|
def search(params)
|
||||||
q = super
|
q = super
|
||||||
|
|
||||||
|
|||||||
@@ -2228,6 +2228,32 @@ class PostTest < ActiveSupport::TestCase
|
|||||||
assert_tag_match([], "commentaryupdater:none")
|
assert_tag_match([], "commentaryupdater:none")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "return posts for the commentary:<query> metatag" do
|
||||||
|
post1 = create(:post)
|
||||||
|
post2 = create(:post)
|
||||||
|
post3 = create(:post)
|
||||||
|
post4 = create(:post)
|
||||||
|
|
||||||
|
artcomm1 = create(:artist_commentary, post: post1, translated_title: "azur lane")
|
||||||
|
artcomm2 = create(:artist_commentary, post: post2, translated_title: "", translated_description: "")
|
||||||
|
artcomm3 = create(:artist_commentary, post: post3, original_title: "", original_description: "", translated_title: "", translated_description: "")
|
||||||
|
|
||||||
|
assert_tag_match([post2, post1], "commentary:true")
|
||||||
|
assert_tag_match([post4, post3], "commentary:false")
|
||||||
|
|
||||||
|
assert_tag_match([post4, post3], "-commentary:true")
|
||||||
|
assert_tag_match([post2, post1], "-commentary:false")
|
||||||
|
|
||||||
|
assert_tag_match([post1], "commentary:translated")
|
||||||
|
assert_tag_match([post4, post3, post2], "-commentary:translated")
|
||||||
|
|
||||||
|
assert_tag_match([post2], "commentary:untranslated")
|
||||||
|
assert_tag_match([post4, post3, post1], "-commentary:untranslated")
|
||||||
|
|
||||||
|
assert_tag_match([post1], 'commentary:"azur lane"')
|
||||||
|
assert_tag_match([post4, post3, post2], '-commentary:"azur lane"')
|
||||||
|
end
|
||||||
|
|
||||||
should "return posts for the date:<d> metatag" do
|
should "return posts for the date:<d> metatag" do
|
||||||
post = FactoryBot.create(:post, created_at: Time.parse("2017-01-01 12:00"))
|
post = FactoryBot.create(:post, created_at: Time.parse("2017-01-01 12:00"))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user