AppleScript Language Guide
AppleScript に関する本は、以前 Online で O’Reilly の書籍が読める Safari が利用できたときにパラパラと読んでいたけど、今ひとつ形にならなかった。最近 Apple が公開している AppleScript Language Guide を読み、やっと基本がわかった気がする。
スクリプトなので、あまり高い期待をしてはいけないのだが、使い方がわかってくると、もっと機能が欲しくなる。汎用的な sort とか、クロージャ的な使い方も見当たらない。対応する物は限られて入るけど、いろいろなアプリケーションをスクリプトで操作できるのは面白い。
外部ライブラリは scpdt 拡張子のバンドルでインストールできるらしい。MySQL の物もあるようだ。
iCal の特定のカレンダーからイベントを抜き出すスクリプトを作ってみた。個々の入力は GUI でやっといて、後で集計目的にイベントをテキストで取り出せる。コマンドでイベントを登録するようにもできるかも。最も、CalDAV を直接たたく方が汎用的なんだろうが。
(* 簡単な関数、引数は date の month, January - December は定義済みの定数 日付のフォーマット関数らしき物は見当たらなかった。月の変換の部分を 手動で行う 値の同一性は、違和感があるかもしれないが = を使う。 最後の値が戻り値になる。 as text はキャストに相当する Coercion という処理、状況に応じて自動的に 行われる事もあるが、ここでは明示的に行っている。 *) on mon2Num(mon) if mon = January then "01" else if mon = February then "02" else if mon = March then "03" else if mon = April then "04" else if mon = May then "05" else if mon = June then "06" else if mon = July then "07" else if mon = August then "08" else if mon = September then "09" else if mon = October then "10" else if mon = November then "11" else if mon = December then "12" else mon as text end if end mon2Num (* date format の様な事を行うハンドラ 文字列の連結は & で行う。 my mon2Num は current target の date オブジェクトに mon2Num を 探しにいかせず、script object の mon2Num を使わせるため。 *) on formatDate(date1) tell date1 set sday to day as text if day < 10 then set sday to "0" & day as text end if year & "/" & my mon2Num(month of date1) & "/" & sday & "-" & time string end tell end formatDate -- 対象のイベントをテキスト形式で保持するリストを宣言、初期化 set targetEvents to {} -- iCal をデフォルトターゲットに tell application "iCal" -- calenders プロパティを iterate repeat with cal in calendars -- log "name: " & name of cal & " desc: " & description of cal -- カレンダーの名前でフィルター if name of cal = "work" then -- log "name: " & name of cal & " desc: " & description of cal -- cal を default target に指定 tell cal -- log "name: " & name & " desc: " & description -- cal の events プロパティを iterate repeat with ei in events -- event のプロパティ allday が false の物を対象に if not allday event of ei then -- 対象のイベント ei をデフォルトターゲットに tell ei -- イベントの長さを分単位の整数値として計算 set durm to ((end date - start date) / minutes) as integer -- 開始次男、長さ、サマリーを文字列にフォーマット set ln to my formatDate(start date of ei) & " " & durm ?? & " " & summary as text -- リストの最後に追加。最後にしか追加できないのか? copy ln to the end of targetEvents end tell end if end repeat end tell end if end repeat end tell (* 結果のリストを \n を区切りに使い join する。 グローバルの text item delimiters リストを一時的に変更し、 元に戻す。 処理を try ブロックで行う事で、エラーが発生しても、 text item delimiters がデフォルトに戻るようにしている。 *) set savedDelimiters to AppleScript's text item delimiters try set AppleScript's text item delimiters to {" "} set input to targetEvents as string set AppleScript's text item delimiters to savedDelimiters on error m number n set AppleScript's text item delimiters to savedDelimiters error m number n end try (* 一時ファイルに出力を行う。 パスは、特に必要なければ POSIX file で扱う方がわかりやすい。 file, alias は : を区切りに使うパスをとり、相対パスは : で 始まるなど、HFS path を使う。 書き込むので open for acess に with write permission を付けて 開く。 write は特に改行を付けてはくれないので、最後に改行を write *) set tmpFilePath to "/tmp/iCalScr.tmp" set tmpFile to POSIX file tmpFilePath set ofile to open for access tmpFile with write permission write input to ofile write " " to ofile close access ofile (* do shell script で一時ファイルをソートする。汎用の sort は 標準ではない。iCal のカレンダーのイベントは開始時間でソート されてかえってくる訳ではない。 *) set output to do shell script "sort " & tmpFilePath log output