paperclip中从id到id_partition的变换脚本

paperclip中从id到id_partition的转换脚本

看过用paperclip中的id_partition代替id这篇文章后,如果你想将原来的配置:

 

  has_attached_file :picture, :styles => {:medium => "480x360>", :thumb => "120x90>", :original =>"480x360>"},
    :path => ":rails_root/public/uploads/:class/:id/:style/picture.:extension",
    :url => "/uploads/:class/:id/:style/picture.:extension"

 

转换成新的配置:

 

  has_attached_file :picture, :styles => {:medium => "480x360>", :thumb => "120x90>", :original =>"480x360>"},
    :path => ":rails_root/public/uploads/:class/:id_partition/:style/picture.:extension",
    :url => "/uploads/:class/:id_partition/:style/picture.:extension"

 

新添加的文件,不会有任何问题。但以前的遗留文件该如何处理呢?

 

按照上面的配置,必须将文件从类似/public/uploads/pictures/1234的目录结构转到/public/uploads/pictures/000/001/234目录结构才行。

 

下面提供一个简单的转换脚本:

 

  task(:partitions => :environment) do
    require 'fileutils'
    start = Time.now
    vars = {}
    ARGV.each do |str|
      vars[$1] = $2 if str =~ /\A(.*?)=(.*)\z/
    end
    raise "必须指定TARGET_DIR. Example: TARGET_DIR=/opt/data/public/uploads/pictures" if vars['TARGET_DIR'].nil?
    FileUtils.cd(vars['TARGET_DIR'])
    dirs_to_move = Dir.glob("*/")
    FileUtils.mkdir '000'
    puts "#{dirs_to_move.size}个文件将被转换..."
    puts "移动文件到新的目录..."
    dirs_to_move.each_with_index do |dir, index|
      puts "还剩" + (dirs_to_move.size.to_i - index.to_i - 1).to_s + "个文件需要转换..."
      parent = "000/"
      parent << add_leading_zeros(File.basename(dir)[0..-4])
      child = File.basename(dir)[-3..-1] || add_leading_zeros(File.basename(dir))
      FileUtils.mkdir_p parent unless FileTest.directory?(parent)
      FileUtils.mv dir, "#{parent}/#{child}" if FileTest.directory?(dir)
      puts "#{index}个文件被移除..." if index%1000 == 0 && index > 0
    end
    puts "Partitioned #{dirs_to_move.size} folders into #{Dir.glob("000/*/").size} partitions in #{Time.now - start} seconds."
  end
  
  def add_leading_zeros(i)
    File.basename(i).to_s.rjust(3, '0')
  end

 

执行完后,原有的文件目录结构便转换成新的目录结构了。