From f3071e66ec0a1ab3b4b765a176e9549bf9d2ffbd Mon Sep 17 00:00:00 2001 From: r888888888 Date: Wed, 30 Dec 2015 18:13:59 -0800 Subject: [PATCH] add user similarity report --- .../stylesheets/specific/reports.css.scss | 21 ++++++++++++ app/controllers/reports_controller.rb | 8 +++++ app/logical/reports/user_similarity.rb | 33 ++++++++++++++++++ app/presenters/user_similarity_presenter.rb | 34 +++++++++++++++++++ app/views/reports/similar_users.html.erb | 28 +++++++++++++++ config/routes.rb | 1 + 6 files changed, 125 insertions(+) create mode 100644 app/logical/reports/user_similarity.rb create mode 100644 app/presenters/user_similarity_presenter.rb create mode 100644 app/views/reports/similar_users.html.erb diff --git a/app/assets/stylesheets/specific/reports.css.scss b/app/assets/stylesheets/specific/reports.css.scss index e69de29bb..f7c6bf5d2 100644 --- a/app/assets/stylesheets/specific/reports.css.scss +++ b/app/assets/stylesheets/specific/reports.css.scss @@ -0,0 +1,21 @@ +#c-reports { + #a-similar-users { + div.box { + h2, h3 { + color: #333; + } + + margin-bottom: 2em; + } + + /* clearfix hacks */ + div.box:before, div.box:after { + content: ""; + display: table; + } + + div.box:after { + clear: both; + } + } +} \ No newline at end of file diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 02c35d329..b93c13161 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -1,4 +1,7 @@ class ReportsController < ApplicationController + before_filter :member_only + before_filter :gold_only, :only => [:similar_users] + def user_promotions @report = Reports::UserPromotions.new end @@ -14,4 +17,9 @@ class ReportsController < ApplicationController def uploads @report = Reports::Uploads.new(params[:min_date], params[:max_date], params[:queries]) end + + def similar_users + @report = Reports::UserSimilarity.new(CurrentUser.id) + @presenter = UserSimilarityPresenter.new(@report) + end end diff --git a/app/logical/reports/user_similarity.rb b/app/logical/reports/user_similarity.rb new file mode 100644 index 000000000..7df23153b --- /dev/null +++ b/app/logical/reports/user_similarity.rb @@ -0,0 +1,33 @@ +module Reports + class UserSimilarity + attr_reader :user_id + + def initialize(user_id) + @user_id = user_id + end + + def user + User.find(user_id) + end + + def fetch_similar_user_ids + return NotImplementedError unless Danbooru.config.report_server + + params = { + "key" => Danbooru.config.shared_remote_key, + "user_id" => user_id + } + uri = URI.parse("#{Danbooru.config.listbooru_server}/reports/user_similarity") + 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 + else + raise "HTTP error code: #{resp.code} #{resp.message}" + end + end + end + end +end diff --git a/app/presenters/user_similarity_presenter.rb b/app/presenters/user_similarity_presenter.rb new file mode 100644 index 000000000..84c454782 --- /dev/null +++ b/app/presenters/user_similarity_presenter.rb @@ -0,0 +1,34 @@ +class UserSimilarityPresenter + attr_reader :report, :not_ready + + def initialize(report) + @report = report + fetch + end + + def not_ready? + not_ready + end + + def insufficient_data? + report.user.favorite_count < 500 + end + + def fetch + user_ids = report.fetch_similar_user_ids + + if user_ids = "not ready" + @not_ready = true + else + @user_ids = user_ids.scan(/\d+/).slice(0, 10) + end + end + + def each_user(&block) + User.where(id: user_ids).each(&block) + end + + def each_favorite_for(user, &block) + user.favorites.limit(6).joins(:post).reorder("favorites.id desc").map(&:post).each(&block) + end +end diff --git a/app/views/reports/similar_users.html.erb b/app/views/reports/similar_users.html.erb new file mode 100644 index 000000000..d07b7d389 --- /dev/null +++ b/app/views/reports/similar_users.html.erb @@ -0,0 +1,28 @@ +
+
+

Similar Users

+ + <% if @presenter.insufficient_data? %> +

You need at least 500 favorites before Danbooru can calculate users similar to you.

+ + <% elsif @presenter.not_ready? %> +

The report is still being generated. Check back in a few minutes.

+ + <% else %> + <% @presenter.each_user do |user| %> +
+

<%= link_to user.pretty_name, user_path(user) %>

+
+ <% @presenter.each_favorite_for(user) do |post| %> + <%= PostPresenter.preview(post, :tags => "fav:#{user.name}") %> + <% end %> +
+
+ <% end %> + <% end %> +
+
+ +<% content_for(:page_title) do %> + Similar Users - <%= Danbooru.config.app_name %> +<% end %> diff --git a/config/routes.rb b/config/routes.rb index 3c9a01db6..c2c7830f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -223,6 +223,7 @@ Rails.application.routes.draw do get "reports/janitor_trials" => "reports#janitor_trials" get "reports/contributors" => "reports#contributors" get "reports/uploads" => "reports#uploads" + get "reports/similar_users" => "reports#similar_users" resources :saved_searches, :except => [:show] do collection do get :categories