06. GUI Scriptingで作業自動化(1) ― 2013-04-24
GUI Scriptingがどんなものかについては自由にお調べ願いますが、ぜひ読んでいただきたいのは「AS Hole(AppleScriptの穴)」さんの以下の記事です。
http://piyocast.com/as/archives/538
「GUI Scriptingによる記述」は飛び飛びですが(4)まであります。スクリプトとしては避けようの無い場合の最終手段であること、UI Browser.appを用いてUI element要素を調べるのが現実的で、それでも駄目な場合がいろいろある、など端的と思われます。
マウスやキー操作を実現していくわけですが、いざ取り組んでみると大変というお話は続きで述べるとして、本稿では自作の簡単な例を。
作業内容は「ブラウザに表示させたモデム管理ページで再起動を実行、環境設定からクッキーの一覧windowを表示させて終了」です。モデム再起動の間に不要なクッキーを手動削除しますので。
tell application "iCab"
GetURL "http://web.setup/index_frame.html"
end tell
tell application "System Events"
tell process "iCab"
set frontmost to true
tell window "Aterm WARPSTAR クイック設定Web"
click button "登録" of UI element 1 of row 2 of table 2 of UI element 1 of scroll area 1 of UI element 1 of scroll area 1
delay 1
click button "OK" of sheet 1
delay 1
click button "OK" of sheet 1
delay 1
click button 1
end tell
set frontmost to true
keystroke "," using command down
tell window "iCab 環境設定"
click button "Cookie"
end tell
tell window "Cookie"
click button "Cookie を表示"
end tell
tell window 1
click radio button "共用 Cookie" of tab group 1
end tell
tell window 2
click button 1
end tell
end tell
end tell
clickとkeystroke合計9個をまとめて、画面をあちこちマウス移動させられる苦痛?が解消、自分としては重宝しています。
作成方法ですが、やはりUI Browser.appを用いてUI elementを調べています。
例えば最初にclickしている"登録"ボタン(押すと再起動開始)はhtmlで動的に作成されているのですが、スクリプトに書くべきUI element要素は私の努力ではUI Browserでしか調べようがありませんでした。次に2回"OK"させられる?確認ボタンも同様です。
それからスクリプトを実行して案外驚くのが、速度の遅さ?とそれをコントロールもできないことです。手作業の苦痛はありませんが作業の進行速度自体は同じ。一発実行には違いなくても今までのスクリプトのような爽快感に欠ける、そんな妙な不満は全く贅沢なのでしょうが(苦笑)。
http://piyocast.com/as/archives/538
「GUI Scriptingによる記述」は飛び飛びですが(4)まであります。スクリプトとしては避けようの無い場合の最終手段であること、UI Browser.appを用いてUI element要素を調べるのが現実的で、それでも駄目な場合がいろいろある、など端的と思われます。
マウスやキー操作を実現していくわけですが、いざ取り組んでみると大変というお話は続きで述べるとして、本稿では自作の簡単な例を。
作業内容は「ブラウザに表示させたモデム管理ページで再起動を実行、環境設定からクッキーの一覧windowを表示させて終了」です。モデム再起動の間に不要なクッキーを手動削除しますので。
tell application "iCab"
GetURL "http://web.setup/index_frame.html"
end tell
tell application "System Events"
tell process "iCab"
set frontmost to true
tell window "Aterm WARPSTAR クイック設定Web"
click button "登録" of UI element 1 of row 2 of table 2 of UI element 1 of scroll area 1 of UI element 1 of scroll area 1
delay 1
click button "OK" of sheet 1
delay 1
click button "OK" of sheet 1
delay 1
click button 1
end tell
set frontmost to true
keystroke "," using command down
tell window "iCab 環境設定"
click button "Cookie"
end tell
tell window "Cookie"
click button "Cookie を表示"
end tell
tell window 1
click radio button "共用 Cookie" of tab group 1
end tell
tell window 2
click button 1
end tell
end tell
end tell
clickとkeystroke合計9個をまとめて、画面をあちこちマウス移動させられる苦痛?が解消、自分としては重宝しています。
作成方法ですが、やはりUI Browser.appを用いてUI elementを調べています。
例えば最初にclickしている"登録"ボタン(押すと再起動開始)はhtmlで動的に作成されているのですが、スクリプトに書くべきUI element要素は私の努力ではUI Browserでしか調べようがありませんでした。次に2回"OK"させられる?確認ボタンも同様です。
それからスクリプトを実行して案外驚くのが、速度の遅さ?とそれをコントロールもできないことです。手作業の苦痛はありませんが作業の進行速度自体は同じ。一発実行には違いなくても今までのスクリプトのような爽快感に欠ける、そんな妙な不満は全く贅沢なのでしょうが(苦笑)。
07. GUI Scriptingで作業自動化(2) ― 2013-04-25
本項のスクリプトでは、「メモ書き倉庫」さんの「AppleScriptであれこれする」から以下のハンドラを拝借して外部参照しています。
ここに巡り会ったおかげで、今回の作業は偶然的に成立しました。素晴らしい仕事に感謝します。
http://memogakisouko.appspot.com/AppleScript.html#mouseClick
画像編集の老舗アプリGraphicConverterの機能のひとつに各種バッチ処理があります。画像の縮尺率の数字、4.5とか0.6などクリップボードに入れておいてスクリプト実行するとバッチファイルが書き換わる、そんな用途です。
マウス・キー操作9回をまとめられて現実に重宝しているのですが、今回の話のポイントは最初のwindowのブロックのところです。
property ExHandler : load script file "MyHD:MyScripts:library:_mouseClick.scpt"
tell application "System Events"
tell process "GraphicConverter"
set frontmost to true
keystroke "m" using {command down, control down}
tell window "Convert & Modify"
set {_x, _y} to get position
ExHandler's mouseClick({_x + 200, _y + 370}, "left", 1, "", 0.1)
end tell
tell window "Batch"
set {_x, _y} to get position
ExHandler's mouseClick({_x + 400, _y + 70}, "left", 1, "", 1)
delay 1
keystroke "v" using command down
keystroke tab
keystroke "v" using command down
keystroke tab
set {_x, _y} to get position
ExHandler's mouseClick({_x + 600, _y + 125}, "left", 2, "", 4)
end tell
tell window "Save"
keystroke return
delay 1
click button "Replace" of sheet 1
end tell
tell window "Batch"
keystroke return
end tell
tell window "Convert & Modify"
set {_x, _y} to get position
ExHandler's mouseClick({_x + 10, _y + 5}, "left", 2, "", 1)
end tell
if not (exists (window "Convert & Modify")) then
display dialog "GC Scale finished " giving up after 1
end if
end tell
end tell
window "Convert & Modify"において、set {_x, _y} to get positionとはモニタ上でのwindowの最左上の座標取得です。
その座標から左200下370ピクセルの位置をクリックしていますが、モニタ上ではそこに目標の"• Edit Batches…"ボタンがあります。
実はUI Browserによって当該ボタンのUI element要素は、「button "• Edit Batches…" of window "Convert & Modify"」と取得できるのですが、なぜかclickコマンドが利きません。
これがGUI Scriptingができない場合なのかと隔靴掻痒していた中で、偶然mouseClickハンドラを思い出してピクセル値を実測、試してみたらたまたま救われた、それが本項の顛末。
スクリーンショットを撮って実測したり、クリックの秒数をあれこれ試したり、掛け値無しに泥縄です(苦笑)。
スクリプトの以下も同様で、全体作業が成功した時は嬉しさよりも疲れが前面に出ました。
以上2回が自分のGUI Scriptingに関しての実体験です。
GUI Scriptingは確かに最終手段と認識しました(笑)。
ここに巡り会ったおかげで、今回の作業は偶然的に成立しました。素晴らしい仕事に感謝します。
http://memogakisouko.appspot.com/AppleScript.html#mouseClick
画像編集の老舗アプリGraphicConverterの機能のひとつに各種バッチ処理があります。画像の縮尺率の数字、4.5とか0.6などクリップボードに入れておいてスクリプト実行するとバッチファイルが書き換わる、そんな用途です。
マウス・キー操作9回をまとめられて現実に重宝しているのですが、今回の話のポイントは最初のwindowのブロックのところです。
property ExHandler : load script file "MyHD:MyScripts:library:_mouseClick.scpt"
tell application "System Events"
tell process "GraphicConverter"
set frontmost to true
keystroke "m" using {command down, control down}
tell window "Convert & Modify"
set {_x, _y} to get position
ExHandler's mouseClick({_x + 200, _y + 370}, "left", 1, "", 0.1)
end tell
tell window "Batch"
set {_x, _y} to get position
ExHandler's mouseClick({_x + 400, _y + 70}, "left", 1, "", 1)
delay 1
keystroke "v" using command down
keystroke tab
keystroke "v" using command down
keystroke tab
set {_x, _y} to get position
ExHandler's mouseClick({_x + 600, _y + 125}, "left", 2, "", 4)
end tell
tell window "Save"
keystroke return
delay 1
click button "Replace" of sheet 1
end tell
tell window "Batch"
keystroke return
end tell
tell window "Convert & Modify"
set {_x, _y} to get position
ExHandler's mouseClick({_x + 10, _y + 5}, "left", 2, "", 1)
end tell
if not (exists (window "Convert & Modify")) then
display dialog "GC Scale finished " giving up after 1
end if
end tell
end tell
window "Convert & Modify"において、set {_x, _y} to get positionとはモニタ上でのwindowの最左上の座標取得です。
その座標から左200下370ピクセルの位置をクリックしていますが、モニタ上ではそこに目標の"• Edit Batches…"ボタンがあります。
実はUI Browserによって当該ボタンのUI element要素は、「button "• Edit Batches…" of window "Convert & Modify"」と取得できるのですが、なぜかclickコマンドが利きません。
これがGUI Scriptingができない場合なのかと隔靴掻痒していた中で、偶然mouseClickハンドラを思い出してピクセル値を実測、試してみたらたまたま救われた、それが本項の顛末。
スクリーンショットを撮って実測したり、クリックの秒数をあれこれ試したり、掛け値無しに泥縄です(苦笑)。
スクリプトの以下も同様で、全体作業が成功した時は嬉しさよりも疲れが前面に出ました。
以上2回が自分のGUI Scriptingに関しての実体験です。
GUI Scriptingは確かに最終手段と認識しました(笑)。
08. Quick Look 的フォルダブラウズ ― 2013-04-26
Quick Lookはファイルを手早くプレビューできて便利ですが、よくある画像ブラウザのような「フォルダを選択しているとその内容をブラウズできる」仕様ではありません。
残念ながらAppleScriptではQuick Lookは扱えませんが、そのデバッグ環境であるqlmanageならシェルスクリプトで可能。
という実験で組んだスクリプトなので、フォルダ1個かQuick Lookのようにファイル(複数可)を選択しながら実行してみてください。
tell application "Finder"
try
set tgtkind to kind of (selection as alias)
if tgtkind = "Folder" then
set theFolder to selection as alias
set these_items to (every item of theFolder) as alias list
set these_paths to ""
repeat with theAlias in these_items
set these_paths to these_paths & space & (the quoted form of the POSIX path of theAlias)
end repeat
else
set these_paths to (the quoted form of the POSIX path of (selection as alias))
end if
on error
set these_items to selection as alias list
set these_paths to ""
repeat with theAlias in these_items
set these_paths to these_paths & space & (the quoted form of the POSIX path of theAlias)
end repeat
end try
end tell
do shell script "qlmanage -p " & these_paths & " >& /dev/null"
結果は、上の画像のようなデバッグウィンドウで中のファイルをブラウズできます。
デバッグ環境なので一覧ウィンドウに切り替えると操作がまるで利かず終了するしかありませんが、Finder windowを閉じてもデバッグウィンドウは残るのが利点?でしょうか。
スクリプトとしては、error処理にてselectionがkindを持たないリスト、つまり複数項目選択の場合を担当しているのが面白いかと。
errorを活用できるケース、確かにあるんですね。
残念ながらAppleScriptではQuick Lookは扱えませんが、そのデバッグ環境であるqlmanageならシェルスクリプトで可能。
という実験で組んだスクリプトなので、フォルダ1個かQuick Lookのようにファイル(複数可)を選択しながら実行してみてください。
tell application "Finder"
try
set tgtkind to kind of (selection as alias)
if tgtkind = "Folder" then
set theFolder to selection as alias
set these_items to (every item of theFolder) as alias list
set these_paths to ""
repeat with theAlias in these_items
set these_paths to these_paths & space & (the quoted form of the POSIX path of theAlias)
end repeat
else
set these_paths to (the quoted form of the POSIX path of (selection as alias))
end if
on error
set these_items to selection as alias list
set these_paths to ""
repeat with theAlias in these_items
set these_paths to these_paths & space & (the quoted form of the POSIX path of theAlias)
end repeat
end try
end tell
do shell script "qlmanage -p " & these_paths & " >& /dev/null"
結果は、上の画像のようなデバッグウィンドウで中のファイルをブラウズできます。
デバッグ環境なので一覧ウィンドウに切り替えると操作がまるで利かず終了するしかありませんが、Finder windowを閉じてもデバッグウィンドウは残るのが利点?でしょうか。
スクリプトとしては、error処理にてselectionがkindを持たないリスト、つまり複数項目選択の場合を担当しているのが面白いかと。
errorを活用できるケース、確かにあるんですね。
09. Image Eventsで参照用画像作成 ― 2013-04-27
上図のように、画像フォルダ群を納めた親フォルダの中に_Picture indexフォルダを作成、各画像フォルダの名前の参照用画像を収納します。
わたしのように「整理できない多くの画像フォルダの参照に困ったら」お助けになるかも、そんな用途です(笑)。
スクリプトは親フォルダ(上図でのwallpaperフォルダ)を選択しながら実行してください。なお_Picture indexフォルダが既に存在するとエラー起こしますので、再実行の場合は前に削除必要です。
tell application "Finder"
set rootfolder to selection as alias
set aList to every folder of (entire contents of rootfolder)
make new folder at rootfolder with properties {name:"_Picture index"}
set indexpath to (rootfolder as text) & "_Picture index:"
end tell
repeat with i from 1 to count of aList
set tgtFolder to item i of aList
repeat with h from 1 to count of tgtFolder
set www to item h in tgtFolder
if (name extension of www) = "jpg" then
exit repeat
else
set www to ""
end if
end repeat
if www is not "" then
set tgtFile to www as alias
tell application "Image Events"
set this_img to open tgtFile
set {_width, _height} to dimensions of this_img
if ((_width > 800) or (_height > 800)) then
scale this_img to size 800
end if
set ppp to name of tgtFolder as text
save this_img in file (indexpath & ppp & ".jpg") as JPEG
close this_img
end tell
end if
end repeat
tell application "Image Events" to quit
画像は各フォルダ内の名前順1枚目のjpgファイルを、縦横最長ピクセル固定に変換しています。変換対象や方法は色々工夫できますね。
AppleScriptのコンポーネントであるImage Eventsは地味な存在ですが、オプションが豊富なので画像ファイルを一括処理する用途にかなり役立つと思います。
わたしのように「整理できない多くの画像フォルダの参照に困ったら」お助けになるかも、そんな用途です(笑)。
スクリプトは親フォルダ(上図でのwallpaperフォルダ)を選択しながら実行してください。なお_Picture indexフォルダが既に存在するとエラー起こしますので、再実行の場合は前に削除必要です。
tell application "Finder"
set rootfolder to selection as alias
set aList to every folder of (entire contents of rootfolder)
make new folder at rootfolder with properties {name:"_Picture index"}
set indexpath to (rootfolder as text) & "_Picture index:"
end tell
repeat with i from 1 to count of aList
set tgtFolder to item i of aList
repeat with h from 1 to count of tgtFolder
set www to item h in tgtFolder
if (name extension of www) = "jpg" then
exit repeat
else
set www to ""
end if
end repeat
if www is not "" then
set tgtFile to www as alias
tell application "Image Events"
set this_img to open tgtFile
set {_width, _height} to dimensions of this_img
if ((_width > 800) or (_height > 800)) then
scale this_img to size 800
end if
set ppp to name of tgtFolder as text
save this_img in file (indexpath & ppp & ".jpg") as JPEG
close this_img
end tell
end if
end repeat
tell application "Image Events" to quit
画像は各フォルダ内の名前順1枚目のjpgファイルを、縦横最長ピクセル固定に変換しています。変換対象や方法は色々工夫できますね。
AppleScriptのコンポーネントであるImage Eventsは地味な存在ですが、オプションが豊富なので画像ファイルを一括処理する用途にかなり役立つと思います。
10. 不要なlprojフォルダを管理者権限で削除 ― 2013-04-28
最初に本項のスクリプトの注意書きから。
・使用するシェルスクリプトは「フォルダ=ディレクトリ、及びその中のファイルを完全に削除します」。ゴミ箱には入りませんので、誤って重要なファイルを消さぬよう留意して下さい。
・スクリプト内に「管理者パスワード」を記入しますので、「公の環境では絶対に用いない」など、情報管理に留意して下さい。
アプリケーションpackageなどのresourceフォルダ内に位置して多言語対応を提供するlprojフォルダ群について、その中から使わないので不要と定めた言語のものを削除できるのがMonolingualアプリです。
しかし、Monolingualアプリは一部System領域のpackageに及びませんので、検索アプリで調べると不要lprojフォルダが残る場合があります。「そこまで気になる方向け」に、手作業を要しますがMonolingualアプリ使用後の補助スクリプトです。
https://dl.dropboxusercontent.com/u/164391356/dellproj.scpt.zip
使い方はソフトウェアアップデートなどの後にまずMonolingualアプリを使用、その後で気になる不要lprojフォルダが残った場合にその情報をスクリプトへ追記して実行します。情報が累積すれば、追記の手間が無くなる訳です。
スクリプトの情報以外の期待しない削除は起こりませんが、こういった危険なスクリプトは「使用環境において仮のフォルダを使って動作を調べてから使う」など慎重に配慮してください。
・使用するシェルスクリプトは「フォルダ=ディレクトリ、及びその中のファイルを完全に削除します」。ゴミ箱には入りませんので、誤って重要なファイルを消さぬよう留意して下さい。
・スクリプト内に「管理者パスワード」を記入しますので、「公の環境では絶対に用いない」など、情報管理に留意して下さい。
アプリケーションpackageなどのresourceフォルダ内に位置して多言語対応を提供するlprojフォルダ群について、その中から使わないので不要と定めた言語のものを削除できるのがMonolingualアプリです。
しかし、Monolingualアプリは一部System領域のpackageに及びませんので、検索アプリで調べると不要lprojフォルダが残る場合があります。「そこまで気になる方向け」に、手作業を要しますがMonolingualアプリ使用後の補助スクリプトです。
https://dl.dropboxusercontent.com/u/164391356/dellproj.scpt.zip
使い方はソフトウェアアップデートなどの後にまずMonolingualアプリを使用、その後で気になる不要lprojフォルダが残った場合にその情報をスクリプトへ追記して実行します。情報が累積すれば、追記の手間が無くなる訳です。
スクリプトの情報以外の期待しない削除は起こりませんが、こういった危険なスクリプトは「使用環境において仮のフォルダを使って動作を調べてから使う」など慎重に配慮してください。
最近のコメント