File limits and processing that matches closer to e6

This commit is contained in:
Kira 2019-06-16 18:47:05 -07:00
parent f5d29b920a
commit a907df4b9a
5 changed files with 95 additions and 56 deletions

View File

@ -24,7 +24,7 @@ class UploadService
end
end
def delete_file(md5, file_ext, upload_id = nil)
def delete_file(md5, file_ext, upload_id = nil)
if Post.where(md5: md5).exists?
if upload_id.present? && Upload.where(id: upload_id).exists?
CurrentUser.as_system do
@ -98,7 +98,8 @@ class UploadService
if upload.is_video?
video = FFMPEG::Movie.new(file.path)
crop_file = generate_video_crop_for(video, Danbooru.config.small_image_width)
preview_file = generate_video_preview_for(video, Danbooru.config.small_image_width, Danbooru.config.small_image_width)
preview_file = generate_video_preview_for(file.path, Danbooru.config.small_image_width)
sample_file = generate_video_sample_for(file.path)
elsif upload.is_ugoira?
preview_file = PixivUgoiraConverter.generate_preview(file)
@ -124,16 +125,27 @@ class UploadService
return crop
end
def generate_video_preview_for(video, width, height)
dimension_ratio = video.width.to_f / video.height
if dimension_ratio > 1
height = (width / dimension_ratio).to_i
else
width = (height * dimension_ratio).to_i
end
def generate_video_preview_for(video, width)
output_file = Tempfile.new(["video-preview", ".jpg"], binmode: true)
video.screenshot(output_file.path, {:seek_time => 0, :resolution => "#{width}x#{height}"})
stdout, stderr, status = Open3.capture3(Danbooru.config.ffmpeg_path, '-y', '-i', video, '-vf', "thumbnail,scale=#{width}:-1", '-frames:v', '1', output_file.path)
unless status == 0
Rails.logger.warn("[FFMPEG PREVIEW STDOUT] #{stdout.chomp!}")
Rails.logger.warn("[FFMPEG PREVIEW STDERR] #{stderr.chomp!}")
raise CorruptFileError.new("could not generate thumbnail")
end
output_file
end
def generate_video_sample_for(video)
output_file = Tempfile.new(["video-sample", ".jpg"], binmode: true)
stdout, stderr, status = Open3.capture3(Danbooru.config.ffmpeg_path, '-y', '-i', video, '-vf', 'thumbnail', '-frames:v', '1', output_file.path)
unless status == 0
Rails.logger.warn("[FFMPEG SAMPLE STDOUT] #{stdout.chomp!}")
Rails.logger.warn("[FFMPEG SAMPLE STDERR] #{stderr.chomp!}")
raise CorruptFileError.new("could not generate sample")
end
output_file
end
@ -148,6 +160,8 @@ class UploadService
upload.image_height = height
end
upload.is_apng = is_animated_png?(upload, file)
upload.validate!(:file)
upload.tag_string = "#{upload.tag_string} #{Utils.automatic_tags(upload, file)}"
@ -169,8 +183,8 @@ class UploadService
UploadDeleteFilesJob.set(wait: 24.hours).perform_later(upload.md5, upload.file_ext, upload.id)
end
# these methods are only really used during upload processing even
# though logically they belong on upload. post can rely on the
# these methods are only really used during upload processing even
# though logically they belong on upload. post can rely on the
# automatic tag that's added.
def is_animated_gif?(upload, file)
return false if upload.file_ext != "gif"
@ -230,7 +244,7 @@ class UploadService
end
if download.data[:ugoira_frame_data].present?
upload.context = {
upload.context = {
"ugoira" => {
"frame_data" => download.data[:ugoira_frame_data],
"content_type" => "image/jpeg"

View File

@ -242,6 +242,7 @@ class Post < ApplicationRecord
end
def has_large?
return true if is_video?
return false if has_tag?("animated_gif|animated_png")
return true if is_ugoira?
is_image? && image_width.present? && image_width > Danbooru.config.large_image_width

View File

@ -7,6 +7,7 @@ class Upload < ApplicationRecord
def validate(record)
validate_file_ext(record)
validate_md5_uniqueness(record)
validate_file_size(record)
validate_video_duration(record)
validate_resolution(record)
end
@ -17,6 +18,16 @@ class Upload < ApplicationRecord
end
end
def validate_file_size(record)
max_size = Danbooru.config.max_file_sizes.fetch(record.file_ext, 0)
if record.file_size > max_size
record.errors[:file_size] << "is too large. Maximum allowed for this file type is #{max_size / (1024*1024)} MiB"
end
if record.is_apng && record.file_size > Danbooru.config.max_apng_file_size
record.errors[:file_size] << "is too large. Maximum allowed for this file type is #{Danbooru.config.max_apng_file_size / (1024*1024)} MiB"
end
end
def validate_md5_uniqueness(record)
if record.md5.nil?
return
@ -48,14 +59,14 @@ class Upload < ApplicationRecord
end
def validate_video_duration(record)
if record.is_video? && record.video.duration > 120
record.errors[:base] << "video must not be longer than 2 minutes"
if record.is_video? && record.video.duration > Danbooru.config.max_video_duration
record.errors[:base] << "video must not be longer than #{Danbooru.config.max_video_duration} seconds"
end
end
end
attr_accessor :as_pending, :replaced_post, :file, :direct_url
attr_accessor :as_pending, :replaced_post, :file, :direct_url, :is_apng
belongs_to :uploader, :class_name => "User"
belongs_to :post, optional: true

View File

@ -1,12 +1,12 @@
<% if post.is_ugoira? %>
<%= content_tag(:video, nil, :id => "image", :width => post.image_width, :height => post.image_height, :autoplay => true, :loop => !post.has_tag?("video_with_sound"), :controls => "controls", :src => post.tagged_large_file_url) %>
<%= content_tag(:video, nil, :id => "image", :width => post.image_width, :height => post.image_height, :loop => !post.has_tag?("video_with_sound"), :controls => "controls", :src => post.tagged_large_file_url) %>
<p><%= link_to "Save this video (right click and save)", post.tagged_large_file_url %></p>
<% else %>
<%= content_tag(:video, nil, :id => "image", :width => post.image_width, :height => post.image_height, :autoplay => true, :loop => !post.has_tag?("video_with_sound"), :controls => "controls", :src => post.tagged_file_url) %>
<%= content_tag(:video, nil, :id => "image", :width => post.image_width, :height => post.image_height, :loop => !post.has_tag?("video_with_sound"), :controls => "controls", poster: post.large_file_url, :src => post.tagged_file_url) %>
<p><%= link_to "Save this video (right click and save)", post.tagged_file_url %></p>
<% end %>
<% end %>

View File

@ -4,24 +4,24 @@ module Danbooru
class Configuration
# The version of this Danbooru.
def version
"2.105.0"
"2.0.0"
end
# The name of this Danbooru.
def app_name
if CurrentUser.safe_mode?
"Safebooru"
"e926"
else
"Danbooru"
"e621"
end
end
def description
"Find good anime art fast"
"Find good furry art, fast"
end
def domain
"donmai.us"
"e621.net"
end
# The canonical hostname of the site.
@ -37,7 +37,7 @@ module Danbooru
# Contact email address of the admin.
def contact_email
"webmaster@#{server_host}"
"management@#{server_host}"
end
def takedown_email
@ -53,7 +53,7 @@ module Danbooru
#
# Run `rake db:seed` to create this account if it doesn't already exist in your install.
def system_user
"DanbooruBot"
"E621_Bot"
end
def upload_feedback_topic
@ -65,7 +65,7 @@ module Danbooru
end
def source_code_url
"https://github.com/r888888888/danbooru"
"https://github.com/zwagoth/e621ng"
end
def commit_url(hash)
@ -118,6 +118,12 @@ module Danbooru
:local_flat
end
# This allows using statically linked copies of ffmpeg in non default locations. Not universally supported across
# the codebase at this time.
def ffmpeg_path
"/usr/bin/ffmpeg"
end
# Thumbnail size
def small_image_width
150
@ -209,22 +215,42 @@ module Danbooru
# Maximum size of an upload. If you change this, you must also change
# `client_max_body_size` in your nginx.conf.
def max_file_size
35.megabytes
100.megabytes
end
def max_file_sizes
{
'jpg' => 100.megabytes,
'gif' => 20.megabytes,
'png' => 100.megabytes,
'swf' => 100.megabytes,
'webm' => 100.megabytes,
'mp4' => 100.megabytes
}
end
def max_apng_file_size
20.megabytes
end
# Measured in seconds
def max_video_duration
600
end
# Maximum resolution (width * height) of an upload. Default: 441 megapixels (21000x21000 pixels).
def max_image_resolution
21000 * 21000
15000 * 15000
end
# Maximum width of an upload.
def max_image_width
40000
15000
end
# Maximum height of an upload.
def max_image_height
40000
15000
end
def member_comment_time_threshold
@ -590,7 +616,7 @@ module Danbooru
def stripe_secret_key
end
def stripe_publishable_key
end
@ -629,31 +655,14 @@ module Danbooru
# For downloads, if the host matches any of these IPs, block it
def banned_ip_for_download?(ip_addr)
raise ArgumentError unless ip_addr.is_a?(IPAddr)
ipv4s = %w(127.0.0.1/8 169.254.0.0/16 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16)
ipv6s = %w(::1 fe80::/10 fd00::/8)
if ip_addr.ipv4?
if IPAddr.new("127.0.0.1") == ip_addr
true
elsif IPAddr.new("169.254.0.0/16").include?(ip_addr)
true
elsif IPAddr.new("10.0.0.0/8").include?(ip_addr)
true
elsif IPAddr.new("172.16.0.0/12").include?(ip_addr)
true
elsif IPAddr.new("192.168.0.0/16").include?(ip_addr)
true
else
false
end
ipv4s.any? {|range| IPAddr.new(range).include?(ip_addr)}
elsif ip_addr.ipv6?
if IPAddr.new("::1") == ip_addr
true
elsif IPAddr.new("fe80::/10").include?(ip_addr)
true
elsif IPAddr.new("fd00::/8").include?(ip_addr)
true
else
false
end
ipv6s.any? {|range| IPAddr.new(range).include?(ip_addr)}
else
false
end
@ -698,6 +707,10 @@ module Danbooru
def reportbooru_key
end
def iqdb_enabled?
false
end
# iqdbs options - see https://github.com/r888888888/iqdbs
def iqdbs_auth_key
end
@ -720,7 +733,7 @@ module Danbooru
def enable_image_cropping
true
end
# Akismet API key. Used for Dmail spam detection. http://akismet.com/signup/
def rakismet_key
end