From 49ba8333c0f3cad3202938d614d19b17fb1e2799 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Mon, 23 Nov 2015 11:08:31 -0800 Subject: [PATCH 1/7] fix saved search refresh --- app/models/saved_search.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/saved_search.rb b/app/models/saved_search.rb index 39412c80a..0363668a2 100644 --- a/app/models/saved_search.rb +++ b/app/models/saved_search.rb @@ -3,11 +3,10 @@ class SavedSearch < ActiveRecord::Base extend ActiveSupport::Concern module ClassMethods - def refresh_listbooru(user_id, name) + def refresh_listbooru(user_id) return unless Danbooru.config.listbooru_auth_key params = { :user_id => user_id, - :name => name, :key => Danbooru.config.listbooru_auth_key } uri = URI.parse("#{Danbooru.config.listbooru_server}/users") From 268a8213542beab59be034dff17c65b780745c93 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Mon, 23 Nov 2015 11:18:32 -0800 Subject: [PATCH 2/7] new version --- config/danbooru_default_config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index 202d7248b..70863f8fc 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -4,7 +4,7 @@ module Danbooru class Configuration # The version of this Danbooru. def version - "2.96.0" + "2.97.0" end # The name of this Danbooru. From 21ab11d92a0054148c5bd5225dc9a1470e04cae9 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Tue, 24 Nov 2015 12:55:18 -0800 Subject: [PATCH 3/7] 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) From 90eb374d063667adc1e856c66290a8109c6180d3 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Tue, 24 Nov 2015 13:11:34 -0800 Subject: [PATCH 4/7] enabled saved search processing only for gold users --- app/models/saved_search.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/saved_search.rb b/app/models/saved_search.rb index f9d43e38e..61a2b2f45 100644 --- a/app/models/saved_search.rb +++ b/app/models/saved_search.rb @@ -5,6 +5,9 @@ class SavedSearch < ActiveRecord::Base module ClassMethods def refresh_listbooru(user_id) return unless Danbooru.config.listbooru_auth_key + user = User.find(user_id) + return unless user.is_gold? + params = { :user_id => user_id, :key => Danbooru.config.listbooru_auth_key From 89794a7ef289dad2b9d281f9c327c176562b7bf3 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Tue, 24 Nov 2015 16:26:04 -0800 Subject: [PATCH 5/7] add saved search gallery link, can only view your own saved searches, normalize saved search categories --- app/logical/post_query_builder.rb | 12 +++--------- app/models/saved_search.rb | 1 + app/models/user.rb | 4 +--- .../saved_searches/_secondary_links.html.erb | 6 ++++++ app/views/saved_searches/edit.html.erb | 2 +- app/views/saved_searches/index.html.erb | 10 ++++++++-- script/fixes/039_fix_saved_search_categories.rb | 15 +++++++++++++++ 7 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 app/views/saved_searches/_secondary_links.html.erb create mode 100644 script/fixes/039_fix_saved_search_categories.rb diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index 9b345e1ef..da7b5148a 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -103,16 +103,10 @@ class PostQueryBuilder 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) + if saved_search == "all" + post_ids = SavedSearch.post_ids(CurrentUser.id) else - user = User.find_by_name(saved_search) - return relation if user.nil? - post_ids = SavedSearch.post_ids(user.id, nil) + post_ids = SavedSearch.post_ids(CurrentUser.id, saved_search) end post_ids = [0] if post_ids.empty? diff --git a/app/models/saved_search.rb b/app/models/saved_search.rb index 61a2b2f45..4b0f9af32 100644 --- a/app/models/saved_search.rb +++ b/app/models/saved_search.rb @@ -109,6 +109,7 @@ class SavedSearch < ActiveRecord::Base end def normalize + self.category = category.strip.gsub(/\s+/, "_").downcase if category self.tag_query = SavedSearch.normalize(tag_query) end diff --git a/app/models/user.rb b/app/models/user.rb index 9e61f6dac..9883eda43 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -460,10 +460,8 @@ class User < ActiveRecord::Base def max_saved_searches if is_platinum? 1_000 - elsif is_gold? - 200 else - 100 + 250 end end diff --git a/app/views/saved_searches/_secondary_links.html.erb b/app/views/saved_searches/_secondary_links.html.erb new file mode 100644 index 000000000..8a6c57c64 --- /dev/null +++ b/app/views/saved_searches/_secondary_links.html.erb @@ -0,0 +1,6 @@ +<% content_for(:secondary_links) do %> + +
  • <%= link_to "Gallery", posts_path(:tags => "search:all") %>
  • +
  • <%= link_to "Listing", saved_searches_path %>
  • +
    +<% end %> diff --git a/app/views/saved_searches/edit.html.erb b/app/views/saved_searches/edit.html.erb index f59a03b9a..989a3861a 100644 --- a/app/views/saved_searches/edit.html.erb +++ b/app/views/saved_searches/edit.html.erb @@ -12,7 +12,7 @@ -<%= render "users/secondary_links" %> +<%= render "secondary_links" %> <% content_for(:page_title) do %> Edit Saved Search - <%= Danbooru.config.app_name %> diff --git a/app/views/saved_searches/index.html.erb b/app/views/saved_searches/index.html.erb index 48b04ae70..23e9c7ebb 100644 --- a/app/views/saved_searches/index.html.erb +++ b/app/views/saved_searches/index.html.erb @@ -3,7 +3,13 @@

    Saved Searches

    <% @categories.each do |category, saved_searches| %> -

    <%= category.present? ? category : "Uncategorized" %>

    +

    + <% if category.present? %> + <%= link_to category, posts_path(:tags => "search:#{category}") %> + <% else %> + Uncategorized + <% end %> +

    @@ -27,7 +33,7 @@ -<%= render "users/secondary_links" %> +<%= render "secondary_links" %> <% content_for(:page_title) do %> Saved Searches - <%= Danbooru.config.app_name %> diff --git a/script/fixes/039_fix_saved_search_categories.rb b/script/fixes/039_fix_saved_search_categories.rb new file mode 100644 index 000000000..b6bb38412 --- /dev/null +++ b/script/fixes/039_fix_saved_search_categories.rb @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config', 'environment')) + +ActiveRecord::Base.connection.execute("set statement_timeout = 0") + +CurrentUser.user = User.admins.first +CurrentUser.ip_addr = "127.0.0.1" + +SavedSearch.where("category is not null and category <> ''").find_each do |ss| + print ss.category + " -> " + ss.normalize + puts ss.category + ss.save +end From ef4936686833fae4ab63ace07c425f5dafbb8a50 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Tue, 24 Nov 2015 16:56:25 -0800 Subject: [PATCH 6/7] pretty print saved search categories --- app/views/saved_searches/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/saved_searches/index.html.erb b/app/views/saved_searches/index.html.erb index 23e9c7ebb..70cedc96c 100644 --- a/app/views/saved_searches/index.html.erb +++ b/app/views/saved_searches/index.html.erb @@ -5,7 +5,7 @@ <% @categories.each do |category, saved_searches| %>

    <% if category.present? %> - <%= link_to category, posts_path(:tags => "search:#{category}") %> + <%= link_to category.tr("_", " "), posts_path(:tags => "search:#{category}") %> <% else %> Uncategorized <% end %> From d8509addcebf7d52e1b12da8463f33b656c7be98 Mon Sep 17 00:00:00 2001 From: r888888888 Date: Tue, 24 Nov 2015 17:16:12 -0800 Subject: [PATCH 7/7] add link for editing saved search --- app/views/saved_searches/index.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/saved_searches/index.html.erb b/app/views/saved_searches/index.html.erb index 70cedc96c..db452e677 100644 --- a/app/views/saved_searches/index.html.erb +++ b/app/views/saved_searches/index.html.erb @@ -23,7 +23,8 @@

    <% end %>
    <%= link_to saved_search.tag_query, posts_path(:tags => saved_search.tag_query) %> - <%= link_to "delete", saved_search_path(saved_search), :method => :delete, :remote => true %> + <%= link_to "edit", edit_saved_search_path(saved_search) %> + | <%= link_to "delete", saved_search_path(saved_search), :method => :delete, :remote => true %>