Merge branch 'master' of https://github.com/r888888888/danbooru
This commit is contained in:
@@ -341,6 +341,8 @@
|
|||||||
$("#image-resize-link").click(function(e) {
|
$("#image-resize-link").click(function(e) {
|
||||||
var $link = $(e.target);
|
var $link = $(e.target);
|
||||||
var $image = $("#image");
|
var $image = $("#image");
|
||||||
|
$image.removeAttr("src");
|
||||||
|
$image.attr("src", "https://www.google.com")
|
||||||
$image.attr("src", $link.attr("href"));
|
$image.attr("src", $link.attr("href"));
|
||||||
$image.width($image.data("original-width"));
|
$image.width($image.data("original-width"));
|
||||||
$image.height($image.data("original-height"));
|
$image.height($image.data("original-height"));
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import "../common/000_vars.css.scss";
|
||||||
|
|
||||||
div#c-explore-posts {
|
div#c-explore-posts {
|
||||||
header {
|
header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -16,4 +18,10 @@ div#c-explore-posts {
|
|||||||
padding: 1em;
|
padding: 1em;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#a-intro {
|
||||||
|
width: 870px;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
0
app/assets/stylesheets/specific/reports.css.scss
Normal file
0
app/assets/stylesheets/specific/reports.css.scss
Normal file
@@ -1,5 +1,5 @@
|
|||||||
class PostsController < ApplicationController
|
class PostsController < ApplicationController
|
||||||
before_filter :member_only, :except => [:show, :show_seq, :index]
|
before_filter :member_only, :except => [:show, :show_seq, :index, :home]
|
||||||
before_filter :builder_only, :only => [:copy_notes]
|
before_filter :builder_only, :only => [:copy_notes]
|
||||||
after_filter :save_recent_tags, :only => [:update]
|
after_filter :save_recent_tags, :only => [:update]
|
||||||
respond_to :html, :xml, :json
|
respond_to :html, :xml, :json
|
||||||
@@ -98,6 +98,14 @@ class PostsController < ApplicationController
|
|||||||
@error = x
|
@error = x
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def home
|
||||||
|
if CurrentUser.user.is_anonymous?
|
||||||
|
redirect_to intro_explore_posts_path
|
||||||
|
else
|
||||||
|
redirect_to posts_path(:tags => params[:tags])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def tag_query
|
def tag_query
|
||||||
params[:tags] || (params[:post] && params[:post][:tags])
|
params[:tags] || (params[:post] && params[:post][:tags])
|
||||||
|
|||||||
@@ -86,15 +86,22 @@ class DText
|
|||||||
|
|
||||||
def self.parse_list(str, options = {})
|
def self.parse_list(str, options = {})
|
||||||
html = ""
|
html = ""
|
||||||
|
current_item = ""
|
||||||
layout = []
|
layout = []
|
||||||
nest = 0
|
nest = 0
|
||||||
|
|
||||||
str.split(/\n/).each do |line|
|
str.split(/\n/).each do |line|
|
||||||
if line =~ /^\s*(\*+) (.+)/
|
if line =~ /^\s*(\*+) (.+)/
|
||||||
|
if nest > 0
|
||||||
|
html += "<li>#{current_item}</li>"
|
||||||
|
elsif not current_item.strip.empty?
|
||||||
|
html += "<p>#{current_item}</p>"
|
||||||
|
end
|
||||||
|
|
||||||
nest = $1.size
|
nest = $1.size
|
||||||
content = parse_inline($2)
|
current_item = parse_inline($2)
|
||||||
else
|
else
|
||||||
content = parse_inline(line)
|
current_item += parse_inline(line)
|
||||||
end
|
end
|
||||||
|
|
||||||
if nest > layout.size
|
if nest > layout.size
|
||||||
@@ -108,10 +115,10 @@ class DText
|
|||||||
html += "</#{elist}>"
|
html += "</#{elist}>"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
html += "<li>#{content}</li>"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
html += "<li>#{current_item}</li>"
|
||||||
|
|
||||||
while layout.any?
|
while layout.any?
|
||||||
elist = layout.pop
|
elist = layout.pop
|
||||||
html += "</#{elist}>"
|
html += "</#{elist}>"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ module PostSets
|
|||||||
|
|
||||||
def posts
|
def posts
|
||||||
@posts ||= begin
|
@posts ||= begin
|
||||||
temp = ::Post.tag_match("#{tag_string} favcount:>10").paginate(page, :search_count => nil, :limit => 6)
|
temp = ::Post.tag_match("#{tag_string} favcount:>3").paginate(page, :search_count => nil, :limit => 5)
|
||||||
temp.all
|
temp.all
|
||||||
temp
|
temp
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,6 +2,19 @@ require 'statistics2'
|
|||||||
|
|
||||||
module Reports
|
module Reports
|
||||||
class UserPromotions
|
class UserPromotions
|
||||||
|
class User
|
||||||
|
attr_reader :user
|
||||||
|
delegate :name, :post_upload_count, :level_string, :level, :created_at, :to => :user
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
@user = user
|
||||||
|
end
|
||||||
|
|
||||||
|
def confidence_interval_for(n)
|
||||||
|
Reports::UserPromotions.confidence_interval_for(user, n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def self.confidence_interval_for(user, n)
|
def self.confidence_interval_for(user, n)
|
||||||
up_votes = Post.where("created_at >= ?", min_time).where(:uploader_id => user.id).where("fav_count >= ?", n).count
|
up_votes = Post.where("created_at >= ?", min_time).where(:uploader_id => user.id).where("fav_count >= ?", n).count
|
||||||
total_votes = Post.where("created_at >= ?", min_time).where(:uploader_id => user.id).count
|
total_votes = Post.where("created_at >= ?", min_time).where(:uploader_id => user.id).count
|
||||||
@@ -23,7 +36,7 @@ module Reports
|
|||||||
end
|
end
|
||||||
|
|
||||||
def users
|
def users
|
||||||
User.where("users.level < ? and users.post_upload_count >= 100", User::Levels::CONTRIBUTOR).order("created_at desc").limit(50)
|
::User.where("users.level < ? and users.post_upload_count >= 100", ::User::Levels::CONTRIBUTOR).order("created_at desc").limit(50).map {|x| Reports::UserPromotions::User.new(x)}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ class JanitorTrial < ActiveRecord::Base
|
|||||||
before_create :initialize_original_level
|
before_create :initialize_original_level
|
||||||
after_create :send_dmail
|
after_create :send_dmail
|
||||||
after_create :promote_user
|
after_create :promote_user
|
||||||
after_destroy :create_feedback
|
|
||||||
validates_presence_of :user
|
validates_presence_of :user
|
||||||
before_validation :initialize_creator
|
before_validation :initialize_creator
|
||||||
|
|
||||||
@@ -61,6 +60,7 @@ class JanitorTrial < ActiveRecord::Base
|
|||||||
|
|
||||||
def demote!
|
def demote!
|
||||||
user.update_column(:level, original_level)
|
user.update_column(:level, original_level)
|
||||||
|
self.create_feedback
|
||||||
destroy
|
destroy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -141,7 +141,12 @@ class Tag < ActiveRecord::Base
|
|||||||
counts = counts.to_a.select {|x| x[1] > trending_count_limit}
|
counts = counts.to_a.select {|x| x[1] > trending_count_limit}
|
||||||
counts = counts.map do |tag_name, recent_count|
|
counts = counts.map do |tag_name, recent_count|
|
||||||
tag = Tag.find_or_create_by_name(tag_name)
|
tag = Tag.find_or_create_by_name(tag_name)
|
||||||
[tag_name, recent_count.to_f / tag.post_count.to_f]
|
if tag.category == Danbooru.config.tag_category_mapping["artist"]
|
||||||
|
# we're not interested in artists in the trending list
|
||||||
|
[tag_name, 0]
|
||||||
|
else
|
||||||
|
[tag_name, recent_count.to_f / tag.post_count.to_f]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
counts.sort_by {|x| -x[1]}.slice(0, 25).map(&:first)
|
counts.sort_by {|x| -x[1]}.slice(0, 25).map(&:first)
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ $("div.comments-for-post[data-post-id=<%= @post.id %>] div.list-of-comments").ht
|
|||||||
|
|
||||||
Danbooru.Comment.initialize_reply_links();
|
Danbooru.Comment.initialize_reply_links();
|
||||||
Danbooru.Comment.initialize_edit_links();
|
Danbooru.Comment.initialize_edit_links();
|
||||||
|
Danbooru.Comment.initialize_vote_links();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<% @presenter.each do |tag, post_set| %>
|
<% @presenter.each do |tag, post_set| %>
|
||||||
<div class="posts">
|
<div class="posts">
|
||||||
<h2><%= link_to tag, posts_path(:tags => tag), :class => "tag-type-3" %></h2>
|
<h2><%= link_to tag, posts_path(:tags => tag) %></h2>
|
||||||
<%= post_set.presenter.post_previews_html(self) %>
|
<%= post_set.presenter.post_previews_html(self) %>
|
||||||
<div class="clearfix"></div>
|
<div class="clearfix"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,25 +4,29 @@
|
|||||||
|
|
||||||
<p>Binomial proportion confidence interval for how likely a user's uploads will achieve a fav count of at at least n with 95% confidence within the past 30 days.</p>
|
<p>Binomial proportion confidence interval for how likely a user's uploads will achieve a fav count of at at least n with 95% confidence within the past 30 days.</p>
|
||||||
|
|
||||||
<table width="100%" class="striped">
|
<table width="100%" class="striped" id="sortable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>User</th>
|
<th data-sort="string">User</th>
|
||||||
<th>Level</th>
|
<th data-sort="int">Level</th>
|
||||||
<th>score:1+</th>
|
<th data-sort="int">Uploads</th>
|
||||||
<th>score:5+</th>
|
<th data-sort="string">Age</th>
|
||||||
<th>score:10+</th>
|
<th data-sort="int">score:1+</th>
|
||||||
|
<th data-sort="int">score:5+</th>
|
||||||
|
<th data-sort="int">score:10+</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<% cache("user-promotions-report/#{Date.today}") do %>
|
<% cache("user-promotions-report/#{Date.today}") do %>
|
||||||
<% @report.users.each do |user| %>
|
<% @report.users.each do |user| %>
|
||||||
<tr>
|
<tr>
|
||||||
<td><%= link_to user.name, user_path(user) %></td>
|
<td><%= link_to user.name, user_path(user.user) %></td>
|
||||||
<td><%= user.level_string %></td>
|
<td data-sort-value="<%= user.level %>"><%= user.level_string %></td>
|
||||||
<td><%= number_to_percentage Reports::UserPromotions.confidence_interval_for(user, 1), :precision => 0 %></td>
|
<td><%= user.post_upload_count %></td>
|
||||||
<td><%= number_to_percentage Reports::UserPromotions.confidence_interval_for(user, 5), :precision => 0 %></td>
|
<td data-sort-value="<%= user.created_at.to_formatted_s(:db) %>"><%= time_ago_in_words user.created_at %></td>
|
||||||
<td><%= number_to_percentage Reports::UserPromotions.confidence_interval_for(user, 10), :precision => 0 %></td>
|
<td><%= number_to_percentage user.confidence_interval_for(1), :precision => 0 %></td>
|
||||||
|
<td><%= number_to_percentage user.confidence_interval_for(5), :precision => 0 %></td>
|
||||||
|
<td><%= number_to_percentage user.confidence_interval_for(10), :precision => 0 %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
@@ -30,3 +34,15 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<%= content_for(:html_header) do %>
|
||||||
|
<%= javascript_include_tag "stupidtable" %>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
$("#sortable").stupidtable().on("aftertablesort", function() {
|
||||||
|
$("#sortable tbody tr:even").removeClass("odd").addClass("even");
|
||||||
|
$("#sortable tbody tr:odd").removeClass("even").addClass("odd");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<% end %>
|
||||||
@@ -4,7 +4,7 @@ module Danbooru
|
|||||||
class Configuration
|
class Configuration
|
||||||
# The version of this Danbooru.
|
# The version of this Danbooru.
|
||||||
def version
|
def version
|
||||||
"2.22.2"
|
"2.23.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
# The name of this Danbooru.
|
# The name of this Danbooru.
|
||||||
|
|||||||
@@ -154,6 +154,9 @@ Danbooru::Application.routes.draw do
|
|||||||
resources :pool_versions, :only => [:index]
|
resources :pool_versions, :only => [:index]
|
||||||
resources :posts do
|
resources :posts do
|
||||||
resources :votes, :controller => "post_votes", :only => [:create, :destroy]
|
resources :votes, :controller => "post_votes", :only => [:create, :destroy]
|
||||||
|
collection do
|
||||||
|
get :home
|
||||||
|
end
|
||||||
member do
|
member do
|
||||||
put :revert
|
put :revert
|
||||||
put :copy_notes
|
put :copy_notes
|
||||||
@@ -286,7 +289,7 @@ Danbooru::Application.routes.draw do
|
|||||||
|
|
||||||
match "/note" => redirect {|params, req| "/notes?page=#{req.params[:page]}"}
|
match "/note" => redirect {|params, req| "/notes?page=#{req.params[:page]}"}
|
||||||
match "/note/index" => redirect {|params, req| "/notes?page=#{req.params[:page]}"}
|
match "/note/index" => redirect {|params, req| "/notes?page=#{req.params[:page]}"}
|
||||||
match "/note/history" => redirect("/note_versions")
|
match "/note/history" => redirect {|params, req| "/note_versions?search[updater_id]=#{req.params[:user_id]}"}
|
||||||
|
|
||||||
match "/pool" => redirect {|params, req| "/pools?page=#{req.params[:page]}"}
|
match "/pool" => redirect {|params, req| "/pools?page=#{req.params[:page]}"}
|
||||||
match "/pool/index" => redirect {|params, req| "/pools?page=#{req.params[:page]}"}
|
match "/pool/index" => redirect {|params, req| "/pools?page=#{req.params[:page]}"}
|
||||||
@@ -353,5 +356,5 @@ Danbooru::Application.routes.draw do
|
|||||||
match "/static/benchmark" => "static#benchmark"
|
match "/static/benchmark" => "static#benchmark"
|
||||||
match "/static/name_change" => "static#name_change", :as => "name_change"
|
match "/static/name_change" => "static#name_change", :as => "name_change"
|
||||||
|
|
||||||
root :to => "posts#index"
|
root :to => "posts#home"
|
||||||
end
|
end
|
||||||
|
|||||||
27
test/functional/explore/posts_controller_test.rb
Normal file
27
test/functional/explore/posts_controller_test.rb
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
module Explore
|
||||||
|
class PostsControllerTest < ActionController::TestCase
|
||||||
|
context "in all cases" do
|
||||||
|
setup do
|
||||||
|
CurrentUser.user = FactoryGirl.create(:user)
|
||||||
|
CurrentUser.ip_addr = "127.0.0.1"
|
||||||
|
FactoryGirl.create(:post)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "#popular" do
|
||||||
|
should "render" do
|
||||||
|
get :popular
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "#intro" do
|
||||||
|
should "render" do
|
||||||
|
get :intro
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -125,6 +125,14 @@ class DTextTest < ActiveSupport::TestCase
|
|||||||
assert_equal('<ul><li><a href="/posts/1">post #1</a></li></ul>', p("* post #1").gsub(/\n/, ""))
|
assert_equal('<ul><li><a href="/posts/1">post #1</a></li></ul>', p("* post #1").gsub(/\n/, ""))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_lists_not_preceded_by_newline
|
||||||
|
assert_equal('<p>ab</p><ul><li>c</li><li>d</li></ul>', p("a\nb\n* c\n* d").gsub(/\n/, ""))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lists_with_multiline_items
|
||||||
|
assert_equal('<p>a</p><ul><li>bc</li><li>de</li></ul>', p("a\n* b\nc\n* d\ne").gsub(/\n/, ""))
|
||||||
|
end
|
||||||
|
|
||||||
def test_inline_tags
|
def test_inline_tags
|
||||||
assert_equal('<p><a href="/posts?tags=tag">tag</a></p>', p("{{tag}}"))
|
assert_equal('<p><a href="/posts?tags=tag">tag</a></p>', p("{{tag}}"))
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ $.widget( "ui.autocomplete", {
|
|||||||
if ( this.menu.active ) {
|
if ( this.menu.active ) {
|
||||||
this.menu.select( event );
|
this.menu.select( event );
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
if ( !this.menu.element.is( ":visible" ) ) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case keyCode.ESCAPE:
|
case keyCode.ESCAPE:
|
||||||
if ( this.menu.element.is( ":visible" ) ) {
|
if ( this.menu.element.is( ":visible" ) ) {
|
||||||
|
|||||||
3
vendor/assets/javascripts/stupidtable.js
vendored
Normal file
3
vendor/assets/javascripts/stupidtable.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
(function(e){e.fn.stupidtable=function(j){return this.each(function(){var d=e(this);j=j||{};j=e.extend({},{"int":function(b,a){return parseInt(b,10)-parseInt(a,10)},"float":function(b,a){return parseFloat(b)-parseFloat(a)},string:function(b,a){return b<a?-1:b>a?1:0},"string-ins":function(b,a){b=b.toLowerCase();a=a.toLowerCase();return b<a?-1:b>a?1:0}},j);d.on("click","th",function(){var b=d.children("tbody").children("tr"),a=e(this),k=0,n=e.fn.stupidtable.dir;d.find("th").slice(0,a.index()).each(function(){var a=
|
||||||
|
e(this).attr("colspan")||1;k+=parseInt(a,10)});var m=a.data("sort-dir")===n.ASC?n.DESC:n.ASC,p=m==n.DESC?a.data("sort-desc")||a.data("sort")||null:a.data("sort")||null;null!==p&&(d.trigger("beforetablesort",{column:k,direction:m}),d.css("display"),setTimeout(function(){var l=[],c=j[p];b.each(function(a,b){var c=e(b).children().eq(k),d=c.data("sort-value"),c="undefined"!==typeof d?d:c.text();l.push(c)});var f=[],g=0;if(a.data("sort-dir")&&!a.data("sort-desc"))for(c=l.length-1;0<=c;c--)f.push(c);else for(var h=
|
||||||
|
l.slice(0).sort(c),c=0;c<l.length;c++){for(g=e.inArray(l[c],h);-1!=e.inArray(g,f);)g++;f.push(g)}d.find("th").data("sort-dir",null).removeClass("sorting-desc sorting-asc");a.data("sort-dir",m).addClass("sorting-"+m);g=b.slice(0);for(h=c=0;h<f.length;h++)c=f[h],g[c]=b[h];f=e(g);d.children("tbody").append(f);d.trigger("aftertablesort",{column:k,direction:m});d.css("display")},10))})})};e.fn.stupidtable.dir={ASC:"asc",DESC:"desc"}})(jQuery);
|
||||||
Reference in New Issue
Block a user