AppleScriptで複数のFTP差分同期を自動化(Transmit)

いろいろ調べたので忘れないように自分用の備忘録。いやーん、わたし、きれい? それは美貌。これは備忘録。

Webサイトの更新には普段は統合開発環境の「Coda2」を使ってる。でも、差分同期したいときは「Transmit」というFTPソフトを使ってる。Transmit は Mac 用の FTP ソフトとしては老舗の部類で、わたしはたぶん20年以上前から使ってると思う。

Transmit は、FTP ソフトの基本であるファイルのアップロード、ダウンロードだけでなく、ローカルフォルダとリモートフォルダの差分同期をする機能もある。この差分同期機能が結構便利。しかもローカルとリモートのセットを「お気に入り」に登録しておけば、さらに簡単になる。

  1. お気に入りから同期したい設定をダブルクリック
  2. ローカルとリモートに接続したら [同期] ボタンをクリック
  3. 同期設定(孤立ファイルの扱いや、ローカルとリモートの差分判断基準など)を確認して問題なければ [実行] ボタンをクリック
  4. 同期が実行される

これを繰り返していけばいい。

繰り返していけばいいんだけど、更新作業するサイトの数が多いと、ひとつの更新作業が終わったら次の更新作業・・・と全部更新作業が終わるまで Mac から離れられない。ひとつひとつの同期作業は1、2分で終わるんだが、これが10カ所のサイトを更新するとなると1、2分おきにポチポチポチポチっと更新実行ボタンをクリックしなきゃならない。間隔が短いからその間に別の仕事はできない。決まりきったボタンをポチポチポチポチ・・・・とてつもなく生産性の低い仕事だ。仕事とすら言えない。これはなんとかせねば。

Mac には AppleScript というプログラム言語が用意されていて、これを使うと Mac での単純作業的な操作を自動化できる。たとえば「特定のフォルダに画像ファイルを保存すると自動的に画像の縦横サイズを所定の大きさに変更して、あらかじめ決めてあるファイル名に変更して、所定のフォルダへ保存する」みたいな画像リサイズの自動化とか。まあいろいろできるのよ。

んで、Transmit はさすが老舗の Mac 専用 FTP ソフトだけあって、AppleScript でさまざまな操作を実行できるように作られている AppleScript 対応ソフトなのだ。

AppleScript で Mac の操作をプログラミングするのに Automator という便利なソフトが付属している。これは子ども用プログラミングソフトで有名な「スクラッチ」とよく似たソフトで、AppleScript の各種命令のブロックを画面で並べていくことで自動処理のプログラムができあがるというすぐれもの。

ということで Automator で Transmit の差分同期作業をポチポチっとプログラムして完成・・・・・・というのが6、7年前の話。なーんだ、昔からやってたんだ。ところがWebサイトの構成が大きくなってきて同期作業にちょっと時間がかかることがでてきた。実は Automator は(というか AppleScript は)、命令を出して2分間応答がないと問題が発生したと判断してプログラムが自動停止する仕様になってる。1年くらい前から差分同期に時間がかかってしまい Automator による自動処理ができないサイトがでてきた。ひとつならそのサイトの更新だけ手動でやってたんだけど、だんだん増えてきてね。これは何か考えないと、と思ったわけだ。

Automator は簡単プログラミング環境なので「2分間」というタイムアウト設定を変更できない(らしい)。しかしその裏で動いているプログラミング言語自体の AppleScript なら簡単プログラミング環境では作れない複雑な命令文だって書けるし、当然ながらタイムアウト設定を一時的に変更する命令だってある。

ということで今日は『Transmit による差分同期作業を簡単プログラミング環境の Automator で自動化していたけど、Automator のタイムアウト設定の問題で使えなくなったので、AppleScript で直接書きました。』という備忘録。

AppleScriptは、かなり独特なプログラミング言語で、参考資料が少ない。ましてやTransmitへの命令文に至ってはほとんど情報がない。AppleScriptは登場した30年くらい前に面白半分にいろいろいじってた経験しかないので、古ーい記憶を頼りに、ネット上の数少ない情報とともに何とか書いたよ。放っておくと絶対忘れるので、ブログに書いておく。

Macに標準インストールされている「スクリプトエディタ」というソフトを起動して、下記のようにスクリプトを記述する。

tell application "Transmit"
 set myRules to (skip rules whose enabled is true)
 set myList to favorites whose name starts with "ABCD."
 repeat with myFave in myList
  tell current tab of (make new document at end)
   connect to myFave
   with timeout of 600 seconds
    synchronize local browser to remote browser using skip rules myRules with delete orphaned items and automatically determine time offset without follow symlinks
   end timeout
   close
  end tell
 end repeat
end tell
tell application "Transmit" to quit

1行目の tell application “Transmit” で Transmit を起動。2行目に activate って書くとTransmit の画面が最前面にくる(アクティブになる)けど、今回は裏で黙々と同期作業をしてくれてればいいので activate は書かない。

2行目は同期除外ルールを選択している。Transmit は条件に合致したファイルは同期対象から除外する「ルール」を作っておくことができる。ここでは Transmit のルールの設定画面であらかじめ使用可になっているルールだけ(skip rules whose enabled is true)を選び出して myRules に格納している。every skip rules で全部選んでもいいし設定済みルールの中のどれを使うかはいろいろ書ける。

3行目の favorites whose name starts with “ABCD.” で、Transmit に登録してあるお気に入りの中から名前が「ABCD.」で始まるお気に入りだけを選び出している。ここは every でお気に入り全部を選択してもいいし、is を使って特定の名前のお気に入りだけを選択してもいいし、end with とか does not start with とかいろいろ書ける。いずれにせよお気に入りの中から必要なものを myList に格納している。

4行目から12行目までが repeat 文で、3行目で作ったお気に入りリストからひとつずつ取り出して myList から取り出したお気に入りは myFave に格納され繰り返し処理をさせる。

5行目は作業ウインドウを新しく作り(make new document)、ウインドウを作ると作業タブがひとつできているので、それ(current tab)を操作対象とする。

6行目で、現在のお気に入り(myFave)の設定で接続を開始

7行目が今回の最大の目的であるタイムアウト設定。with timeout から9行目の end timeout までの処理については600秒(10分間)を待ち時間にしている。これで時間がかかる同期作業でもタイムアウトでエラーにならずにすむ。

8行目が Transmit への差分同期実行命令。local browser to remote browser で同期方向を指定。using skip rules で同期除外ルールを指定。with delete orphaned で同期先だけに存在するファイルは削除する設定(without にすれば削除しない設定)。with automatically determine time offset はローカルマシンとリモートマシンの時計のズレを自動調整する設定(without ならズレを指定できる)。without follow symlinks はシンボリックリンクを参照しない設定(with にすれば参照する)。

10行目で作業ウインドウを閉じる。

選択したお気に入りリスト全部の差分同期が終わったら最後14行目で Transmit を終了。

書き終わったらスクリプトを保存。保存形式で「スクリプト」を選ぶとスクリプトエディタで開いて実行するか、スクリプトメニューから選んで実行。「アプリケーション」形式で保存するとそれをダブルクリックするとスクリプトが実行される。