[PostSets/Pools] Handle metatag additions when set/pool is full (#669)

This commit is contained in:
Donovan Daniels 2024-07-25 16:47:59 -05:00 committed by Cinder
parent 7bdabdf2b4
commit b3b16759c4
7 changed files with 183 additions and 36 deletions

View File

@ -140,16 +140,15 @@ class PostsController < ApplicationController
if post.errors.any?
@message = post.errors.full_messages.join("; ")
render :template => "static/error", :status => 500
else
response_params = {:q => params[:tags_query], :pool_id => params[:pool_id], post_set_id: params[:post_set_id]}
response_params.reject!{|key, value| value.blank?}
redirect_to post_path(post, response_params)
if flash[:notice].present?
flash[:notice] += "\n\n" + @message
else
flash[:notice] = @message
end
end
end
format.json do
render :json => post
response_params = { q: params[:tags_query], pool_id: params[:pool_id], post_set_id: params[:post_set_id] }
response_params.compact_blank!
redirect_to post_path(post, response_params)
end
end
end

View File

@ -757,9 +757,12 @@ Post.update = function (post_id, params) {
Post.notice_update("dec");
Post.update_data(data);
},
error: function () {
error: function (data) {
Post.notice_update("dec");
$(window).trigger("danbooru:error", "There was an error updating <a href=\"/posts/" + post_id + "\">post #" + post_id + "</a>");
const message = $
.map(data.responseJSON.errors, function (msg) { return msg; })
.join("; ");
$(window).trigger("danbooru:error", `There was an error updating <a href="/posts/${post_id}">post #${post_id}</a>: ${message}`);
},
});
});

View File

@ -194,8 +194,9 @@ class Pool < ApplicationRecord
post_ids_before = post_ids_before_last_save || post_ids_was
added = post_ids - post_ids_before
return unless added.size > 0
if post_ids.size > 1_000
errors.add(:base, "Pools can have up to 1,000 posts each")
max = Danbooru.config.pool_post_limit(CurrentUser.user)
if post_ids.size > max
errors.add(:base, "Pools can only have up to #{ActiveSupport::NumberHelper.number_to_delimited(max)} posts each")
false
else
true
@ -211,6 +212,7 @@ class Pool < ApplicationRecord
reload
self.skip_sync = true
update(post_ids: post_ids + [post.id])
raise(ActiveRecord::Rollback) unless valid?
self.skip_sync = false
post.add_pool!(self)
post.save
@ -232,6 +234,7 @@ class Pool < ApplicationRecord
reload
self.skip_sync = true
update(post_ids: post_ids - [post.id])
raise(ActiveRecord::Rollback) unless valid?
self.skip_sync = false
post.remove_pool!(self)
post.save

View File

@ -730,40 +730,76 @@ class Post < ApplicationRecord
@post_metatags.each do |tag|
case tag
when /^-pool:(\d+)$/i
pool = Pool.find_by_id($1.to_i)
pool.remove!(self) if pool
pool = Pool.find_by(id: $1.to_i)
if pool
pool.remove!(self)
if pool.errors.any?
errors.add(:base, pool.errors.full_messages.join("; "))
end
end
when /^-pool:(.+)$/i
pool = Pool.find_by_name($1)
pool.remove!(self) if pool
pool = Pool.find_by(name: $1)
if pool
pool.remove!(self)
if pool.errors.any?
errors.add(:base, pool.errors.full_messages.join("; "))
end
end
when /^pool:(\d+)$/i
pool = Pool.find_by_id($1.to_i)
pool.add!(self) if pool
pool = Pool.find_by(id: $1.to_i)
if pool
pool.add!(self)
if pool.errors.any?
errors.add(:base, pool.errors.full_messages.join("; "))
end
end
when /^pool:(.+)$/i
pool = Pool.find_by_name($1)
pool.add!(self) if pool
when /^newpool:(.+)$/i
pool = Pool.find_by_name($1)
pool.add!(self) if pool
when /^(?:new)?pool:(.+)$/i
pool = Pool.find_by(name: $1)
if pool
pool.add!(self)
if pool.errors.any?
errors.add(:base, pool.errors.full_messages.join("; "))
end
end
when /^set:(\d+)$/i
set = PostSet.find_by_id($1.to_i)
set.add!(self) if set&.can_edit_posts?(CurrentUser.user)
set = PostSet.find_by(id: $1.to_i)
if set&.can_edit_posts?(CurrentUser.user)
set.add!(self)
if set.errors.any?
errors.add(:base, set.errors.full_messages.join("; "))
end
end
when /^-set:(\d+)$/i
set = PostSet.find_by_id($1.to_i)
set.remove!(self) if set&.can_edit_posts?(CurrentUser.user)
set = PostSet.find_by(id: $1.to_i)
if set&.can_edit_posts?(CurrentUser.user)
set.remove!(self)
if set.errors.any?
errors.add(:base, set.errors.full_messages.join("; "))
end
end
when /^set:(.+)$/i
set = PostSet.find_by_shortname($1)
set.add!(self) if set&.can_edit_posts?(CurrentUser.user)
set = PostSet.find_by(shortname: $1)
if set&.can_edit_posts?(CurrentUser.user)
set.add!(self)
if set.errors.any?
errors.add(:base, set.errors.full_messages.join("; "))
end
end
when /^-set:(.+)$/i
set = PostSet.find_by_shortname($1)
set.remove!(self) if set&.can_edit_posts?(CurrentUser.user)
set = PostSet.find_by(shortname: $1)
if set&.can_edit_posts?(CurrentUser.user)
set.remove!(self)
if set.errors.any?
errors.add(:base, set.errors.full_messages.join("; "))
end
end
when /^child:none$/i
children.each do |post|

