Обработчик скрепки не может найти его файл - PullRequest
0 голосов
/ 25 января 2011

Ранее: запуск метода модели во вложении скрепки после создания или обновления (обратные вызовы скрепки не работают)

Редактировать (позже в тот же день) Я понял мою проблему. Процессор, очевидно, работает с файлом, который обновляется, но не сохраняет никаких файлов до окончания обработки. Я изменил свой Zip :: ZipFile, чтобы открыть «файл», а не «attachment.path», так как путь к вложению на самом деле еще ничего не содержит. Это решило первую проблему. Теперь у меня другие проблемы, которые мне нужно отследить. Но ответ ниже в основном правильный.

Изменить (31.01.2011):

Итак, я воспользовался советом по созданию процессора для моего вложения, который будет выполнять все необходимые действия. Пока что похоже, что это должно работать; процессор запускается и выполняет все действия по инициализации, по-видимому. Однако, когда я получаю сообщение о том, что хочу получить доступ к загружаемому zip-файлу, я получаю сообщение об ошибке, в котором говорится, что файл не найден. Код для моего процессора ниже:

class Extractor < Processor
    attr_accessor :resolution, :whiny
    def initialize(file, options = {}, attachment = nil)
      super
      @file = file
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(@file.path, File.extname(@file.path))
      @attachment = attachment
      @instance = attachment.instance
    end
    def make
      # do your conversions here, you've got @file, @attachment and @basename to work with
      export_path = attachment.path.gsub('.zip', '_content')

      Zip::ZipFile.open(attachment.path) { |zip_file|
        zip_file.each { |image|
          image_path = File.join(export_path, image.name)
          FileUtils.mkdir_p(File.dirname(image_path))
          unless File.exist?(image_path)
            zip_file.extract(image, image_path)
            # ..stuff that it does..
          end
        }
      }
      # clean up source files, but leave the zip
      FileUtils.remove_dir(export_path)


      # you return a file handle which is the processed result
      dst = File.open result_file_path
    end
end

И вот содержание ошибки, которую я получаю:

Zip::ZipError in GalleriesController#create

File /home/joshua/railscamp/moments_on_three/public/assets/archives/delrosario.zip not found

Rails.root: /home/joshua/railscamp/moments_on_three
Application Trace | Framework Trace | Full Trace

config/initializers/extractor.rb:16:in `make'
app/controllers/galleries_controller.rb:32:in `new'
app/controllers/galleries_controller.rb:32:in `create'

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"0s4L4MrlqjDTMjzjgkUdvUxeHklZNOIShDhT6fgOICY=",
 "gallery"=>{"name"=>"DelRosario",
 "public"=>"0",
 "owner_id"=>"1",
 "shoot_date(1i)"=>"2011",
 "shoot_date(2i)"=>"1",
 "shoot_date(3i)"=>"31",
 "category_id"=>"1",
 "archive"=>#<ActionDispatch::Http::UploadedFile:0x00000004148d78 @original_filename="delrosario.zip",
 @content_type="application/zip",
 @headers="Content-Disposition: form-data; name=\"gallery[archive]\"; filename=\"delrosario.zip\"\r\nContent-Type: application/zip\r\n",
 @tempfile=#<File:/tmp/RackMultipart20110131-9745-14u347v>>},
 "commit"=>"Create Gallery"}

Из того, что я могу сказать, он ищет файл в нужном месте, но, похоже, файл еще не загружен для доступа к нему. Насколько я знаю, Paperclip достаточно умен, чтобы знать и ждать загрузки вложения, прежде чем оно попытается его обработать. Кто-нибудь может заметить, что я здесь делаю неправильно?

Большое спасибо.

Старые вещи:

Я занимаюсь разработкой приложения для создания фотогалереи с использованием Rails 3 и Paperclip. Администратор может создать галерею и загрузить ZIP-файл, содержащий несколько изображений.

Что я хочу, чтобы произошло:

  1. Введите информацию о галерее и zip-файл для загрузки в форму.
  2. Нажмите кнопку «Создать галерею».
  3. Формируйте сообщения, сохраняйте галерею и загружайте zip-файл.
  4. После загрузки zip-файла запустите метод: extract_photos (кстати, этот код работает). 4.a. В конце этого метода zip-файл уничтожается.
  5. Администратор перенаправлен на страницу галереи со всеми фотографиями в ней (где галерея имеет много фотографий).

Я пытался сделать эту работу несколькими разными способами.

Раньше я создавал метод контроллера, который позволял бы администратору щелкать ссылку, которая запускала метод: extract_photos. Это работало на моем компьютере, но по какой-то причине у сервера возникли проблемы с маршрутизацией на компьютере клиента. Так что это не пойдет. К тому же я думал, что это уродливый способ сделать это.

Недавно я попытался использовать методы обратного вызова. after_save не работал, потому что он явно прерывает форму POST, и файл не загружается, а метод: extract_photos не может найти файл.

Я проверил методы обратного вызова на странице github Paperclip, и он говорит о обратных вызовах:

До и после постобработки шаг, скрепка перезванивает модель с несколькими обратными вызовами, позволяющая модель, чтобы изменить или отменить этап обработки. Обратные вызовы "before_post_process" и "after_post_process" (которые называются до и после обработки каждое вложение), а прикрепление конкретных "beforepost_process" и "Afterpost_process". Обратные вызовы должен быть как можно ближе к нормальному ActiveRecord обратные вызовы, насколько это возможно, так если вы вернете false (в частности, возвращение ноль не то же самое) в перед фильтром, постобработка шаг остановится. Возвращая ложь в после фильтра ничего не остановится, но вы можете получить доступ к модели и тому вложение при необходимости.

Я пытался использовать before_post_process и after_post_process, но он не может найти файл для запуска процесса, поэтому файл, очевидно, не загружается к тому времени, когда эти методы вызываются (что я считаю странным). Кроме того, когда я пытаюсь выполнить beforepost_process и afterpost_process, я получаю NoMethodError.

Так как мне вызвать метод для вложения, когда он создается или обновляется, но после загрузки файла и в нужном месте?

UPDATE

Я попробовал приведенный ниже код, переместив код метода извлечения в метод make процессора. Я продвинулся дальше, чем раньше, пытаясь написать процессор, но он все еще не запущен. Процесс выдает исключение, как только я пытаюсь открыть загруженный файл для обработки, говоря, что файл не существует. Схема именования верна и все, но все еще ничего не загружается до того, как процесс запускается. У кого-нибудь есть идеи, почему это происходит?

1 Ответ

2 голосов
/ 27 января 2011

Вы можете написать свой собственный процессор для этого.

в вашей модели при объявлении скрепки добавьте пользовательский процессор

  has_attached_file :my_attachment, {
    :styles => {:original => {:processors => [:my_processor]}}
  }.merge(PAPERCLIP_SETTINGS)

затем напишите свой собственный процессор и поместите его в config / initializers:

module Paperclip
  class MyProcessor < Processor
    attr_accessor :resolution, :whiny
    def initialize(file, options = {}, attachment = nil)
      super
      @file = file
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(@file.path, File.extname(@file.path))
      @attachment = attachment
    end
    def make
      # do your conversions here, you've got @file, @attachment and @basename to work with

      # you return a file handle which is the processed result
      dst = File.open result_file_path
    end
  end
end

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

...