From a4df18e650de5204ea057b213b90b00548de0e83 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 14 Jun 2020 00:24:15 -0500 Subject: [PATCH] Refactor Reportbooru API clients. * Combine MissedSearchService, PostViewCountService, and PopularSearchService into single ReportbooruService class. * Use Danbooru::Http for these services instead of HTTParty. --- app/controllers/explore/posts_controller.rb | 8 +-- app/controllers/static_controller.rb | 2 +- app/logical/missed_search_service.rb | 29 --------- app/logical/popular_search_service.rb | 61 ------------------- app/logical/post_sets/post.rb | 8 ++- app/logical/post_view_count_service.rb | 25 -------- app/logical/reportbooru_service.rb | 49 +++++++++++++++ .../explore/posts/missed_searches.html.erb | 2 +- app/views/explore/posts/searches.html.erb | 4 +- .../posts/partials/index/_related.html.erb | 4 +- app/views/static/sitemap.xml.erb | 4 +- .../explore/posts_controller_test.rb | 10 +++ test/functional/posts_controller_test.rb | 6 +- test/functional/static_controller_test.rb | 1 + test/test_helper.rb | 2 - test/test_helpers/reportbooru_helper.rb | 26 +++++--- ...ce_test.rb => reportbooru_service_test.rb} | 4 +- 17 files changed, 102 insertions(+), 143 deletions(-) delete mode 100644 app/logical/missed_search_service.rb delete mode 100644 app/logical/popular_search_service.rb delete mode 100644 app/logical/post_view_count_service.rb create mode 100644 app/logical/reportbooru_service.rb rename test/unit/{post_view_count_service_test.rb => reportbooru_service_test.rb} (84%) diff --git a/app/controllers/explore/posts_controller.rb b/app/controllers/explore/posts_controller.rb index c2d7e25c3..e40d6c5b3 100644 --- a/app/controllers/explore/posts_controller.rb +++ b/app/controllers/explore/posts_controller.rb @@ -22,23 +22,23 @@ module Explore def viewed @date, @scale, @min_date, @max_date = parse_date(params) - @posts = PostViewCountService.new.popular_posts(@date) + @posts = ReportbooruService.new.popular_posts(@date) respond_with(@posts) end def searches @date, @scale, @min_date, @max_date = parse_date(params) - @search_service = PopularSearchService.new(@date) + @search_service = ReportbooruService.new end def missed_searches - @search_service = MissedSearchService.new + @search_service = ReportbooruService.new end private def parse_date(params) - date = params[:date].present? ? Date.parse(params[:date]) : Time.zone.today + date = params[:date].present? ? Date.parse(params[:date]) : Date.today scale = params[:scale].in?(["day", "week", "month"]) ? params[:scale] : "day" min_date = date.send("beginning_of_#{scale}") max_date = date.send("next_#{scale}").send("beginning_of_#{scale}") diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index fc151ebd7..8dff5678f 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -17,7 +17,7 @@ class StaticController < ApplicationController end def sitemap - @popular_search_service = PopularSearchService.new(Date.yesterday) + @reportbooru_service = ReportbooruService.new @posts = Post.where("created_at > ?", 1.week.ago).order(score: :desc).limit(200) @posts = @posts.select(&:visible?) render layout: false diff --git a/app/logical/missed_search_service.rb b/app/logical/missed_search_service.rb deleted file mode 100644 index f98e3d395..000000000 --- a/app/logical/missed_search_service.rb +++ /dev/null @@ -1,29 +0,0 @@ -# queries reportbooru to find missed post searches -class MissedSearchService - def self.enabled? - Danbooru.config.reportbooru_server.present? - end - - def initialize - if !MissedSearchService.enabled? - raise NotImplementedError.new("the Reportbooru service isn't configured. Missed searches are not available.") - end - end - - def each_search(&block) - fetch_data.scan(/(.+?) (\d+)\.0\n/).each(&block) - end - - def fetch_data - Cache.get("ms", 1.minute) do - url = URI.parse("#{Danbooru.config.reportbooru_server}/missed_searches") - response = HTTParty.get(url, Danbooru.config.httparty_options.reverse_merge(timeout: 6)) - if response.success? - response = response.body - else - response = "" - end - response.force_encoding("utf-8") - end - end -end diff --git a/app/logical/popular_search_service.rb b/app/logical/popular_search_service.rb deleted file mode 100644 index 026684f3c..000000000 --- a/app/logical/popular_search_service.rb +++ /dev/null @@ -1,61 +0,0 @@ -# queries reportbooru to find popular post searches -class PopularSearchService - attr_reader :date - - def self.enabled? - Danbooru.config.reportbooru_server.present? - end - - def initialize(date) - if !PopularSearchService.enabled? - raise NotImplementedError.new("the Reportbooru service isn't configured. Popular searches are not available.") - end - - @date = date - end - - def each_search(limit = 100, &block) - JSON.parse(fetch_data.to_s).slice(0, limit).each(&block) - end - - def tags - JSON.parse(fetch_data.to_s).map {|x| x[0]} - end - - def fetch_data - return [] unless self.class.enabled? - - dates = date.strftime("%Y-%m-%d") - - data = Cache.get("ps-day-#{dates}", 1.minute) do - url = "#{Danbooru.config.reportbooru_server}/post_searches/rank?date=#{dates}" - response = HTTParty.get(url, Danbooru.config.httparty_options.reverse_merge(timeout: 3)) - if response.success? - response = response.body - else - response = "[]" - end - response - end.to_s.force_encoding("utf-8") - - if data.blank? || data == "[]" - dates = date.yesterday.strftime("%Y-%m-%d") - - data = Cache.get("ps-day-#{dates}", 1.minute) do - url = "#{Danbooru.config.reportbooru_server}/post_searches/rank?date=#{dates}" - response = HTTParty.get(url, Danbooru.config.httparty_options.reverse_merge(timeout: 3)) - if response.success? - response = response.body - else - response = "[]" - end - response - end.to_s.force_encoding("utf-8") - end - - data - rescue StandardError => e - DanbooruLogger.log(e) - return [] - end -end diff --git a/app/logical/post_sets/post.rb b/app/logical/post_sets/post.rb index e12315873..88c415c13 100644 --- a/app/logical/post_sets/post.rb +++ b/app/logical/post_sets/post.rb @@ -169,8 +169,8 @@ module PostSets end def popular_tags - if PopularSearchService.enabled? - PopularSearchService.new(Date.today).tags + if reportbooru_service.enabled? + reportbooru_service.popular_searches(Date.today, limit: MAX_SIDEBAR_TAGS).map(&:first) else frequent_tags end @@ -199,6 +199,10 @@ module PostSets def tag_list_html(**options) tag_set_presenter.tag_list_html(name_only: query.is_metatag?(:search), **options) end + + def reportbooru_service + @reportbooru_service ||= ReportbooruService.new + end end end end diff --git a/app/logical/post_view_count_service.rb b/app/logical/post_view_count_service.rb deleted file mode 100644 index 7e1bbd8c9..000000000 --- a/app/logical/post_view_count_service.rb +++ /dev/null @@ -1,25 +0,0 @@ -class PostViewCountService - attr_reader :http, :reportbooru_server - - def initialize(http: Danbooru::Http.new, reportbooru_server: Danbooru.config.reportbooru_server) - @reportbooru_server = reportbooru_server - @http = http - end - - def enabled? - reportbooru_server.present? - end - - def fetch_rank(date = Date.today) - raise NotImplementedError, "Reportbooru not configured, post views not available." unless enabled? - - response = http.get("#{reportbooru_server}/post_views/rank?date=#{date}") - return [] if response.status != 200 - JSON.parse(response.to_s) - end - - def popular_posts(date = Date.today) - ranking = fetch_rank(date) - ranking.slice(0, 50).map {|x| Post.find(x[0])} - end -end diff --git a/app/logical/reportbooru_service.rb b/app/logical/reportbooru_service.rb new file mode 100644 index 000000000..83c8bc895 --- /dev/null +++ b/app/logical/reportbooru_service.rb @@ -0,0 +1,49 @@ +class ReportbooruService + attr_reader :http, :reportbooru_server + + def initialize(http: Danbooru::Http.new, reportbooru_server: Danbooru.config.reportbooru_server) + @reportbooru_server = reportbooru_server + @http = http + end + + def enabled? + reportbooru_server.present? + end + + def missed_search_rankings(expires_in: 1.minutes) + raise NotImplementedError, "Reportbooru not configured, missed searches not available." unless enabled? + + response = http.cache(expires_in).get("#{reportbooru_server}/missed_searches") + return [] if response.status != 200 + + body = response.to_s.force_encoding("utf-8") + body.lines.map(&:split).map { [_1, _2.to_i] } + end + + def post_search_rankings(date = Date.today, expires_in: 1.minutes) + raise NotImplementedError, "Reportbooru not configured, popular searches not available." unless enabled? + + response = http.cache(expires_in).get("#{reportbooru_server}/post_searches/rank?date=#{date}") + return [] if response.status != 200 + JSON.parse(response.to_s.force_encoding("utf-8")) + end + + def post_view_rankings(date = Date.today, expires_in: 1.minutes) + raise NotImplementedError, "Reportbooru not configured, post views not available." unless enabled? + + response = http.get("#{reportbooru_server}/post_views/rank?date=#{date}") + return [] if response.status != 200 + JSON.parse(response.to_s.force_encoding("utf-8")) + end + + def popular_searches(date = Date.today, limit: 100) + ranking = post_search_rankings(date) + ranking = post_search_rankings(date.yesterday) if ranking.blank? + ranking.take(limit).map(&:first) + end + + def popular_posts(date = Date.today, limit: 100) + ranking = post_view_rankings(date) + ranking.take(limit).map { |x| Post.find(x[0]) } + end +end diff --git a/app/views/explore/posts/missed_searches.html.erb b/app/views/explore/posts/missed_searches.html.erb index 2575d1694..df5e730bd 100644 --- a/app/views/explore/posts/missed_searches.html.erb +++ b/app/views/explore/posts/missed_searches.html.erb @@ -15,7 +15,7 @@ - <% @search_service.each_search do |tags, count| %> + <% @search_service.missed_search_rankings do |tags, count| %> <%= link_to tags, posts_path(:tags => tags) %> diff --git a/app/views/explore/posts/searches.html.erb b/app/views/explore/posts/searches.html.erb index 42770ad5a..18d02f8bf 100644 --- a/app/views/explore/posts/searches.html.erb +++ b/app/views/explore/posts/searches.html.erb @@ -3,7 +3,7 @@
-

Popular Searches - <%= @search_service.date %>

+

Popular Searches - <%= @date %>

@@ -13,7 +13,7 @@ - <% @search_service.each_search do |tags, count| %> + <% @search_service.post_search_rankings(@date) do |tags, count| %> diff --git a/app/views/posts/partials/index/_related.html.erb b/app/views/posts/partials/index/_related.html.erb index d23a094fc..c979869b8 100644 --- a/app/views/posts/partials/index/_related.html.erb +++ b/app/views/posts/partials/index/_related.html.erb @@ -5,10 +5,8 @@ - <% if PopularSearchService.enabled? %> + <% if ReportbooruService.enabled? %>
  • <%= link_to "Searches", searches_explore_posts_path %>
  • - <% end %> - <% if PostViewCountService.enabled? %>
  • <%= link_to "Viewed", viewed_explore_posts_path %>
  • <% end %> <% end %> diff --git a/app/views/static/sitemap.xml.erb b/app/views/static/sitemap.xml.erb index 4c8e1ece5..dc44779c3 100644 --- a/app/views/static/sitemap.xml.erb +++ b/app/views/static/sitemap.xml.erb @@ -16,7 +16,7 @@ <% cache("sitemap", :expires_in => 24.hours) do %> - <% @popular_search_service.each_search do |tags, count| %> + <% @reportbooru_service.post_search_rankings(Date.yesterday) do |tags, count| %> <%= posts_url(tags: tags) %> <%= Date.today %> @@ -38,4 +38,4 @@ <% end %> <% end %> - \ No newline at end of file + diff --git a/test/functional/explore/posts_controller_test.rb b/test/functional/explore/posts_controller_test.rb index 171235f32..5fd79d5e1 100644 --- a/test/functional/explore/posts_controller_test.rb +++ b/test/functional/explore/posts_controller_test.rb @@ -28,8 +28,17 @@ module Explore end end + context "#viewed" do + should "render" do + mock_post_view_rankings(Date.today, [[@post.id, 100]]) + get viewed_explore_posts_path + assert_response :success + end + end + context "#searches" do should "render" do + mock_post_search_rankings(Date.today, [["1girl", 100], ["original", 50]]) get searches_explore_posts_path assert_response :success end @@ -37,6 +46,7 @@ module Explore context "#missed_searches" do should "render" do + mock_missed_search_rankings([["1girl", 100], ["original", 50]]) get missed_searches_explore_posts_path assert_response :success end diff --git a/test/functional/posts_controller_test.rb b/test/functional/posts_controller_test.rb index d488062f0..548ecacab 100644 --- a/test/functional/posts_controller_test.rb +++ b/test/functional/posts_controller_test.rb @@ -3,13 +3,15 @@ require "test_helper" class PostsControllerTest < ActionDispatch::IntegrationTest context "The posts controller" do setup do - PopularSearchService.stubs(:enabled?).returns(false) - @user = travel_to(1.month.ago) {create(:user)} @post = as(@user) { create(:post, tag_string: "aaaa") } end context "index action" do + setup do + mock_post_search_rankings(Date.today, [["1girl", 100], ["original", 50]]) + end + should "render" do get posts_path assert_response :success diff --git a/test/functional/static_controller_test.rb b/test/functional/static_controller_test.rb index 0fd2bd57b..ee8dca354 100644 --- a/test/functional/static_controller_test.rb +++ b/test/functional/static_controller_test.rb @@ -16,6 +16,7 @@ class StaticControllerTest < ActionDispatch::IntegrationTest context "sitemap action" do should "work" do create_list(:post, 3) + mock_post_search_rankings(Time.zone.yesterday, [["1girl", 100.0], ["2girls", 50.0]]) get sitemap_path, as: :xml assert_response :success end diff --git a/test/test_helper.rb b/test/test_helper.rb index e395a6195..700bf1e6d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -43,8 +43,6 @@ class ActiveSupport::TestCase setup do Socket.stubs(:gethostname).returns("www.example.com") - mock_popular_search_service! - mock_missed_search_service! WebMock.allow_net_connect! storage_manager = StorageManager::Local.new(base_dir: Dir.mktmpdir("uploads-test-storage-")) diff --git a/test/test_helpers/reportbooru_helper.rb b/test/test_helpers/reportbooru_helper.rb index 441df8216..051c33395 100644 --- a/test/test_helpers/reportbooru_helper.rb +++ b/test/test_helpers/reportbooru_helper.rb @@ -1,12 +1,24 @@ module ReportbooruHelper - def mock_popular_search_service! - Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:3003") - stub_request(:get, "http://localhost:3003/post_searches/month?date=#{Date.today}").to_return(body: "kantai_collection 1000.0\ntouhou 500.0") - stub_request(:get, "http://localhost:3003/post_searches/day?date=#{Date.today}").to_return(body: "kantai_collection 1000.0\ntouhou 500.0") + def mock_request(url, method: :get, status: 200, body: nil, http: Danbooru::Http.any_instance) + response = HTTP::Response.new(status: status, body: body, version: "1.1") + http.stubs(method).with(url).returns(response) end - def mock_missed_search_service! - Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:3003") - stub_request(:get, "http://localhost:3003/missed_searches").to_return(body: "kantai_collection 1000.0\ntouhou 500.0") + def mock_post_search_rankings(date = Date.today, rankings) + Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:1234") + url = "http://localhost:1234/post_searches/rank?date=#{date}" + mock_request(url, body: rankings.to_json) + end + + def mock_missed_search_rankings(date = Date.today, rankings) + Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:1234") + url = "http://localhost:1234/missed_searches" + mock_request(url, body: rankings.to_json) + end + + def mock_post_view_rankings(date = Date.today, rankings) + Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:1234") + url = "http://localhost:1234/post_views/rank?date=#{date}" + mock_request(url, body: rankings.to_json) end end diff --git a/test/unit/post_view_count_service_test.rb b/test/unit/reportbooru_service_test.rb similarity index 84% rename from test/unit/post_view_count_service_test.rb rename to test/unit/reportbooru_service_test.rb index d134ecc5a..3d795d130 100644 --- a/test/unit/post_view_count_service_test.rb +++ b/test/unit/reportbooru_service_test.rb @@ -1,8 +1,8 @@ require 'test_helper' -class PostViewCountServiceTest < ActiveSupport::TestCase +class ReportbooruServiceTest < ActiveSupport::TestCase def setup - @service = PostViewCountService.new(reportbooru_server: "http://localhost:1234") + @service = ReportbooruService.new(reportbooru_server: "http://localhost:1234") @post = create(:post) @date = "2000-01-01" end
    <%= link_to tags, posts_path(:tags => tags) %> <%= count.to_i %>