Skip to content

Instantly share code, notes, and snippets.

@GarPit
Created March 18, 2014 09:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GarPit/9616489 to your computer and use it in GitHub Desktop.
Save GarPit/9616489 to your computer and use it in GitHub Desktop.
paperclip_restructure.rake
#require "ruby-debug"
require "logger"
Thread.abort_on_exception = true
namespace :paperclip_restructure do
namespace :assets do
desc "Migrate assets to new folder structure"
task :migrate, :workers, :needs => :preload do |t, args|
args.with_defaults(:workers => 4)
logger = Logger.new(Rails.root.join('log', 'migration.log'))
logger.formatter = Logger::Formatter.new
migration_folder = Rails.root.join('public', 'assets', 'products')
queue = Queue.new
Dir.entries(migration_folder).each do |entry|
# Folder is an Asset ID.
asset_id = File.basename(entry)
# We're not interested in these folders.
next if %w(. ..).include?(asset_id)
unless File.directory?(File.join(migration_folder, entry))
logger.info("SKIP #{asset_id}: is not a directory.")
next
end
queue.push(asset_id)
end
workers = []
args[:workers].to_i.times do |i|
workers[i] = Thread.new do
while !queue.empty? && asset_id = queue.pop
begin
asset = Image.find(asset_id)
rescue ActiveRecord::RecordNotFound
logger.warn("SKIP #{asset_id}: couldn't find record!")
next
rescue ActiveRecord::SubclassNotFound
logger.info("CLEANUP #{asset_id}: asset without subclass is an orphaned record.")
Image.delete(asset_id)
next
rescue => e
logger.error("FAILED QUEUEING #{asset_id}: unknown error.\nException: #{e.inspect}\nBacktrace: #{e.backtrace}")
next
end
begin
File.open(image_path(asset), "rb") do |image|
logger.info("PROCESSING #{asset_id}")
asset.attachment = image
asset.save(false)
end
rescue Errno::ENOENT
logger.warn("SKIP #{asset_id}: no such file!")
next
rescue => e
logger.error("FAILED PROCESSING #{asset_id}: unknown error.\nException: #{e.inspect}\nBacktrace: #{e.backtrace}")
next
end
end
end
end
workers.each{ |w| w.join }
logger.close
end
task :preload => :environment do
$LOAD_PATH.unshift Rails.root.join('app', 'models')
%w(image image_decorator).each do |klass|
require klass
end
end
# Path to image with old style path.
def image_path(asset)
options = { :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension" }
Paperclip::Attachment.new(:attachment, asset, options).path(:original)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment