Archive for 6月, 2008

2008/06/28 指定のディスクイメージが暗号化されているかどうかを判定する

USのAppleScript Users MLに流れていたScriptです。あんまり使い道は見当たらないものの、地道にファイルしておくことにしました。

スクリプト名:指定のディスクイメージが暗号化されているかどうかを判定する
set a to choose file
set b to isEncrypted(a) of me
> 暗号化されていればtrueが、されていなければfalseが返る

指定のディスクイメージ(dmgファイル)が暗号化されているかどうかを判定する
By Luther Fuller
on isEncrypted(imageAlias)
  set imagePath to quoted form of (POSIX path of imageAlias)
  
try
    do shell scriptecho -n ‘’ | hdiutil imageinfo -stdinpass ” & imagePath
  on error
    return true
  end try
  
return false
end isEncrypted

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

2008/06/26 真偽値の反転

真偽値(true/false)を反転させる演算は、フラグ処理などで割とよく使います。また、タイマー割り込みの許可/禁止などでも使ったりします。

AppleScript/AppleScript Studioでもidleハンドラによるタイマ割り込み処理が行えるため、かなり凝ったことができたりするわけですが、メインの処理を行っている間にはタイマ割り込みサービスを行ってほしくないケースなども多々あります。

そんなときに、booleanで変数内に保持しているフラグの内容をnotで反転させるとか、まあそんなところでしょうか。ちなみに、AppleScriptの変数は型がとくにないうえに宣言もいらないので(代入文を実行した時点で勝手に作られる)、booleanを代入している変数に対して文字列とかアプリケーションのオブジェクトを突っ込むといったこともできます。業界的には「やっぱり変数の型にはある程度の決まりがあったほうがミスを誘発しなくていいよね」という感じですが、AppleScriptは意外と歴史が長い(1994年生まれ)のでこんな仕様になっています。

スクリプト名:真偽値の反転
set a to true

set b to not a
> false

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

2008/06/22 Dockに登録されている情報を取得する(アプリ、書類、ウィンドウ)

MLでDockの情報を取得する話題が出ており、defaults readコマンドで設定を読み取る方法が紹介されていましたが、それでは日本語環境では完全に取得できないようです(Mac OS X 10.4.11)。

Dockの登録情報を取得するには、plistを読み取る以外にもGUI Scripting経由で行う方法もあり、単に情報を取得するだけならplistファイルからdefaults readコマンドで内容を読み取るよりも十分な内容を取得できるようです。

DockのScripting対応機能については、Mac OS Xの初期から貧弱このうえなく、Appleとしてはアプリケーションのインストーラによって操作する以外に操作してほしくない、ということなのか……それとも、単にDockまわりを担当しているチームがAppleScriptに関する知識を持ち合わせていないのか……はたまた、AppleのAppleScriptチームがAppleScriptのコンセプト(あるいは対応の必然性)を社内の他のチームに十分説明できていないために万事中途半端になっているのか…………いずれにしても、社内の開発チーム間の連絡がうまく行っていないことを強く感じるものです。

Automatorの話もUNIX系のチームから出てきたものをAppleScriptチームが聞きつけて参加したとの話が紹介されていますが、その後の議論が不十分でありコンセプトが右往左往している様子が見て取れます。

スクリプト名:Dockに登録されている情報を取得する
set dockRes to retDockPrefs() of me
> {apps:{”Finder”, “アクティビティモニタ”, “Okaeri”, “DragThing”, “Mail”, “Safari”, “FileMaker Pro”, “プレビュー”, “スクリプトエディタ”, “ターミナル”, “UI Browser”}, docs:{”指定フォルダ内の指定ファイルを削除”}, wins:{”Apple Home Page powered by Excite”, “受信”, “AppleScript Users ― この Mac 内 (メッセージ 1218 件、未開封 186 件)”}}

Dockに登録されている情報を取得する
on retDockPrefs()
  tell applicationSystem Events
    tell application processDock
      tell list 1
        –アプリケーション
        
set apList to title of every UI element whose description is equal toapplication dock item
        –
登録された書類
        
set docList to title of every UI element whose description is equal todocument dock item
        –
最小化されたウィンドウ
        
set winList to title of every UI element whose description is equal tominimized window dock item
      end tell
    end tell
  end tell
  
return {apps:apList, docs:docList, wins:winList}
end retDockPrefs

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

