#!/usr/bin/ruby -w # #Usage: ape_convert [options] # -d, --directory DIRECTORY The directory to search for ape files in # -t, --test # -v, --verbose Verbose output mode # -f, --file FILE The specific file you wish to convert # -m, --mac MAC Path to your mac binary (ape conversion utility) # http://supermmx.org/linux/mac # -l, --lame LAME Path to your lame encoder binary # -s, --mp3splt MP3SPLT Path to your mp3splt binary # -o, --output OUTPUT Output directory for converted files. Liked named files will be overwritten! # -c, --clean Remove files after each stage of converting # -h, --help Prints this usage message require "rubygems" require "optparse" require "ostruct" require "term/ansicolor" require "pathname" require 'fileutils' $c = Term::ANSIColor $options = OpenStruct.new $options.mac=`which mac`.chomp $options.lame=`which lame`.chomp $options.mp3splt=`which mp3splt`.chomp $options.dir = "" $options.file = "" $options.output = "" $options.clean = false $options.test = false $options.verbos = true $lameList = Array.new $mp3spltList = Array.new opts = OptionParser.new do |opts| opts.on("-d", "--directory DIRECTORY", "The directory to search for ape files in") do |dir| $options.dir = dir end opts.on("-t", "--test") do $options.test = true end opts.on"-v", "--verbose", "Verbose output mode" do $options.verbose = true end opts.on("-f", "--file FILE", "The specific file you wish to convert") do |file| $options.file = file end opts.on("-m", "--mac MAC", "Path to your mac binary (ape conversion utility) http://supermmx.org/linux/mac") do |mac| $options.mac = mac end opts.on("-l", "--lame LAME","Path to your lame encoder binary") do |lame| $options.lame end opts.on("-s", "--mp3splt MP3SPLT", "Path to your mp3splt binary") do |mp3splt| $options.mp3splt = mp3splt end opts.on("-o", "--output OUTPUT", "Output directory for converted files. Liked named files will be overwritten!") do |output| $options.output = output end opts.on("-c", "--clean", "Remove files after each stage of converting") do $options.clean = true end opts.on("-h", "--help", "Prints this usage message") do puts opts exit! end end def cleanup(p,dir) cdir = dir.to_s.gsub(/#{ENV['HOME'].gsub(/ /,"\\ ")}/,"") trashdir = "#{ENV['HOME']}/.Trash"+cdir if $options.verbose then print $c.green, "Moving File:", $c.clear,"\n" print $c.blue, "\t#{p}", $c.clear, "\n" print $c.green, "\tto:\n", $c.clear, "\n" print $c.blue, "\t#{trashdir}", $c.clear, "\n" end FileUtils.mkdir_p(trashdir) FileUtils.mv p.to_s, trashdir end begin opts.parse!(ARGV) if $options.file.empty? and $options.dir.empty? then raise "You must specify either a file or directory to convert!" elsif !$options.file.empty? and !$options.dir.empty? then raise "You cannot specify both a directory and a file!" end raise "Could not find mac binary!" if $options.mac.empty? raise "Could not find lame binary!" if $options.lame.empty? raise "Could not find mp3splt binary!" if $options.mp3splt.empty? rescue Exception => e print $c.red, "ERROR: ",e, "", $c.clear, "\n\n" puts opts exit end def getFiles file_list = `find #{$options.dir} -name *.ape -print`.split("\n") print $c.green, "Found #{file_list.size} ape files in: ", $c.clear,$options.dir, "\n" return file_list end def progress(process,path,regex,error,processName,warning) line = "" current = 0 print $c.green, "#{processName} converting: ",$c.clear,path.basename," " print $c.green,"["+(" " * 51) + "]",$c.clear completed_output = Array.new while c = process.getc if c.chr != "\r" and c.chr != "\n" line << c.chr elsif match = line.match(regex) print "\r" print $c.green, "#{processName} converting: ",$c.clear,path.basename," " current = (match[1].to_i / 2) print $c.green,"[" ,$c.clear print $c.blue,("=" * current)+ ">",$c.clear print " " * (50 - current) print $c.green,"]",$c.clear completed_output.push(match[2]) if processName.eql?("MP3SPLT") line = "" elsif match = line.match(error) print "\n" raise "#{match[1]}!" elsif warning and match = line.match(warning) print $c.blue, "\nWarning: #{match[1]}",$c.clear,"\n" else line = "" end $stdout.flush end print "\n" if processName.eql?("MP3SPLT") then print $c.green, "mp3splt successfully created the following mp3's", $c.clear, "\n" print $c.blue, completed_output.join("\n"), $c.clear, "\n" end process.close end def ape2wav(file) p = Pathname.new(file) input = p.basename dir = p.dirname output = "#{p.basename(".ape")}.wav" processName = "Mac" command = "#{$options.mac} '#{p}' '#{dir}/#{output}' -d 2>&1" print $c.green,"Command: ", $c.clear if $options.verbose print $c.yellow, command,$c.clear, "\n" if $options.verbose # gets the percent complete in integer form. represents precent complete match = Regexp.new(/Progress: (\d+\.\d+)%/) # gets error message if it occurs error = Regexp.new(/(?:Error: )?(\d+$|Input File Not Found)/) if !$options.test then begin mac = IO.popen(command) progress(mac,p,match,error,processName,nil) if $options.clean then cleanup(p,dir) end rescue Exception => e print $c.red, "ERROR: ",e, "", $c.clear, "\n\n" exit end end print "\n" return "#{dir}/#{output}" end def wav2mp3(file) p = Pathname.new(file) dir = p.dirname output = "#{p.basename(".wav")}.mp3" command = "#{$options.lame} --preset extreme '#{p}' '#{dir}/#{output}' 2>&1" print $c.green,"Command: ", $c.clear if $options.verbose print $c.yellow, command,$c.clear, "\n" if $options.verbose processName = "Lame" error = Regexp.new(/Error(.+)/) match = Regexp.new(/\(\s*(\d+)%\)/) if !$options.test then begin lame = IO.popen(command) progress(lame,p,match,error,processName,nil) if $options.clean then cleanup(p,dir) end rescue Exception => e print $c.red, "ERROR: ", e, "", $c.clear, "\n\n" end end return "#{dir}/#{output}" end def splitmp3(file) p = Pathname.new(file) dir = p.dirname basename = "#{p.basename(".mp3")}" command = "#{$options.mp3splt} -d '#{dir}' -f -c '#{dir}/#{basename}.cue' '#{dir}/#{basename}.mp3' 2>&1" print $c.green,"Command: ", $c.clear if $options.verbose print $c.yellow, command,$c.clear, "\n" if $options.verbose processName = "MP3SPLT" # match[1] = percent complete # match[2] = name of created file match = Regexp.new(/\s*(\d+) % -> #{dir.to_s.gsub(/\//,"\\/")}\/(.+\.mp3)\.\.\./) error = Regexp.new(/(?:Error:|.+\.mp3:) (.+$)/) warning = Regexp.new(/Warning: (.*$)/) if !$options.test then begin mp3splt = IO.popen(command) progress(mp3splt,p,match,error,processName,warning) if $options.clean then cleanup(Pathname.new("#{dir}/#{basename}.cue"),dir) cleanup(Pathname.new("#{dir}/#{basename}.mp3"),dir) end rescue Exception => e print "\n" print $c.red, "ERROR: ", e, "", $c.clear, "\n" end end end if !$options.dir.empty? then getFiles.each {|file| $lameList.push(ape2wav(file))} $lameList.each {|wav| $mp3spltList.push(wav2mp3(wav))} $mp3spltList.each {|mp3| splitmp3(mp3)} else wav = ape2wav($options.file) mp3 = wav2mp3(wav) # mp3 = "/Users/jkyle/Downloads/Beethoven Edition Box-1/Complete Beethoven Edition Vol.01 - Symphonies/CD 1/CDImage.mp3" splitmp3(mp3) end