View File

@ -136,8 +136,9 @@ class PostSet < ApplicationRecord
post_ids_before = post_ids_before_last_save || post_ids_was
added = post_ids - post_ids_before
return unless added.size > 0
if post_ids.size > 10_000
errors.add(:base, "Sets can have up to 10,000 posts each")
max = Danbooru.config.set_post_limit(CurrentUser.user)
if post_ids.size > max
errors.add(:base, "Sets can only have up to #{ActiveSupport::NumberHelper.number_to_delimited(max)} posts each")
false
else
true
@ -203,6 +204,7 @@ class PostSet < ApplicationRecord
reload
self.skip_sync = true
update(post_ids: post_ids + [post.id])
raise(ActiveRecord::Rollback) unless valid?
post.add_set!(self, true)
post.save
end
@ -219,6 +221,7 @@ class PostSet < ApplicationRecord
reload
self.skip_sync = true
update(post_ids: post_ids - [post.id])
raise(ActiveRecord::Rollback) unless valid?
post.remove_set!(self)
post.save
end

View File

@ -337,6 +337,14 @@ module Danbooru
20_000
end
def pool_post_limit(_user)
1_000
end
def set_post_limit(_user) # rubocop:disable Naming/AccessorMethodName
10_000
end
def discord_site
end

View File

@ -2269,4 +2269,99 @@ class PostTest < ActiveSupport::TestCase
end
end
end
context "Metatags:" do
context "set:" do
setup do
@set = create(:post_set, creator: @user)
@post = create(:post)
end
context "with an id" do
should "work" do
@post.update(tag_string_diff: "set:#{@set.id}")
assert_equal([@post.id], @set.reload.post_ids)
assert_equal("set:#{@set.id}", @post.pool_string)
end
should "gracefully fail if the set is full" do
Danbooru.config.stubs(:set_post_limit).returns(0)
@post.update(tag_string_diff: "set:#{@set.id}")
assert_equal(["Sets can only have up to 0 posts each"], @post.errors.full_messages)
assert_equal([], @set.reload.post_ids)
assert_equal("", @post.pool_string)
end
end
context "with a shortname" do
should "work" do
@post.update(tag_string_diff: "set:#{@set.shortname}")
assert_equal([@post.id], @set.reload.post_ids)
assert_equal("set:#{@set.id}", @post.pool_string)
end
should "gracefully fail if the set is full" do
Danbooru.config.stubs(:set_post_limit).returns(0)
@post.update(tag_string_diff: "set:#{@set.shortname}")
assert_equal(["Sets can only have up to 0 posts each"], @post.errors.full_messages)
assert_equal([], @set.reload.post_ids)
assert_equal("", @post.pool_string)
end
end
end
context "pool:" do
setup do
@pool = create(:pool)
@post = create(:post)
end
context "with an id" do
should "work" do
@post.update(tag_string_diff: "pool:#{@pool.id}")
assert_equal([@post.id], @pool.reload.post_ids)
assert_equal("pool:#{@pool.id}", @post.pool_string)
end
should "gracefully fail if the pool is full" do
Danbooru.config.stubs(:pool_post_limit).returns(0)
@post.update(tag_string_diff: "pool:#{@pool.id}")
assert_equal(["Pools can only have up to 0 posts each"], @post.errors.full_messages)
assert_equal([], @pool.reload.post_ids)
assert_equal("", @post.pool_string)
end
end
context "with a name" do
should "work" do
@post.update(tag_string_diff: "pool:#{@pool.name}")
assert_equal([@post.id], @pool.reload.post_ids)
assert_equal("pool:#{@pool.id}", @post.pool_string)
end
should "gracefully fail if the pool is full" do
Danbooru.config.stubs(:pool_post_limit).returns(0)
@post.update(tag_string_diff: "pool:#{@pool.name}")
assert_equal(["Pools can only have up to 0 posts each"], @post.errors.full_messages)
assert_equal([], @pool.reload.post_ids)
assert_equal("", @post.pool_string)
end
end
end
context "newpool:" do
setup do
@post = create(:post)
end
should "work" do
assert_difference("Pool.count", 1) do
@post.update(tag_string_diff: "newpool:test")
end
@pool = Pool.last
assert_equal([@post.id], @pool.reload.post_ids)
assert_equal("pool:#{@pool.id}", @post.pool_string)
end
end
end
end