无法将图像上传到AWS S3中的存储桶中
我有一个场景,其中上传的照片必须存储在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
您可以尝试上传一个更简单的方法。
将图像上传到具有不同文件夹的固定存储桶,用于每个对象或应用程序。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,你应该可以保存它。如果按照方法
它有很多依赖关系,所以我无法更改。你能告诉我我错在哪里吗 –
@sachingod我看到你正在使用幻影,你想截图然后保存。如果是,我会更新我的答案 – Bijendra
。我正在尝试截图并保存。 –
中指定的方式传递user_id,这将会为用户保存图像路径。这看起来像是完成文件上传的最困难的方式lol。下载'paperclip gem'以与S3一起使用并移除95%的此代码。 – bkunzi01
它有很多依赖关系,所以我无法更改。 –