2016-09-23 169 views
0

我有一個場景,其中上傳的照片必須存儲在AWS S3存儲桶中,並通過電子郵件調用圖像,但在無法存儲Rails和相應的寶石升級後S3中的圖像。我將aws-s3版本從0.6.1升級到0.6.3,aws-sdk從1.3.5升級到1.3.9,right_aws從3.0.0升級到3.0.5,最後將Rails從3.2.1升級到4.2.6。無法將圖像上傳到AWS S3中的存儲桶中

我已經通過put命令進行了測試,它將使用所有方法,但是我懷疑@type上的上傳方法是否有任何語法更改(這裏@type是2個存儲桶名稱photo_screenshots和indicator_screenshots)。 請幫幫我。

這是我的lib/screenshot.rb:

class Screenshot 
     attr_reader :user_id, :report_id, :type 

     def initialize(user_id, report_id, type) 
      @user_id, @report_id, @type = user_id, report_id, type 
      capture 
      resize(500, 686) if @type == 'report_screenshots' 
      upload 
      delete_local_copy 
     end 

     def capture 
     if Rails.env.production? 
      phantom = Rails.root.join('vendor/javascripts/phantomjs_linux/bin/phantomjs') 
      url  = Rails.application.config.custom.domain_url + "users/#{@user_id}/reports/#{@report_id}" 
     end 
     js   = Rails.root.join("vendor/javascripts/#{@type}.js") 
     image  = Rails.root.join("public/#{@type}/#{@report_id}.png") 

     `/bin/bash -c "DISPLAY=:0 #{phantom} #{js} #{url} #{image}"` 
     end 

     def resize(width, height) 
     path = "public/#{@type}/#{@report_id}.png" 
     img = Magick::Image::read(path).first 
     #img.thumbnail!(width, height) 
     img.change_geometry("#{width}x#{height}") do |cols, rows, img| 
      img.thumbnail!(cols, rows) 
     end 
     img.write(path) 
     end 

     def upload 
     file_name = Rails.root.join("public/#{@type}/#{@report_id}.png") 
     s3config = YAML.load_file(Rails.root.join('config', 's3.yml'))[Rails.env] 
     s3 = RightAws::S3.new(s3config["access_key_id"], s3config["secret_access_key"]) 
     @type == 'report_screenshots' ? s3.bucket("my_project.#{Rails.env}", true).put("#{@type}/#{@report_id}.png", File.open(file_name), {}, 'public-read', { 'content-type' => 'image/png' }) : s3.bucket("my_project.#{Rails.env}", true).put("indicator_screenshots/#{@report_id}.png", File.open(file_name), {}, 'public-read', { 'content-type' => 'image/png' }) 
     report = Report.find(@report_id) 
     @type == 'report_screenshots' ? report.update_attribute(:report_screenshot_at, Time.now) : report.update_attribute(:indicator_screenshot_at, Time.now) 
     end 

     def delete_local_copy 
     file_name = Rails.root.join("public/#{@type}/#{@report_id}.png") 
     File.delete(file_name) 
     end 

     def self.delete_s3_copy(report_id, type) 
     s3config = YAML.load_file(Rails.root.join('config', 's3.yml'))[Rails.env] 
     s3 = RightAws::S3.new(s3config["access_key_id"], s3config["secret_access_key"]) 
     s3.bucket("my_project.#{Rails.env}").key("#{type}/#{report_id}.png").delete 
     end 


end 

每當我點擊發送一封電子郵件,這是發生了什麼:

控制器:

def send_test_email 
    if @report.photos.empty? 
     Rails.env.development? ? Screenshot.new(@user.id, @report.id, Rails.application.config.custom.indicator_screenshot_bucket) : Screenshot.delay.new(@user.id, @report.id, Rails.application.config.custom.indicator_screenshot_bucket) 
    else 
     Rails.env.development? ? Screenshot.new(@user.id, @report.id, "photo_screenshots") : Screenshot.delay.new(@user.id, @report.id, "photo_screenshots") 
    end 
    ReportMailer.delay.test_report_email(@user, @report) 
    respond_to do |format| 
     format.json { render :json => { :success => true, :report_id => @report.id, :notice => 'Test email was successfully sent!' } } 
    end 
    end 

這是RAILS_ENV =生產日誌:

