97 lines
2.7 KiB
Ruby
97 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class PreviewDocumentPageController < ActionController::API
|
|
include ActiveStorage::SetCurrent
|
|
|
|
FORMAT = Templates::ProcessDocument::FORMAT
|
|
|
|
TMPFILE_PREFIX = 'attachment-'
|
|
TMPFILE_TTL = 5.minutes
|
|
TMPFILE_MAX_TOTAL_SIZE = Docuseal.multitenant? ? 400.megabytes : 1.gigabyte
|
|
|
|
def show
|
|
result_data =
|
|
ApplicationRecord.signed_id_verifier.verified(params[:signed_key], purpose: :attachment)
|
|
|
|
attachment =
|
|
if result_data.is_a?(Array) && result_data.compact_blank.size == 2
|
|
attachment_id, attachment_uuid = result_data
|
|
|
|
ActiveStorage::Attachment.find_by(id: attachment_id, uuid: attachment_uuid)
|
|
elsif result_data
|
|
ActiveStorage::Attachment.find_by(uuid: result_data)
|
|
end
|
|
|
|
return head :not_found unless attachment
|
|
|
|
@template = attachment.record
|
|
|
|
preview_image = attachment.preview_images.joins(:blob)
|
|
.find_by(blob: { filename: ["#{params[:id]}.png", "#{params[:id]}.jpg"] })
|
|
|
|
if preview_image
|
|
return redirect_to preview_image.url(time: ActiveStorage::Attachment.service_url_time),
|
|
allow_other_host: true
|
|
end
|
|
|
|
preview_image =
|
|
open_attachment_io(attachment) do |io|
|
|
Templates::ProcessDocument.generate_pdf_preview_from_io(attachment, io, params[:id].to_i)
|
|
end
|
|
|
|
redirect_to preview_image.url(time: ActiveStorage::Attachment.service_url_time), allow_other_host: true
|
|
end
|
|
|
|
def open_attachment_io(attachment, &)
|
|
return File.open(ActiveStorage::Blob.service.path_for(attachment.key), 'rb', &) if attachment.service.name == :disk
|
|
|
|
file_name = "#{TMPFILE_PREFIX}#{Digest::SHA1.hexdigest("#{attachment.id}-#{attachment.uuid}")}"
|
|
|
|
file_path = File.join(Dir.tmpdir, file_name)
|
|
|
|
File.open(file_path, File::RDWR | File::CREAT, 0o644) do |file|
|
|
file.flock(File::LOCK_EX)
|
|
|
|
# rubocop:disable Style/ZeroLengthPredicate
|
|
if file.size.zero?
|
|
cleanup_stale_tempfiles
|
|
|
|
file.binmode
|
|
|
|
file.write(attachment.download)
|
|
else
|
|
FileUtils.touch(file_path)
|
|
end
|
|
# rubocop:enable Style/ZeroLengthPredicate
|
|
|
|
file.flock(File::LOCK_UN)
|
|
|
|
yield file
|
|
end
|
|
end
|
|
|
|
def cleanup_stale_tempfiles
|
|
entries =
|
|
Dir.glob(File.join(Dir.tmpdir, "#{TMPFILE_PREFIX}*")).filter_map do |path|
|
|
stat = File.stat(path)
|
|
|
|
[path, stat.mtime, stat.size]
|
|
rescue Errno::ENOENT
|
|
nil
|
|
end
|
|
|
|
total_size = entries.sum(&:last)
|
|
stale_time = TMPFILE_TTL.ago
|
|
|
|
entries.sort_by(&:second).each do |path, mtime, size|
|
|
break if mtime > stale_time && total_size <= TMPFILE_MAX_TOTAL_SIZE
|
|
|
|
File.unlink(path)
|
|
|
|
total_size -= size
|
|
rescue Errno::ENOENT
|
|
nil
|
|
end
|
|
end
|
|
end
|