From 21ab11d92a0054148c5bd5225dc9a1470e04cae9 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Tue, 24 Nov 2015 12:55:18 -0800 Subject: [PATCH] add support for saved search metatag + tests --- app/logical/post_query_builder.rb | 26 ++++++++++++ app/models/saved_search.rb | 38 ++++++++--------- app/models/tag.rb | 6 ++- test/factories/saved_search.rb | 5 +++ .../unit/saved_searches/get-named.yml | 42 +++++++++++++++++++ .../unit/saved_searches/get-unnamed.yml | 42 +++++++++++++++++++ test/unit/post_test.rb | 18 ++++++++ test/unit/saved_search_test.rb | 25 +++++++++++ 8 files changed, 182 insertions(+), 20 deletions(-) create mode 100644 test/factories/saved_search.rb create mode 100644 test/fixtures/vcr_cassettes/unit/saved_searches/get-named.yml create mode 100644 test/fixtures/vcr_cassettes/unit/saved_searches/get-unnamed.yml diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index d7d7c5da9..9b345e1ef 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -101,6 +101,27 @@ class PostQueryBuilder relation end + def add_saved_search_relation(saved_searches, relation) + saved_searches.each do |saved_search| + if saved_search =~ /^(.+?):(.+)$/ + user_name = $1 + name = $2 + user = User.find_by_name(user_name) + return relation if user.nil? + post_ids = SavedSearch.post_ids(user.id, name) + else + user = User.find_by_name(saved_search) + return relation if user.nil? + post_ids = SavedSearch.post_ids(user.id, nil) + end + + post_ids = [0] if post_ids.empty? + relation = relation.where(["posts.id IN (?)", post_ids]) + end + + relation + end + def build(relation = nil) unless query_string.is_a?(Hash) q = Tag.parse_query(query_string) @@ -208,6 +229,11 @@ class PostQueryBuilder has_constraints! end + if q[:saved_searches] + relation = add_saved_search_relation(q[:saved_searches], relation) + has_constraints! + end + if q[:uploader_id_neg] relation = relation.where("posts.uploader_id not in (?)", q[:uploader_id_neg]) end diff --git a/app/models/saved_search.rb b/app/models/saved_search.rb index 0363668a2..f9d43e38e 100644 --- a/app/models/saved_search.rb +++ b/app/models/saved_search.rb @@ -86,6 +86,25 @@ class SavedSearch < ActiveRecord::Base Tag.scan_query(tag_query).join(" ") end + def self.post_ids(user_id, name = nil) + params = { + "key" => Danbooru.config.listbooru_auth_key, + "user_id" => user_id, + "name" => name + } + uri = URI.parse("#{Danbooru.config.listbooru_server}/users") + uri.query = URI.encode_www_form(params) + + Net::HTTP.start(uri.host, uri.port) do |http| + resp = http.request_get(uri.request_uri) + if resp.is_a?(Net::HTTPSuccess) + resp.body.scan(/\d+/).map(&:to_i) + else + raise "HTTP error code: #{resp.code} #{resp.message}" + end + end + end + def normalize self.tag_query = SavedSearch.normalize(tag_query) end @@ -107,23 +126,4 @@ class SavedSearch < ActiveRecord::Base user.update_attribute(:has_saved_searches, false) end end - - def post_ids - params = { - "key" => Danbooru.config.listbooru_auth_key, - "user_id" => user_id, - "name" => category - } - uri = URI.parse("#{Danbooru.config.listbooru_server}/users") - uri.query = URI.encode_www_form(params) - - Net::HTTP.start(uri.host, uri.port) do |http| - resp = http.request_get(uri.request_uri) - if resp.is_a?(Net::HTTPSuccess) - resp.body.scan(/\d+/) - else - raise "HTTP error code: #{resp.code} #{resp.message}" - end - end - end end diff --git a/app/models/tag.rb b/app/models/tag.rb index f08a3c421..ff946eae0 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -1,5 +1,5 @@ class Tag < ActiveRecord::Base - METATAGS = "-user|user|-approver|approver|commenter|comm|noter|noteupdater|artcomm|-pool|pool|ordpool|-favgroup|favgroup|-fav|fav|ordfav|sub|md5|-rating|rating|-locked|locked|width|height|mpixels|ratio|score|favcount|filesize|source|-source|id|-id|date|age|order|limit|-status|status|tagcount|gentags|arttags|chartags|copytags|parent|-parent|child|pixiv_id|pixiv" + METATAGS = "-user|user|-approver|approver|commenter|comm|noter|noteupdater|artcomm|-pool|pool|ordpool|-favgroup|favgroup|-fav|fav|ordfav|sub|md5|-rating|rating|-locked|locked|width|height|mpixels|ratio|score|favcount|filesize|source|-source|id|-id|date|age|order|limit|-status|status|tagcount|gentags|arttags|chartags|copytags|parent|-parent|child|pixiv_id|pixiv|search" SUBQUERY_METATAGS = "commenter|comm|noter|noteupdater|artcomm" attr_accessible :category, :as => [:moderator, :janitor, :gold, :member, :anonymous, :default, :builder, :admin] attr_accessible :is_locked, :as => [:moderator, :admin] @@ -493,6 +493,10 @@ class Tag < ActiveRecord::Base q[:subscriptions] ||= [] q[:subscriptions] << $2 + when "search" + q[:saved_searches] ||= [] + q[:saved_searches] << $2 + when "md5" q[:md5] = $2.downcase.split(/,/) diff --git a/test/factories/saved_search.rb b/test/factories/saved_search.rb new file mode 100644 index 000000000..7940ca213 --- /dev/null +++ b/test/factories/saved_search.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory(:saved_search) do + tag_query "aaa" + end +end diff --git a/test/fixtures/vcr_cassettes/unit/saved_searches/get-named.yml b/test/fixtures/vcr_cassettes/unit/saved_searches/get-named.yml new file mode 100644 index 000000000..04986f09b --- /dev/null +++ b/test/fixtures/vcr_cassettes/unit/saved_searches/get-named.yml @@ -0,0 +1,42 @@ +--- +http_interactions: +- request: + method: get + uri: http://localhost:3001/users?key=blahblahblah&name=blah&user_id=1 + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: 'OK ' + headers: + Content-Type: + - text/html;charset=utf-8 + Content-Length: + - '7' + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + Server: + - WEBrick/1.3.1 (Ruby/2.1.3/2014-09-19) + Date: + - Tue, 24 Nov 2015 20:43:18 GMT + Connection: + - Keep-Alive + body: + encoding: UTF-8 + string: '["1","2","3","4"]' + http_version: + recorded_at: Tue, 24 Nov 2015 20:43:18 GMT +recorded_with: VCR 2.9.3 diff --git a/test/fixtures/vcr_cassettes/unit/saved_searches/get-unnamed.yml b/test/fixtures/vcr_cassettes/unit/saved_searches/get-unnamed.yml new file mode 100644 index 000000000..f9e661c10 --- /dev/null +++ b/test/fixtures/vcr_cassettes/unit/saved_searches/get-unnamed.yml @@ -0,0 +1,42 @@ +--- +http_interactions: +- request: + method: get + uri: http://localhost:3001/users?key=blahblahblah&name&user_id=1 + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: 'OK ' + headers: + Content-Type: + - text/html;charset=utf-8 + Content-Length: + - '7' + X-Xss-Protection: + - 1; mode=block + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + Server: + - WEBrick/1.3.1 (Ruby/2.1.3/2014-09-19) + Date: + - Tue, 24 Nov 2015 20:43:18 GMT + Connection: + - Keep-Alive + body: + encoding: UTF-8 + string: '["1","2","3","4"]' + http_version: + recorded_at: Tue, 24 Nov 2015 20:43:18 GMT +recorded_with: VCR 2.9.3 diff --git a/test/unit/post_test.rb b/test/unit/post_test.rb index 86eb369cc..280e21de0 100644 --- a/test/unit/post_test.rb +++ b/test/unit/post_test.rb @@ -1371,6 +1371,24 @@ class PostTest < ActiveSupport::TestCase assert_equal(1, relation.count) end + should "return posts for a metatag" do + SavedSearch.stubs(:update_listbooru_on_create) + post1 = FactoryGirl.create(:post, :tag_string => "aaa") + sub = FactoryGirl.create(:saved_search, :tag_query => "aaa", :name => "zzz", :user_id => CurrentUser.id) + SavedSearch.expects(:post_ids).returns([post1.id]) + relation = Post.tag_match("search:#{CurrentUser.name}") + assert_equal(1, relation.count) + end + + should "return posts for a named metatag" do + SavedSearch.stubs(:update_listbooru_on_create) + post1 = FactoryGirl.create(:post, :tag_string => "aaa") + sub = FactoryGirl.create(:saved_search, :tag_query => "aaa", :name => "zzz", :user_id => CurrentUser.id) + SavedSearch.expects(:post_ids).returns([post1.id]) + relation = Post.tag_match("search:#{CurrentUser.name}:zzz") + assert_equal(1, relation.count) + end + should "return posts for a particular rating" do post1 = FactoryGirl.create(:post, :rating => "s") post2 = FactoryGirl.create(:post, :rating => "q") diff --git a/test/unit/saved_search_test.rb b/test/unit/saved_search_test.rb index 64f3642f3..c850a9bf9 100644 --- a/test/unit/saved_search_test.rb +++ b/test/unit/saved_search_test.rb @@ -1,6 +1,31 @@ require 'test_helper' class SavedSearchTest < ActiveSupport::TestCase + context "Fetching the post ids for a search" do + setup do + Danbooru.config.stubs(:listbooru_auth_key).returns("blahblahblah") + Danbooru.config.stubs(:listbooru_server).returns("http://localhost:3001") + end + + context "with a name" do + should "return a list of ids" do + VCR.use_cassette("unit/saved_searches/get-named", :record => :once) do + post_ids = SavedSearch.post_ids(1, "blah") + assert_equal([1,2,3,4], post_ids) + end + end + end + + context "without a name" do + should "return a list of ids" do + VCR.use_cassette("unit/saved_searches/get-unnamed", :record => :once) do + post_ids = SavedSearch.post_ids(1) + assert_equal([1,2,3,4], post_ids) + end + end + end + end + context "Creating a saved search" do setup do @user = FactoryGirl.create(:user)