Posted in ruby, mac, scripting macs | Thursday, January 17th, 2008 | Trackback
In working on Ruby Scripting Leopard, I’ve been helped by searching for AppleScript examples, such as those at Doug’s AppleScripts for iTunes. To pay it forward, I offer an example to some future searcher after the jump. Since WordPress (or something) is turning quotes into “smart” quotes, follow this link if you want plain text.
This should work on stock Leopard.
I run it via launchd, the replacement for cron(1). Lingon is a convenient way to create a launchd configuration file.
require ‘osx/cocoa‘
include OSX
OSX.require_framework ‘ScriptingBridge‘
PLAYLIST_NAME = "today’s tunes"
def main
todays_tunes = make_empty_playlist
tracks = tracks_beginning_with(some_random_character, all_songs)
tracks.each do | track |
track.duplicateTo(todays_tunes)
end
end
def make_empty_playlist
ensure_no_playlist(PLAYLIST_NAME)
p = ITunesPlaylist.alloc.initWithProperties({’name‘ => PLAYLIST_NAME})
LIBRARY.userPlaylists.insertObject_atIndex(p,0)
p.shuffle = true
p
end
def tracks_beginning_with(letter, tracks)
tracks.find_all do | track |
name = if starts_with_qualifier?(track.name)
phrase_tail(track.name)
else
track.name
end
/^#{letter}/i =~ name
end
end
def ensure_no_playlist(name)
p = LIBRARY.playlists.objectWithName(name)
p.delete if p.exists == 1
end
def all_songs
LIBRARY.playlists.objectWithName(’Library‘).tracks
end
def some_random_character
possibilities = (’a‘..’z‘).to_a + (’0‘..’9‘).to_a
possibilities[rand(possibilities.length)]
end
def starts_with_qualifier?(name)
name =~ /^thes/i || name =~ /^ans/i || name =~ /^as/i
end
def phrase_tail(name)
name.gsub(/^w+s+/, ‘‘)
end
def bapp(bundle_name)
SBApplication.applicationWithBundleIdentifier(bundle_name)
end
ITUNES = bapp(’com.apple.iTunes‘)
LIBRARY = ITUNES.sources.objectWithName(’Library‘)
if $0 == __FILE__
main
end
|
November 5th, 2008 at 6:53 pm
FYI: I have done a lot of ruby scripting on microsoft with Watir for testing Time Warner Telecom webapps. Before I retired from TWTC, I converted three of my fellow testers to Ruby from Perl. Now I do iTunes for me and Excel for my CPA daughter’s business. I want to use rb-appscript for iTunes and Excel. I copied your text version (see it below), saved it as createPlaylist.rb, ran it to create a playlist named “today’s tunes” from textmate (command-R) and got results below. I still have a lot to learn about my MacPro. Am also delving into RubyCocoa. I will keep on hacking. I love Ruby. I am 68 now. I am a refugee from COBOL, FORTRAN and Sperry aka Unisys mainframes. I have an O’Reilly Safari subscription and bought your RubyCocoa book and roughcut. I also have hard copy of Everyday Scripting that I am working through now. Very instructive. I didn’t know how to use “collect”.
RubyMate
Ruby
Theme:
copy output
RubyMate r8136 running Ruby r1.8.6 (/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby)
>>> createPlaylist.rb
ruby: unknown type name “tdta”.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
/Users/pwoeber/ruby/rb-appscripts/createPlaylist.rb:64:in `starts_with_qualifier?’: ‘NSString#=~’ doesn’t work correctly. Because it returns byte indexes. Please use ‘String#=~’ instead.
Program exited.
Here is the script:
#!/usr/bin/env ruby
# Run to create a playlist named “today’s tunes”. The playlist is
# populated with tracks selected because the first character of their
# names begins with a randomly selected letter or digit. For example,
# my list today begins like this:
# Galang
# Gamma Ray
# Gary Stomp
# Gear
require ‘osx/cocoa’
include OSX
OSX.require_framework ‘ScriptingBridge’
PLAYLIST_NAME = “today’s tunes”
def main
todays_tunes = make_empty_playlist
tracks = tracks_beginning_with(some_random_character, all_songs)
tracks.each do | track |
track.duplicateTo(todays_tunes)
end
end
def make_empty_playlist
ensure_no_playlist(PLAYLIST_NAME)
p = ITunesPlaylist.alloc.initWithProperties({’name’ => PLAYLIST_NAME})
# TODO: why does following fail?
# LIBRARY.userPlaylists.addObject(p)
LIBRARY.userPlaylists.insertObject_atIndex(p,0)
p.shuffle = true
p
end
def tracks_beginning_with(letter, tracks)
tracks.find_all do | track |
name = if starts_with_qualifier?(track.name)
phrase_tail(track.name)
else
track.name
end
/^#{letter}/i =~ name
end
end
def ensure_no_playlist(name)
p = LIBRARY.playlists.objectWithName(name)
p.delete if p.exists == 1
end
def all_songs
LIBRARY.playlists.objectWithName(’Library’).tracks
end
def some_random_character
possibilities = (’a’..’z').to_a + (’0′..’9′).to_a
possibilities[rand(possibilities.length)]
end
# Works with either a NSCFString or a string.
# TODO: Change tests to indicate that?
def starts_with_qualifier?(name)
name =~ /^the\s/i || name =~ /^an\s/i || name =~ /^a\s/i
end
def phrase_tail(name)
name.gsub(/^\w+\s+/, ”)
end
def bapp(bundle_name)
SBApplication.applicationWithBundleIdentifier(bundle_name)
end
ITUNES = bapp(’com.apple.iTunes’)
LIBRARY = ITUNES.sources.objectWithName(’Library’)
if $0 == __FILE__
main
end