Archive for 5月, 2010

2010/05/27 マウント中のdiskimage中のファイルをすべて削除

マウント中のdiskimageの全フォルダ階層を走査して、ファイルが存在したら削除する……というAppleScriptです。

まずは……どうしてこんなものを作ったのかといえば、いくつもファイルサーバーもマウントして、データ内容から出力先のファイルサーバーを自動選択してファイルコピーするような(割と大きめの……数千行オーダーの)AppleScriptのプログラムを作っていました。

ところが、実環境ではファイルサーバーが運用されているものの、同じ環境を再現できなかったので、マウント状態だけでも再現しようと思い立ち、実環境の名称と同じドライブをマウントしている状態を作り出すために、sparseimage(可変容量)のdisk imageを作成して、デスクトップにマウントしていました。

マウントした状態でプログラムを実行し、出力状態などを評価していたわけですが……ファイル出力状況を確認したら、また元に戻さなければなりません。

元のdisk imageをアーカイブしてオリジナルの状態で保存しておいてもよかったのですが、ちょっと容量が大きかったのと作業中のドライブの残量が少なかったので、オリジナルのdisk image(のコピー)を取っておくのはいかがなものか、という話に。

そこで、マウント中のdisk imageの全階層を走査(entire contents)してファイルをリストアップし、削除するというAppleScriptを作成した次第です。

ejectableなdiskをdisk imageとみなしているので、もしかしたらUSBメモリなどもマウントしていたら、一緒に削除してしまうかもしれませんが……USBメモリはあらかじめ抜いておくということで対処していました。

disk imageのみをリストアップする、というプログラムは、なかなかに奥が深そうなので後日リトライしてみたいところです。

スクリプト名:diskimage中のファイルをすべて削除
–disk imageをリストアップする
tell application "Finder"
  set dList to every disk whose ejectable is true
end tell

repeat with i in dList
  set j to contents of i
  
deleteInsideFolder(j) of me
end repeat

on deleteInsideFolder(a)
  tell application "Finder"
    set fList to entire contents of a as alias list
  end tell
  
  
set aList to {}
  
repeat with i in fList
    set j to contents of i
    
set aClass to (info for j)
    
set bClass to folder of aClass
    
    
if bClass = false then
      set the end of aList to j
    end if
  end repeat
  
  
tell application "Finder"
    delete aList
    
–empty trash
  end tell
end deleteInsideFolder

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/05/24 Terminalから内容を取得する

Terminal.appの最前面のWindowで、その内容を取得するAppleScriptです。

一般的には、do shell scriptでshellコマンドを実行して結果を取得する方が有用性が高いですが、まれにTerminal.appをコントロールする必要が出てきたりします(3年に1度ぐらいかな、、、)。

とりあえず、指定ウィンドウ中の、

 表示されている範囲の内容を取得するならcontents
 コマンド履歴すべてを取得するならhistory

でアクセスできます。ただ、本当にTerminal.appをコントロールする機会は日常的に発生しないので、活用できるのかどうか謎ですが、、、、

スクリプト名:Terminalから内容を取得する
tell application "Terminal"
  tell window 1
    set aCon to history –すべてのヒストリの内容を取得
    
set bCon to contents –Window内に表示されている文字(表示されている分だけ)
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/05/21 エラートラップを使って、レコードをstringに変換する

トリッキーな方法で、レコードをstring(文字列)に変換するAppleScriptです。

recordの内容を手っ取り早く文字列に変換したいような場合……常識的に考えれば、レコード内の要素をひとつひとつ取り出して、stringに変換するしかありません。要素が少ないときにはいいですが、数十・数百の要素があるとか、それらがリストで入れ子になっているような場合には、とてもやっていられません(それでもやらなくてはならない場合もありますが)。

ただ単に、recordの内容をテキストに書き出したいとか、ログに記録したいというような場合、もう手段なんて選ばないからできるだけ楽にrecordの内容をテキスト化したい、という方にお勧めのやりかたです。

