逃避とか色々かねて、以前より懸案だった「モニター、キーボード、マウスのついていないMac Miniで皆の音楽をためて、コントロールする」という事を実装した。で、小さいプロジェクトだし、割とストレートにできそうだからlighttpd + FastCGI + Catalystを試してみた。


ちょっとハックが必要だったのがMac::iTunes。まずなんもドキュメントに書いてない!get_current_track_artist()とか存在さえも隠蔽されてる(笑)Security through obscurityかっつーのw。あとはプレイリストの内容を表示するのにget_track_names_in_playlistを直接ハックして


(良い子の皆さんはまねしないように)ページングできるようにしてみた。基本的にはAppleScriptの内容をこんな感じに変更:



# 前提:ユーザーから$limit, $offset, $playlistを指定してもらう

my $script = <<"SCRIPT";
set myPlalist to "$playlist"
return count of tracks in playlist myPlaylist
SCRIPT
my $psize = $self->tell( $script );

if ($limit > $psize) {
$limit = $psize;
$offset = 0;
} elsif ($limit + $offset > $psize) {
$limit = $psize - $offset;
}

my $start = $offset + 1;
my $end = $offset + $limit;

$script = <<"SCRIPT";
set myPlaylist to "$playlist"
set myString to ""
repeat with i from $offset to $end
set thisName to name of track i in playlist myPlaylist
set myString to mystring & thisName & return
end repeat
return myString
SCRIPT

my $result = $self->tell($script);
my @list = split /\015/, $result;
return \@list

これをApp::Controller::iTunes からたたく:



# play / pause / stopとかは全部一緒
sub play : Local
{
my($self, $c) = @_;
my $itunes = Mac::iTunes->controller;
$itunes->play;
$c->response->redirect('/itunes/status'); # 現在の状況を表示ページ
}

sub library : Local
{
my($self, $c) = @_;

my $itunes = Mac::iTunes->controller;
my $page = $c->req->param('p');
my $limit = 100;
my $offset = ($page - 1) * $limit + 1;

# ↓ちょっとこの辺の呼び出し方はてきとー
my $list = $itunes->get_track_names_in_playlist('Library', 100, 0);

my $position = $offset;
foreach my $name (@$list) {
# トラック番号がないと後でどーしようもない
push @tracks, { position => $position++, name => $name };
}
$c->stash->{tracks} = \@tracks;
$c->stath->{template} = 'library.tt';
}

こんな感じ。テンプレートはまぁ想像できるんじゃなかろうか。で、あとはlighttpdをどこん、と起動しておしまい。Mac::iTunesのソースコード(特にMac::iTunes::AppleScript)を読まなかったらきっとなんもわからんかった。ぼへぼへ。