2015-10-11 3 views
1

У меня есть приложение rails, размещенное на Heroku. Вот ситуация: пользователь должен иметь возможность загружать PDF (экземпляр Batch) в наше приложение с помощью s3; пользователь должен также иметь возможность взять веб-адрес s3 загруженного PDF-файла и разделить его на более PDF-файлы, используя HyPDF, указав путь к файлу и нужные разделы, которые нужно разделить (для создания экземпляров эссе).Запись файлов темпа в Heroku из файла с размещенным S3

Все это происходит в том же POST-запросе до /essays.

Вот код, я работаю с сегодня:

def create 
    if params[:essay].class == String 
     batch_id = params[:batch_id].gsub(/[^\d]/, '').to_i 
     break_up_batch(params, batch_id) 
     redirect_to Batch.find(batch_id), notice: 'Essays were successfully created.' 
    else 
     @essay = Essay.new(essay_params) 
     respond_to do |format| 
     if @essay.save 
      format.html { redirect_to @essay, notice: 'Essay was successfully created.' } 
      format.json { render :show, status: :created, location: @essay } 
     else 
      format.html { render :new } 
      format.json { render json: @essay.errors, status: :unprocessable_entity } 
     end 
     end 
    end 
end 

# this is a private method 
def break_up_batch(params, batch_id) 
    essay_data = [] 
    # create a seperate essay for each grouped essay 
    local_batch = File.open(Rails.root.join('tmp').to_s + "temppdf.pdf" , 'wb') do |f| 
    f.binmode 
    f.write HTTParty.get(Batch.find(batch_id).document.url).parsed_response 
    f.path 
    end 

    params["essay"].split("~").each do |data| 
    data = data.split(" ") 
    hypdf_url = HyPDF.pdfextract(
     local_batch, 
     first_page: data[1].to_i, 
     last_page: data[2].to_i, 
     bucket: 'essay101', 
     public: true 

    ) 
     object = {student_name: data[0], batch_id: batch_id, url: hypdf_url[:url]} 
     essay_data << object 
    end 

    essay_data.each {|essay| Essay.create(essay)} 
    File.delete(local_batch) 
end 

Я не могу получить файл, чтобы показать на Heroku, и я проверяю с heroku run bash и ls tmp. Поэтому, когда этот метод запущен, пустой файл загружается на S3. Я написал некоторый jQuery, чтобы заполнить скрытое поле, поэтому в середине кода есть фанковое расщепление.

+0

Команда Heroku toolbelt 'heroku run bash' создает новое развертывание вашего приложения, поэтому вы не увидите никаких файлов, созданных с помощью вашего приложения rails. Не существует обмена файловым пространством между приложениями Heroku, поэтому рекомендуется использовать ведра S3. – jr0cket

ответ

0

Выходит, используя класс File, это был неправильный путь. Но работает Tempfile!

def break_up_batch(params, batch_id, current_user) 
     essay_data = [] 
     # create a seperate essay for each grouped essay 
     tempfile = Tempfile.new(['temppdf', '.pdf'], Rails.root.join('tmp')) 
     tempfile.binmode 
     tempfile.write HTTParty.get(Batch.find(batch_id).document.url).parsed_response 
     tempfile.close 
     save_path = tempfile.path 

     params["essay"].split("~").each do |data| 
     data = data.split(" ") 
     hypdf_url = HyPDF.pdfextract(
      save_path, 
      first_page: data[1].to_i, 
      last_page: data[2].to_i, 
      bucket: 'essay101', 
      public: true 

     ) 
      object = {student_name: data[0], batch_id: batch_id, url: hypdf_url[:url]} 
      essay_data << object 
     end 
     essay_data.each do |essay| 
     saved_essay = Essay.create(essay) 
     saved_essay.update_attributes(:company_id => current_user.company_id) if current_user.company_id 
     end 
     tempfile.unlink 
    end 
1

Из-за эфемерной файловой системы Heroku я настоятельно рекомендую как можно быстрее удалить этот файл с вашей файловой системы. Возможно, используя следующий:

  1. добавления пользователя в S3 (желательно прямое: https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails)
  2. Стартового фон рабочего извлечь файл и сделать обработку, необходимую в памяти
  3. Если пользователь должен быть сообщается, когда файл правильно обработан, установите поле «статус» в вашей БД и разрешите внешнему приложению опросить веб-сервер на наличие обновлений. Покажите «Обработка» пользователю, пока фоновый рабочий не изменит свой статус.

Этот метод также позволяет вашему веб-процессу быстро реагировать, не связывая ресурсы и потенциально вызывая ошибку H12 (тайм-аут запроса).