Rails 5 pdf 预览与 Shrine Gem
Rails 5 pdf preview with Shrine Gem
我正在使用 Shrine Gem 上传图片,想知道如果可能的话,我如何才能在我的模板中显示第一页预览,就像每次显示图片一样。我可以使用 jQuery 或其他库。下面是我的文件上传代码,包括我的 Shrine 初始化程序和上传文件。
查看
...
<div class="col-md-4 upload-block">
<%= f.label :spec_sheet, 'Spec Sheet' %>
<% if @product.spec_sheet.present? %>
<div class="product-image">
<%= image_tag(@product.spec_sheet_url(:thumb)) %>
<div class="input-checkbox input-checkbox--switch">
<input name="product[remove_spec_sheet]" type="hidden" value="0">
<input id="checkbox-switch" type="checkbox" name="product[remove_spec_sheet]">
<label for="checkbox-switch"></label>
</div>
<span>Remove Spec Sheet</span>
</div>
<% end %>
<%= f.hidden_field :spec_sheet, value: @product.cached_spec_sheet_data %>
<%= f.file_field :spec_sheet %>
</div>
...
初始化器
require 'shrine'
require 'shrine/storage/file_system'
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/cache'),
store: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/store'),
}
Shrine.plugin :activerecord
Shrine.plugin :remove_attachment
Shrine.plugin :delete_raw
Shrine.plugin :cached_attachment_data # for forms
上传者
require 'image_processing/mini_magick'
class ImageUploader < Shrine
MAX_IMAGE_SIZE_MB = 5
include ImageProcessing::MiniMagick
plugin :determine_mime_type
plugin :remove_attachment
plugin :store_dimensions
plugin :validation_helpers
plugin :processing
plugin :versions
plugin(:default_url) { |_| '/img/preview-not-available.jpg' }
Attacher.validate do
validate_max_size MAX_IMAGE_SIZE_MB.megabytes, message: "is too large (max is #{MAX_IMAGE_SIZE_MB} MB)"
validate_mime_type_inclusion %w[image/jpeg image/jpg image/png image/gif]
end
process(:store) do |io|
original = io.download
size_1500 = resize_to_limit!(original, 1500, 600)
size_500 = resize_to_limit(size_1500, 500, 500)
size_300 = resize_to_limit(size_500, 300, 300)
{original: size_1500, medium: size_500, thumb: size_300 }
end
end
如果您想显示 PDF 预览,您需要在服务器端生成它们。在这种情况下,最好使用 direct uploads (see the demo 作为客户端实现的示例。
然后您可以在直接上传时生成 PDF 预览:
# config/initializers/shrine.rb
Shrine.plugin :determine_mime_type
# app/models/image_uploader.rb
class ImageUploader < Shrine
plugin :processing
plugin :versions
process(:upload) do |io, context|
if Shrine.determine_mime_type(io) == "application/pdf"
preview = Tempfile.new(["shrine-pdf-preview", ".pdf"], binmode: true)
begin
IO.popen *%W[mutool draw -F png -o - #{io.path} 1], "rb" do |command|
IO.copy_stream(command, preview)
end
rescue Errno::ENOENT
fail "mutool is not installed"
end
preview.open # flush & rewind
end
versions = { original: io }
versions[:preview] = preview if preview && preview.size > 0
versions
end
end
upload_endpoint
设置了:upload
处理动作,所以就是process(:upload)
的意思
- 我们对
IO.popen
使用rb
,这样Ruby使用二进制编码,更安全,跨平台
Kernel#spawn
和任何使用 spawn
的方法(system
、IO.popen
等)将在 shell 命令被执行时引发 Errno::ENOENT
未找到
- 我们使用
*%W[]
而不是仅仅 ""
以便 Ruby 避免 shell (以及任何可能的 shell 转义问题)并通过命令直接到 OS
- 我们检查
preview
文件是否为空,因为万一 mutool
命令失败,它会是空的(在这种情况下,我们可能想回退到不显示预览)
对 upload_endpoint
的 POST 请求的结果现在将包含预览的上传文件 ID,您可以使用它来生成对预览的 URL .在你的情况下是 "/uploads/cache" + id
.
请注意,这意味着您必须稍微修改缓存文件提升为永久存储时调用的处理代码。在 process(:store) do |io, context|
块中,io
现在将是版本的散列,因此您可以通过 io[:original]
访问原始缓存文件。并确保在该块的结果中也包含预览文件,因为您可能希望保留它。
process(:store) do |io, context|
original = io[:original].download
# processing...
versions = io.dup
versions[:small] = small
versions[:medium] = medium
# ...
versions
end
我正在使用 Shrine Gem 上传图片,想知道如果可能的话,我如何才能在我的模板中显示第一页预览,就像每次显示图片一样。我可以使用 jQuery 或其他库。下面是我的文件上传代码,包括我的 Shrine 初始化程序和上传文件。
查看
...
<div class="col-md-4 upload-block">
<%= f.label :spec_sheet, 'Spec Sheet' %>
<% if @product.spec_sheet.present? %>
<div class="product-image">
<%= image_tag(@product.spec_sheet_url(:thumb)) %>
<div class="input-checkbox input-checkbox--switch">
<input name="product[remove_spec_sheet]" type="hidden" value="0">
<input id="checkbox-switch" type="checkbox" name="product[remove_spec_sheet]">
<label for="checkbox-switch"></label>
</div>
<span>Remove Spec Sheet</span>
</div>
<% end %>
<%= f.hidden_field :spec_sheet, value: @product.cached_spec_sheet_data %>
<%= f.file_field :spec_sheet %>
</div>
...
初始化器
require 'shrine'
require 'shrine/storage/file_system'
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/cache'),
store: Shrine::Storage::FileSystem.new('public', prefix: 'uploads/store'),
}
Shrine.plugin :activerecord
Shrine.plugin :remove_attachment
Shrine.plugin :delete_raw
Shrine.plugin :cached_attachment_data # for forms
上传者
require 'image_processing/mini_magick'
class ImageUploader < Shrine
MAX_IMAGE_SIZE_MB = 5
include ImageProcessing::MiniMagick
plugin :determine_mime_type
plugin :remove_attachment
plugin :store_dimensions
plugin :validation_helpers
plugin :processing
plugin :versions
plugin(:default_url) { |_| '/img/preview-not-available.jpg' }
Attacher.validate do
validate_max_size MAX_IMAGE_SIZE_MB.megabytes, message: "is too large (max is #{MAX_IMAGE_SIZE_MB} MB)"
validate_mime_type_inclusion %w[image/jpeg image/jpg image/png image/gif]
end
process(:store) do |io|
original = io.download
size_1500 = resize_to_limit!(original, 1500, 600)
size_500 = resize_to_limit(size_1500, 500, 500)
size_300 = resize_to_limit(size_500, 300, 300)
{original: size_1500, medium: size_500, thumb: size_300 }
end
end
如果您想显示 PDF 预览,您需要在服务器端生成它们。在这种情况下,最好使用 direct uploads (see the demo 作为客户端实现的示例。
然后您可以在直接上传时生成 PDF 预览:
# config/initializers/shrine.rb
Shrine.plugin :determine_mime_type
# app/models/image_uploader.rb
class ImageUploader < Shrine
plugin :processing
plugin :versions
process(:upload) do |io, context|
if Shrine.determine_mime_type(io) == "application/pdf"
preview = Tempfile.new(["shrine-pdf-preview", ".pdf"], binmode: true)
begin
IO.popen *%W[mutool draw -F png -o - #{io.path} 1], "rb" do |command|
IO.copy_stream(command, preview)
end
rescue Errno::ENOENT
fail "mutool is not installed"
end
preview.open # flush & rewind
end
versions = { original: io }
versions[:preview] = preview if preview && preview.size > 0
versions
end
end
upload_endpoint
设置了:upload
处理动作,所以就是process(:upload)
的意思
- 我们对
IO.popen
使用rb
,这样Ruby使用二进制编码,更安全,跨平台 Kernel#spawn
和任何使用spawn
的方法(system
、IO.popen
等)将在 shell 命令被执行时引发Errno::ENOENT
未找到- 我们使用
*%W[]
而不是仅仅""
以便 Ruby 避免 shell (以及任何可能的 shell 转义问题)并通过命令直接到 OS - 我们检查
preview
文件是否为空,因为万一mutool
命令失败,它会是空的(在这种情况下,我们可能想回退到不显示预览)
对 upload_endpoint
的 POST 请求的结果现在将包含预览的上传文件 ID,您可以使用它来生成对预览的 URL .在你的情况下是 "/uploads/cache" + id
.
请注意,这意味着您必须稍微修改缓存文件提升为永久存储时调用的处理代码。在 process(:store) do |io, context|
块中,io
现在将是版本的散列,因此您可以通过 io[:original]
访问原始缓存文件。并确保在该块的结果中也包含预览文件,因为您可能希望保留它。
process(:store) do |io, context|
original = io[:original].download
# processing...
versions = io.dup
versions[:small] = small
versions[:medium] = medium
# ...
versions
end