search: clean up filetype: metatag.

* Fix not being able to use the filetype: metatag twice in the same search.
* Support comma-separated filetypes (filetype:png,jpg).
This commit is contained in:
evazion
2020-04-20 04:07:59 -05:00
parent c92ac9ab89
commit fef90b46ee
3 changed files with 25 additions and 13 deletions

View File

@@ -265,7 +265,7 @@ module Searchable
def apply_default_order(params) def apply_default_order(params)
if params[:order] == "custom" if params[:order] == "custom"
parse_ids = PostQueryBuilder.parse_range(params[:id]) parse_ids = PostQueryBuilder.parse_range(params[:id], :integer)
if parse_ids[0] == :in if parse_ids[0] == :in
return find_ordered(parse_ids[1]) return find_ordered(parse_ids[1])
end end

View File

@@ -93,7 +93,7 @@ class PostQueryBuilder
def attribute_matches(values, field, type = :integer) def attribute_matches(values, field, type = :integer)
values.to_a.reduce(Post.all) do |relation, value| values.to_a.reduce(Post.all) do |relation, value|
operator, *args = PostQueryBuilder.parse_range(value, type) operator, *args = PostQueryBuilder.parse_metatag_value(value, type)
relation.where_operator(field, operator, *args) relation.where_operator(field, operator, *args)
end end
end end
@@ -280,6 +280,9 @@ class PostQueryBuilder
relation = relation.merge(attribute_matches(q[:pixiv_id], :pixiv_id)) relation = relation.merge(attribute_matches(q[:pixiv_id], :pixiv_id))
relation = relation.merge(attribute_matches(q[:post_tag_count], :tag_count)) relation = relation.merge(attribute_matches(q[:post_tag_count], :tag_count))
relation = relation.merge(attribute_matches(q[:filetype], :file_ext, :enum))
relation = relation.merge(attribute_matches(q[:filetype_neg], :file_ext, :enum).negate(:nor)) if q[:filetype_neg].present?
TagCategory.categories.each do |category| TagCategory.categories.each do |category|
relation = relation.merge(attribute_matches(q["#{category}_tag_count".to_sym], "tag_count_#{category}".to_sym)) relation = relation.merge(attribute_matches(q["#{category}_tag_count".to_sym], "tag_count_#{category}".to_sym))
end end
@@ -296,14 +299,6 @@ class PostQueryBuilder
relation = relation.merge(status_matches(query).negate) relation = relation.merge(status_matches(query).negate)
end end
if q[:filetype]
relation = relation.where("posts.file_ext": q[:filetype])
end
if q[:filetype_neg]
relation = relation.where.not("posts.file_ext": q[:filetype_neg])
end
if q[:source] if q[:source]
if q[:source] == "none" if q[:source] == "none"
relation = relation.where_like(:source, '') relation = relation.where_like(:source, '')
@@ -1015,10 +1010,12 @@ class PostQueryBuilder
q[:embedded] = g2.downcase q[:embedded] = g2.downcase
when "filetype" when "filetype"
q[:filetype] = g2.downcase q[:filetype] ||= []
q[:filetype] << g2
when "-filetype" when "-filetype"
q[:filetype_neg] = g2.downcase q[:filetype_neg] ||= []
q[:filetype_neg] << g2
when "pixiv_id", "pixiv" when "pixiv_id", "pixiv"
q[:pixiv_id] ||= [] q[:pixiv_id] ||= []
@@ -1100,6 +1097,9 @@ class PostQueryBuilder
def parse_cast(object, type) def parse_cast(object, type)
case type case type
when :enum
object.to_s.downcase
when :integer when :integer
object.to_i object.to_i
@@ -1143,7 +1143,15 @@ class PostQueryBuilder
end end
end end
def parse_range(string, type = :integer) def parse_metatag_value(string, type)
if type == :enum
[:in, string.split(/[, ]+/).map { |x| parse_cast(x, type) }]
else
parse_range(string, type)
end
end
def parse_range(string, type)
range = case string range = case string
when /\A(.+?)\.\.\.(.+)/ # A...B when /\A(.+?)\.\.\.(.+)/ # A...B
lo, hi = [parse_cast($1, type), parse_cast($2, type)].sort lo, hi = [parse_cast($1, type), parse_cast($2, type)].sort

View File

@@ -496,6 +496,10 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match([png], "filetype:png") assert_tag_match([png], "filetype:png")
assert_tag_match([jpg], "-filetype:png") assert_tag_match([jpg], "-filetype:png")
assert_tag_match([jpg, png], "filetype:png,jpg")
assert_tag_match([], "filetype:png filetype:jpg")
assert_tag_match([], "-filetype:png -filetype:jpg")
assert_tag_match([], "filetype:garbage")
end end
should "return posts for the tagcount:<n> metatags" do should "return posts for the tagcount:<n> metatags" do