require 'fileutils' def album(song) if song =~ /\.ogg\Z/i File.open(song) { |f| f.read(2048)[/album=(( |[^\0-\63])+)/, 1] } elsif song =~ /\.mp3\Z/i `mp3info -p "%l" "#{song}"` end end def track(song) if song =~ /\.ogg\Z/i File.open(song) { |f| f.read(2048)[/tracknumber=(\d+)/, 1].to_i } elsif song =~ /\.mp3\Z/i `mp3info -p "%n" "#{song}"`.to_i end end count = 1 ARGV.each { |dir| unless File.directory? dir warn "`#{dir}' is not a directory. Skipping." end songs = Dir[dir + "/**/*{ogg,mp3}"].map { |f| f.squeeze '/' } ordered = songs.sort_by { |song| [album(song), track(song)] } ordered.each { |song| dirname, basename = File.split song basename = basename[5..-1] if basename =~ /\A\d{4}-/ newname = File.join(dirname, "%04d-%s" % [count, basename]) unless song == newname FileUtils.mv song, newname, :verbose => true end count += 1 } }