読者です 読者をやめる 読者になる 読者になる

Eye-FiからApertureに自動転送

最近Eye-Fiを買って撮った写真をMacに自動で転送しています.iPhotoなら問題ないのですがApertureに転送すると言うことがEye-Fiでは直接行えないので,フォルダアクションを使ってApertrureに転送するようにしてみました.
ちなみに公式ではAperture Hot Folderを使用して転送する方法が紹介されています.
Eyefi
この方法ではApertureに転送したいファイルを取りこぼすことが頻繁に起こります.

ほかの方法はAperture Folder Checkerというプログラムを使用します.
Aperture Folder Checker | oblonczek.net
この方法ではDockにプログラムが表示されてしまうので少し邪魔かと思います.

ボクが考案した方法では,Mac標準の機能(Automator, Applescipt, OS標準でインストールされているRuby)だけで動作でき,Dockに不要なアプリケーションが常住することが無いです.
常に起動するプログラムがありますが,そのプログラム自体は基本的にスリープしているので多くのリソースを消費することはないはずです.ボクの環境では動作していない時ではCPU使用率は0,実メモリは2.7MBしか消費していません.


このフォルダアクションはこれ単体では動作できず,デーモンを起動する必要があります.
フォルダアクションがどのようにして動作しているのかちゃんと記述しているドキュメントが手元に無いので推測ではありますが,どうやらフォルダアクションが実行されてる間にファイルが追加されると,そのファイルは無視されてしまうようです.しかも次のアクションにも使われないみたいです.
なのでフォルダアクションに割り当てるワークフローはなるべく処理時間が短い物を指定した方がよいです.
Apertureに写真を追加するワークフローは処理時間が長いのでフォルダアクションに直接すると取りこぼしが起こる可能性があります.

このフォルダアクションではApertureに転送したいファイルのパスをデーモンに投げ処理を終了します.実際にApertureに読み込ませるのはデーモンに処理をさせます.

Eye-Fiの設定

管理で写真のアップロード先を"フォルダ"に,サブフォルダオプションを"日付ベースのサブフォルダを作成しない"にします.
アップロード先フォルダは何でも良いです.

Automatorの設定

  • フォルダアクション(保存されるディレクトリ)
  • Finder項目にフィルタを適応("種類がイメージである"に設定)
  • シェルスクリプトを実行(シェルを/usr/bin/ruby,入力の引き渡し方法を"引数として"に設定,プログラムは以下の物を書いてください)
require 'drb/drb'

r = DRbObject.new_with_uri "drbunix:/tmp/aperture_upload.soc"
r.push ARGV

ワークフローの内容はイメージだけのファイルをフィルタリングしたら,rubyでそのパスをデーモンプログラムに投げています.
一度に追加されるファイルの量にもよりますが,ほとんどの場合で0.5秒以内にはワークフローが終了するようになっています.

デーモンプログラム

#!/usr/bin/ruby
# coding: utf-8

require 'drb/drb'
require 'thread'

pid = fork do
  Process.setsid
  fork do
    Dir::chdir '/'
    File.umask 0
    STDIN.reopen  '/dev/null'
    STDOUT.reopen '/dev/null', 'w'
    STDERR.reopen '/dev/null', 'w'

    q = Queue.new
    t = Thread.new do
      loop do
        data = q.pop.map {|d| "'#{d.chomp}'" }
        system("osascript /Users/user/bin/move_to_aperture.scpt " + data.join(' '))
      end
    end

    soc_file = "/tmp/aperture_upload.soc"
    File.delete soc_file if File.exist? soc_file
    DRb.start_service('drbunix:' + soc_file , q, :UNIXFileMode => 0600)
    DRb.thread.join
    t.join
  end
end
Process.waitpid pid

追記: webrickdaemonを使うとうまくいかなかったので自力でdaemonizeするようにしました.
このプログラムを適当なディレクトリに保存し,teminalから実行します.Macを再起動するたびにいちいち起動するのが面倒であればログイン項目に設定してしまいましょう.
20行目のsystem...の部分のApplescriptのパスは次に説明するApplescriptのファイルのパスに合わせてください.


フォルダアクションではQueue.pushを呼び出すようにしているのでフォルダアクション自体の動作が単純になっています.
実際にApertureにファイルを追加する処理は別スレッドでApplescriptを呼び出して処理するようになっています.このような書き方はApplescriptにはスレッドがないのでできません.
なお,受け取ったイメージのパスに'が含まれているとおそらく失敗します.

move_to_aperture.scpt

on run argv
	set importFiles to {}
	repeat with item_argv in argv
		set end of importFiles to (POSIX file item_argv)
	end repeat
	
	tell application "Aperture"
		set theProject to project "From Eye-Fi" of library 1
		import importFiles into theProject
	end tell
end run

この例ではApertureの"From Eye-Fi"というプロジェクトに写真が追加されるようになります.変更したい場合は8行目の該当部分を変更してください.
なお該当するプロジェクトがApertureに存在しない場合,処理が失敗します.