From c056f821bdb9ac4eeafca8d3b7a75ab937393f25 Mon Sep 17 00:00:00 2001 From: Sing Wong Date: Mon, 11 Nov 2024 12:07:41 +0800 Subject: [PATCH 1/7] [Docker] Adding Apple Silicon Mac support in Docker Container (#785) --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2f4e3ba37..29e5e2818 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 From 0af8600caed34cc9d40f34de95d99e38e3f282e6 Mon Sep 17 00:00:00 2001 From: Sing Wong Date: Mon, 11 Nov 2024 12:18:58 +0800 Subject: [PATCH 2/7] [Posts] Fix parent children preview too small in mobile view (#786) --- app/javascript/src/styles/common/z_responsive.scss | 5 ++--- app/javascript/src/styles/specific/posts.scss | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/javascript/src/styles/common/z_responsive.scss b/app/javascript/src/styles/common/z_responsive.scss index c32414b1d..be1c43a97 100644 --- a/app/javascript/src/styles/common/z_responsive.scss +++ b/app/javascript/src/styles/common/z_responsive.scss @@ -212,8 +212,7 @@ text-align: center; vertical-align: middle; display: inline-block; - width: 100%; - container-type: inline-size; + width: fit-content; a { margin: 0 auto; @@ -234,7 +233,7 @@ img { height: auto; max-height: none; - max-width: none; + max-width: fit-content; width: 100cqw; &.has-cropped-false { diff --git a/app/javascript/src/styles/specific/posts.scss b/app/javascript/src/styles/specific/posts.scss index 44772ee9a..e8cc8474c 100644 --- a/app/javascript/src/styles/specific/posts.scss +++ b/app/javascript/src/styles/specific/posts.scss @@ -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; @@ -156,11 +156,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; From 0fb0418d7bd01a8ecbda578950d0c8636eb7ee74 Mon Sep 17 00:00:00 2001 From: clragon Date: Mon, 11 Nov 2024 05:21:10 +0100 Subject: [PATCH 3/7] [PostVersions] Fix version ordering (#787) --- app/logical/elastic_post_version_query_builder.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/logical/elastic_post_version_query_builder.rb b/app/logical/elastic_post_version_query_builder.rb index 2048145d3..ad720d472 100644 --- a/app/logical/elastic_post_version_query_builder.rb +++ b/app/logical/elastic_post_version_query_builder.rb @@ -61,5 +61,7 @@ class ElasticPostVersionQueryBuilder < ElasticQueryBuilder must.push({ term: { version: 1 } }) end end + + apply_basic_order end end From cf94b1b827847a2fa6301297b3c0e0d87e1471a4 Mon Sep 17 00:00:00 2001 From: Tarrgon <61888458+Tarrgon@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:22:14 -0500 Subject: [PATCH 4/7] [DangerZone] Allow admins to hide pending posts for a specified amount of hours (#760) --- .../admin/danger_zone_controller.rb | 9 ++++++ app/controllers/posts_controller.rb | 2 ++ app/logical/danger_zone.rb | 18 +++++++++++ app/logical/elastic_post_query_builder.rb | 32 +++++++++++++++++++ app/views/admin/danger_zone/index.html.erb | 10 ++++++ config/routes.rb | 1 + .../admin/danger_zone_controller_test.rb | 8 +++++ 7 files changed, 80 insertions(+) diff --git a/app/controllers/admin/danger_zone_controller.rb b/app/controllers/admin/danger_zone_controller.rb index 0bbb2a6da..cdfb0708f 100644 --- a/app/controllers/admin/danger_zone_controller.rb +++ b/app/controllers/admin/danger_zone_controller.rb @@ -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 diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index a7d7d0fbb..31b6aa2c6 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -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) diff --git a/app/logical/danger_zone.rb b/app/logical/danger_zone.rb index fe251e620..85c42e3ec 100644 --- a/app/logical/danger_zone.rb +++ b/app/logical/danger_zone.rb @@ -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 diff --git a/app/logical/elastic_post_query_builder.rb b/app/logical/elastic_post_query_builder.rb index 8a61c92de..fd73fdc83 100644 --- a/app/logical/elastic_post_query_builder.rb +++ b/app/logical/elastic_post_query_builder.rb @@ -314,5 +314,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 diff --git a/app/views/admin/danger_zone/index.html.erb b/app/views/admin/danger_zone/index.html.erb index b1a883df6..5bf57b1c4 100644 --- a/app/views/admin/danger_zone/index.html.erb +++ b/app/views/admin/danger_zone/index.html.erb @@ -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 %> +

Pending Posts

+ <% if DangerZone.hide_pending_posts_for > 0 %> + Unapproved posts are currently only visible to staff for <%= DangerZone.hide_pending_posts_for %> 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 %> diff --git a/config/routes.rb b/config/routes.rb index 3d529365d..55fa01dd9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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 diff --git a/test/functional/admin/danger_zone_controller_test.rb b/test/functional/admin/danger_zone_controller_test.rb index d2f38623e..b1804f454 100644 --- a/test/functional/admin/danger_zone_controller_test.rb +++ b/test/functional/admin/danger_zone_controller_test.rb @@ -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 From 9a9f175da4559d885969dca25b6c6d731c63c116 Mon Sep 17 00:00:00 2001 From: Tarrgon <61888458+Tarrgon@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:22:40 -0500 Subject: [PATCH 5/7] [DText] Add newline normalization (#699) --- app/models/blip.rb | 1 + app/models/comment.rb | 1 + app/models/dmail.rb | 1 + app/models/forum_post.rb | 1 + app/models/note.rb | 1 + app/models/pool.rb | 1 + app/models/post.rb | 1 + app/models/ticket.rb | 1 + app/models/user.rb | 1 + app/models/user_feedback.rb | 1 + app/models/wiki_page.rb | 1 + 11 files changed, 11 insertions(+) diff --git a/app/models/blip.rb b/app/models/blip.rb index 62bc2ac94..64e23a295 100644 --- a/app/models/blip.rb +++ b/app/models/blip.rb @@ -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 diff --git a/app/models/comment.rb b/app/models/comment.rb index 859aa119b..8e2a0b7ed 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -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 diff --git a/app/models/dmail.rb b/app/models/dmail.rb index a4d7d6858..1d5ed6698 100644 --- a/app/models/dmail.rb +++ b/app/models/dmail.rb @@ -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 } diff --git a/app/models/forum_post.rb b/app/models/forum_post.rb index 45f650981..fcab44ea3 100644 --- a/app/models/forum_post.rb +++ b/app/models/forum_post.rb @@ -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 diff --git a/app/models/note.rb b/app/models/note.rb index 2cf867288..79884049c 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -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 diff --git a/app/models/pool.rb b/app/models/pool.rb index 0aa60bb24..7930268ba 100644 --- a/app/models/pool.rb +++ b/app/models/pool.rb @@ -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 } diff --git a/app/models/post.rb b/app/models/post.rb index 680a11af5..ad1954289 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -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 diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 81f550c77..3a4ab31ea 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -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 } diff --git a/app/models/user.rb b/app/models/user.rb index 53a5f8b92..5c0956c23 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 } diff --git a/app/models/user_feedback.rb b/app/models/user_feedback.rb index d8a4ab158..d3361d98f 100644 --- a/app/models/user_feedback.rb +++ b/app/models/user_feedback.rb @@ -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 } diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 42969006f..a0ae4c1cd 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -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? From c137f17f9cd3f863ba82c64943fa6b10839498e9 Mon Sep 17 00:00:00 2001 From: jmortiger Date: Sun, 10 Nov 2024 23:23:56 -0500 Subject: [PATCH 6/7] [Blacklist] Add fuzzy direct equality to filesize blacklist tag (#784) The search metatag `filesize`, when using a direct equality comparison (`=`, e.g. `filesize:10kb`), instead uses a range comparison (`..`) with the bounds being the value + & - 5% (e.g. `filesize:10kb` is equal to `filesize:9.5kb..10.5kb`). The equivalent blacklist tag mirrored the search metatag in all aspects but this; this commit adds this fuzzy matching capability. --- app/javascript/src/javascripts/models/Filter.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/javascript/src/javascripts/models/Filter.js b/app/javascript/src/javascripts/models/Filter.js index f8d5e85d1..24eeabbd7 100644 --- a/app/javascript/src/javascripts/models/Filter.js +++ b/app/javascript/src/javascripts/models/Filter.js @@ -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), + ]; + } + } } /** From 414f9e662982be684875c087db64a3dfcb9158bb Mon Sep 17 00:00:00 2001 From: Cinder Date: Tue, 12 Nov 2024 15:16:19 -0800 Subject: [PATCH 7/7] [Posts] Fix thumbnail issues (#789) --- .../src/styles/common/z_responsive.scss | 22 +++++++------------ app/javascript/src/styles/specific/users.scss | 3 ++- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/app/javascript/src/styles/common/z_responsive.scss b/app/javascript/src/styles/common/z_responsive.scss index be1c43a97..697d23eb0 100644 --- a/app/javascript/src/styles/common/z_responsive.scss +++ b/app/javascript/src/styles/common/z_responsive.scss @@ -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,7 +211,7 @@ text-align: center; vertical-align: middle; display: inline-block; - width: fit-content; + width: 31vw; a { margin: 0 auto; @@ -220,7 +219,7 @@ img { max-height: 150px; - max-width: 100cqw; + max-width: 31vw; } .desc { @@ -230,11 +229,13 @@ .user-disable-cropped-false { article.post-preview { + width: 31vw; + img { height: auto; max-height: none; - max-width: fit-content; - width: 100cqw; + max-width: none; + width: 31vw; &.has-cropped-false { object-fit: cover; @@ -313,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 { diff --git a/app/javascript/src/styles/specific/users.scss b/app/javascript/src/styles/specific/users.scss index a092d5814..7e9305cb7 100644 --- a/app/javascript/src/styles/specific/users.scss +++ b/app/javascript/src/styles/specific/users.scss @@ -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 {