uploads: replace old upload limits with new upload limits.

This commit is contained in:
evazion
2020-02-03 18:37:14 -06:00
parent 24cb920608
commit 3c2a379d6f
20 changed files with 67 additions and 158 deletions

View File

@@ -1,11 +0,0 @@
class DanbooruMath
def self.ci_lower_bound(pos, n, confidence = 0.95)
if n == 0
return 0
end
z = Statistics2.pnormaldist(1 - (1 - confidence) / 2)
phat = 1.0 * pos / n
100 * (phat + z * z / (2 * n) - z * Math.sqrt((phat * (1 - phat) + z * z / (4 * n)) / n)) / (1 + z * z / n)
end
end

View File

@@ -11,7 +11,23 @@ class UploadLimit
end
def limited?
used_upload_slots >= upload_slots
if user.can_upload_free?
false
elsif user.created_at > 1.week.ago
true
else
used_upload_slots >= upload_slots
end
end
def limit_reason
if user.created_at > 1.week.ago
"cannot upload during your first week of registration"
elsif limited?
"have reached your upload limit"
else
nil
end
end
def used_upload_slots

View File

@@ -27,6 +27,7 @@ class Post < ApplicationRecord
validate :has_enough_tags
validate :post_is_not_its_own_parent
validate :updater_can_change_rating
validate :uploader_is_not_limited, on: :create
before_save :update_tag_post_counts
before_save :set_tag_counts
before_create :autoban
@@ -1280,7 +1281,7 @@ class Post < ApplicationRecord
give_favorites_to_parent(options) if options[:move_favorites]
is_automatic = (reason == "Unapproved in three days")
uploader.new_upload_limit.update_limit!(self, incremental: is_automatic)
uploader.upload_limit.update_limit!(self, incremental: is_automatic)
unless options[:without_mod_action]
ModAction.log("deleted post ##{id}, reason: #{reason}", :post_delete)
@@ -1648,6 +1649,10 @@ class Post < ApplicationRecord
end
end
def uploader_is_not_limited
errors[:uploader] << uploader.upload_limit.limit_reason if uploader.upload_limit.limited?
end
def added_tags_are_valid
new_tags = added_tags.select { |t| t.post_count <= 0 }
new_general_tags = new_tags.select { |t| t.category == Tag.categories.general }

View File

@@ -32,7 +32,7 @@ class PostApproval < ApplicationRecord
post.update(approver: user, is_flagged: false, is_pending: false, is_deleted: false)
ModAction.log("undeleted post ##{post_id}", :post_undelete) if is_undeletion
post.uploader.new_upload_limit.update_limit!(post, incremental: !is_undeletion)
post.uploader.upload_limit.update_limit!(post, incremental: !is_undeletion)
end
def self.search(params)

View File

@@ -60,7 +60,6 @@ class Upload < ApplicationRecord
before_validation :initialize_attributes, on: :create
before_validation :assign_rating_from_tags
validate :uploader_is_not_limited, on: :create
# validates :source, format: { with: /\Ahttps?/ }, if: ->(record) {record.file.blank?}, on: :create
validates :rating, inclusion: { in: %w(q e s) }, allow_nil: true
validates :md5, confirmation: true, if: ->(rec) { rec.md5_confirmation.present? }
@@ -235,12 +234,6 @@ class Upload < ApplicationRecord
extend SearchMethods
include SourceMethods
def uploader_is_not_limited
if !uploader.can_upload?
errors.add(:uploader, uploader.upload_limited_reason)
end
end
def assign_rating_from_tags
if rating = Tag.has_metatag?(tag_string, :rating)
self.rating = rating.downcase.first

View File

