- ベストアンサー
Automatorのフォルダアクションでネットワークフォルダを監視してファイルを処理する方法
- Automatorを使用して、Mac mini Serverからネットワークフォルダを監視して、条件に合致したファイルが追加されたら自動で処理を実行する方法について説明します。
- 問題なく動いている場合と失敗する場合で、何が異なるのか調べてみてもPCやネットワークなどの環境は同じ条件だったので原因がわからず、拾いこぼしの原因と対策について相談します。
- 具体的な手順として、1. Automatorのフォルダアクションで「シェルスクリプトを実行」する設定をし、2. 特定条件に合致するファイルを処理するadd_data2.appを実行する方法を説明します。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
こんな方法はいかがでしょうか 基本的には今までのようにフォルダアクションとします。取りこぼしが有ったときのためにタイマーあるいは手動での処理を追加します。 ただし、フォルダアクションによって引き渡されるファイルを処理するのではなく、最後に処理したファイルの日時から未処理のものを探し出し、もし未処理のものが有った場合にはそれを処理するようにする。処理対象のファイル名でフォルダアクションが発生したときはそれを処理しますし、取りこぼしがあった時にはそれを探し出して処理されます。 それと、フォルダアクションで渡されるファイル名からフォルダ名を取り出してそれだけを使っています。フォルダ名を別途設定する手間を省いています。 ちょっとプログラムを書いてみました。 # encoding: utf-8 if RUBY_VERSION < %[1.9.0] require %[jcode] $KCODE=%[utf-8] else Encoding.default_external=%[utf-8] end last_file_stamp=%[140628120012].to_i # 最後に処理したファイルのyymmddhhmmssを取り出し整数型に # どのように記録されている分かりませんのでここは書き換えてください。 ARGV.each do |f| folder_name=File.dirname(f) # フォルダアクションで渡されたファイル名からフォルダ名を取り出す lzh_files=Dir.glob(%[#{folder_name}/*.lzh]) # 拡張子がlzhのファイル名 target_files=lzh_files.select{|f| File.basename(f)[/^\d{6}(12|16)\d{4}/]} # 12時と16時台のファイルだけに target_files=target_files.select{|f| File.basename(f)[/^\d{12}/].to_i>last_file_stamp} # 日時でlast_file_stamp以降のファイルだけに target_files=target_files.sort_by{|f| File.basename(f)[/^\d{12}/].to_i} # 日時で並び替え target_files.each do |f| abort %[エラーが発生しました] unless system %[open -W -a add_data2.app #{f}] # データ登録作業 end end ただし、last_file_stamp=の所は書き換えてください。 タイマーあるいは手動での処理の追加ですが、 該当するフォルダにダミーファイルを作ることで強制的にフォルダアクションを発生させるのでいかがでしょうか。 shellだと touch フォルダ名/dummy_file で空のファイルができます。仮にdummy_fileの名前にしていますが、一目で分かる名前がよいと思います。 手動でも良いし、タイマーでファイルを作成するとフォルダアクションが発生しますので、いつでも取り返しができます。
その他の回答 (4)
- ki073
- ベストアンサー率77% (491/634)
簡単にテストしたつもりだったのですが、いろいろ問題が有りそうですね。すみません。 Automatorでのデバック結構大変なのです。 私自身は、ワークフローに変更して、「Finder項目の選択を求める」を最初に入れてやっています。 多分同じことをやっているのだと思います。 >「print」を入れながら確認をしてみたところ それよりも代わりにpを入れる方がいろいろな場合に対応できます。 >ARGV.each do |fn| の部分で、ディレクトリの末尾に「/」が付いていない フォルダアクションの場合にはファイル名が渡されるはずですので、もう一度確認してみてください。 Rubyで大掛かりなソフトを書く時には、Rubyのdebug機能を使うと便利です。Automatorとは離れて作業しなければならないのですが、変数を確認したり、変数を書き換えたりできますので非常に便利です。 この後で、Automatorに組み込んでということをしています。100行くらいのスクリプトが入っているのがあったりします。 今回の場合は、上のような方法(pを付け加える)のが簡単だと思います。
補足
ki073様 なかなか「できました!」というご報告ができずに申し訳ありません。 Windowsの方が別PCにお引越し後も調子が悪くて、結局新しく購入することになり、今到着待ちです。 受注の方は別のPCにメールで送ってもらったものを手動で処理をしているので、特に問題はない状況です。 早く「p」を入れるデバッグを試してみたいです。 PCが届いて、再度試せるようになりましたら結果をご報告させていただきます。 > フォルダアクションの場合にはファイル名が渡されるはずですので、もう一度確認してみてください。 そうですよね、おっしゃる通りなので私が寝ぼけていたのかも知れません。 すみませんm(_ _)m 次は「p」で確認してみます! では、またご報告にあがります。 取り急ぎお礼まで。。。 ありがとうございましたm(_ _)m
- ki073
- ベストアンサー率77% (491/634)
No.3の修正です。 変数fが上書きされる可能性があるので ARGV.each do |fn| folder_name=File.dirname(fn) # フォルダアクションで渡されたファイル名からフォルダ名を取り出す の二カ所のfをfnに Ruby1.8.7(OSX 10.8までで使われているもの)では問題がでると思います。幸い基本的にはARGV.eachは一回しか実行されないので問題が顕在化しなかっただけですが。より新しいバージョンのRubyでは多分問題はないと思われますが、まぎらわしいので修正をしてください。
補足
ki073様 お礼が遅くなって大変失礼いたしました。 ネットワークフォルダのPCが昨日から起動しなくなり、別のPCにお引越しをしたりバタバタしておりました。 今日の夕方、実際と同じ環境でダミーのフォルダを作成して、教えていただいた方法を試してみたのですが、何も起きませんでした。 AppleScriptのように動きがログに表示されないので、よくわからないのですが、Automatorでデバッグをしながら「結果を表示」というアクションを最後に入れてみたところ、結果は ( "" ) と表示されていました。 「print」を入れながら確認をしてみたところ、 ARGV.each do |fn| の部分で、ディレクトリの末尾に「/」が付いていないため、次の行の folder_name=File.dirname(fn) の部分で、目的のネットワークフォルダが表示されず、1つ上の階層のフォルダが表示されました。 |fn|の後ろにスラッシュを付ける方法がわからなかったので、とりあえず次の行の lzh_files=Dir.glob(%[#{folder_name}/*.lzh]) を lzh_files=Dir.glob("/Volumes/AAA/BBB/*.lzh") としました。 次の「12時と16時台のファイルだけに絞り込む部分」も正しい結果を得られました。 ところが、その次の「日時でlast_file_stamp以降のファイルだけに絞り込む」部分 target_files=target_files.select{|f| File.basename(f)[/^\d{12}/].to_i>last_file_stamp} の結果が該当なしの( "" )となってしまいました。 Finderのファイル名も変更日も「last_file_stamp」のものよりも新しいのですがダメでした。 直接「140702121111」と入れてもダメでした。 上記の動きの確認はAutomatorでのデバッグで、実際のフォルダアクションでは反応がありませんでした。 「日時でlast_file_stamp以降のファイルだけに絞り込む」部分をコメントアウトしてみたらフォルダアクションが反応しました。 その後のApplescriptによる解凍、データ登録の処理で一度エラーを出してしまうとフォルダアクションが無反応になってしまいました。 ちょっと煮詰まってきました・・・。 さっきまで動いていたものが急に動かなくなる不安はなかなかのストレスで、フォルダアクションを外してみたり、Finderを強制終了してみたり、試行錯誤しましたがAutomatorのデバッグ画面のログで「実行中‐シェルスクリプトを実行」のまま動かなくなりました。 ちょっと頭を冷やして、もう一度挑戦してみます。 m(_ _)m
- ki073
- ベストアンサー率77% (491/634)
これまでの話でだいぶ理解できているのですが、少し確認を 1) Automatorのスクリプトを実行しているのはMac mini Server(OSX 10.8)ですよね。 2) そのMacからネットワーク経由で見ているyymmdd12mmss○○○.lzhなどのファイルが保存されるサーバーはWindowsなのでしょうか? 3) 処理するyymmdd12mmss○○○.lzhが作られた時だけでなく、.txtなど直接関係のないファイルができた時もフォルダアクションが実行されます。かなり短縮できます。そこまで待てるかどうかです。もし待てないのなら時間を決めて確認するプログラムを実行する必要があります。 >ネットワークフォルダからローカルフォルダにlzhファイルをコピーしてから解凍しているので、解凍されたフォルダ名から最後に処理をしたファイル名の特定はできます。 これを使うのが良さそうですね。
補足
お世話になっております。 お忙しいところ、ご回答ありがとうございます。 購入したRubyの本を参考に学習を始めましたが、お恥ずかしいことになかなか教えていただいたレベルまでの道のりは遠く、先に進めずにおります。 1) Automatorのスクリプトを実行しているのはMac mini Server(OSX 10.8)ですよね。 ⇒はい、Mac mini ServerのOS10.8です。 2) そのMacからネットワーク経由で見ているyymmdd12mmss○○○.lzhなどのファイルが保存されるサーバーはWindowsなのでしょうか? ⇒はい、Windows XPです。 3) 処理するyymmdd12mmss○○○.lzhが作られた時だけでなく、.txtなど直接関係のないファイルができた時もフォルダアクションが実行されます。かなり短縮できます。そこまで待てるかどうかです。もし待てないのなら時間を決めて確認するプログラムを実行する必要があります。 ⇒.txtなど直接関係のないファイルが追加されるタイミングも日々バラバラで、1時間に1つも作成されない場合もあり、次のファイルが作成されるまで待つことは難しい状況です。 やはり時間を決めて確認をするしかなさそうですね。 最初はその方法でやっていたのですが、作成される時間がバラバラのため、自動で監視をする方法をこちらでご指導いただいた、という経緯でした。 もうちょっと悩んでみて、手も足も出なければ時間を決めて確認する方法に戻すか、取りこぼしの発生した時は手動で動かすか、どちらかにしようと思います。 融通のきかない環境のため、すばらしいご提案をたくさんいただいたのに実践できずに申し訳ありません。 取り急ぎお礼まで。 ありがとうございましたm(_ _)m
- ki073
- ベストアンサー率77% (491/634)
フォルダアクションの仕組みがよくわからないので、根本的な解決方法は分からないのですが、 取りこぼしがあっても、フォルダアクションが動作した時に、直前にチェックしたファイルより後に作成されたファイル(取りこぼしがあったときには複数になる)についてチェックするということでいかがでしょうか? そのようにすると、処理が抜けても次のフォルダアクションで挽回できます。 どこまで処理が済んでいるのか覚えておく必要があるのと、未処理のファイルを探す手段が必要です。 1) 最後に処理したファイル名(日付時刻がファイル名で分かる?)からそれ以降に作られたファイルが特定できたり、 2) ファイルの修正時間が記録されていますがそれが信頼できるなら、(こちらの方が簡単そう) その情報を頼りに未処理のファイルを特定できますでしょうか? 上のような方法でできそうな気がします。自力で解決が無理でしたら書き込んでください。
補足
ki073様お世話になっております。 またまた躓いてしまい、相談させていただきました。 宜しくお願い致します。 月曜から金曜まで毎日12時と16時に処理を実行していて、12時台で取りこぼしがあった場合にも16時まで待つことはできないので、今は目で確認しながら、取りこぼしが発生した時には手動で動かしています。 受注データなので、次の処理まで待つ余裕がなく、すぐに処理に回さないといけないのです。。。 1) 最後に処理したファイル名(日付時刻がファイル名で分かる?)からそれ以降に作られたファイルが特定できたり、 ⇒処理に必要なファイルは「yymmdd12mmss○○○.lzh」で、 時間帯の部分が「12」か「16」のファイルの2つだけです。 他に10時台のファイルや、.txtファイルも作成されます。 1日の最後に処理をするファイル名は「yymmdd16mmss○○○.lzh」なので、処理以降に作成されたファイルの特定は可能です。 2) ファイルの修正時間が記録されていますがそれが信頼できるなら、(こちらの方が簡単そう) その情報を頼りに未処理のファイルを特定できますでしょうか? ⇒修正時間というのは、Finderに表示されている「変更日」のことですか? 圧縮ファイルの中身を編集はしないので、変更日から未処理のファイルを特定するとしたら、「変更日の最新のもの」かつ、時間帯が「12」か「16」で拡張子が「lzh」のもの、という条件になるとお思います。 あとは、ネットワークフォルダからローカルフォルダにlzhファイルをコピーしてから解凍しているので、解凍されたフォルダ名から最後に処理をしたファイル名の特定はできます。 もう少し自力で悩んでみます。 ありがとうございましたm(_ _)m
お礼
ki073様 ちゃんとお礼ができないまま随分時間が経ってしまい、大変失礼しました。 あの後、長期入院して先月退院しました。 体調がだいぶ良くなってきましたので、ki073様に教えていただいたフォルダアクションの続きに取り掛かろうと思います。 ただでさえ知識がないのに、期間が空いてしまったのでほとんど忘れてしまったと思います(泣) 幸いなことに、入院前に、Mac mini Serverを再起動しておいたところ、入院中から最近までずっと取りこぼしなく安定していました。 スクリプトはki073様に前回教えていただいもののままです。 また先日、取りこぼしが出てしまい、それからは全く動いている様子がないのでこの質問で教えていただいた方法に改めて挑戦したいと思っています。 とりあえずお礼をお伝えしたかったので・・・。 ありがとうございましたm(_ _)m
補足
ki073様、お礼が遅くなってすみません。 お忙しい中、プログラムまで作っていただきましてありがとうございます。 m(_ _)m 私のOS 10.9.3 , ruby 2.0.0 ではなぜか動かないので、明日、会社のPCで試してみたいと思います。 今、私のMacと闘っています。 取り急ぎお礼まで・・・。 本当にありがとうございます m(_ _)m