ファイルをパスワード付きzipにしてDropboxのフォルダにコピーする
Dropboxってすばらしい。なんていまさら言うほどのことじゃないですね^^ だけど、ぼくにはちょっと気がかりなことがあります。もしDropboxが誰かに覗かれたりした時、ぼくのムフフな画像とか見られたらイヤじゃないですかー。...っていうか、そんなもんクラウドに上げてんじゃねえよ!
まあ、ムフフでもムフフでなくても大切なファイルは気をつけたいものです。そもそも漏らしちゃいけないモノはクラウドに上げてはいけません。世界のソニーだってお漏らししちゃうくらいですから、安全なクラウドなんてないんですよね。安全神話なんて最初からないです。
ってことを念頭に置いた上で、Dropboxをすこしセキュアに使いたいって話です。セキュアって言っても大掛かりなものじゃなくて、パスワード付きzipをもう少し便利に使えたらいいな、と。Windows環境だと、標準でパスワード付きzipが作れます。しかし、Macだとターミナルからコマンドを打ち込まなくちゃいけません。もうちょっと簡単にドラッグ&ドロップだけパスワード付きzipを作りたいと思って去年書いたスクリプトがこちら:
で、Dropboxに馴れてくると、わざわざドロップレットにドラッグ&ドロップするのも面倒になってきます。ファイルの変更を当該マシンでしかやらないなら、定期的に自動でzipファイルを作ってDropboxのフォルダにコピーしてくれないかな... 人間ってどこまでも堕ちていくものですね。
ターゲットファイルとコピー先が1対1なので、簡単な感じのシェルスクリプトを書いてみます。
#! /bin/sh cd /Volumes/myVolumeName/foo/ #カレントディレクトリを移動 zip -P xxxxxxxxxx hoge.zip hoge.txt #hoge.txtをパスワードxxxxxxxxxxでzip mv -f hoge.zip ~/Dropbox/foo/var/hoge.zip #Dropboxの所定のフォルダへ移動
ちなみにファイルじゃなくてフォルダhogeをzipするときはこんな感じになります。
zip -rP xxxxxxxxxx hoge.zip hoge/ -x '*.DS_Store' '*__MACOSX/'
あとはcronで定時実行してやればいいのかな。cronについてはこちらを参考にしてください。
まだちょっと問題があります。cronで動かした時、ターゲットファイルが更新されていようといまいと、全部再処理されちゃうんですね。ひとつやふたつなら気にしませんが、たくさんあるともったいないオバケが出て来ちゃいます。ファイルの更新時間も見て、更新されたものだけ処理してくれたらいいな。ぼくがもう少しシェルスクリプトを書ける人だったらいいんですけれど、どうも苦手。
で、最初のドロップレットを少し改造するだけで、更新されたファイルだけ処理するようになります。アプリケーション形式で保存して、ログイン項目に追加したり、cronでopenしたりして使ってください。
最初の設定部分を適宜書き換えて使ってください。設定my_filesが多重リストになっているのが注意。
(* copy_to_DropboxFolder_with_password 指定ファイル(またはフォルダ)のパスワード付きzipを生成してDropboxの所定のフォルダにコピーする。 ログイン項目に入れるとか、crontabで定期実行する。 ターゲットファイルの更新日を記憶し、ファイルが新しくなった時だけコピーを実行する。ただし、初回起動は常にコピー。 パスワードの設定を書き込まなければ、起動ごとにパスワードを入力するようになる。生成パスワードはクリップボードに保存 日本語ファイル名とか、記号類が使ってあるファイル名はサポートしない。いつものことだけど。 zipフォルダの伸長はunzipコマンドを使うのが吉。 for Mac OS X 10.7.2 2012-1-11 ver0.1 とりあえず (c)2012 seuzo *) --======================設定 --パスワードの設定。空なら毎回パスワードを入力する set my_password to "xxxxxxxxxxxxx" --ターゲットファイルと保存フォルダのリスト。{{"ターゲットファイル", "保存フォルダ", ファイル更新日}, {"ターゲットファイル", "保存フォルダ", ファイル更新日}, ...}形式の多重リスト。ファイル更新日は初回起動時に自動的に追加される property my_files : {{"/Volumes/myVolumeName/foo/hoge.txt", "~/Dropbox/foo/var/"}, {"~/foo/var/", "~/Dropbox/foo/var/"}} --====================== --パスワードが空ならダイアログを出す if my_password is "" then set my_password to my get_password() set the clipboard to my_password --クリップボードにパスワードを保存 end if set my_files to my first_run(my_files) --初回起動時にファイル更新日を追加 --各ファイル処理 repeat with i in my_files set target_file to item 1 of i set copy_folder to item 2 of i set modification_date to item 3 of i --ターゲットファイルが新しいならzip©を実行 if (my get_modification_date(target_file) > modification_date) then set item 3 of i to my get_modification_date(target_file) --書き換え my zip_and_copy(target_file, copy_folder, my_password) --zip & copy end if end repeat --パスワードを生成 to generate_password(n) set pass to "" set str to "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" repeat n times set pass to pass & (some character of str) end repeat return pass end generate_password --パスワードを得る to get_password() set my_password to (text returned of (display dialog "Input Zip Password" & return & "(空白にすれば、パスワードを自動生成します)" & return & "終了後、パスワードはクリップボードに保存されます" default answer "" default button 2 with hidden answer)) if (my_password is "") then set my_password to my generate_password(10) else set password_test to do shell script "echo " & my_password & " | perl -pe 's/[0-9A-Za-z]+//;'" if (password_test is not "") then display dialog "パスワードに半角英数字以外の文字が使われています。" buttons {"Cancel"} default button 1 with icon 1 --キャンセルで終了 end if end if return my_password end get_password --初回起動時にファイル更新日を追加 to first_run(tmp_files) if (length of item 1 of tmp_files is 2) then tell application "Finder" repeat with i from 1 to (length of tmp_files) set f to item 1 of item i of tmp_files set f to (f as POSIX file) as alias set item i of tmp_files to item i of tmp_files & ((modification date of f) - 60) --1分だけ過去を設定 end repeat end tell end if return tmp_files end first_run --POSIX形式からファイル更新日を得る to get_modification_date(f) tell application "Finder" set f to (f as POSIX file) as alias return modification date of f end tell end get_modification_date --同名ファイルの警告 to alert_same_name(file_path) tell application "Finder" if (exists (file_path as POSIX file)) then display dialog file_path & " は同名のファイルがあります" & return & "上書きしますか?" buttons {"Cancel", "上書き"} default button 1 with icon 1 --キャンセルで終了 end if end tell end alert_same_name --ファイル名の警告 to violation_name(file_path) set file_path to quoted form of ((POSIX path of file_path) as Unicode text) --まずPOSIX pathにする set file_path_test to do shell script "echo " & file_path & " | perl -pe 's/[\\/\\.0-9A-Za-z _-]+//;'" if (file_path_test is not "") then display dialog file_path & " のファイル名には英数字以外の文字が使われています。" & return & "圧縮・送信・伸長時にトラブルになるかもしれません。続行しますか?" buttons {"Cancel", "続行"} default button 1 with icon 1 --キャンセルで終了 end if end violation_name --フルパス名を、コンテナディレクトリ/ファイル名+拡張子/ファイル名/拡張子に分割する --引数fはファイルの参照。alias/POSIX path(文字列)/HFS path(文字列) --引数path_typeは返値のパス形式。"alias"/"POSIX_path"/"HFS_path" --返値はレコード {full_path:フルパス dir:コンテナディレクトリ名, name_ext:ファイル名(拡張子付き), f_name:ファイル名(拡張子なし), dot_ext:拡張子(.ドット付き), ext:拡張子(.ドットなし)} to split_path(f, path_type) try set f to (POSIX path of f) as Unicode text set f to (f as POSIX file) as alias on error errMsg number errNo display dialog "Path変換エラーです" & return & errMsg & return & errNo buttons {"Cancel"} default button 1 with icon 1 --キャンセルで終了 end try tell application "Finder" --fがボリュームだった if (kind of f) is "ボリューム" then set ne to name of f --ファイル名+拡張子 if path_type is "POSIX_path" then set f to POSIX path of f else if path_type is "HFS_path" then set f to f as Unicode text end if return {full_path:f, dir:"", name_ext:ne, f_name:ne, dot_ext:"", ext:""} end if --fはファイルまたはフォルダ set d to (container of f) as alias --コンテナディレクトリ set ne to name of f --ファイル名+拡張子 set e to name extension of f --拡張子(.なし) if e is "" then set n to ne --ファイル名(拡張子なし) set de to "" else set n to text 1 thru (-2 - (length of e)) of ne --拡張子を削除 set de to "." & e --拡張子(.付き) end if --出力するpathのタイプ if path_type is "POSIX_path" then if (kind of f) is "フォルダ" then set ne to ne & "/" --フォルダなら最後に/をつける set f to POSIX path of f set d to POSIX path of d else if path_type is "HFS_path" then if (kind of f) is "フォルダ" then set ne to ne & ":" --フォルダなら最後に:をつける set f to f as Unicode text set d to d as Unicode text else if path_type is "alias" then --set f to f as alias --set d to d as alias end if return {full_path:f, dir:d, name_ext:ne, f_name:n, dot_ext:de, ext:e} end tell end split_path --リストの結合 to as_join(thedelimit, theList) set oldDelim to AppleScript's text item delimiters set AppleScript's text item delimiters to thedelimit set tmpstr to theList as text set AppleScript's text item delimiters to oldDelim return tmpstr end as_join --パスワード付きzipとコピー to zip_and_copy(target_file, copy_folder, my_password) my violation_name(target_file) --ファイル名の警告 set file_path to my split_path(target_file, "POSIX_path") --ファイルパスの分割 set file_path_zip to quoted form of (f_name of file_path & ".zip") --.zip拡張子 set file_path_org to quoted form of name_ext of file_path --同じディレクトリに展開するので、ファイル名のみ try set my_script to "cd " & dir of file_path & "; zip -rP " & my_password & " " & file_path_zip & " " & file_path_org & " -x '*.DS_Store' '*__MACOSX/' ; mv -f " & file_path_zip & " " & copy_folder & (f_name of file_path & ".zip") --display dialog my_script set add_files to do shell script my_script --display dialog add_files on error errMsg number errNo display dialog "zip実行エラーです" & return & errMsg & return & errNo buttons {"Cancel"} default button 1 with icon 1 --キャンセルで終了 end try end zip_and_copy