Создать предварительный просмотр PDF с Shrine - PullRequest
0 голосов
/ 25 апреля 2019

Я конвертирую загрузку нашего внутреннего файла для работы со Shrine. Мне удалось довольно легко загрузить и запустить миниатюру изображений, но я изо всех сил пытался сделать то же самое с файлами PDF.

Сама загрузка работает, однако мне не удается сгенерировать миниатюру / превью для файла. Я использую Shrine вместе с ImageProcessing и vipslib.

Я пытался использовать метод миниатюр, предоставляемый vips, но, похоже, он работает только с файлами изображений, и я также пытался следовать этому SO , но безуспешно.

Позвольте мне дать вам некоторый контекст:

Это инициализатор Храма

require "shrine"
require "shrine/storage/file_system"
require "shrine/storage/google_cloud_storage"


Shrine.storages = {
  cache: Shrine::Storage::GoogleCloudStorage.new(bucket: ENV['CACHE_BUCKET']),
  store: Shrine::Storage::GoogleCloudStorage.new(bucket: ENV['STORE_BUCKET'])
}

Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data # for retaining the cached file across form redisplays
Shrine.plugin :restore_cached_data # re-extract metadata when attaching a cached file
Shrine.plugin :determine_mime_type

А это загрузчик

class DocumentUploader < Shrine
  require 'vips'

  def generate_location(io, context)
    "documents/#{Time.now.to_i}/#{super}"
  end


  plugin :processing
  # plugin :processing # allows hooking into promoting
  # plugin :versions   # enable Shrine to handle a hash of files
  # plugin :delete_raw # delete processed files after uploading
  # plugin :determine_mime_type
  #
  process(:store) do |io, context|
    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

    versions = { original: io }
    versions[:preview] = preview if preview && preview.size > 0
    versions
  end
end

Как уже упоминалось, загрузчик в данный момент является тем, что ломается и не генерирует предварительный просмотр. Предыдущая версия файла выглядела так:

class DocumentUploader < Shrine
  require 'vips'

  def generate_location(io, context)
    "documents/#{Time.now.to_i}/#{super}"
  end


  plugin :processing
  # plugin :processing # allows hooking into promoting
  # plugin :versions   # enable Shrine to handle a hash of files
  # plugin :delete_raw # delete processed files after uploading
  # plugin :determine_mime_type
  #
  process(:store) do |io, context|
    thumb = Vips::Image.thumbnail(io.metadata["filename"], 300)
    thumb
  end
end

Я видел очень мало документации по этой теме в Интернете.

Обновление: ответы на вопросы

Команда vips pdfload выплевывает информацию об использовании, и это действительно говорит о том, что PDF будет загружен с использованием libpoppler.

Я установил tar-файл прямо со страницы их загрузки, и в системе Debian работает версия 8.7.0.

Спасибо за информацию о лицензии - также разберемся с этим!

1 Ответ

1 голос
/ 26 апреля 2019

После нескольких часов борьбы вчера я наконец-то заставил это работать.

Решение в конце было довольно простым.Я использовал плагин управления версиями, предлагаемый shrine, и сохранил там оригинальную версию.

class DocumentUploader < Shrine
  include ImageProcessing::Vips

  def generate_location(io, context)
    "documents/#{Time.now.to_i}/#{super}"
  end


  plugin :processing # allows hooking into promoting
  plugin :versions   # enable Shrine to handle a hash of files
  plugin :delete_raw # delete processed files after uploading


  process(:store) do |io, context|
    versions = { original: io } # retain original

    io.download do |original|
      pipeline = ImageProcessing::Vips.source(original)
      pipeline = pipeline.convert("jpeg").saver(interlace: true)
      versions[:large]  = pipeline.resize_to_limit!(800, 800)
      versions[:medium] = pipeline.resize_to_limit!(500, 500)
      versions[:small]  = pipeline.resize_to_limit!(300, 300)
    end

    versions # return the hash of processed files
  end
end
...