とりあえず、recordをstringに変換します。ただ、そのまま変換したのでは、エラーが発生してしまいます。

このエラーを(逆に)利用します。

try〜on error〜end tryの構文でエラートラップを仕掛けます。途中のエラー処理部分「on error」では、エラーメッセージを受信する「on error someVal」のような記述が行えます。someValにはエラーメッセージが入る仕組みです。

この、エラーメッセージから定型部分を削除して、recordからstringへの変換を行います。トリッキーすぎて、とてもおすすめできませんが、万策尽きたような場合にどうぞ(ええ、実際に万策尽きていたのでこんなワザを苦し紛れに、、、)。

スクリプト名:エラートラップを使って、レコードをstringに変換する
set aRec to {aData:1, bData:2}

–エラートラップを使って、わざとエラーを発生させ、エラーメッセージからレコードをstringに変換する
try
  set a to aRec as string
on error aMsg
  set a to aMsg
end try

set b to repChar(a, “のタイプを string に変換できません。”, “”)
–> “{aData:1, bData:2} “

–文字置換ルーチン
on repChar(origText, targStr, repStr)
  set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
  
set temp to text items of origText
  
set AppleScript’s text item delimiters to repStr
  
set res to temp as text
  
set AppleScript’s text item delimiters to txdl
  
return res
end repChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/05/07 手書き文字認識アプリケーション「QuickScript」がバージョン3.0でAppleScriptに対応

macnnによれば、Axiotronの手書き文字認識ソフトウェア「QuickScript」がAppleScriptに対応したとのこと。コマンドScriptフォルダに入っているAppleScriptのファイル名と同じ文を手書き文字認識させると、対応するコマンドScriptが実行されます(確認済み)。

QuickScriptの文字認識エンジンはVison Objects社からの提供を受けたもので、「26言語をサポート」と元記事には書かれています。ただ、実際にインストールしてみたところ、画面表示はたしかに日本語で行われるものの……文字認識エンジン自体は英語のみであることを確認しました。この点については、注意が必要です。

最近のMacBook/MacBook Proに採用されている大型のガラス製トラックパッドを疑似的にタブレットとして使用するソフトウェア「inklet」と併用できたりすると(未確認ですが)、面白いかもしれません。

ただ……機構的には、Appleが標準で組み込んできてもおかしくはなさそうな内容です。

qs1.jpg
▲QuickScriptを起動してタブレットから「sleep」と入力して文字認識させたところ。コマンドは英単語(もしくは単語としてparseされない程度の短いアルファベットの組み合わせ)でないとダメ。

qs2.jpg
▲「sleep」AppleScriptが実行されたところ

qs3.jpg
▲コマンド用AppleScriptが入っている場所

qs4.jpg
▲QuickScriptをインストールすると標準で入ってくるAppleScriptコマンド。編集可能なAppleScript書類で提供されている。短縮コマンドも入っている

2010/05/07 指定のtarアーカイブを展開する

指定のtarアーカイブを展開(元に戻す)するAppleScriptです。

スクリプト名:指定のtarアーカイブを展開する
set a to choose file with prompt ".tarファイルを指定してください"
set b to extractTar(a) of me

–指定tarアーカイブを展開する
on extractTar(a)
  set anAlias to a as alias
  
  
tell application "Finder"
    set aParent to parent of anAlias
    
set aFileName to name of anAlias
  end tell
  
  
set aParent to aParent as alias
  
  
set preCMD to "cd " & quoted form of POSIX path of aParent
  
set tarCMD to "tar xf " & quoted form of (aFileName)
  
  
try
    set aRes to do shell script (preCMD & " && " & tarCMD)
  on error
    return false
  end try
  
  
set newName to text 1 thru -5 of aFileName –展開後の、".tar"を除去した名前
  
set extractFol to (aParent as string) & newName & ":"
  
  
try
    return (extractFol as alias)
  on error
    return false
  end try
  
end extractTar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/05/05 指定フォルダをtarでまとめる

指定フォルダをtarでまとめるAppleScriptです。

