require 'find' require 'pp' class DiscFullError < Exception end class ToolFailedError < Exception end class Mp3CD attr_reader :files,:size def initialize @files=Hash.new @size=0 @tempfiles = [] @@decoders=[ \ [ /flac$/i , proc{|file| "flac.exe -d -o - \"#{file}\" "}], \ [ /wv$/i , proc{|file| "wvunpack.exe \"#{file}\" - " }]] @@encoder_ext = "mp3" @@encoder = proc{ |name| "lame -V4 - \"#{name}\"" } @@speed = 16 @@device = "0,0,0" #run `cdrecord -checkbus` to find device number end def add file,folder @size += FileTest.size file[0] if (@size > 700*1024*1024) @size -= FileTest.size file[0] raise DiscFullError end @files[folder] ||= [] @files[folder] << file end def transcode_or_append file,folder if (/\.mp3$/i =~ file) || (/\.wma$/i =~ file) add([file,file.split('/').last],folder) else @@decoders.each do |decoder| match = decoder[0].match(file) if match temp = make_tmp_name @@encoder_ext convert(file,decoder[1],temp,@@encoder) @tempfiles << temp add([temp,file.split('/').last.gsub(match[0],@@encoder_ext)],folder) end end end end def convert file,decoder,temp,encoder raise ToolFailedError unless system(decoder.call(file)+"|"+encoder.call(temp)) end def make_tmp_name ext loop do dir=File.join(ENV['TEMP'].gsub("\\","/"),"burn_"+rand(100000).to_s+"."+ext) return dir unless File.exist? dir end end def << file file = file.gsub("\\","/") if FileTest.file? file transcode_or_append(file,:root) elsif FileTest.directory? file Find.find file do |path| if FileTest.file? path transcode_or_append(path,File.dirname(path)[File.dirname(file).length..-1]) end end end end def burn pathmap=File.open("paths.txt","wb") # 'wb' `cos need unix line-endings for mkisofs @files.each_pair do |folder, filess| filess.each do |file| pathmap<< File.join(folder==:root ? "/" : folder,file[1])+"="+file[0]+"\n" end end pathmap.close iso = make_tmp_name "iso" #You could run without the image by using mkisofs | cdrecord, might be risky raise ToolFailedError unless system("mkisofs -J -r -graft-points -path-list paths.txt -o \"#{ iso }\"") @tempfiles << iso raise ToolFailedError unless system("cdrecord -v -dummy driveropts=burnfree speed=#{@@speed} dev=#{@@device} #{iso}") end def del_temp if @tempfiles @tempfiles.each { |file| File.delete file } end end end puts "Cheap burning tool" puts "Drag Folders and Files into this window and press enter twice when done." puts "> " cd=Mp3CD.new loop do begin break if gets.strip.split(/"{1,2}/).each { |match| cd << match }.empty? rescue DiscFullError puts "File could not be added. Disc Full." rescue ToolFailedError puts "An external command failed." end puts "Current size: #{ cd.size / 1024 / 1024 }MB" puts "> " end puts "Thank you. Preparing to burn..." cd.burn puts "Burnt. Deleting temp files..." cd.del_temp puts "Done." system("pause")