Tutorial: OS X automation with MacRuby and the Scripting Bridge
One more for the road
以降にある iTunes のサンプルを実行すると
... `<main>': undefined method `playlists' for nil:NilClass (NoMethodError)
playlists がない?
なーんてことはなくて単に日本語システムだからだった。
要素名を日本語に変えればよいのだった。
...
.find {|s| s.name == "ライブラリ"}
.playlists.find {|p| p.name == "トップ 25"} #Top 25 Most Played"}
...
この内容を理解する為、基本的な AppleScript を動かす。
tell application "iTunes"
repeat with i in playlists
if name of i is "ミュージック" then
get tracks
end if
end repeat
end tell
AppleScript Editor.app のイベントログで
playlists の要素や tracks の属性を確認できた。
sources にアクセスしなくても、playlists を獲得できた。
MacRuby でも playlists 要素を目視したい為...
framework "ScriptingBridge"
i = SBApplication.applicationWithBundleIdentifier("com.apple.iTunes")
i.sources.select{|x|
x.playlists.each{|y|
puts y.name
if y.name == "トップ 25" # "トップレート", "ミュージック"
songs = y.tracks.sort{|t1,t2| t2.playedCount <=> t1.playedCount}
# songs[0..2].map{|t| puts "#{t.artist} - #{t.name} (#{t.playedCount})"}
end
}
}
puts y.name でプレイリスト名一覧を確認できた。
ライブラリ
ミュージック
ムービー
テレビ番組
Podcast
iTunes U
ブック
iTunes DJ
90 年代ミュージック
クラシック音楽
トップ 25
トップレート
ミュージックビデオ
最近再生した項目
最近追加した項目
ラジオ
書き換えながらいろいろ試す。
framework "ScriptingBridge"
i = SBApplication.applicationWithBundleIdentifier("com.apple.iTunes")
ary = i.sources.map{|x| x.playlists}.flatten
top25 = ary.find{|i| i.name == "トップ 25"}
songs = top25.tracks.sort{|t1,t2| t2.playedCount <=> t1.playedCount}
songs.find_all{|t| t.rating > 2}.map{|t| puts "#{t.artist} - #{t.name} (#{t.playedCount})"}
Ruby らしい(つもりの)書き方へ。
framework "ScriptingBridge"
class MyiTunes
def initialize(str)
exit if (str.empty? or str.nil?)
@str = str
# iTunes Object
i = SBApplication.applicationWithBundleIdentifier("com.apple.iTunes")
# playlist Object
@ary = i.sources.map{|x| x.playlists}.flatten
@songs = @ary.find{|i| i.name == @str}.tracks
end
def debug
@ary.each{|x| puts x.name}
end
def view
print "-- #{@str}\n"
find_all
count_sort
to_s
end
private
def count_sort
@songs = @songs.sort {|t1,t2| t2.playedCount <=> t1.playedCount}
end
def find_all
@songs = @songs.find_all{|t| t.rating > 60}
end
def to_s
@songs.each_with_index{|x,n|
break if n > 2
puts "#{x.artist} - #{x.name} (#{x.playedCount}) [#{x.rating}]"
}
end
end
MyiTunes.new("トップ 25").view
# MyiTunes.new("トップ 25").debug
実行結果
-- トップ 25
Glenn Gould - Bach: Goldberg Variations, BWV 988 - Aria (5) [100]
Glenn Gould - Bach: Goldberg Variations, BWV 988 - Var. 7 (5) [60]
Glenn Gould - Bach: Goldberg Variations, BWV 988 - Var. 5 (4) [80]
%
MyiTunes クラスは
"トップ25" から、
星が3つ以上の曲を抽出し、
再生回数順にソートし
3行出力したら終わる。
.rating
に注意を払っていなかった。
puts 表示させてよくみてみると
星が 5つだと 100で、
星が 4つだと 80 で、
星が 3つだと 60 に、
なっていた。
星が3つ以上( > 60 )に変えた。
# t.rating > 60
iTunes.app 環境設定で表示する項目を減らして
MyiTunes.new("トップ 25").debug
を実行すると...正しく捕獲できた。
ライブラリ
ミュージック
ブック
90 年代ミュージック
クラシック音楽
トップ 25
トップレート
ミュージックビデオ
最近再生した項目
最近追加した項目
%
MyiTunes.new("ミュージック")
でも OK だった。
-- 追記
OS X 10.7.2 で自力で MacRuby をインストールしていない為
/System/Library/PrivateFrameworks/MacRuby.framework/Versions/A/usr/bin/macruby
を使った。
最後に、~/Library/Logs/CrashReporter で
MacRuby がクラッシュしていないかみてみたが
大丈夫だった。
[2011-11-12]
最短?
i = SBApplication.applicationWithBundleIdentifier("com.apple.iTunes")
top25 = i.sources.flat_map{|x| x.playlists}.find{|t| t.name == "トップ 25"}
p top25.name
songs = top25.tracks
p songs.size
=>
"トップ 25"
25
[2011-11-22]
続き
0 件のコメント:
コメントを投稿