forked from e621ng/e621ng
Merge branch 'master' into master2
This commit is contained in:
commit
0d5984af63
@ -1,6 +1,6 @@
|
||||
FROM ruby:3.3.1-alpine3.19 as ruby-builder
|
||||
|
||||
RUN apk --no-cache add build-base cmake git glib-dev postgresql15-dev
|
||||
RUN apk --no-cache add build-base cmake git glib-dev postgresql15-dev gcompat
|
||||
|
||||
COPY Gemfile Gemfile.lock ./
|
||||
RUN gem i foreman && BUNDLE_IGNORE_CONFIG=true bundle install -j$(nproc) \
|
||||
@ -19,7 +19,7 @@ FROM ruby:3.3.1-alpine3.19
|
||||
RUN apk --no-cache add ffmpeg vips \
|
||||
postgresql15-client \
|
||||
git jemalloc tzdata \
|
||||
sudo
|
||||
sudo gcompat
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
@ -16,5 +16,14 @@ module Admin
|
||||
end
|
||||
redirect_to admin_danger_zone_index_path
|
||||
end
|
||||
|
||||
def hide_pending_posts
|
||||
duration = params[:hide_pending_posts][:duration].to_f
|
||||
if duration >= 0 && duration != DangerZone.hide_pending_posts_for
|
||||
DangerZone.hide_pending_posts_for = duration
|
||||
StaffAuditLog.log(:hide_pending_posts_for, CurrentUser.user, { duration: duration })
|
||||
end
|
||||
redirect_to admin_danger_zone_index_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -26,6 +26,8 @@ class PostsController < ApplicationController
|
||||
def show
|
||||
@post = Post.find(params[:id])
|
||||
|
||||
raise User::PrivilegeError.new("Post unavailable") unless DangerZone.post_visible?(@post, CurrentUser.user)
|
||||
|
||||
include_deleted = @post.is_deleted? || (@post.parent_id.present? && @post.parent.is_deleted?) || CurrentUser.is_approver?
|
||||
@parent_post_set = PostSets::PostRelationship.new(@post.parent_id, :include_deleted => include_deleted, want_parent: true)
|
||||
@children_post_set = PostSets::PostRelationship.new(@post.id, :include_deleted => include_deleted, want_parent: false)
|
||||
|
@ -170,7 +170,19 @@ class FilterToken {
|
||||
];
|
||||
}
|
||||
}
|
||||
} else this.value = FilterUtils.normalizeData(raw, this.type);
|
||||
} else {
|
||||
this.value = FilterUtils.normalizeData(raw, this.type);
|
||||
if (this.comparison === "=" && this.type === "filesize") {
|
||||
// If the comparison uses direct equality, mirror the fudging behavior of
|
||||
// the filesize search metatag by changing the comparison to a range of
|
||||
// the initial value -5% and +5%.
|
||||
this.comparison = "..";
|
||||
this.value = [
|
||||
Math.trunc(this.value * 0.95),
|
||||
Math.trunc(this.value * 1.05),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,9 +199,8 @@
|
||||
|
||||
#posts #posts-container {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 1vw;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
@ -212,8 +211,7 @@
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
container-type: inline-size;
|
||||
width: 31vw;
|
||||
|
||||
a {
|
||||
margin: 0 auto;
|
||||
@ -221,7 +219,7 @@
|
||||
|
||||
img {
|
||||
max-height: 150px;
|
||||
max-width: 100cqw;
|
||||
max-width: 31vw;
|
||||
}
|
||||
|
||||
.desc {
|
||||
@ -231,11 +229,13 @@
|
||||
|
||||
.user-disable-cropped-false {
|
||||
article.post-preview {
|
||||
width: 31vw;
|
||||
|
||||
img {
|
||||
height: auto;
|
||||
max-height: none;
|
||||
max-width: none;
|
||||
width: 100cqw;
|
||||
width: 31vw;
|
||||
|
||||
&.has-cropped-false {
|
||||
object-fit: cover;
|
||||
@ -314,13 +314,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 800px) and (horizontal-viewport-segments: 2) {
|
||||
body.resp {
|
||||
#posts #posts-container {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 660px) {
|
||||
body.resp {
|
||||
|
@ -6,7 +6,7 @@
|
||||
article.post-preview {
|
||||
box-sizing: border-box;
|
||||
height: auto;
|
||||
width: 154px;
|
||||
width: fit-content;
|
||||
margin: 0 10px 10px 0;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
@ -160,11 +160,10 @@ body[data-user-can-approve-posts="true"] .post-preview {
|
||||
}
|
||||
|
||||
#has-parent-relationship-preview, #has-children-relationship-preview {
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
article.post-preview {
|
||||
width: auto;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 5px 5px 10px;
|
||||
|
@ -160,7 +160,7 @@ div#c-users {
|
||||
grid-area: p-posts;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
justify-content: flex-start;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
gap: 1em;
|
||||
@ -173,6 +173,7 @@ div#c-users {
|
||||
@include window-larger-than(800px) {
|
||||
flex-wrap: nowrap;
|
||||
border-top-left-radius: 0;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
article.post-preview {
|
||||
|
@ -5,6 +5,14 @@ module DangerZone
|
||||
user.level < min_upload_level
|
||||
end
|
||||
|
||||
def self.post_visible?(post, user)
|
||||
if hide_pending_posts_for <= 0
|
||||
return true
|
||||
end
|
||||
|
||||
post.uploader_id == user.id || user.is_staff? || !post.is_pending? || post.created_at.before?(hide_pending_posts_for.hours.ago)
|
||||
end
|
||||
|
||||
def self.min_upload_level
|
||||
(Cache.redis.get("min_upload_level") || User::Levels::MEMBER).to_i
|
||||
rescue Redis::CannotConnectError
|
||||
@ -14,4 +22,14 @@ module DangerZone
|
||||
def self.min_upload_level=(min_upload_level)
|
||||
Cache.redis.set("min_upload_level", min_upload_level)
|
||||
end
|
||||
|
||||
def self.hide_pending_posts_for
|
||||
Cache.redis.get("hide_pending_posts_for").to_f || 0
|
||||
rescue Redis::CannotConnectError
|
||||
PostPruner::DELETION_WINDOW * 24
|
||||
end
|
||||
|
||||
def self.hide_pending_posts_for=(duration)
|
||||
Cache.redis.set("hide_pending_posts_for", duration)
|
||||
end
|
||||
end
|
||||
|
@ -324,5 +324,37 @@ class ElasticPostQueryBuilder < ElasticQueryBuilder
|
||||
else
|
||||
order.push({id: :desc})
|
||||
end
|
||||
|
||||
if !CurrentUser.user.is_staff? && DangerZone.hide_pending_posts_for > 0
|
||||
should = [
|
||||
{
|
||||
range: {
|
||||
created_at: {
|
||||
lte: DangerZone.hide_pending_posts_for.hours.ago,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
pending: false,
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
unless CurrentUser.user.id.nil?
|
||||
should.push({
|
||||
term: {
|
||||
uploader: CurrentUser.user.id,
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
must.push({
|
||||
bool: {
|
||||
should: should,
|
||||
minimum_should_match: 1,
|
||||
},
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -61,5 +61,7 @@ class ElasticPostVersionQueryBuilder < ElasticQueryBuilder
|
||||
must.push({ term: { version: 1 } })
|
||||
end
|
||||
end
|
||||
|
||||
apply_basic_order
|
||||
end
|
||||
end
|
||||
|
@ -5,6 +5,7 @@ class Blip < ApplicationRecord
|
||||
simple_versioning
|
||||
belongs_to_creator
|
||||
belongs_to_updater optional: true
|
||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||
validates :body, presence: true
|
||||
validates :body, length: { minimum: 5, maximum: Danbooru.config.blip_max_size }
|
||||
validate :validate_parent_exists, on: :create
|
||||
|
@ -6,6 +6,7 @@ class Comment < ApplicationRecord
|
||||
simple_versioning
|
||||
belongs_to_creator
|
||||
belongs_to_updater
|
||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||
validate :validate_post_exists, on: :create
|
||||
validate :validate_creator_is_not_limited, on: :create
|
||||
validate :post_not_comment_locked, on: :create
|
||||
|
@ -1,6 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Dmail < ApplicationRecord
|
||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||
validates :title, :body, presence: { on: :create }
|
||||
validates :title, length: { minimum: 1, maximum: 250 }
|
||||
validates :body, length: { minimum: 1, maximum: Danbooru.config.dmail_max_size }
|
||||
|
@ -16,6 +16,7 @@ class ForumPost < ApplicationRecord
|
||||
before_validation :initialize_is_hidden, :on => :create
|
||||
after_create :update_topic_updated_at_on_create
|
||||
after_destroy :update_topic_updated_at_on_destroy
|
||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||
validates :body, :creator_id, presence: true
|
||||
validates :body, length: { minimum: 1, maximum: Danbooru.config.forum_post_max_size }
|
||||
validate :validate_topic_is_unlocked
|
||||
|
@ -7,6 +7,7 @@ class Note < ApplicationRecord
|
||||
belongs_to :post
|
||||
belongs_to_creator
|
||||
has_many :versions, -> {order("note_versions.id ASC")}, :class_name => "NoteVersion", :dependent => :destroy
|
||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||
validates :post_id, :creator_id, :x, :y, :width, :height, :body, presence: true
|
||||
validate :user_not_limited
|
||||
validate :post_must_exist
|
||||
|
@ -7,6 +7,7 @@ class Pool < ApplicationRecord
|
||||
array_attribute :post_ids, parse: %r{(?:https://(?:e621|e926)\.net/posts/)?(\d+)}i, cast: :to_i
|
||||
belongs_to_creator
|
||||
|
||||
normalizes :description, with: ->(desc) { desc.gsub("\r\n", "\n") }
|
||||
validates :name, uniqueness: { case_sensitive: false, if: :name_changed? }
|
||||
validates :name, length: { minimum: 1, maximum: 250 }
|
||||
validates :description, length: { maximum: Danbooru.config.pool_descr_max_size }
|
||||
|
@ -18,6 +18,7 @@ class Post < ApplicationRecord
|
||||
before_validation :fix_bg_color
|
||||
before_validation :blank_out_nonexistent_parents
|
||||
before_validation :remove_parent_loops
|
||||
normalizes :description, with: ->(desc) { desc.gsub("\r\n", "\n") }
|
||||
validates :md5, uniqueness: { :on => :create, message: ->(obj, data) {"duplicate: #{Post.find_by_md5(obj.md5).id}"} }
|
||||
validates :rating, inclusion: { in: %w(s q e), message: "rating must be s, q, or e" }
|
||||
validates :bg_color, format: { with: /\A[A-Fa-f0-9]{6}\z/ }, allow_nil: true
|
||||
|
@ -10,6 +10,7 @@ class Ticket < ApplicationRecord
|
||||
before_validation :initialize_fields, on: :create
|
||||
after_initialize :validate_type
|
||||
after_initialize :classify
|
||||
normalizes :reason, with: ->(reason) { reason.gsub("\r\n", "\n") }
|
||||
validates :qtype, presence: true
|
||||
validates :reason, presence: true
|
||||
validates :reason, length: { minimum: 2, maximum: Danbooru.config.ticket_max_size }
|
||||
|
@ -65,6 +65,7 @@ class User < ApplicationRecord
|
||||
validates :email, length: { maximum: 100 }
|
||||
validate :validate_email_address_allowed, on: [:create, :update], if: ->(rec) { (rec.new_record? && rec.email.present?) || (rec.email.present? && rec.email_changed?) }
|
||||
|
||||
normalizes :profile_about, :profile_artinfo, with: ->(value) { value.gsub("\r\n", "\n") }
|
||||
validates :name, user_name: true, on: :create
|
||||
validates :default_image_size, inclusion: { :in => %w(large fit fitv original) }
|
||||
validates :per_page, inclusion: { :in => 1..320 }
|
||||
|
@ -5,6 +5,7 @@ class UserFeedback < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to_creator
|
||||
belongs_to_updater
|
||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||
validates :body, :category, presence: true
|
||||
validates :category, inclusion: { in: %w[positive negative neutral] }
|
||||
validates :body, length: { minimum: 1, maximum: Danbooru.config.user_feedback_max_size }
|
||||
|
@ -7,6 +7,7 @@ class WikiPage < ApplicationRecord
|
||||
before_validation :normalize_other_names
|
||||
before_validation :normalize_parent
|
||||
after_save :create_version
|
||||
normalizes :body, with: ->(body) { body.gsub("\r\n", "\n") }
|
||||
validates :title, uniqueness: { :case_sensitive => false }
|
||||
validates :title, presence: true
|
||||
validates :title, tag_name: true, if: :title_changed?
|
||||
|
@ -7,6 +7,16 @@
|
||||
<%= f.input :min_level, collection: User.level_hash.select {|k,v| v >= User::Levels::MEMBER }.to_a, selected: DangerZone.min_upload_level %>
|
||||
<%= f.button :submit, value: "Submit" %>
|
||||
<% end %>
|
||||
<h2>Pending Posts</h2>
|
||||
<% if DangerZone.hide_pending_posts_for > 0 %>
|
||||
Unapproved posts are currently only visible to staff for <b><%= DangerZone.hide_pending_posts_for %></b> hours.
|
||||
<% else %>
|
||||
Unapproved posts are currently not hidden.
|
||||
<% end %>
|
||||
<%= custom_form_for(:hide_pending_posts, url: hide_pending_posts_admin_danger_zone_index_path, method: :put) do |f| %>
|
||||
<%= f.input :duration, as: :float, hint: "in hours", input_html: { value: DangerZone.hide_pending_posts_for } %>
|
||||
<%= f.button :submit, value: "Submit" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -29,6 +29,7 @@ Rails.application.routes.draw do
|
||||
resources :danger_zone, only: [:index] do
|
||||
collection do
|
||||
put :uploading_limits
|
||||
put :hide_pending_posts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -10,6 +10,7 @@ class Admin::DangerZoneControllerTest < ActionDispatch::IntegrationTest
|
||||
|
||||
teardown do
|
||||
DangerZone.min_upload_level = User::Levels::MEMBER
|
||||
DangerZone.hide_pending_posts_for = 0
|
||||
end
|
||||
|
||||
context "index action" do
|
||||
@ -25,5 +26,12 @@ class Admin::DangerZoneControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_equal DangerZone.min_upload_level, User::Levels::PRIVILEGED
|
||||
end
|
||||
end
|
||||
|
||||
context "hide pending posts action" do
|
||||
should "work" do
|
||||
put_auth hide_pending_posts_admin_danger_zone_index_path, @admin, params: { hide_pending_posts: { duration: 24 } }
|
||||
assert_equal DangerZone.hide_pending_posts_for, 24
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user