【发布时间】:2011-09-21 15:05:17
【问题描述】:
我有大约 16,000 张图片正在尝试上传到亚马逊。现在,它们在我的本地文件系统上。我想使用 Paperclip 将它们上传到 S3,但我不想先将它们上传到我的服务器。我正在使用 Heroku,它们限制了 slug 的大小。
有没有办法使用 rake 任务通过 Paperclip 将图像直接从我的本地文件系统上传到 S3?
【问题讨论】:
标签: ruby-on-rails amazon-s3 paperclip
我有大约 16,000 张图片正在尝试上传到亚马逊。现在,它们在我的本地文件系统上。我想使用 Paperclip 将它们上传到 S3,但我不想先将它们上传到我的服务器。我正在使用 Heroku,它们限制了 slug 的大小。
有没有办法使用 rake 任务通过 Paperclip 将图像直接从我的本地文件系统上传到 S3?
【问题讨论】:
标签: ruby-on-rails amazon-s3 paperclip
您可以将您的应用配置为在开发中使用 Amazon S3 进行回形针存储 (see my example) 并使用 rake 任务上传文件,如下所示:
假设你的图片文件夹在your_app_folder/public/images,你可以创建一个类似的rake任务。
namespace :images do
desc "Upload images."
task :create => :environment do
@images = Dir["#{RAILS_ROOT}/public/images/*.*"]
for image in @images
MyModel.create(:image => File.open(image))
end
end
end
【讨论】:
是的。我在我的第一个个人 Rails 项目中做了类似的事情。这是以前的 SO 问题 (Paperclip S3 download remote images),其答案链接到我很久以前找到答案的地方 (http://trevorturk.com/2008/12/11/easy-upload-via-url-with-paperclip/)。
【讨论】:
很好的答案约翰尼格拉斯和很好的问题克里斯。我的本地机器、Heroku、回形针和 s3 上有几百个 tif 文件。一些 tiff 文件大于 100MB,因此让 heroku 注意到长期需要延迟的工作和一些额外的工作。由于这主要是一个一次性的批处理过程(5 个不同的图像形式从每个创建 5 次上传),因此 rake 任务的想法非常适合。如果有帮助,这里是我创建的 rake 任务,假设像 Johnny 写的那样,您的开发数据库具有当前数据(使用 pg 备份获取新的 id 集)并连接到 S3。
我有一个名为“项目”的模型,带有附件“图像”。我想检查现有项目是否已经有图像,如果没有,则上传新的。效果是镜像一个源文件目录。好的扩展可能是检查日期并查看本地 tif 是否更新。
# lib/image_management.rake
namespace :images do
desc 'upload images through paperclip with postprocessing'
task :create => :environment do
directory = "/Volumes/data/historicus/_projects/deeplandscapes/library/tifs/*.tif"
images = Dir[directory]
puts "\n\nProcessing #{ images.length } images in #{directory}..."
items_with_errors = []
items_updated = []
items_skipped = []
images.each do |image|
# find the needed record
image_basename = File.basename(image)
id = image_basename.gsub("it_", "").gsub(".tif", "").to_i
if id > 0
item = Item.find(id) rescue nil
# check if it has an image already
if item
unless item.image.exists?
# create the image
success = item.update_attributes(:image => File.open(image))
if success
items_updated << item
print ' u '
else
items_with_errors << item
print ' e '
end
else
items_skipped << item
print ' s '
end
else
print "[#{id}] "
end
else
print " [no id for #{image_basename}] "
end
end
unless items_with_errors.empty?
puts "\n\nThe following items had errors: "
items_with_errors.each do |error_image|
puts "#{error_image.id}: #{error_image.errors.full_messages}"
end
end
puts "\n\nUpdated #{items_updated.length} items."
puts "Skipped #{items_skipped.length} items."
puts "Update complete.\n"
end
end
【讨论】: