简体   繁体   English

将回形针S3图像迁移到新的URL /路径格式

[英]Migrating paperclip S3 images to new url/path format

Is there a recommended technique for migrating a large set of paperclip S3 images to a new :url and :path format? 是否有推荐的技术将大量回形针S3图像迁移到新的:url和:路径格式?

The reason for this is because after upgrading to rails 3.1, new versions of thumbs are not being shown after cropping (previously cached version is shown). 原因是因为在升级到rails 3.1之后,裁剪后没有显示新版本的拇指(显示以前缓存的版本)。 This is because the filename no longer changes (since asset_timestamp was removed in rails 3.1). 这是因为文件名不再更改(因为在rails 3.1中删除了asset_timestamp)。 I'm using :fingerprint in the url/path format, but this is generated from the original, which doesn't change when cropping. 我正在使用:url / path格式的指纹,但这是从原始生成的,在裁剪时不会改变。

I was intending to insert :updated_at in the url/path format, and update attachment.updated_at during cropping, but after implementing that change all existing images would need to be moved to their new location. 我打算在url / path格式中插入:updated_at,并在裁剪期间更新attachment.updated_at,但在实现该更改后,所有现有图像都需要移动到新位置。 That's around half a million images to rename over S3. 大约有50万张图像要重命名为S3。

At this point I'm considering copying them to their new location first, then deploying the code change, then moving any images which were missed (ie uploaded after the copy), but I'm hoping there's an easier way... any suggestions? 此时我正在考虑先将它们复制到新位置,然后部署代码更改,然后移动任何遗漏的图像(即复制后上传),但我希望有更简单的方法...任何建议?

I had to change my paperclip path in order to support image cropping, I ended up creating a rake task to help out. 我不得不改变我的回形针路径以支持图像裁剪,我最终创建了一个rake任务来帮助我。

namespace :paperclip_migration do

  desc 'Migrate data'
  task :migrate_s3 => :environment do
    # Make sure that all of the models have been loaded so any attachments are registered
    puts 'Loading models...'
    Dir[Rails.root.join('app', 'models', '**/*')].each { |file| File.basename(file, '.rb').camelize.constantize }

    # Iterate through all of the registered attachments
    puts 'Migrating attachments...'
    attachment_registry.each_definition do |klass, name, options|
      puts "Migrating #{klass}: #{name}"
      klass.find_each(batch_size: 100) do |instance|
        attachment = instance.send(name)

        unless attachment.blank?
          attachment.styles.each do |style_name, style|
            old_path = interpolator.interpolate(old_path_option, attachment, style_name)
            new_path = interpolator.interpolate(new_path_option, attachment, style_name)
            # puts "#{style_name}:\n\told: #{old_path}\n\tnew: #{new_path}"
            s3_copy(s3_bucket, old_path, new_path)
          end
        end
      end
    end

    puts 'Completed migration.'
  end

  #############################################################################
  private

  # Paperclip Configuration
  def attachment_registry
    Paperclip::AttachmentRegistry
  end

  def s3_bucket
    ENV['S3_BUCKET']
  end

  def old_path_option
    ':class/:id_partition/:attachment/:hash.:extension'
  end

  def new_path_option
    ':class/:attachment/:id_partition/:style/:filename'
  end

  def interpolator
    Paperclip::Interpolations
  end

  # S3
  def s3
    AWS::S3.new(access_key_id: ENV['S3_KEY'], secret_access_key: ENV['S3_SECRET'])
  end

  def s3_copy(bucket, source, destination)
    source_object = s3.buckets[bucket].objects[source]
    destination_object = source_object.copy_to(destination, {metadata: source_object.metadata.to_h})
    destination_object.acl = source_object.acl
    puts "Copied #{source}"
  rescue Exception => e
    puts "*Unable to copy #{source} - #{e.message}"
  end

end

Didn't find a feasible method for migrating to a new url format. 没有找到一种可行的方法来迁移到新的url格式。 I ended up overriding Paperclip::Attachment#generate_fingerprint so it appends :updated_at . 我最终覆盖了Paperclip::Attachment#generate_fingerprint因此它附加了:updated_at

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM