Refactor Reportbooru API clients.
* Combine MissedSearchService, PostViewCountService, and PopularSearchService into single ReportbooruService class. * Use Danbooru::Http for these services instead of HTTParty.
This commit is contained in:
@@ -22,23 +22,23 @@ module Explore
|
|||||||
|
|
||||||
def viewed
|
def viewed
|
||||||
@date, @scale, @min_date, @max_date = parse_date(params)
|
@date, @scale, @min_date, @max_date = parse_date(params)
|
||||||
@posts = PostViewCountService.new.popular_posts(@date)
|
@posts = ReportbooruService.new.popular_posts(@date)
|
||||||
respond_with(@posts)
|
respond_with(@posts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def searches
|
def searches
|
||||||
@date, @scale, @min_date, @max_date = parse_date(params)
|
@date, @scale, @min_date, @max_date = parse_date(params)
|
||||||
@search_service = PopularSearchService.new(@date)
|
@search_service = ReportbooruService.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def missed_searches
|
def missed_searches
|
||||||
@search_service = MissedSearchService.new
|
@search_service = ReportbooruService.new
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse_date(params)
|
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"
|
scale = params[:scale].in?(["day", "week", "month"]) ? params[:scale] : "day"
|
||||||
min_date = date.send("beginning_of_#{scale}")
|
min_date = date.send("beginning_of_#{scale}")
|
||||||
max_date = date.send("next_#{scale}").send("beginning_of_#{scale}")
|
max_date = date.send("next_#{scale}").send("beginning_of_#{scale}")
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class StaticController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def sitemap
|
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 = Post.where("created_at > ?", 1.week.ago).order(score: :desc).limit(200)
|
||||||
@posts = @posts.select(&:visible?)
|
@posts = @posts.select(&:visible?)
|
||||||
render layout: false
|
render layout: false
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -169,8 +169,8 @@ module PostSets
|
|||||||
end
|
end
|
||||||
|
|
||||||
def popular_tags
|
def popular_tags
|
||||||
if PopularSearchService.enabled?
|
if reportbooru_service.enabled?
|
||||||
PopularSearchService.new(Date.today).tags
|
reportbooru_service.popular_searches(Date.today, limit: MAX_SIDEBAR_TAGS).map(&:first)
|
||||||
else
|
else
|
||||||
frequent_tags
|
frequent_tags
|
||||||
end
|
end
|
||||||
@@ -199,6 +199,10 @@ module PostSets
|
|||||||
def tag_list_html(**options)
|
def tag_list_html(**options)
|
||||||
tag_set_presenter.tag_list_html(name_only: query.is_metatag?(:search), **options)
|
tag_set_presenter.tag_list_html(name_only: query.is_metatag?(:search), **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reportbooru_service
|
||||||
|
@reportbooru_service ||= ReportbooruService.new
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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
|
|
||||||
49
app/logical/reportbooru_service.rb
Normal file
49
app/logical/reportbooru_service.rb
Normal file
@@ -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
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% @search_service.each_search do |tags, count| %>
|
<% @search_service.missed_search_rankings do |tags, count| %>
|
||||||
<tr class="tag-type-<%= Tag.category_for(tags) %>">
|
<tr class="tag-type-<%= Tag.category_for(tags) %>">
|
||||||
<td><%= link_to tags, posts_path(:tags => tags) %></td>
|
<td><%= link_to tags, posts_path(:tags => tags) %></td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<div id="c-explore-posts">
|
<div id="c-explore-posts">
|
||||||
<div id="a-searches">
|
<div id="a-searches">
|
||||||
<h1>Popular Searches - <%= @search_service.date %></h1>
|
<h1>Popular Searches - <%= @date %></h1>
|
||||||
|
|
||||||
<table class="striped" width="100%">
|
<table class="striped" width="100%">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% @search_service.each_search do |tags, count| %>
|
<% @search_service.post_search_rankings(@date) do |tags, count| %>
|
||||||
<tr class="tag-type-<%= Tag.category_for(tags) %>">
|
<tr class="tag-type-<%= Tag.category_for(tags) %>">
|
||||||
<td><%= link_to tags, posts_path(:tags => tags) %></td>
|
<td><%= link_to tags, posts_path(:tags => tags) %></td>
|
||||||
<td style="text-align: right;"><%= count.to_i %></td>
|
<td style="text-align: right;"><%= count.to_i %></td>
|
||||||
|
|||||||
@@ -5,10 +5,8 @@
|
|||||||
<li id="secondary-links-posts-hot"><%= link_to "Hot", posts_path(:tags => "order:rank") %></li>
|
<li id="secondary-links-posts-hot"><%= link_to "Hot", posts_path(:tags => "order:rank") %></li>
|
||||||
<li id="secondary-links-posts-popular"><%= link_to "Popular", popular_explore_posts_path %></li>
|
<li id="secondary-links-posts-popular"><%= link_to "Popular", popular_explore_posts_path %></li>
|
||||||
<li id="secondary-links-posts-curated"><%= link_to "Curated", curated_explore_posts_path %></li>
|
<li id="secondary-links-posts-curated"><%= link_to "Curated", curated_explore_posts_path %></li>
|
||||||
<% if PopularSearchService.enabled? %>
|
<% if ReportbooruService.enabled? %>
|
||||||
<li><%= link_to "Searches", searches_explore_posts_path %></li>
|
<li><%= link_to "Searches", searches_explore_posts_path %></li>
|
||||||
<% end %>
|
|
||||||
<% if PostViewCountService.enabled? %>
|
|
||||||
<li><%= link_to "Viewed", viewed_explore_posts_path %></li>
|
<li><%= link_to "Viewed", viewed_explore_posts_path %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</url>
|
</url>
|
||||||
|
|
||||||
<% cache("sitemap", :expires_in => 24.hours) do %>
|
<% 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| %>
|
||||||
<url>
|
<url>
|
||||||
<loc><%= posts_url(tags: tags) %></loc>
|
<loc><%= posts_url(tags: tags) %></loc>
|
||||||
<lastmod><%= Date.today %></lastmod>
|
<lastmod><%= Date.today %></lastmod>
|
||||||
|
|||||||
@@ -28,8 +28,17 @@ module Explore
|
|||||||
end
|
end
|
||||||
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
|
context "#searches" do
|
||||||
should "render" do
|
should "render" do
|
||||||
|
mock_post_search_rankings(Date.today, [["1girl", 100], ["original", 50]])
|
||||||
get searches_explore_posts_path
|
get searches_explore_posts_path
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
@@ -37,6 +46,7 @@ module Explore
|
|||||||
|
|
||||||
context "#missed_searches" do
|
context "#missed_searches" do
|
||||||
should "render" do
|
should "render" do
|
||||||
|
mock_missed_search_rankings([["1girl", 100], ["original", 50]])
|
||||||
get missed_searches_explore_posts_path
|
get missed_searches_explore_posts_path
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,13 +3,15 @@ require "test_helper"
|
|||||||
class PostsControllerTest < ActionDispatch::IntegrationTest
|
class PostsControllerTest < ActionDispatch::IntegrationTest
|
||||||
context "The posts controller" do
|
context "The posts controller" do
|
||||||
setup do
|
setup do
|
||||||
PopularSearchService.stubs(:enabled?).returns(false)
|
|
||||||
|
|
||||||
@user = travel_to(1.month.ago) {create(:user)}
|
@user = travel_to(1.month.ago) {create(:user)}
|
||||||
@post = as(@user) { create(:post, tag_string: "aaaa") }
|
@post = as(@user) { create(:post, tag_string: "aaaa") }
|
||||||
end
|
end
|
||||||
|
|
||||||
context "index action" do
|
context "index action" do
|
||||||
|
setup do
|
||||||
|
mock_post_search_rankings(Date.today, [["1girl", 100], ["original", 50]])
|
||||||
|
end
|
||||||
|
|
||||||
should "render" do
|
should "render" do
|
||||||
get posts_path
|
get posts_path
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class StaticControllerTest < ActionDispatch::IntegrationTest
|
|||||||
context "sitemap action" do
|
context "sitemap action" do
|
||||||
should "work" do
|
should "work" do
|
||||||
create_list(:post, 3)
|
create_list(:post, 3)
|
||||||
|
mock_post_search_rankings(Time.zone.yesterday, [["1girl", 100.0], ["2girls", 50.0]])
|
||||||
get sitemap_path, as: :xml
|
get sitemap_path, as: :xml
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ class ActiveSupport::TestCase
|
|||||||
|
|
||||||
setup do
|
setup do
|
||||||
Socket.stubs(:gethostname).returns("www.example.com")
|
Socket.stubs(:gethostname).returns("www.example.com")
|
||||||
mock_popular_search_service!
|
|
||||||
mock_missed_search_service!
|
|
||||||
WebMock.allow_net_connect!
|
WebMock.allow_net_connect!
|
||||||
|
|
||||||
storage_manager = StorageManager::Local.new(base_dir: Dir.mktmpdir("uploads-test-storage-"))
|
storage_manager = StorageManager::Local.new(base_dir: Dir.mktmpdir("uploads-test-storage-"))
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
module ReportbooruHelper
|
module ReportbooruHelper
|
||||||
def mock_popular_search_service!
|
def mock_request(url, method: :get, status: 200, body: nil, http: Danbooru::Http.any_instance)
|
||||||
Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:3003")
|
response = HTTP::Response.new(status: status, body: body, version: "1.1")
|
||||||
stub_request(:get, "http://localhost:3003/post_searches/month?date=#{Date.today}").to_return(body: "kantai_collection 1000.0\ntouhou 500.0")
|
http.stubs(method).with(url).returns(response)
|
||||||
stub_request(:get, "http://localhost:3003/post_searches/day?date=#{Date.today}").to_return(body: "kantai_collection 1000.0\ntouhou 500.0")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def mock_missed_search_service!
|
def mock_post_search_rankings(date = Date.today, rankings)
|
||||||
Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:3003")
|
Danbooru.config.stubs(:reportbooru_server).returns("http://localhost:1234")
|
||||||
stub_request(:get, "http://localhost:3003/missed_searches").to_return(body: "kantai_collection 1000.0\ntouhou 500.0")
|
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
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class PostViewCountServiceTest < ActiveSupport::TestCase
|
class ReportbooruServiceTest < ActiveSupport::TestCase
|
||||||
def setup
|
def setup
|
||||||
@service = PostViewCountService.new(reportbooru_server: "http://localhost:1234")
|
@service = ReportbooruService.new(reportbooru_server: "http://localhost:1234")
|
||||||
@post = create(:post)
|
@post = create(:post)
|
||||||
@date = "2000-01-01"
|
@date = "2000-01-01"
|
||||||
end
|
end
|
||||||
Reference in New Issue
Block a user