无法在Rails

时间:2016-09-23 10:53:19

标签: ruby-on-rails amazon-web-services amazon-s3 phantomjs

我有一个场景,我上传的照片必须存储在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。

我已经通过put puts命令进行了测试,它将涉及所有方法,但我怀疑@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使用共享连接模式打开新的   与my_project.production.s3.amazonaws.com的HTTPS连接:443打开   新的HTTPS连接到s3.amazonaws.com:443 2016-09-26T10:48:46 + 0000:   [工人(delayed_job主持人:ip-172-31-24-139 pid:8769)]工作   Screenshot.new(id = 528)与Errno :: ENOENT失败(先前16次尝试):   没有这样的文件或目录@ rb_sysopen -   /var/www/html/project/my_project/public/photo_screenshots/50031.png   2016-09-26T10:48:46 + 0000:[工人(delayed_job主持人:ip-172-31-24-139   pid:8769)] Job Screenshot.new(id = 529)RUNNING   2016-09-26T10:48:46 + 0000:[工人(delayed_job主持人:ip-172-31-24-139   pid:8769)] Job Screenshot.new(id = 529)FAILED(16次尝试先前)   Magick :: ImageMagickError:无法打开文件   `公共/ report_screenshots / 50031.png' @ error / png.c / ReadPNGImage / 3733   2016-09-26T10:48:46 + 0000:[工人(delayed_job主持人:ip-172-31-24-139   pid:8769)] 2个工作以1.6978 j / s处理,2个工作失败

这是AWS生产日志:

  

New RightAws :: S3Interface使用共享连接模式   2016-09-26T16:00:30 + 0530:[工人(主持人:OSI-L-0397 pid:7117)]工作   与Errno :: ENOENT:截去.new(id = 50)失败(先前6次尝试):   没有这样的文件或目录@ rb_sysopen -   /home/abcuser/Desktop/project/my_project/public/photo_screenshots/10016.png   2016-09-26T16:00:30 + 0530:[工人(主持人:OSI-L-0397 pid:7117)]工作   Screenshot.new(id = 51)RUNNING 2016-09-26T16:00:30 + 0530:   [工作者(主持人:OSI-L-0397 pid:7117)]工作截图。新(id = 51)失败   (先前6次尝试)与Magick :: ImageMagickError:无法打开文件   `公共/ report_screenshots / 10016.png' @ error / png.c / ReadPNGImage / 3667   2016-09-26T16:00:30 + 0530:[工人(主持人:OSI-L-0397 pid:7117)] 2个工作   处理速度为0.2725 j / s,2次失败

1 个答案:

答案 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}"`

确实需要 / bin / bash ,将其更改为代码以下它应该可以正常工作。

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

如果它打破别的东西就让它成为现实。 由于您了解最终图像位置图像。将此直接传递给save_screenshot_to_s3,您应该可以保存它。如果您按照方法

中的指定传递user_id,这也会将图像路径保存到用户