@@ -417,26 +417,6 @@ class User < ApplicationRecord
end
end
def can_upload?
if can_upload_free?
true
elsif is_admin?
true
elsif created_at > 1.week.ago
false
else
upload_limit > 0
end
end
def upload_limited_reason
if created_at > 1.week.ago
"cannot upload during your first week of registration"
else
"have reached your upload limit for the day"
end
end
def can_comment?
if is_gold?
true
@@ -469,38 +449,8 @@ class User < ApplicationRecord
(is_moderator? && flag.not_uploaded_by?(id)) || flag.creator_id == id
end
def new_upload_limit
@new_upload_limit ||= UploadLimit.new(self)
end
def upload_limit
[max_upload_limit - used_upload_slots, 0].max
end
def used_upload_slots
uploaded_count = posts.where("created_at >= ?", 23.hours.ago).count
uploaded_comic_count = posts.tag_match("comic").where("created_at >= ?", 23.hours.ago).count / 3
uploaded_count - uploaded_comic_count
end
memoize :used_upload_slots
def max_upload_limit
[(base_upload_limit * upload_limit_multiplier).ceil, 10].max
end
def upload_limit_multiplier
(1 - (adjusted_deletion_confidence / 15.0))
end
def adjusted_deletion_confidence
[deletion_confidence(60.days.ago), 15].min
end
memoize :adjusted_deletion_confidence
def deletion_confidence(date)
deletions = posts.deleted.where("created_at >= ?", date).count
total = posts.where("created_at >= ?", date).count
DanbooruMath.ci_lower_bound(deletions, total)
@upload_limit ||= UploadLimit.new(self)
end
def base_upload_limit
@@ -624,7 +574,6 @@ class User < ApplicationRecord
forum_post_count comment_count favorite_group_count
appeal_count flag_count positive_feedback_count
neutral_feedback_count negative_feedback_count upload_limit
max_upload_limit
]
end

View File

@@ -43,22 +43,6 @@ class UserPresenter
Post.tag_match("search:#{category}").limit(10)
end
def upload_limit(template)
if user.can_upload_free?
return "none"
end
slots_tooltip = "Next free slot: #{template.time_ago_in_words(user.next_free_upload_slot)}"
limit_tooltip = <<-EOS.strip_heredoc
Base: #{user.base_upload_limit}
Del. Rate: #{format("%.2f", user.adjusted_deletion_confidence)}
Multiplier: (1 - (#{format("%.2f", user.adjusted_deletion_confidence)} / 15)) = #{user.upload_limit_multiplier}
Upload Limit: #{user.base_upload_limit} * #{format("%.2f", user.upload_limit_multiplier)} = #{user.max_upload_limit}
EOS
%{<abbr title="#{slots_tooltip}">#{user.used_upload_slots}</abbr> / <abbr title="#{limit_tooltip}">#{user.max_upload_limit}</abbr>}.html_safe
end
def uploads
Post.tag_match("user:#{user.name}").limit(6)
end

View File

@@ -2,11 +2,13 @@
<div id="a-new">
<h1>Upload</h1>
<% if CurrentUser.can_upload? %>
<% if !CurrentUser.user.upload_limit.limited? %>
<%= embed_wiki("help:upload_notice", id: "upload-guide-notice") %>
<% unless CurrentUser.can_upload_free? %>
<p>Upload limit: <strong><%= CurrentUser.user.presenter.upload_limit(self) %></strong>.</p>
<p id="upload-limit">
Upload Limit: <%= render "users/upload_limit", user: CurrentUser.user %>
</p>
<% end %>
<%= render "image" %>
@@ -80,7 +82,7 @@
<%= render "related_tags/container" %>
<% end %>
<% else %>
<h2 style="margin-bottom: 1em;">You <%= CurrentUser.user.upload_limited_reason %></h2>
<h2 style="margin-bottom: 1em;">You <%= CurrentUser.user.upload_limit.limit_reason %></h2>
<% end %>
</div>
</div>

View File

@@ -63,15 +63,8 @@
<tr>
<th>Upload Limit</th>
<td><%= presenter.upload_limit(self) %> (<%= link_to_wiki "help", "about:upload_limits" %>)</td>
</tr>
<tr>
<th>New Upload Limit</th>
<td>
<%= link_to user.new_upload_limit.used_upload_slots, posts_path(tags: "user:#{user.name} status:pending") %>
/
<%= tag.abbr user.new_upload_limit.upload_slots, title: "Next level: #{user.new_upload_limit.approvals_on_current_level} / #{user.new_upload_limit.approvals_for_next_level} approvals" %>
<%= render "users/upload_limit", user: user %>
</td>
</tr>

View File

@@ -0,0 +1,10 @@
<%# user %>
<% if user.can_upload_free? %>
none
<% else %>
<%= link_to user.upload_limit.used_upload_slots, posts_path(tags: "user:#{user.name} status:pending") %> /
<%= tag.abbr user.upload_limit.upload_slots, title: "#{pluralize(user.upload_limit.approvals_for_next_level - user.upload_limit.approvals_on_current_level, "approved post")} needed for next level (progress: #{user.upload_limit.approvals_on_current_level} / #{user.upload_limit.approvals_for_next_level}) " %>
<% end %>
(<%= link_to_wiki "help", "about:upload_limits" %>)