From cd501fe27beab2ec6a9cee5342135b475eafa9f4 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 14 Jun 2020 01:06:51 -0500 Subject: [PATCH] iqdb: switch to Danbooru::Http. --- app/controllers/iqdb_queries_controller.rb | 2 +- app/logical/iqdb_proxy.rb | 33 +++++++----- .../iqdb_queries_controller_test.rb | 52 +++++-------------- test/test_helpers/iqdb_test_helper.rb | 10 ++-- 4 files changed, 37 insertions(+), 60 deletions(-) diff --git a/app/controllers/iqdb_queries_controller.rb b/app/controllers/iqdb_queries_controller.rb index 21a063838..659c22950 100644 --- a/app/controllers/iqdb_queries_controller.rb +++ b/app/controllers/iqdb_queries_controller.rb @@ -5,7 +5,7 @@ class IqdbQueriesController < ApplicationController # XXX allow bare search params for backwards compatibility. search_params.merge!(params.slice(:url, :image_url, :file_url, :post_id, :limit, :similarity, :high_similarity).permit!) - @high_similarity_matches, @low_similarity_matches, @matches = IqdbProxy.search(search_params) + @high_similarity_matches, @low_similarity_matches, @matches = IqdbProxy.new.search(search_params) respond_with(@matches, template: "iqdb_queries/show") end diff --git a/app/logical/iqdb_proxy.rb b/app/logical/iqdb_proxy.rb index a812596ff..e1b1f195f 100644 --- a/app/logical/iqdb_proxy.rb +++ b/app/logical/iqdb_proxy.rb @@ -1,19 +1,23 @@ class IqdbProxy class Error < StandardError; end + attr_reader :http, :iqdbs_server - def self.enabled? - Danbooru.config.iqdbs_server.present? + def initialize(http: Danbooru::Http.new, iqdbs_server: Danbooru.config.iqdbs_server) + @iqdbs_server = iqdbs_server + @http = http end - def self.download(url, type) + def enabled? + iqdbs_server.present? + end + + def download(url, type) download = Downloads::File.new(url) file, strategy = download.download!(url: download.send(type)) file end - def self.search(params) - raise NotImplementedError, "the IQDBs service isn't configured" unless enabled? - + def search(params) limit = params[:limit]&.to_i&.clamp(1, 1000) || 20 similarity = params[:similarity]&.to_f&.clamp(0.0, 100.0) || 0.0 high_similarity = params[:high_similarity]&.to_f&.clamp(0.0, 100.0) || 65.0 @@ -46,15 +50,18 @@ class IqdbProxy file.try(:close) end - def self.query(params) - response = HTTParty.post("#{Danbooru.config.iqdbs_server}/similar", body: params, **Danbooru.config.httparty_options) - raise Error, "IQDB error: #{response.code} #{response.message}" unless response.success? - raise Error, "IQDB error: #{response.parsed_response["error"]}" if response.parsed_response.is_a?(Hash) - raise Error, "IQDB error: #{response.parsed_response.first}" if response.parsed_response.try(:first).is_a?(String) - response.parsed_response + def query(params) + raise NotImplementedError, "the IQDBs service isn't configured" unless enabled? + response = http.post("#{iqdbs_server}/similar", body: params) + + raise Error, "IQDB error: #{response.status}" if response.status != 200 + raise Error, "IQDB error: #{response.parse["error"]}" if response.parse.is_a?(Hash) + raise Error, "IQDB error: #{response.parse.first}" if response.parse.try(:first).is_a?(String) + + response.parse end - def self.decorate_posts(json) + def decorate_posts(json) post_ids = json.map { |match| match["post_id"] } posts = Post.where(id: post_ids).group_by(&:id).transform_values(&:first) diff --git a/test/functional/iqdb_queries_controller_test.rb b/test/functional/iqdb_queries_controller_test.rb index eb0f3d206..e9af6770d 100644 --- a/test/functional/iqdb_queries_controller_test.rb +++ b/test/functional/iqdb_queries_controller_test.rb @@ -3,61 +3,33 @@ require 'test_helper' class IqdbQueriesControllerTest < ActionDispatch::IntegrationTest context "The iqdb controller" do setup do - Danbooru.config.stubs(:iqdbs_server).returns("https://karasuma.donmai.us") @user = create(:user) - @posts = as(@user) { create_list(:post, 2) } + @post = as(@user) { create(:post) } end context "show action" do context "with a url parameter" do - setup do - @url = "https://google.com" - @params = { url: @url } - @mocked_response = [{ - "post" => @posts[0], - "post_id" => @posts[0].id, - "score" => 1 - }] - end - should "render a response" do - IqdbProxy.expects(:query).returns(@mocked_response) - get_auth iqdb_queries_path, @user, as: :javascript, params: @params + @url = "https://google.com" + @matches = [{ "post_id" => @post.id, "width" => 128, "height" => 128, "score" => 95.0 }] + mock_iqdb_matches(@matches) + + get_auth iqdb_queries_path, @user, as: :javascript, params: { url: @url } assert_response :success - assert_select("#post_#{@posts[0].id}") + assert_select("#post_#{@post.id}") end end context "with a post_id parameter" do - setup do - @params = { post_id: @posts[0].id } - @url = @posts[0].preview_file_url - @mocked_response = [{ - "post" => @posts[0], - "post_id" => @posts[0].id, - "score" => 1 - }] - end - should "redirect to iqdbs" do - IqdbProxy.expects(:query).returns(@mocked_response) - get_auth iqdb_queries_path, @user, params: @params + @matches = [{ "post_id" => @post.id, "width" => 128, "height" => 128, "score" => 95.0 }] + mock_iqdb_matches(@matches) + + get_auth iqdb_queries_path, @user, params: { post_id: @post.id } assert_response :success - assert_select("#post_#{@posts[0].id}") - end - end - - context "with matches" do - setup do - json = @posts.map {|x| {"post_id" => x.id, "score" => 1}}.to_json - @params = { matches: json } - end - - should "render with matches" do - get_auth iqdb_queries_path, @user, params: @params - assert_response :success + assert_select("#post_#{@post.id}") end end end diff --git a/test/test_helpers/iqdb_test_helper.rb b/test/test_helpers/iqdb_test_helper.rb index 1feeffabc..4b52eade7 100644 --- a/test/test_helpers/iqdb_test_helper.rb +++ b/test/test_helpers/iqdb_test_helper.rb @@ -21,11 +21,9 @@ module IqdbTestHelper Danbooru.config.stubs(:iqdbs_server).returns("http://localhost:3004") end - def mock_iqdb_matches!(post_or_source, matches) - source = post_or_source.is_a?(Post) ? post_or_source.preview_file_url : post_or_source - url = "http://localhost:3004/similar?key=hunter2&url=#{CGI.escape source}&ref" - body = matches.map { |post| { post_id: post.id } }.to_json - - stub_request(:get, url).to_return(body: body) + def mock_iqdb_matches(matches) + Danbooru.config.stubs(:iqdbs_server).returns("http://localhost:3004") + response = HTTP::Response.new(status: 200, body: matches.to_json, headers: { "Content-Type": "application/json" }, version: "1.1") + HTTP::Client.any_instance.stubs(:post).returns(response) end end