Merge branch 'master' of github.com:r888888888/danbooru
This commit is contained in:
@@ -101,6 +101,21 @@ class PostQueryBuilder
|
|||||||
relation
|
relation
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_saved_search_relation(saved_searches, relation)
|
||||||
|
saved_searches.each do |saved_search|
|
||||||
|
if saved_search == "all"
|
||||||
|
post_ids = SavedSearch.post_ids(CurrentUser.id)
|
||||||
|
else
|
||||||
|
post_ids = SavedSearch.post_ids(CurrentUser.id, saved_search)
|
||||||
|
end
|
||||||
|
|
||||||
|
post_ids = [0] if post_ids.empty?
|
||||||
|
relation = relation.where(["posts.id IN (?)", post_ids])
|
||||||
|
end
|
||||||
|
|
||||||
|
relation
|
||||||
|
end
|
||||||
|
|
||||||
def build(relation = nil)
|
def build(relation = nil)
|
||||||
unless query_string.is_a?(Hash)
|
unless query_string.is_a?(Hash)
|
||||||
q = Tag.parse_query(query_string)
|
q = Tag.parse_query(query_string)
|
||||||
@@ -208,6 +223,11 @@ class PostQueryBuilder
|
|||||||
has_constraints!
|
has_constraints!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if q[:saved_searches]
|
||||||
|
relation = add_saved_search_relation(q[:saved_searches], relation)
|
||||||
|
has_constraints!
|
||||||
|
end
|
||||||
|
|
||||||
if q[:uploader_id_neg]
|
if q[:uploader_id_neg]
|
||||||
relation = relation.where("posts.uploader_id not in (?)", q[:uploader_id_neg])
|
relation = relation.where("posts.uploader_id not in (?)", q[:uploader_id_neg])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ class SavedSearch < ActiveRecord::Base
|
|||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def refresh_listbooru(user_id, name)
|
def refresh_listbooru(user_id)
|
||||||
return unless Danbooru.config.listbooru_auth_key
|
return unless Danbooru.config.listbooru_auth_key
|
||||||
|
user = User.find(user_id)
|
||||||
|
return unless user.is_gold?
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
:user_id => user_id,
|
:user_id => user_id,
|
||||||
:name => name,
|
|
||||||
:key => Danbooru.config.listbooru_auth_key
|
:key => Danbooru.config.listbooru_auth_key
|
||||||
}
|
}
|
||||||
uri = URI.parse("#{Danbooru.config.listbooru_server}/users")
|
uri = URI.parse("#{Danbooru.config.listbooru_server}/users")
|
||||||
@@ -87,7 +89,27 @@ class SavedSearch < ActiveRecord::Base
|
|||||||
Tag.scan_query(tag_query).join(" ")
|
Tag.scan_query(tag_query).join(" ")
|
||||||
end
|
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
|
def normalize
|
||||||
|
self.category = category.strip.gsub(/\s+/, "_").downcase if category
|
||||||
self.tag_query = SavedSearch.normalize(tag_query)
|
self.tag_query = SavedSearch.normalize(tag_query)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -108,23 +130,4 @@ class SavedSearch < ActiveRecord::Base
|
|||||||
user.update_attribute(:has_saved_searches, false)
|
user.update_attribute(:has_saved_searches, false)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class Tag < ActiveRecord::Base
|
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"
|
SUBQUERY_METATAGS = "commenter|comm|noter|noteupdater|artcomm"
|
||||||
attr_accessible :category, :as => [:moderator, :janitor, :gold, :member, :anonymous, :default, :builder, :admin]
|
attr_accessible :category, :as => [:moderator, :janitor, :gold, :member, :anonymous, :default, :builder, :admin]
|
||||||
attr_accessible :is_locked, :as => [:moderator, :admin]
|
attr_accessible :is_locked, :as => [:moderator, :admin]
|
||||||
@@ -493,6 +493,10 @@ class Tag < ActiveRecord::Base
|
|||||||
q[:subscriptions] ||= []
|
q[:subscriptions] ||= []
|
||||||
q[:subscriptions] << $2
|
q[:subscriptions] << $2
|
||||||
|
|
||||||
|
when "search"
|
||||||
|
q[:saved_searches] ||= []
|
||||||
|
q[:saved_searches] << $2
|
||||||
|
|
||||||
when "md5"
|
when "md5"
|
||||||
q[:md5] = $2.downcase.split(/,/)
|
q[:md5] = $2.downcase.split(/,/)
|
||||||
|
|
||||||
|
|||||||
@@ -460,10 +460,8 @@ class User < ActiveRecord::Base
|
|||||||
def max_saved_searches
|
def max_saved_searches
|
||||||
if is_platinum?
|
if is_platinum?
|
||||||
1_000
|
1_000
|
||||||
elsif is_gold?
|
|
||||||
200
|
|
||||||
else
|
else
|
||||||
100
|
250
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
6
app/views/saved_searches/_secondary_links.html.erb
Normal file
6
app/views/saved_searches/_secondary_links.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<% content_for(:secondary_links) do %>
|
||||||
|
<menu>
|
||||||
|
<li><%= link_to "Gallery", posts_path(:tags => "search:all") %></li>
|
||||||
|
<li><%= link_to "Listing", saved_searches_path %></li>
|
||||||
|
</menu>
|
||||||
|
<% end %>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= render "users/secondary_links" %>
|
<%= render "secondary_links" %>
|
||||||
|
|
||||||
<% content_for(:page_title) do %>
|
<% content_for(:page_title) do %>
|
||||||
Edit Saved Search - <%= Danbooru.config.app_name %>
|
Edit Saved Search - <%= Danbooru.config.app_name %>
|
||||||
|
|||||||
@@ -3,7 +3,13 @@
|
|||||||
<h1>Saved Searches</h1>
|
<h1>Saved Searches</h1>
|
||||||
|
|
||||||
<% @categories.each do |category, saved_searches| %>
|
<% @categories.each do |category, saved_searches| %>
|
||||||
<h2><%= category.present? ? category : "Uncategorized" %></h2>
|
<h2>
|
||||||
|
<% if category.present? %>
|
||||||
|
<%= link_to category.tr("_", " "), posts_path(:tags => "search:#{category}") %>
|
||||||
|
<% else %>
|
||||||
|
Uncategorized
|
||||||
|
<% end %>
|
||||||
|
</h2>
|
||||||
<table class="striped" width="100%">
|
<table class="striped" width="100%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -17,7 +23,8 @@
|
|||||||
<tr id="saved-search-<%= saved_search.id %>">
|
<tr id="saved-search-<%= saved_search.id %>">
|
||||||
<td><%= link_to saved_search.tag_query, posts_path(:tags => saved_search.tag_query) %></td>
|
<td><%= link_to saved_search.tag_query, posts_path(:tags => saved_search.tag_query) %></td>
|
||||||
<td>
|
<td>
|
||||||
<%= 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 %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
@@ -27,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= render "users/secondary_links" %>
|
<%= render "secondary_links" %>
|
||||||
|
|
||||||
<% content_for(:page_title) do %>
|
<% content_for(:page_title) do %>
|
||||||
Saved Searches - <%= Danbooru.config.app_name %>
|
Saved Searches - <%= Danbooru.config.app_name %>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module Danbooru
|
|||||||
class Configuration
|
class Configuration
|
||||||
# The version of this Danbooru.
|
# The version of this Danbooru.
|
||||||
def version
|
def version
|
||||||
"2.96.0"
|
"2.97.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
# The name of this Danbooru.
|
# The name of this Danbooru.
|
||||||
|
|||||||
15
script/fixes/039_fix_saved_search_categories.rb
Normal file
15
script/fixes/039_fix_saved_search_categories.rb
Normal file
@@ -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
|
||||||
5
test/factories/saved_search.rb
Normal file
5
test/factories/saved_search.rb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
FactoryGirl.define do
|
||||||
|
factory(:saved_search) do
|
||||||
|
tag_query "aaa"
|
||||||
|
end
|
||||||
|
end
|
||||||
42
test/fixtures/vcr_cassettes/unit/saved_searches/get-named.yml
vendored
Normal file
42
test/fixtures/vcr_cassettes/unit/saved_searches/get-named.yml
vendored
Normal file
@@ -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
|
||||||
42
test/fixtures/vcr_cassettes/unit/saved_searches/get-unnamed.yml
vendored
Normal file
42
test/fixtures/vcr_cassettes/unit/saved_searches/get-unnamed.yml
vendored
Normal file
@@ -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
|
||||||
@@ -1371,6 +1371,24 @@ class PostTest < ActiveSupport::TestCase
|
|||||||
assert_equal(1, relation.count)
|
assert_equal(1, relation.count)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "return posts for a <search> 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 <search> 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
|
should "return posts for a particular rating" do
|
||||||
post1 = FactoryGirl.create(:post, :rating => "s")
|
post1 = FactoryGirl.create(:post, :rating => "s")
|
||||||
post2 = FactoryGirl.create(:post, :rating => "q")
|
post2 = FactoryGirl.create(:post, :rating => "q")
|
||||||
|
|||||||
@@ -1,6 +1,31 @@
|
|||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class SavedSearchTest < ActiveSupport::TestCase
|
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
|
context "Creating a saved search" do
|
||||||
setup do
|
setup do
|
||||||
@user = FactoryGirl.create(:user)
|
@user = FactoryGirl.create(:user)
|
||||||
|
|||||||
Reference in New Issue
Block a user