search: clean up saved search: metatag.

* Fix not being able to negate the search: metatag.
* Fix not being able to use the search: metatag twice in the same search.
This commit is contained in:
evazion
2020-04-20 22:12:00 -05:00
parent f6fb3c0169
commit 6eb98c6572
3 changed files with 41 additions and 49 deletions

View File

@@ -38,6 +38,7 @@ class PostQueryBuilder
-filetype filetype -filetype filetype
-disapproved disapproved -disapproved disapproved
-parent parent -parent parent
-search search
md5 md5
width width
height height
@@ -53,7 +54,6 @@ class PostQueryBuilder
tagcount tagcount
child child
pixiv_id pixiv pixiv_id pixiv
search
embedded embedded
] + TagCategory.short_name_list.map {|x| "#{x}tags"} + COUNT_METATAGS + COUNT_METATAG_SYNONYMS ] + TagCategory.short_name_list.map {|x| "#{x}tags"} + COUNT_METATAGS + COUNT_METATAG_SYNONYMS
@@ -156,19 +156,13 @@ class PostQueryBuilder
relation relation
end end
def add_saved_search_relation(saved_searches, relation) def saved_search_matches(label)
saved_searches.each do |saved_search| case label.downcase
if saved_search == "all" when "all"
post_ids = SavedSearch.post_ids_for(CurrentUser.id) Post.where(id: SavedSearch.post_ids_for(CurrentUser.id))
else else
post_ids = SavedSearch.post_ids_for(CurrentUser.id, label: saved_search) Post.where(id: SavedSearch.post_ids_for(CurrentUser.id, label: label))
end
post_ids = [0] if post_ids.empty?
relation = relation.where("posts.id": post_ids)
end end
relation
end end
def status_matches(status) def status_matches(status)
@@ -348,8 +342,12 @@ class PostQueryBuilder
relation = relation.merge(commentary_matches(query)) relation = relation.merge(commentary_matches(query))
end end
if q[:saved_searches] q[:saved_searches_neg].to_a.each do |query|
relation = add_saved_search_relation(q[:saved_searches], relation) relation = relation.merge(saved_search_matches(query).negate)
end
q[:saved_searches].to_a.each do |query|
relation = relation.merge(saved_search_matches(query))
end end
q[:user_neg].to_a.each do |username| q[:user_neg].to_a.each do |username|
@@ -886,6 +884,10 @@ class PostQueryBuilder
q[:commentary] ||= [] q[:commentary] ||= []
q[:commentary] << g2 q[:commentary] << g2
when "-search"
q[:saved_searches_neg] ||= []
q[:saved_searches_neg] << g2
when "search" when "search"
q[:saved_searches] ||= [] q[:saved_searches] ||= []
q[:saved_searches] << g2 q[:saved_searches] << g2

View File

@@ -14,7 +14,6 @@ class SavedSearch < ApplicationRecord
memoize :redis memoize :redis
def post_ids_for(user_id, label: nil) def post_ids_for(user_id, label: nil)
label = normalize_label(label) if label
queries = queries_for(user_id, label: label) queries = queries_for(user_id, label: label)
post_ids = Set.new post_ids = Set.new
queries.each do |query| queries.each do |query|
@@ -135,13 +134,10 @@ class SavedSearch < ApplicationRecord
concerning :Queries do concerning :Queries do
class_methods do class_methods do
def queries_for(user_id, label: nil, options: {}) def queries_for(user_id, label: nil, options: {})
SavedSearch searches = SavedSearch.where(user_id: user_id)
.where(user_id: user_id) searches = searches.labeled(label) if label.present?
.labeled(label) queries = searches.pluck(:query).map { |query| PostQueryBuilder.normalize_query(query, sort: true) }
.pluck(:query) queries.sort.uniq
.map {|x| PostQueryBuilder.normalize_query(x, sort: true)}
.sort
.uniq
end end
end end
@@ -160,7 +156,7 @@ class SavedSearch < ApplicationRecord
validate :validate_count validate :validate_count
before_validation :normalize_query before_validation :normalize_query
before_validation :normalize_labels before_validation :normalize_labels
scope :labeled, ->(label) { label.present? ? where("labels @> string_to_array(?, '~~~~')", label) : where("true") } scope :labeled, ->(label) { where_array_includes_any_lower(:labels, [normalize_label(label)]) }
def validate_count def validate_count
if user.saved_searches.count + 1 > user.max_saved_searches if user.saved_searches.count + 1 > user.max_saved_searches

View File

@@ -597,34 +597,28 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match([post], "pixiv_id:none") assert_tag_match([post], "pixiv_id:none")
end end
context "saved searches" do should "return posts for the search: metatag" do
setup do @post1 = create(:post, tag_string: "aaa")
@post1 = create(:post, tag_string: "aaa") @post2 = create(:post, tag_string: "bbb")
@post2 = create(:post, tag_string: "bbb") create(:saved_search, query: "aaa", labels: ["zzz"], user: CurrentUser.user)
create(:saved_search, query: "aaa", labels: ["zzz"], user: CurrentUser.user) create(:saved_search, query: "bbb", user: CurrentUser.user)
create(:saved_search, query: "bbb", user: CurrentUser.user)
end
context "labeled" do Redis.any_instance.stubs(:exists).with("search:aaa").returns(true)
should "work" do Redis.any_instance.stubs(:exists).with("search:bbb").returns(true)
SavedSearch.expects(:post_ids_for).with(CurrentUser.id, label: "zzz").returns([@post1.id]) Redis.any_instance.stubs(:smembers).with("search:aaa").returns([@post1.id])
assert_tag_match([@post1], "search:zzz") Redis.any_instance.stubs(:smembers).with("search:bbb").returns([@post2.id])
end
end
context "missing" do assert_tag_match([@post1], "search:zzz")
should "work" do assert_tag_match([@post1], "search:ZZZ")
SavedSearch.expects(:post_ids_for).with(CurrentUser.id, label: "uncategorized").returns([@post2.id]) assert_tag_match([@post2, @post1], "search:all")
assert_tag_match([@post2], "search:uncategorized") assert_tag_match([@post2, @post1], "search:ALL")
end assert_tag_match([], "search:does_not_exist")
end
context "all" do assert_tag_match([@post2], "-search:zzz")
should "work" do assert_tag_match([@post2], "-search:ZZZ")
SavedSearch.expects(:post_ids_for).with(CurrentUser.id).returns([@post1.id, @post2.id]) assert_tag_match([], "-search:all")
assert_tag_match([@post2, @post1], "search:all") assert_tag_match([], "-search:ALL")
end assert_tag_match([@post2, @post1], "-search:does_not_exist")
end
end end
should "return posts for a rating:<s|q|e> metatag" do should "return posts for a rating:<s|q|e> metatag" do