指定のフォルダを渡すと、指定フォルダと同じ階層に指定フォルダ名でtarアーカイブを作成します。オリジナルのフォルダは削除せず、そのまま残しておきます。エラー時にはfalseが、正常動作時にはtarアーカイブへのaliasが返ります。

一般的には、フォルダをアーカイブする場合にはZipコマンドで圧縮してまとめたほうが手っ取り早いところですが、対象のファイルが巨大(数百Mバイトオーダー、数Gバイトオーダー)である場合などは「圧縮」するのが大変です。さらに、そもそも圧縮されているデータ(ムービーや画像)なので「再圧縮する意味がない」という場合もあります。

そこで、圧縮せずに単に「1ファイルにまとめる」tarアーカイブを用いた方が便利なケースがあります。本AppleScriptはそのために作成したものです。ただし、tarアーカイブにまとめるファイルには、日本語のファイル名やフォルダ名を使った場合に「展開時にファイル名を戻せない」といった問題(そもそもtarがそういう仕様)があるため、英数字のみのファイル名を使用するなどの注意が必要です。

tarは、語源が「Tape ARchive」であるとおり、HDDの内容をテープストリーマ(バックアップ装置)に転送するために、複数のファイルをまとめて1つのtarファイルにして磁気テープに書き出すためのものです。ExabyteのDATストリーマーなどをUNIXワークステーションで使ったことはありますが、さすがにMac OS X環境で磁気テープストリーマを使ったことはありません、、、

スクリプト名:指定フォルダをtarでまとめる
set a to choose folder
set b to tarFolder(a) of me

–指定フォルダをtarでまとめる
on tarFolder(a)
  set anAlias to a as alias
  
  
tell application “Finder”
    set aParent to parent of anAlias
    
set aFolName to name of anAlias
  end tell
  
  
set aParent to aParent as alias
  
  
set preCMD to “cd “ & quoted form of POSIX path of aParent
  
set tarCMD to “tar cvf “ & quoted form of (aFolName & “.tar”) & ” “ & quoted form of (aFolName & “/”)
  
  
try
    set aRes to do shell script (preCMD & ” && “ & tarCMD)
  on error
    return false
  end try
  
  
  
tell application “Finder”
    set tarAlias to ((aParent as string) & aFolName & “.tar”) as alias
    
set tarEx to exists of tarAlias
  end tell
  
  
if tarEx = true then
    return tarAlias
  else
    return false
  end if
end tarFolder

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/05/04 Xcode 3.2.2+Snow LeopardでAppleScript Studio環境を復活させる

Twitter経由で、「AppleScript applications with Xcode 3.2.2」なる記事を見つけました。

記事を読んで、最初はわけが分からなかったのですが……以下の手順でできることを確認しました。

(1)S.J. Louw氏が配布している「AppleScript-App-Templates-Xcode32.pkg」をダウンロードしてインストール。「Download Link」の文字が、黒地にグレーの文字で見つけにくいので要注意!!

downlink.jpg
▲視力検査なのか?!

inst0.jpg

(2)Terminal上で、「defaults write com.apple.InterfaceBuilder3 IBEnableAppleScriptStudioSupport -bool YES」を実行

inst011.jpg

(3)Xcode 3.2.2を起動して、「Application」テンプレートの中に新たにできた「AppleScript Application」をクリック

ass1.jpg

以下、従来どおりのAppleScript Studio環境(Xcode+Interface Builder)がMac OS X 10.6.3+Xcode 3.2.2の環境で使えることを確認しました。

ただ、Interface Builder上で使用できるGUI部品に一部制限があるようで、新しいルック&フィールをベースにしたGUI部品はAppleScript Studio環境では表示されなかったりします。

それでも、AppleScript Studio環境がMac OS X 10.6上で使用できることの意義は大きいと思います。長い目で見ればAppleScript ObjCに移行した方が「できること」が大幅に増えるので、移行すべきだとは思うのですが……そうそう急にAppleScript ObjCによる開発の仕事が発生するものでもないですし(汗)

