I wrote this one for my father as he has several audio tapes worth of MP3s to put into iTunes on Windows. It reads down through a directory structure for music files, using the nested directory names as metadata. It expects a nested directory structure as follows:
Root Dir
|- Artist Dirs
|- Album Dirs
|- Music files
Admittedly, this is my first usage of yield in anger. It hurt — but now my brain has been further fortified with vitamin Ruby.
Code follows…
require 'win32ole'
cwd = `cd`
cwd.gsub! "\\\\", "/"
path = ARGV[0] if not ARGV[0].nil?
path = “.” if path.nil?
app = WIN32OLE.new ‘iTunes.Application’
exit if app.nil?
$music = app.LibrarySource.Playlists.ItemByName ‘Music’
def for_each_in_dir(dir, contained_dir_type, meta={})
dir.each do |dir_name|
next if not File.directory? dir_name or dir_name =~ /^\\./
Dir.open dir_name do |nested_dir|
Dir.chdir dir_name
meta[contained_dir_type] = dir_name
yield nested_dir, meta
Dir.chdir ‘..’
end
end
end
def read_tracks_for(artist, album, album_dir)
album_dir.each do |t|
next if File.directory? t or t =~ /^\\./
title, junk = t.split ‘.’
if title =~ /^(\\d+)\\b(.*)/
track_number = $1.to_i
title = $2.strip
end
puts “Adding Track ‘#{title}’, Album ‘#{album}’, Artist ‘#{artist}’”
file_path = `cd`.chop << "\\\\#{t}"
$music.AddFile file_path
# AddFile may fork because sometimes no track is
# returned from ItemByName unless I sleep as below.
# You may need a sleep time greater than 1 depending upon
# your system's performance.
sleep 1
track = $music.Tracks.ItemByName title
if track.nil?
next
end
track.TrackNumber = track_number if track_number
track.Name = title
track.Album = album
track.Artist = artist
end
end
Dir.open path do |start_dir|
Dir.chdir path
for_each_in_dir start_dir, :artist do |artist_dir, artist_meta|
for_each_in_dir artist_dir, :album, artist_meta do |album_dir, album_meta|
read_tracks_for album_meta[:artist], album_meta[:album], album_dir
end
end
end



0 comments ↓
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment