以干净的层次结构导出回形针图像

Export paperclip images in a clean hierarchy

我正在开发一个即将关闭的 rails 3.2.8 应用程序。

此应用有 post 个模型 has_many 资产。

资产模型采用回形针管理。

class Asset < ActiveRecord::Base
attr_accessible :post_id, :photo
  belongs_to :post                
  has_attached_file :photo, 
                    :styles => {
                      :thumb => '260x260#',
                      :normal => {
                        :geometry => '600x600>',
                      }
                    }
end

我需要登录生产环境和 运行 将每张照片备份到文件系统中另一个文件夹的命令,如下所示:

~/backup-folder/post-name-foo/post-name-foo-1.png
~/backup-folder/post-name-foo/post-name-foo-2.png
~/backup-folder/post-name-bar/post-name-bar-1.png
~/backup-folder/post-name-bar/post-name-bar-2.png
~/backup-folder/post-name-bar/post-name-bar-3.png
~/backup-folder/post-name-baz/post-name-baz-1.jpg

图片可以是 png 或 jpg 格式,也可以是 JPG(大写),posts 可以有任意数量的附件。

我只需要 运行 命令一次,如果可能的话,我希望避免对应用程序进行更改(比如安装新的 gem)。

这里是如何使用rake命令备份文件的示例,您可以增强其文件夹备份的逻辑,希望对您有所帮助

  1. <root_folder>/lib/task/photo_backup.rake.

    中创建一个 rake 文件
    task :photo_backup => :environment do
        require 'rubygems'
        require 'rake'
    
        # file path on production 
        filename = "post-name-foo-1.png"  
        path_to_file = "#{Rails.root.to_s}/images_folder/#{filename}"
    
        # backup folder on production
        backup_folder_path = "#{Rails.root.to_s}/backup_folder"
        backup_dir = FileUtils.makedirs(backup_folder_path).first
    
        begin
           f = File.new("#{backup_dir}/#{filename}", "w+")
           data = open(path_to_file).read
           f.write(data)
        rescue Exception => exp
           puts("Error message : #{exp.message}")
        ensure
           f.close unless f == nil
        end
    end
    
  2. 从控制台在您的项目根目录中执行以下命令。

    rake photo_backup
    

我会使用shell cp命令将资产复制到备份目录;这应该比打开和阅读 Ruby:

中的每个资产要快得多
require 'shellwords'

backup_destination = '/home/app/backup_directory'

# create the backup base directory
FileUtils.mkdir_p backup_destination

Post.find_each do |post|
  # change this if you generate your 'nice' post URLs in a different manner
  post_name       = post.to_param
  post_backup_dir = File.join(backup_destination, post_name)

  FileUtils.mkdir_p post_backup_dir

  post.assets.each_with_index do |asset, index|
    file_extension = File.extname(asset.photo_file_name)
    new_file_name  = "#{post_name}-#{index}#{file_extension}"

    # escape spaces in paths
    source_path = Shellwords.shellescape asset.photo.path(:original)
    target_path = Shellwords.shellescape File.join(post_backup_dir, new_file_name)

    output = `cp #{source_path} #{target_path} 2>&1`

    # make sure cp worked correctly
    unless $?.exitstatus == 0
      puts "WARNING: failed to copy asset #{asset.id} from #{source_path} to #{target_path}: #{output}"
    end
  end
end