New RightAws::S3Interface using shared connections mode Opening new HTTPS connection to my_project.production.s3.amazonaws.com:443 Opening new HTTPS connection to s3.amazonaws.com:443 2016-09-26T10:48:46+0000: [Worker(delayed_job host:ip-172-31-24-139 pid:8769)] Job Screenshot.new (id=528) FAILED (16 prior attempts) with Errno::ENOENT: No such file or directory @ rb_sysopen - /var/www/html/project/my_project/public/photo_screenshots/50031.png 2016-09-26T10:48:46+0000: [Worker(delayed_job host:ip-172-31-24-139 pid:8769)] Job Screenshot.new (id=529) RUNNING 2016-09-26T10:48:46+0000: [Worker(delayed_job host:ip-172-31-24-139 pid:8769)] Job Screenshot.new (id=529) FAILED (16 prior attempts) with Magick::ImageMagickError: unable to open file `public/report_screenshots/50031.png' @ error/png.c/ReadPNGImage/3733 2016-09-26T10:48:46+0000: [Worker(delayed_job host:ip-172-31-24-139 pid:8769)] 2 jobs processed at 1.6978 j/s, 2 failed

這是AWS生產日誌:

New RightAws::S3Interface using shared connections mode 2016-09-26T16:00:30+0530: [Worker(host:OSI-L-0397 pid:7117)] Job Screenshot.new (id=50) FAILED (6 prior attempts) with Errno::ENOENT: No such file or directory @ rb_sysopen - /home/abcuser/Desktop/project/my_project/public/photo_screenshots/10016.png 2016-09-26T16:00:30+0530: [Worker(host:OSI-L-0397 pid:7117)] Job Screenshot.new (id=51) RUNNING 2016-09-26T16:00:30+0530: [Worker(host:OSI-L-0397 pid:7117)] Job Screenshot.new (id=51) FAILED (6 prior attempts) with Magick::ImageMagickError: unable to open file `public/report_screenshots/10016.png' @ error/png.c/ReadPNGImage/3667 2016-09-26T16:00:30+0530: [Worker(host:OSI-L-0397 pid:7117)] 2 jobs processed at 0.2725 j/s, 2 failed

+0

中指定的方式傳遞user_id,這將會爲用戶保存圖像路徑。這看起來像是完成文件上傳的最困難的方式lol。下載'paperclip gem'以與S3一起使用並移除95%的此代碼。 – bkunzi01

+0

它有很多依賴關係,所以我無法更改。 –

回答

0

您可以嘗試上傳一個更簡單的方法。

將圖像上傳到具有不同文件夾的固定存儲桶,用於每個對象或應用程序。s3保留存儲桶創建次數的限制,而存儲桶內的內容不存在限制。

此代碼將使用aws-sdk gem將用戶的圖像上傳到s3。上傳的圖片和圖片將公開 ,以便上傳的圖片可以直接訪問。所需的輸入是圖像完整路徑 ,它存在的位置,應該上傳的文件夾以及要上傳的應用程序 的user_id。

  def save_screenshot_to_s3(image_location, folder_name,user_id) 
       service = AWS::S3.new(:access_key_id => ACCESS_KEY_ID, 
            :secret_access_key => SECRET_ACCESS_KEY) 
       bucket_name = "app-images" 
       if(service.buckets.include?(bucket_name)) 
       bucket = service.buckets[bucket_name] 
       else 
       bucket = service.buckets.create(bucket_name) 
       end 
       bucket.acl = :public_read 
       key = folder_name.to_s + "/" + File.basename(image_location) 
       s3_file = service.buckets[bucket_name].objects[key].write(:file => image_location) 
       s3_file.acl = :public_read 
       user = User.where(id: user_id).first 
       user.image = s3_file.public_url.to_s 
       user.save 
      end  

處理的截圖部分,在您的捕獲方法,你必須使用做了這樣的事情。

`/bin/bash -c "DISPLAY=:0 #{phantom} #{js} #{url} #{image}"` 

是在/斌/慶典真正需要的事情,將其更改爲下面的代碼,它應該工作。

 `DISPLAY=:0 "#{phantom}" "#{js}" "#{url}" "#{image}"` 

讓它成爲,如果它打破別的東西。 由於您知道最終圖像位置是圖片。直接傳遞給save_screenshot_to_s3,你應該可以保存它。如果按照方法

+0

它有很多依賴關係,所以我無法更改。你能告訴我我錯在哪裏嗎 –

+0

@sachingod我看到你正在使用幻影,你想截圖然後保存。如果是,我會更新我的答案 – Bijendra

+0

。我正在嘗試截圖並保存。 –

相關問題