Merge pull request #3744 from r888888888/iqdb-drop
Enable drag-and-drop support for IQDB search
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the ForumPostVotesController controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
41
app/assets/stylesheets/specific/dropzone.scss
Normal file
41
app/assets/stylesheets/specific/dropzone.scss
Normal file
@@ -0,0 +1,41 @@
|
||||
#filedropzone {
|
||||
border: 4px dashed #DDD;
|
||||
padding: 0;
|
||||
min-height: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
|
||||
.placeholder {
|
||||
font-style: italic;
|
||||
color: #333;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: darken(#f2dede, 30%);
|
||||
background-color: #f2dede;
|
||||
}
|
||||
|
||||
&.success {
|
||||
border-color: darken(#dff0d8, 30%);
|
||||
background-color: #dff0d8;
|
||||
}
|
||||
}
|
||||
|
||||
.dz-preview {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.dz-progress {
|
||||
height: 20px;
|
||||
width: 300px;
|
||||
border: 1px solid #CCC;
|
||||
|
||||
.dz-upload {
|
||||
background-color: #F5F5FF;
|
||||
display: block;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,9 @@ div#c-iqdb-queries {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#filedropzone {
|
||||
margin: 1em 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,48 +34,6 @@ div#c-uploads {
|
||||
div.field_with_errors {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#filedropzone {
|
||||
border: 4px dashed #DDD;
|
||||
padding: 0;
|
||||
min-height: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
|
||||
.placeholder {
|
||||
font-style: italic;
|
||||
color: #333;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: darken(#f2dede, 30%);
|
||||
background-color: #f2dede;
|
||||
}
|
||||
|
||||
&.success {
|
||||
border-color: darken(#dff0d8, 30%);
|
||||
background-color: #dff0d8;
|
||||
}
|
||||
}
|
||||
|
||||
.dz-preview {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.dz-progress {
|
||||
height: 20px;
|
||||
width: 300px;
|
||||
border: 1px solid #CCC;
|
||||
|
||||
.dz-upload {
|
||||
background-color: #F5F5FF;
|
||||
display: block;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div#a-index {
|
||||
|
||||
@@ -1,29 +1,12 @@
|
||||
# todo: move this to iqdbs
|
||||
class IqdbQueriesController < ApplicationController
|
||||
respond_to :html, :json, :xml
|
||||
|
||||
def show
|
||||
@results = find_similar
|
||||
|
||||
respond_with(@results) do |fmt|
|
||||
fmt.html { render :layout => false, :action => "create_by_url" }
|
||||
fmt.js { render :layout => false, :action => "create_by_post" }
|
||||
if params[:matches]
|
||||
@matches = JSON.parse(params[:matches])
|
||||
@matches = @matches.map {|x| [Post.find(x[0]), x[1]]}
|
||||
end
|
||||
end
|
||||
|
||||
def check
|
||||
@results = find_similar
|
||||
respond_with(@results)
|
||||
end
|
||||
|
||||
# Support both POST /iqdb_queries and GET /iqdb_queries.
|
||||
alias_method :create, :show
|
||||
|
||||
protected
|
||||
def find_similar
|
||||
return [] if params[:url].blank? && params[:post_id].blank?
|
||||
|
||||
params[:url] = Post.find(params[:post_id]).preview_file_url if params[:post_id].present?
|
||||
Iqdb::Download.find_similar(params[:url])
|
||||
respond_with(@matches)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -192,7 +192,7 @@ class UploadService
|
||||
# in case this upload never finishes processing, we need to delete the
|
||||
# distributed files in the future
|
||||
Danbooru.config.other_server_hosts.each do |host|
|
||||
UploadService::Utils.delay(queue: host, run_at: 10.minutes.from_now).delete_file(upload.md5, upload.file_ext, upload.id)
|
||||
UploadService::Utils.delay(queue: host, run_at: 30.minutes.from_now).delete_file(upload.md5, upload.file_ext, upload.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<div id="c-iqdb-queries">
|
||||
<div id="a-check">
|
||||
<h1>IQDB Queries</h1>
|
||||
<section>
|
||||
<%= form_tag(check_iqdb_queries_path, :method => :get, :class => "simple_form inline-form" ) do %>
|
||||
<div class="input string optional">
|
||||
<%= label_tag "url", "URL", class: "string optional" %>
|
||||
<%= text_field_tag "url", params[:url] %>
|
||||
</div>
|
||||
<div class="input string optional">
|
||||
<%= label_tag "post_id", "Post ID", class: "string optional" %>
|
||||
<%= text_field_tag "post_id", params[:post_id] %>
|
||||
</div>
|
||||
<%= submit_tag "Check" %>
|
||||
<% end %>
|
||||
</section>
|
||||
<% if params[:url].present? || params[:post_id].present? %>
|
||||
<section>
|
||||
<h2>Similar results</h2>
|
||||
<% if @results.any? %>
|
||||
<% @results.each do |match| %>
|
||||
<%= PostPresenter.preview(match[:post], :tags => "status:any", :size => true, :similarity => match[:score]) %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p>No matches found</p>
|
||||
<% end %>
|
||||
</section>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% content_for(:page_title) do %>
|
||||
IQDB Queries - <%= Danbooru.config.app_name %>
|
||||
<% end %>
|
||||
78
app/views/iqdb_queries/show.html.erb
Normal file
78
app/views/iqdb_queries/show.html.erb
Normal file
@@ -0,0 +1,78 @@
|
||||
<div id="c-iqdb-queries">
|
||||
<div id="a-check">
|
||||
<h1>Similar Images Search</h1>
|
||||
<section>
|
||||
<p>You can upload a file or paste a URL to perform an image similarity search with every upload on <%= Danbooru.config.app_name %>. Note that this page will redirect you to <%= link_to "IQDBS", Danbooru.config.iqdbs_server %>. You will be redirected back here once the search is executed.</p>
|
||||
|
||||
<%= form_tag("#{Danbooru.config.iqdbs_server}/similar", method: :post, class: "simple_form", multipart: true ) do %>
|
||||
<%= hidden_field_tag "callback", iqdb_queries_url %>
|
||||
|
||||
<div class="input string optional">
|
||||
<%= label_tag "url", "URL", class: "string optional" %>
|
||||
<%= text_field_tag "url", params[:url] %>
|
||||
</div>
|
||||
|
||||
<div class="input string optional fallback">
|
||||
<%= label_tag "file", "File", class: "string optional" %>
|
||||
<%= file_field_tag :file, :size => 50 %>
|
||||
</div>
|
||||
|
||||
<div id="filedropzone">
|
||||
<span class="hint">Drag and drop a file here</span>
|
||||
</div>
|
||||
|
||||
<%= submit_tag "Search" %>
|
||||
<% end %>
|
||||
</section>
|
||||
|
||||
<% if @matches %>
|
||||
<section>
|
||||
<h2>Similar results</h2>
|
||||
<% if @matches.any? %>
|
||||
<% @matches.each do |post, score| %>
|
||||
<%= PostPresenter.preview(post, :tags => "status:any", :size => true, :similarity => score) %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p>No matches found</p>
|
||||
<% end %>
|
||||
</section>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% content_for(:page_title) do %>
|
||||
Similar Images Search - <%= Danbooru.config.app_name %>
|
||||
<% end %>
|
||||
|
||||
<% content_for(:html_header) do %>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
$("#filedropzone").dropzone({
|
||||
paramName: "file",
|
||||
url: "/iqdb_queries",
|
||||
createImageThumbnails: false,
|
||||
addRemoveLinks: false,
|
||||
maxFiles: 1,
|
||||
acceptedFiles: "image/jpeg,image/png,image/gif",
|
||||
previewTemplate: '<div class="dz-preview dz-file-preview"><div class="dz-details"><div class="dz-filename"><span data-dz-name></span></div><div class="dz-size" data-dz-size></div></div><div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div><div class="dz-error-message"><span data-dz-errormessage></span></div></div>',
|
||||
init: function() {
|
||||
$(".fallback").hide();
|
||||
|
||||
this.on("drop", function(event) {
|
||||
$("#filedropzone .placeholder").hide();
|
||||
});
|
||||
this.on("complete", function(file) {
|
||||
$("#filedropzone .dz-progress").hide();
|
||||
});
|
||||
this.on("success", function(file) {
|
||||
$("#filedropzone").addClass("success");
|
||||
});
|
||||
this.on("error", function(file, msg) {
|
||||
$("#filedropzone").addClass("error");
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
||||
@@ -16,6 +16,7 @@
|
||||
<% if CurrentUser.is_moderator? %>
|
||||
<li><%= link_to("Mass Edit", edit_moderator_tag_path) %></li>
|
||||
<% end %>
|
||||
<li><%= link_to("Similar Images Search", iqdb_queries_path) %></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><h1>Post Events</h1></li>
|
||||
@@ -33,7 +34,6 @@
|
||||
<li><%= link_to("Bookmarklet", bookmarklet_path) %></li>
|
||||
<li><%= link_to("User Scripts", wiki_pages_path(title: "about:userscripts")) %></li>
|
||||
<li><%= link_to("API Documentation", wiki_pages_path(:title => "help:api")) %></li>
|
||||
<li><%= link_to("IQDB Queries", check_iqdb_queries_path) %></li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><h1>Artists</h1></li>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<li><%= link_to "Listing", uploads_path %></li>
|
||||
<li><%= link_to "New", new_upload_path %></li>
|
||||
<li><%= link_to "Batch Upload", batch_uploads_path %></li>
|
||||
<li><%= link_to "IQDB", check_iqdb_queries_path %></li>
|
||||
<li><%= link_to "Similar Images Search", iqdb_queries_path %></li>
|
||||
<li><%= link_to "Help", wiki_pages_path(search: { title: "help:upload" }) %></li>
|
||||
</menu>
|
||||
<% end %>
|
||||
|
||||
@@ -154,9 +154,7 @@ Rails.application.routes.draw do
|
||||
resource :visit, :controller => "forum_topic_visits"
|
||||
end
|
||||
resources :ip_bans
|
||||
resource :iqdb_queries, :only => [:create, :show, :check] do
|
||||
get :check
|
||||
end
|
||||
resource :iqdb_queries, :only => [:show]
|
||||
resources :janitor_trials do
|
||||
collection do
|
||||
get :test
|
||||
|
||||
@@ -7,28 +7,12 @@ class IqdbQueriesControllerTest < ActionDispatch::IntegrationTest
|
||||
as_user do
|
||||
@posts = FactoryBot.create_list(:post, 2)
|
||||
end
|
||||
mock_iqdb_service!
|
||||
end
|
||||
|
||||
context "create action" do
|
||||
should "render with a post_id" do
|
||||
mock_iqdb_matches!(@posts[0], @posts)
|
||||
post_auth iqdb_queries_path, @user, params: { post_id: @posts[0].id, format: "js" }
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
should "render with an url" do
|
||||
mock_iqdb_matches!(@posts[0].source, @posts)
|
||||
post_auth iqdb_queries_path, @user, params: { url: @posts[0].source }
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
should "render for a json response" do
|
||||
mock_iqdb_matches!(@posts[0].source, @posts)
|
||||
get_auth iqdb_queries_path, @user, params: { url: @posts[0].source, format: "json" }
|
||||
|
||||
context "show action" do
|
||||
should "render with matches" do
|
||||
json = @posts.map {|x| [x.id, 1]}.to_json
|
||||
get_auth iqdb_queries_path, @user, params: { matches: json }
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user