以下、インストール手順を紹介します。

inst011.jpg

TerminalからAppleScript Studio復活コマンドを実行。以前からAppleがこれを紹介していたが、そのとおりにやってもASSは復活しなかった。Appleはダンマリを決め込んだまま……。ちなみに、これってインストーラーパッケージの中で実行するようにしておけばいいんじゃないかと>S.J. Louw氏

注釈:S.J.Louw氏本人からコメントがあって、「インストーラのScript中で実行しているから、わざわざコマンドラインで実行する必要はないよ」だそうです(汗) 話が早くてけっこうなことで。

inst1.jpg

▲インストーラをダウンロードして実行

inst2.jpg

▲Xcodeが起動中であればいったん終了させてくれ、とメッセージ表示。Interface Builderも同様

ass1.jpg

▲なつかしの、AppleScript Studioテンプレートが選択可能に

ass2.jpg

▲Xcode 3.2.2上でAppleScript Studioプロジェクトを新規作成したところ

ass3.jpg

▲XcodeでXibファイルをダブルクリックしてInterface Builderを起動。IBのインスペクタでAppleScript Studioの各種イベントハンドラが指定可能になっていることを確認できます

ass4.jpg

▲かる〜いご挨拶。これ1行を書いただけでバグが発覚したXcodeの恥ずかしいリリース版とかも過去にありました

ass5.jpg

▲ビルドして実行したところ。きちんと日本語が表示されています

2010/05/03 MacJournal 5.2.1でエントリのtag情報(tags)を取得/設定

MacJournal 5.2.1で、エントリのキーワード(tag)の情報を取得、設定できるようになりました。

mj20.jpg
▲この状態のエントリのtag情報を取得すると……

tagsの情報を取得すると、tag情報がリストで返ってきます。

スクリプト名:MacJournalでエントリのtag情報を取得する
tell application "MacJournal"
  tell document 1
    set aSel to selected entries
    
repeat with i in aSel
      tell i
        set aKey to tags
        
–> {"radio"}
      end tell
    end repeat
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

一方、取得するだけでなく設定もできます。以下のAppleScriptを実行すると、実際にtag情報が付加されたことをGUI側からも確認できます。

スクリプト名:MacJournalでエントリのtag情報を取得・設定する
tell application "MacJournal"
  tell document 1
    set aSel to selected entries
    
repeat with i in aSel
      tell i
        set aKey to tags
        
–> {"radio"}
        
        
set the end of aKey to "piyomaru"
        
set tags to aKey
      end tell
    end repeat
  end tell
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

mj21.jpg
▲tag情報「piyomaru」が追加された

2010/05/03 MacJournal 5.2.1で「選択中のエントリ」の実装を増強。複数選択に対応

MacJournal 5.2.1で増強されたAppleScript用語辞書のうち、「選択中のエントリ」を扱うもの(selected entry/selected entries)を解説します。

McJournalでは、documentオブジェクトのプロパティとして「選択中のエントリ」を示す「selected entry」という属性値がありますが、これは表示中のエントリを指し示すもののようで、複数のエントリを選択状態にするとmissing valueが返ってきました。

mj10.jpg

mj11.jpg
▲1つのエントリ(記事)を選択中の状態

スクリプト名:MacJournalで選択中のエントリを取得する
tell application “MacJournal”
  tell document 1
    set aSel to selected entry
  end tell
end tell
–> journal entry 1 of journal 3 of journal 15 of journal 10 of journal 1 of application “MacJournal”

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

mj12.jpg
▲複数のエントリを選択中の状態

スクリプト名:MacJournalで選択中のエントリを取得する2
tell application “MacJournal”
  tell document 1
    set aSel to selected entry
  end tell
end tell
–> missing value

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

MacJournal 5.2.1で追加された「selceted entries」では、1つのエントリが選択されていても、複数のエントリが選択されていても結果がリストで返ってくるようになっており、こちらのほうがAppleScript対応アプリケーションにおける一般的な実装になっているといえます。

スクリプト名:MacJournalで選択中のエントリを取得する3
tell application “MacJournal”
  tell document 1
    set aSel to selected entries –selceted entryとは挙動が違う
  end tell
end tell
–> {journal entry 1 of journal 3 of journal 15 of journal 10 of journal 1 of application “MacJournal”} –1つのエントリを選択している場合
–> {journal entry 1 of journal 3 of journal 15 of journal 10 of journal 1 of application “MacJournal”, journal entry 2 of journal 3 of journal 15 of journal 10 of journal 1 of application “MacJournal”}–2つのエントリを選択している場合

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2010/05/03 MacJournal 5.2.1で大幅なAS用語辞書の増強が

MacJournalでは、バージョン5.1.3b6および5.2.1でAS用語辞書の改変が行われており、これから先もいろいろと改変がありそうです。

mj1.jpg

「よろずデータスクラップブック系」とでも呼ぶべきMacJournalのようなアプリケーションは、サーバー側にデータをため込み将来的にはサーバー側でさまざまな処理を行うことが予想される「Evernote」などのソフトウェアと、ローカルにデータを蓄えユーザーが好き勝手に処理できるMacJournalなどのソフトウェアの2系統に分化していきそうです。

MacJournalのAS用語辞書の増強は、Evernoteのローカル処理が箸にも棒にもつかない、まるで使い物にならないレベルであることに対して、ローカル処理での圧倒的な優位性を確保しようというものでしょうか。他のさまざまなアプリケーションと連携して処理を行うという意味において、Evernoteではまるっきり使い物にならないので、個人的には極力MacJournalを応援したいところです。

長い目で見れば、おそらくMacJournalがオンラインサービスとの連携や、場合によってはEvernoteをはじめとするサーバー側のサービスと連携するといった方向に進化していくのかもしれません。

Evernoteでは、データのバックアップ的な方向にしかAppleScript系の機能が実装されておらず、AppleScriptによって各種アプリケーションを連携させるようなワークフローにおいては、まるっきり使い物にならないのが現状です(ローカルのEvernoteアプリと通信するより、直接サーバーのAPIと通信したほうがやりやすそう)。

ローカル系では「Devon Think」がシソーラス(類語)辞書を背景に高度な検索処理を行ってくれていますが、DevonThinkのシソーラス辞書は英語にしか効かないのでイマイチな感じがします。

2010/05/03 iPhotoで選択中の写真のコメントに「花」+日付を入れる

iPhoto上で選択中の写真のコメントに、「花」+日付(YYMMDD)を入れるAppleScriptです。

実家に帰った際に、iPhoto上に父親がため込んでいる花の写真をまとめてCD-Rに焼いて海外のご友人に送りたい、という相談を受け……新規アルバムを作成してドラッグ&ドロップすることを勧めたのですが、これがなかなか(父親には)難しい操作で、頻繁にミスをしてしまいます。

しばし考えた末に、「iPhoto上で花の写真を複数選択しておいて、Script Menuからコメントにマークを入れるAppleScriptを用意すればいいだろう」ということになり、5分ぐらいで作ってしまいました。

iphoto10.jpeg

「花」+日付のコメントが入っている写真をまとめる「スマートアルバム」を作成しておけば、Scriptを実行した対象の写真がこのスマートアルバムに入るので、あとはiPhotoの「共有」メニューから「ディスクを作成」すればスマートアルバムに入った花の写真をCD-Rに手軽に焼けるという寸法です。

iphoto11.jpg

当初はコメントに「花」とだけ入れていたのですが、「次回、新たなCDを作成する場合には困るだろう」という話になって、「花」+日付を入れることで、あとでまた新しいCDを作るような場合にも対処してみました。

スクリプト名:iPhotoで選択中の画像のコメントに「花」+YYMMDDを入れる
set dText to do shell script “date +%Y%m%d”

tell application “iPhoto”
  set a to selection
  
set aClass to class of first item of a
  
if aClass is not equal to photo then return
  
  
repeat with i in a
    set comment of i to “花” & dText
  end repeat
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に