So today I was copying the music off of my iPod onto one of my HDDs. All was going well, at least I thought. I went to add a few directories to XMMS to randomize and play when I realized something had gone wrong- no files were added to my play list. On further inspection I learned that the reason behind this is the application I used to extract the songs didn’t give them their .mp3 extension. Come to find out when I was customizing the format for the file names (I’m picky) I had to explicitly define “.%e” or whatever, for the extension.
Whoops.
So I was left with 4,500 tracks and none of them had an extension. Enter: Ruby. After some quick prototyping in the Ruby IRB, I wrote up a quick and dirty script that would loop through my music structure (Music Directory / Artist / Album / <songs>) and add “.mp3″ to the end of every extension. I’ve gone ahead and modified it a little to be less dirty, so I figure I’ll share with you what I have.
#!/usr/bin/ruby class AddMp3Extension # Take in the main music directory, slice off the ending slash if it exists, # initialize our instance variables and kick off the show. # # @param string The top level of our music directory def initialize(musicDir) if musicDir[-1, 1] == "/" musicDir = musicDir[0, musicDir.length - 1] end @musicDirectory = musicDir @numRenamed = 0 puts "Starting rename process..." begin_main_loop puts "Rename process complete! #{@numRenamed} files were renamed." end private # Begin looping through the directory. Every time we find another # directory we'll enter it (it'll be an album) and then rename all # the junk inside it. def begin_main_loop(dir = @musicDirectory) curDir = dir curDirContents = Dir.entries(dir) curDirContents.each do |f| unless f == "." || f == ".." curFile = "#{curDir/#{f}" find_extension = curFile.split(".") if is_directory?(curFile) begin_main_loop(curFile) end if is_file?(curFile) && find_extension.last != "mp3" newName = "#{curFile}.mp3" File.rename(curFile, newName) @numRenamed += 1 end end end end # Takes a file path and checks to see if it's a directory. If it # is we shoot back a true value. # # @param string The directory we're interested in def is_directory?(dir) dir = File.ftype(dir).downcase if dir == "directory" return true end return false end # Check to see if we're working with a file, rather than a directory. # If so then more likely than not (barring any user error) we have # ourselves an mp3 without its extension. # # @param string Location of the file we're validating def is_file?(file) file = File.ftype(file).downcase if file == "file" return true end return false end # Every *nix directory has two special placeholders within it: . and .. # So take the current file and make sure it's neither of those. # # @param string Location of the file we're validating def is_special?(file) return true if file == "." || file == ".." return false end end unless ARGV[0].empty? begin_renaming = AddMp3Extension.new(ARGV[0]) else puts "Correct format: add_mp3_extension " end
Now I make no claim that this is the best way to accomplish the goal. Perhaps tomorrow, when I haven’t been up for about 20 hours I’ll write a version that is closer to being production quality.
Either way, just thought I’d share. Later.