2008/06/17 リスト中のアイテムのヌル要素に指定文字列を入れる

リストの中のヌル要素(なんにも入っていない要素、”")に対して、指定文字列を入れるサブルーチンです。InDesign CS3のドキュメントに対して指定フォントを置換するAppleScriptを書いた際に、table中の文字が何も入っていないセルの書式が置換されずに残ってしまったため、強制的に文字を入れて置換することを試みた時に作成したものです。
(more…)

2008/06/15 指定フォルダ内の指定ファイルを削除

データベースの各レコードの内容をPDFに書き出して、メールで送信するAppleScriptを作るときに作ったサブルーチンです。デスクトップフォルダに出力してある特定のファイル(PDFファイル)をあらかじめ削除しておく、という処理を行います。

アプリケーションからPDFを出力するには、FileMaker ProならFileMaker Script内で指定できますが、通常のアプリケーションからの出力であれば、CUPS-PDFをインストールして(ちゃらんぽらん「CUPS-PDFとAppleScript」参照)これを指定してAppleScriptからPDF出力することも可能です。ただ、この程度の機能はOS標準でサポートしておいて欲しいものではあります。

スクリプト名:指定フォルダ内の指定ファイルを削除

set a to path to desktop folder from user domain
set aName to "pdfOut.pdf"
deleteAFileInsideFolder(a, aName) of me

指定フォルダ内の指定ファイルを削除
on deleteAFileInsideFolder(aFol, aFileName)
  set aU to (POSIX path of aFol)
  
  
if aU does not end with "/" then
    set aU to aU & "/"
  end if
  
set aU to (quoted form of aU) & aFileName
  
try
    do shell script "rm -rf " & aU
  end try
end deleteAFileInsideFolder

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

2008/06/15 指定アプリのメインウィンドウのサイズを返す

指定したアプリケーションのメインウィンドウ(たぶん)のサイズをGUI Scriptingを使って取得するサブルーチンです。GUI Scriptingがオンになっていないと使用できません。

画面のキャプチャをAppleScriptから行い、キャプチャした画像からウィンドウの部分をトリミングしてsaveする処理を書くために作ったサブルーチンです。

スクリプト名:指定アプリのメインウィンドウのサイズを返す
set wRes to retAppscreenSize(”FileMaker Pro“) of me
> {19, 19, 1234, 628} –ウィンドウがなければfalseが返る

指定アプリのメインウィンドウのサイズを返す
GUI Scriptingがオンになっていることが前提
on retAppscreenSize(procName)
  tell applicationSystem Events
    tell process procName
      set wCount to count every window
      
if wCount = 0 then return false
      
      
tell window 1
        set {posX, posY} to position
        
set {sizeX, sizeY} to size
      end tell
    end tell
  end tell
  
  
set rectX1 to posX
  
set rectY1 to posX
  
set rectX2 to (posX + sizeX)
  
set rectY2 to (posY + sizeY)
  
  
return {rectX1, rectY1, rectX2, rectY2}
end retAppscreenSize

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

2008/06/14 ヨドバシ.comのWebの画面に表示されている200×200ピクセル以上の画像をダウンロードする v2

ヨドバシカメラで大量に物品購入を行う際に、申請のあった製品の審査を行うため、データベースに各製品のヨドバシ.com上のURLを溜め込んでいました。そこで、せっかくURLが集まったんだからと、AppleScriptでプログラムを書いて、製品画像だけを抽出して指定フォルダにダウンロードさせてみました。本来は、FileMaker ProのDBに対してアクセスする部分とペアになっているのですが、そのURLと申請者IDを取り出した直後の状態からの処理がこのルーチンです。URLを2つ処理しているのは、1申請者あたり2製品までというスペックで申請を受け付けた事情によるものです。
(more…)

2008/06/08 指定時間、ファイルが生成されるのを待つ

すでに、「指定ファイルがTIFFで128×128であれば、icnsファイルに変換する」サブルーチン内で掲載していますが……非同期に実行される処理の結果を待つ場合の定石的な処理がこのサブルーチンです。先のルーチンでは、icnsファイルが非同期で生成されるのを待つというのがその目的でした。そして、非同期処理の完了を指定時間だけ待って、指定時間が経過したらエラーを返すという処理になります。

処理待ちループの中にdelayコマンドを入れているのは、単に趣味とか気分のレベルの問題ですが……処理待ちループ内でwaitなしに結果を確認すると(低速CPUのマシンでは)負荷がかかって本来の処理が遅れてしまうのではないか、という心配をしているためです。こういう場合に、CPUのクロックやタイプを調べて、高速な複数CPUコア搭載マシン(G5とかIntelプロセッサとか)であれば、ウェイトを行わないという手もあることでしょう。ただ、実際にどの程度影響を与えるかはケースバイケースとしかいいようがないため、いろいろ条件を変えてテストしておくしかありません。

AppleScriptで高速処理を行うためには、このようなチューニングを積み重ねることが重要で、なにもチューニングを施していない素人レベルのScriptと、プロがチューニングしたAppleScriptでは、まったくの別物といってよいほどスピードに差が出るようです。

スクリプト名:指定時間、ファイルが生成されるのを待つ

set maxWait to 300 * 10300 seconds
set wRes to waitForExists(aFile, maxWait) of me

指定時間、ファイルが生成されるのを待つ
on waitForExists(aFile, maxWait)
  tell applicationFinder
    repeat
      do shell scriptsync
      
      
set anExists to exists of file aFile
      
if anExists = true then return true
      
      
delay 0.1
      
      
set maxWait to maxWait - 1
      
if maxWait = 0 then
        return false
      end if
    end repeat
  end tell
end waitForExists

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

2008/06/06 Pagesで表示中のページ上の要素をすべて選択する

Script Menuに入れておくタイプのスクリプトです。Pagesで現在表示中の書類の表示中のページ上のページアイテムを選択状態にします。Pagesでドキュメントを作っていて、複数のオブジェクトを選択するのに、マウスでエリアを選択すればその矩形内のオブジェクトがすべて選択される…………という風にはなっておらず、[SHIFT]キーを押しながら、対象のオブジェクトをクリックしていくという地味で地道で不毛な操作が必要になります。実にバカバカしいことこの上ない! そこで、これを一気に解決しようと思い、ささっとAppleScriptを書いてみた次第。

しかしながら、Pagesではtext boxとかlineとかgraphicとかimageとかtableといったページアイテムに対して汎用的にアクセスするオブジェクトが定義されていないため、仕方なく特定ページ上のすべてのオブジェクトタイプに対してselect命令を実行しています。汎用オブジェクトが定義されていれば、もう少しスマートに処理を記述できるのですが……。

スクリプト名:Pagesで表示中のページ上の要素をすべて選択する
tell applicationPages
  tell window 1
    set two up to false
    
set vPageList to visible pages
  end tell
  
  
set aPage to first item of vPageList
  
tell aPage to set aP to page number
  
  
tell document 1
    tell page aP
      tell every text box to select
      
tell every table to select
      
tell every shape to select
      
tell every line to select
      
tell every image to select
      
tell every graphic to select
      
tell every chart to select
    end tell
  end tell
  
end tell

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

2008/06/03 QuickTime Playerで録画を開始する

録音開始Scriptを作ったときに、一緒に作っておいたものです。音声ログを残しておこうという気にはなりますが、あまり動画ログを残しておこうというつもりは……。ただ、本Scriptはさまざまな用途に使えるものと思われます。

スクリプト名:QuickTime Playerで録画を開始する
tell application "QuickTime Player"
  new movie recording
  
start first recording
end tell

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

2008/06/03 QuickTime Playerで録音を開始する

「Xcodeのプロジェクトに音声ログを保存する」AppleScriptを作るときに作成しました。ソースコードにコメントを残しておくだけでなく、プロジェクト全体の様子を音声ログで残しておこうとしたものです。

作成したAppleScriptでは、メニューから呼び出してすぐに録音を開始し、録音終了(QuickTime Playerのボタンをユーザーが操作)すると、すぐさま録音した音声ファイルをXcodeプロジェクトのディレクトリにコピーするようにしました。こうして、少ない操作で音声ログを残せるようにしてみたものです。本当であれば、XcodeのプラグインとしてAppleScript Studioでプログラムを作っておくのですが、Xcode 2.5/3.0ともに起動時にXcodeプラグインの読み込みを行わないという「バグ」があるため、プラグインにはできていません。

1日も早く、こうしたつまらないバグが解消されることを希望するものです。というか、そんなトンでもないバグを残したままリリースするAppleの連中の気が知れません(ーー;;

スクリプト名:QuickTime Playerで録音を開始する
tell applicationQuickTime Player
  new audio recording
  
start first recording
end tell

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