uploads: use storage manager to distribute files.
Refactors the upload process to pass around temp files, rather than passing around file paths and directly writing output to the local filesystem. This way we can pass the storage manager the preview / sample / original temp files, so it can deal with storage itself. * Change Download::File#download! to return a temp file. * Change DanbooruImageResizer and PixivUgoiraConverter to accept/return temp files instead of file paths. * Change Upload#generate_resizes to return temp files for previews and samples. * Change Upload#generate_resizes to generate ugoira .webm samples synchronously instead of asynchronously.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
module DanbooruImageResizer
|
||||
def resize(read_path, write_path, width, height, resize_quality = 90)
|
||||
image = Magick::Image.read(read_path).first
|
||||
def resize(file, width, height, resize_quality = 90)
|
||||
image = Magick::Image.read(file.path).first
|
||||
geometry = "#{width}x>"
|
||||
|
||||
if width == Danbooru.config.small_image_width
|
||||
@@ -17,14 +17,15 @@ module DanbooruImageResizer
|
||||
image = flatten(image, width, height)
|
||||
image.strip!
|
||||
|
||||
image.write(write_path) do
|
||||
output_file = Tempfile.new(binmode: true)
|
||||
image.write("jpeg:" + output_file.path) do
|
||||
self.quality = resize_quality
|
||||
# setting PlaneInterlace enables progressive encoding for JPEGs
|
||||
self.interlace = Magick::PlaneInterlace
|
||||
end
|
||||
|
||||
image.destroy!
|
||||
FileUtils.chmod(0664, write_path)
|
||||
output_file
|
||||
end
|
||||
|
||||
def flatten(image, width, height)
|
||||
|
||||
@@ -3,9 +3,9 @@ module Downloads
|
||||
class Error < Exception ; end
|
||||
|
||||
attr_reader :data, :options
|
||||
attr_accessor :source, :original_source, :downloaded_source, :file_path
|
||||
attr_accessor :source, :original_source, :downloaded_source
|
||||
|
||||
def initialize(source, file_path, options = {})
|
||||
def initialize(source, options = {})
|
||||
# source can potentially get rewritten in the course
|
||||
# of downloading a file, so check it again
|
||||
@source = source
|
||||
@@ -14,9 +14,6 @@ module Downloads
|
||||
# the URL actually downloaded after rewriting the original source.
|
||||
@downloaded_source = nil
|
||||
|
||||
# where to save the download
|
||||
@file_path = file_path
|
||||
|
||||
# we sometimes need to capture data from the source page
|
||||
@data = {}
|
||||
|
||||
@@ -35,12 +32,13 @@ module Downloads
|
||||
def download!
|
||||
url, headers, @data = before_download(@source, @data)
|
||||
|
||||
::File.open(@file_path, "wb") do |out|
|
||||
http_get_streaming(uncached_url(url, headers), out, headers)
|
||||
end
|
||||
output_file = Tempfile.new(binmode: true)
|
||||
http_get_streaming(uncached_url(url, headers), output_file, headers)
|
||||
|
||||
@downloaded_source = url
|
||||
@source = after_download(url)
|
||||
|
||||
output_file
|
||||
end
|
||||
|
||||
def before_download(url, datums)
|
||||
@@ -91,7 +89,8 @@ module Downloads
|
||||
end
|
||||
|
||||
if res.success?
|
||||
return
|
||||
file.rewind
|
||||
return file
|
||||
else
|
||||
raise Error.new("HTTP error code: #{res.code} #{res.message}")
|
||||
end
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
class PixivUgoiraConverter
|
||||
def self.convert(source_path, output_path, preview_path, frame_data)
|
||||
folder = Zip::File.new(source_path)
|
||||
write_webm(folder, output_path, frame_data)
|
||||
write_preview(folder, preview_path)
|
||||
RemoteFileManager.new(output_path).distribute
|
||||
RemoteFileManager.new(preview_path).distribute
|
||||
end
|
||||
def self.generate_webm(ugoira_file, frame_data)
|
||||
folder = Zip::File.new(ugoira_file.path)
|
||||
output_file = Tempfile.new(binmode: true)
|
||||
write_path = output_file.path
|
||||
|
||||
def self.write_webm(folder, write_path, frame_data)
|
||||
Dir.mktmpdir do |tmpdir|
|
||||
FileUtils.mkdir_p("#{tmpdir}/images")
|
||||
folder.each_with_index do |file, i|
|
||||
@@ -64,14 +60,17 @@ class PixivUgoiraConverter
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
output_file
|
||||
end
|
||||
|
||||
def self.write_preview(folder, path)
|
||||
Dir.mktmpdir do |tmpdir|
|
||||
file = folder.first
|
||||
temp_path = File.join(tmpdir, file.name)
|
||||
file.extract(temp_path)
|
||||
DanbooruImageResizer.resize(temp_path, path, Danbooru.config.small_image_width, Danbooru.config.small_image_width, 85)
|
||||
end
|
||||
def self.generate_preview(ugoira_file)
|
||||
file = Tempfile.new(binmode: true)
|
||||
zipfile = Zip::File.new(ugoira_file.path)
|
||||
zipfile.entries.first.extract(file.path) { true } # 'true' means overwrite the existing tempfile.
|
||||
|
||||
DanbooruImageResizer.resize(file, Danbooru.config.small_image_width, Danbooru.config.small_image_width, 85)
|
||||
ensure
|
||||
file.close!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,32 +1,10 @@
|
||||
class PixivUgoiraService
|
||||
attr_reader :width, :height, :frame_data, :content_type
|
||||
|
||||
def self.regen(post)
|
||||
service = new()
|
||||
service.load(
|
||||
:is_ugoira => true,
|
||||
:ugoira_frame_data => post.pixiv_ugoira_frame_data.data
|
||||
)
|
||||
service.generate_resizes(post.file_path, post.large_file_path, post.preview_file_path, false)
|
||||
end
|
||||
|
||||
def save_frame_data(post)
|
||||
PixivUgoiraFrameData.create(:data => @frame_data, :content_type => @content_type, :post_id => post.id)
|
||||
end
|
||||
|
||||
def generate_resizes(source_path, output_path, preview_path, delay = true)
|
||||
# Run this a bit in the future to give the upload process time to move the file
|
||||
if delay
|
||||
PixivUgoiraConverter.delay(:queue => Socket.gethostname, :run_at => 10.seconds.from_now, :priority => -1).convert(source_path, output_path, preview_path, @frame_data)
|
||||
else
|
||||
PixivUgoiraConverter.convert(source_path, output_path, preview_path, @frame_data)
|
||||
end
|
||||
|
||||
# since the resizes will be delayed, just touch the output file so the
|
||||
# file distribution wont break
|
||||
FileUtils.touch([output_path, preview_path])
|
||||
end
|
||||
|
||||
def calculate_dimensions(source_path)
|
||||
folder = Zip::File.new(source_path)
|
||||
tempfile = Tempfile.new("ugoira-dimensions")
|
||||
|
||||
Reference in New Issue
Block a user