You are currently browsing the monthly archive for June 2010.
I recently bought a new Windows computer and, since there is no AppleScript on Windows, I have to do without the Doug’s scripts for ITunes that I used on Mac OS X to automate the management of my music library. But Apple has made available a COM API, that can be used by any language to script iTunes, as long as it supports COM. This includes Ruby MRI, with the Win32OLE package in the standard library. But I was curious about IronRuby, the .NET implementation of Ruby, which recently reached version 1.0 and therefore, I decided to reimplement with it some of the scripts I used the most.
The scripts shown in this post can be downloaded here.
Installing IronRuby
- First install .NET 4.0
- Then install IronRuby for .NET 4.0
The PATH environment variable is updated and now contains the “ir.exe” executable.
Connecting to the iTunes COM object
Since this functionality is going to be used by all the scripts, I extracted it in a separate file called “iTunesLib.rb” :
module ITunes
def self.app
begin
itunes_type = System::Type.get_type_from_prog_i_d("iTunes.Application")
itunes = System::Activator.create_instance(itunes_type)
 yield itunes
rescue Exception => e
puts e
end
end
end
This modules hides all the COM plumbing from the scripts. It uses the standard .NET libraries to interface with COM: For example, by using the System.Activator class. One nice thing IronRuby does is to allow the use of rubyfied names for methods, using undescores. It is still possible to use the original .NET names though.
Prefix to track number
The first script is very simple: All it does is check if the “Song” fields of the tracks currently selected in iTunes begin with a number, and if they do, copy this number to the “Track Number” field: “07 – Hypersurface” will have track number 7.
require "iTunesLib"
ITunes.app do |itunes|
sels = itunes.selected_tracks
if sels.nil?
puts "No selection"
break
end
1.upto(sels.count) do |i|
track = sels.item(i)
if track.name =~ /^\s*(\d+)/
track.track_number = $1.to_i
end
end
end
After selecting some tracks with the iTunes interface, the script can be run on the command line like this (no arguments are necessary):
ir.exe prefix_to_track_number.rb
(Note: This really modifies the tracks. No undo is possible…)
Remove n characters from front or back
This script removes an arbitrary number of characters, from the front and/or back of either the “Artist”, “Album” or “Song” field. At the beginning, there are various checks of the arguments, followed by the main code, which loops through the tracks currently selected in iTunes. Update: Added checks for the field inside the loop
require "iTunesLib"
if ARGV.length <= 1
puts "Usage: #{__FILE__} [a|l|n] [<f or b> <num chars to remove>]+"
puts "a => artist, l => album, n => song name"
exit
end
scope = ARGV.shift
if scope !~ /a|l|n/
puts "Bad scope"
exit
end
rff = nil
rfb = nil
ARGV.each_with_index do |a,i|
if a == "f"
rff = ARGV[i + 1].to_i if i < ARGV.length - 1
elsif a == "b"
rfb = ARGV[i + 1].to_i if i < ARGV.length - 1
end
end
if rff.nil? and rfb.nil?
puts "Nothing to do"
exit
end
ITunes.app do |itunes|
sels = itunes.selected_tracks
if sels.nil?
puts "No selection"
break
end
1.upto(sels.count) do |i|
track = sels.item(i)
if scope == "n"
name = track.name
elsif scope == "l"
name = track.album
else
name = track.artist
end
if !rff.nil?
#name is an immutable .NET string
name = name.slice(rff..-1)
end
if !rfb.nil?
name = name.slice(0..-(rfb+1))
end
if scope == "n"
track.name = name
elsif scope == "l"
track.album = name
else
track.artist = name
end
end
end
One of the only gotchas I encountered with IronRuby had to do with the fact that .NET strings are immutable. But in Ruby, strings are mutable and there are methods ending with “!” (such as “slice!”) that can be used to modify the current String instance instead of returning a new one. Those methods cannot be used on .NET/CLR strings (that are returned by the methods of .NET objects). This is why I used “name = name.slice” instead of something like “name.slice!” in the code above. I later learned that the “to_s” method could have been used on a .NET string to obtain a Ruby string.
After selecting some tracks with the iTunes interface, the script can be run on the command line like this:
ir.exe remove_n_characters_from_front_or_back.rb n f 5
(“n” means the “Song” field; “f” means the front of the field; “5″ the number of characters to remove)
Using the previous song name example: “07 – Hypersurface” will become “Hypersurface”.
Bonus
You have read the complete article! Here is a great track as a reward:








Recent Comments