Перенос изображений скрепки S3 в новый формат URL / пути - PullRequest
5 голосов
/ 16 января 2012

Есть ли рекомендуемый метод переноса большого набора изображений S3 скрепки в новый формат: url и: path?

Причина этого в том, что после обновления до rails 3.1 новые версии превью не отображаются после обрезки (отображается ранее кэшированная версия).Это потому, что имя файла больше не меняется (так как asset_timestamp был удален в rails 3.1).Я использую: отпечаток пальца в формате url / path, но он генерируется из оригинала, который не изменяется при кадрировании.

Я намеревался вставить: updated_at в формате url / path и обновить attachment.updated_at во время обрезки, но после внесения этого изменения все существующие изображения необходимо будет переместить на новое место.Это около полумиллиона изображений для переименования в S3.

На данный момент я планирую сначала скопировать их в новое местоположение, затем развернуть изменение кода, а затем переместить любые изображения, которые были пропущены (т. Е. Загружены после копирования), но я надеюсь, что есть прощеКстати ... есть предложения?

Ответы [ 2 ]

6 голосов
/ 14 августа 2013

Мне пришлось изменить путь скрепки для поддержки обрезки изображения, в итоге я создал задачу 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
2 голосов
/ 23 января 2012

Не удалось найти подходящий способ перехода на новый формат URL. В итоге я переопределил Paperclip::Attachment#generate_fingerprint, поэтому он добавляет :updated_at.

...