lib/paperclip/paperclip_processors/chainer.rb
require 'zip'
require 'av'
module Paperclip
class Chainer < Processor
attr_accessor :file, :whiny, :destination, :extension, :basename, :supported_formats
def initialize file, options = {}, attachment = nil
@file = file
@whiny = options[:whiny].nil? ? true : options[:whiny]
@destination = Pathname.new("#{Dir.tmpdir}/#{SecureRandom.uuid}")
@extension = File.extname(@file.path)
@basename = File.basename(@file.path, @extension)
@supported_formats = ['.zip']
end
def make
if @supported_formats.include?(@extension)
log "Received supported file #{@file.path}"
case @extension
when '.zip'
unzip
end
result = concatenate
log "Successfully concatenated source into #{result.path}"
# Explicitly return in order to allow the next processor in the chain to work
# on the new file
return result
end
log "Skipping file with unsupported format: #{@file.path}"
# If the file is not supported, just return it
@file
end
def unzip
if @supported_formats.include?(@extension)
log "Extracting contents to #{@destination}"
Zip::File.open(File.expand_path(@file.path)) do |zip_file|
log "Creating #{@destination}"
FileUtils.mkdir_p(@destination)
zip_file.each do |source|
# Extract to file/directory/symlink
Paperclip.log "[chainer] Extracting #{source.name}"
target_file = @destination.join(source.name)
@target_format = File.extname(source.name)
zip_file.extract(source, target_file) unless File.exists?(target_file)
end
end
end
end
def concatenate
list = Dir["#{@destination}/*"]
target = Tempfile.new(['chainer-', @target_format])
log "Concatentating #{list.inspect} from #{@destination} into #{target.path}"
begin
::Av.logger = Paperclip.logger
cli = ::Av.cli(log: true)
cli.reset_input_filters
cli.filter_concat(list)
cli.add_destination(target.path)
cli.run
return target
rescue Cocaine::ExitStatusError => e
raise Paperclip::Error, "error while concatenating video for #{@file.path}: #{e}" if @whiny
end
end
def log message
Paperclip.log "[chainer] #{message}"
end
end
end