BibTeX から iTunes へ
以前,PDF の管理を iTunes でできるという記事を /.-j で読んだ.フォルダ指向でなく属性指向のインタフェースで使い勝手がいいという.なんとなく気になってた.
試しに手元の数個の PDF を放り込んでみたが,確かに検索やソートが使いやすい.うん,悪くない.で,本格的に使おうとしたときに障害になるのが,ファイルのプロパティをどう入力するか,である.手持ちの PDF は論文が多いのだけど,曲名=論文タイトル,アーティスト=著者,アルバム名=書誌名…みたいなのを数百件も手で入力するなんてヤダ.
/.-j でも同意見がちらほら.
- http://slashdot.jp/comments.pl?sid=243522&cid=704358
- http://slashdot.jp/comments.pl?sid=243522&cid=704139
ていうことで,Perl でなんとかなりそうなので,BibTeX ファイルを読み込んで iTunes 用インポートファイルを吐き出すようなものを,やっつけ仕事で作ってみた.Perl レベル 4 なのでそのつもりで(ぉ.なお,インポートファイルはタブ区切りテキストです.iTunes の扱う XML は仕様がまるで謎だったので.
なお,以下では
- Perl スクリプトは Unix で動かす
- iTunes は Windows で動かす
- PDF ファイルは単一のディレクトリに置いてある.このディレクトリは Samba かなんかで共有されてて,Unix からは $pdfdir,Windows からは $pdfdirwin として見える.
- PDF ファイルの名前は,BibteX エントリ名 に拡張子 .pdf をつけたものである.
では,とりあえず Text::BibTeX というものを入れて手を抜く.あとは Perl レベル 3 くらいの人であればすぐに書ける.
まず iTune インポートファイル用のヘッダを出力.これをはじめ,iTunes に喰わせるテキストは SJIS,CL+LF でないといけない.
$header = "名前\tアーティスト\t作曲者\tアルバム\t分類\tジャンル\tサイズ\t時間\tディスク番号\tディスク数\tトラック番号\tトラック数\t年\t変更日\t追加日\tビットレート\tサンプルレート\t音量調整\t種類\tイコライザ\tコメント\t再生回数\t最後に再生した日\tマイレート\t場所\x0D\x0A"; jcode::convert(\$header, 'sjis'); print $header;
次に bib ファイルの読み込み.ここで気をつけないといけないのは,bib ファイルは EUC で書かれてないといけない.必要なら前段で文字コード変換する.Perl でのスマートな方法が思い付かないので略(ぉ.
$bibfile = new Text::BibTeX::File "hoge.bib"; $bibfile->set_structure ('Bib'); while ($entry = new Text::BibTeX::Entry $bibfile) { &action; }
で,sub action の中ではまず,
warn "error in input" unless $entry->parse_ok; my $type = $entry->type; my $key = $entry->key; # only for BTE_REGULAR metatype my $num_fields = $entry->num_fields; my @fieldlist = $entry->fieldlist; my $title = $entry->get ('title'); my $year = $entry->get('year'); my $vol = $entry->get('volume') unless ( $entry->get('volume') =~ /\D/ ); my $num = $entry->get('number') unless ( $entry->get('number') =~ /\D/ ); my $pages = $entry->get('pages'); if ( $entry->exists ('journal') ){ my $journal = $entry->get('journal'); } if ( $entry->exists ('booktitle') ){ my $journal = $entry->get('booktitle'); } my $comment = $entry->get('comment'); if ( $entry->exists ('author') ){ my @authors = $entry->split ('author'); ($first_author) = $entry->names ('author'); } else { my @authors = $entry->split ('editor'); } my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat( "$pdfdir$key.pdf" );
雑誌によっては,数字以外の文字が含まれる巻号だったりしますが (J82-D-II とかww),そういうのは省いてます.iTunes のアルバム番号エントリは数字以外許さないので.
次に,ファイル情報から出力をでっちあげます.
if ( $size ne "" ){ my $pdfpath = "$pdfdirwin$key\.pdf"; my @mdate = localtime( $mtime ); my $mt = sprintf("%d/%02d/%02d %d:%d", $mdate[5]+1900, $mdate[4]+1, $mdate[3], $mdate[2], $mdate[1]); my @cdate = localtime( $ctime ); my $ct = sprintf("%d/%02d/%02d %d:%d", $cdate[5]+1900, $cdate[4]+1, $cdate[3], $cdate[2], $cdate[1]); my @adate = localtime( $atime ); my $at = sprintf("%d/%02d/%02d %d:%d",\ $adate[5]+1900, $adate[4]+1, $adate[3], $adate[2], $adate[1]); my $output = "$title\t@authors\t\t$journal\t$pages\t$type\t$size\t\t$vol\t\t$num\t\t$year\t$mt\t$ct\t\t\t\tPDF 書類\t\t$comment\t\t\t\t$pdfpath\x0D\x0A"; jcode::convert(\$output, 'sjis', 'euc'); print $output; }
ctime,mtime,atime はなくても動く.ていうか所詮合ってないので,単なる気休め.
で,最後にこんなことを書くと怒られそうなのですが,なぜか手元の環境では年号が正しく iTunes で読めません.出力したテキストファイルは合ってるはずなんだけど.謎.
あと,これをやると iTunes の「ジャンル」の項目が汚くなるのも問題.Rocks とか Classics の中に inproceedings とか入ってきちゃうので.なので,スクリプトを書いただけで満足して,結局活用してません(激ぉ