DTPab

印刷やデザイン、アドビ製アプリやスクリプトなど、雑多な技術ブログ

パスワード付きzip圧縮を行うAppleScript

パスワード付きzipファイルを作業のたびに毎回作成する…というお仕事がありまして。これまでターミナルからzipコマンドを叩いて凌いでいたものの、さすがに面倒臭すぎて耐えきれず、AppleScriptを書きましたw

コード

tell application "Finder"
    set scptList to {"cd ~/Desktop/" & linefeed, "zip", "-rj", "-P"}
    set psw to display dialog "設定するパスワードを入力" default button 2 default answer ""
    if (button returned of psw is not "OK") or (text returned of psw is "") then
        error number -128 --スクリプトの終了
    end if
    set end of scptList to (text returned of psw)
    set zipName to display dialog "生成するzipファイル名を入力" default button 2 default answer "hoge.zip"
    if (button returned of zipName is not "OK") or (text returned of zipName is "") then
        error number -128 --スクリプトの終了
    end if
    set end of scptList to (text returned of zipName)
    set tgtFiles to choose file with prompt "圧縮するファイルを選択" with multiple selections allowed
    repeat with i in tgtFiles
        set end of scptList to quoted form of (POSIX path of (i as string))
    end repeat
    set end of scptList to "-x \"*.DS_Store\""
    
    -- リストをテキストに変換
    set defaultDelimit to AppleScript's text item delimiters
    set AppleScript's text item delimiters to " "
    set scptBody to scptList as text
    set AppleScript's text item delimiters to defaultDelimit
    
    do shell script scptBody
end tell

説明

全体の流れ

  • シェルコマンドを小分けにしてリストに登録
  • パスワードやzipファイル名を変数として受け取り、そのリストに加える
  • リストをスペースでつなげてシェルコマンドとして実行

という処理になっています。

zipファイルの書き出し場所

zipファイルの書き出し先が変数scptListの最初の要素"cd ~/Desktop/" & linefeedの部分です。
cdの後ろの~/Desktop/に適当なパスを書いてください。

zipコマンドオプション

同じリストにzip -rj -Pと続きます。これはシェルのzipコマンドのオプションです。
詳しくは調べてみてください。

パスワードとzipファイル名の入力

AppleScriptでテキスト入力ダイアログを表示するにはdisplay dialogのオプションを利用します。

display dialog "質問" default button 2 default answer "入力"

default answerのすぐ後に文字列を渡すと、それがテキスト入力欄にすでに入った状態でダイアログが生成されます。
空のテキスト入力エリアにしたい場合は、スクリプトのように空の文字列""を渡しておきます。

戻り値

テキスト入力ダイアログの戻り値はレコードになっています。

キー
button returned string 押されたボタンの内容
text returned string テキスト入力エリアの内容

JSONと違い、キーにスペースがさしはさまれていることに以前つまづいた覚えがあります。

例外の処理

InDesignのExtendScriptだと、便利なexit()メソッドが存在するので、ネストを深くすることなく例外時に強制的にスクリプトを終了することができます。
AppleScriptでも似たようなことができて、特定のエラーを渡すことでユーザーにキャンセルされたとしてスクリプトを終了できます。

error number -128 --スクリプトの終了

このエラー処理がそれです。これを呼び出すと スンッ… とスクリプトが終わってくれるので、ifでネストせずに処理を書けます。良き。

ファイル選択ダイアログ

これは定型句。

choose file with prompt "質問" with multiple selections allowed

複数選択を許容しているので、後ろにwith multiple selections allowedというオプションを付けています。
ただ、ファイル選択じゃなくて、ドロップレットにするとか、Finderで選択したファイルを右クリックから*1、ってやったほうがもう少し使いやすいと思われる。そこはまたいずれ。

.DS_Storeファイルを除外

zipコマンドの-xオプションで実装。詳しくは末尾の参考サイトを参照ください。

リストをテキストに変換

これももはや定型句ですね。

set defaultDelimit to AppleScript's text item delimiters
set AppleScript's text item delimiters to " "
set scptBody to scptList as text
set AppleScript's text item delimiters to defaultDelimit

以前書いた別のスクリプトからコピペした。

シェルコマンドとして実行

do shell script scptBody

これでシェルコマンドとして実行できる。

To DO

  • Finderからコンテクストメニューにしよう
  • パスワード自動生成機能付けたい
  • JXAで実装したい

参考

*1:Automatorのサービスとして登録、という意味