Hatena::ブログ(Diary)

名もないテクノ手 このページをアンテナに追加 RSSフィード Twitter

EPUB版『InDesign者のための正規表現入門』

InDesignのTips一覧

2011-10-30

[]ドラッグ&ドロップでパスワード付きzipを作る

オンラインストレージやUSBメモリーなどを一般的に使うきょうび、大事なファイルはパスワード付きで保存したいものです。セキュリティがゆるゆるのFTPサーバーなども、ファイルにパスワードがついていれば少しは気休めになるかもしれません。

Mac OS X環境にはFinderやサービスからzip圧縮を使えますが、パスワード付きzipはターミナルからコマンドを叩く必要があります。

$ zip -rP password archive.zip targetfiles

みたいな感じ。そんな面倒なコマンドじゃないんですけれど、ちょっとでもラクしたい人たちはたくさんいて、AppleScriptAutomatorで自作する人は後を絶ちません。

ほかにもたくさんあると思いますけれど、どうもいまひとつ自分の仕様に合っていない感じがします。

  • ランダムなパスワードと任意のパスワードを両方使いたい
  • 同名のアーカイブが出来てしまう時、なんらかの警告を出したい
  • 複数のファイルをアーカイブしたい
  • フルパス名に英数字以外が使ってある場合は、警告してやりたい

ってことでAppleScriptのドロップレットを書いてみました。まだ改良の余地はあるかと思いますが、とりあえずってことで。

(追記:2011-10-31T15:29:26+0900)'*.DS_Store' '*__MACOSX/'をzipアーカイブに含めないようにしました。

(*
zip_with_password
ファイル(フォルダ)のドラッグ&ドロップでパスワード付きzipを生成
生成パスワードはクリップボードに保存
日本語ファイル名とか、記号類が使ってあるファイル名はサポートしない。いつものことだけど。
zipファイルの伸長はunzipコマンドを使うのが吉。

for Mac OS X 10.7.2

2011-10-30	ver0.1	とりあえず
2011-10-31	ver0.2	'*.DS_Store' '*__MACOSX/'をzipアーカイブに含めないようにした
(c)2011 seuzo
*)


--パスワードを生成
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 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


--フルパス名を、コンテナディレクトリ・ファイル名+拡張子・ファイル名・拡張子に分割する
--返値はPOSIX pathのレコード {dir:"", name_ext:"", f_name:"", ext:""}
to split_path(f)
	set f to quoted form of ((POSIX path of f) as Unicode text) --まずPOSIX pathにする
	set d to do shell script "echo " & f & " | perl -pe 's/^(.+\\/).+$/$1/;'" --コンテナディレクトリ
	set ne to do shell script "echo " & f & " | perl -pe 's/^.+\\/(.)/$1/;'" --ファイル名+拡張子
	if f ends with "/'" then --フォルダの場合
		set n to text 1 thru -2 of ne
		set e to ""
	else
		set e to do shell script "echo '" & ne & "' | perl -pe 's/^.+(\\..+)$/$1/;'"
		if e is not "" then
			set n to do shell script "echo '" & ne & "' | perl -pe 's/" & e & "$//;'"
		end if
	end if
	
	return {dir:d, name_ext:ne, f_name:n, ext:e}
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


--ドラッグ&ドロップで実行
on open of my_files
	set my_password to my get_password()
	
	set file_path_org to {} --圧縮するファイルのリスト
	if 1 < (length of my_files) then --2つ以上のファイルがドラッグ&ドロップされた
		--zipファイル
		set today_str to do shell script "date +%Y-%m-%d" --本日の日付
		set file_path_zip to choose file name with prompt "保存先:" default name today_str & ".zip" --同名ファイルを作ろうとするとここで怒られる
		my violation_name(file_path_zip) --ファイル名の警告
		set file_path to my split_path(file_path_zip) --ファイルパスの分割
		set file_path_zip to quoted form of (name_ext of file_path)
		set current_path to dir of file_path --カレントパス
		
		--ターゲットファイル
		repeat with i in my_files
			set aFile to (POSIX path of (i as alias))
			my violation_name(aFile) --ファイル名の警告
			set tmp_path to split_path(aFile) --ファイルパスの分割
			if (dir of tmp_path) is current_path then --zipアーカイブと同じディレクトリなら
				set end of file_path_org to quoted form of (name_ext of tmp_path) --ファイル名だけ
			else
				set end of file_path_org to quoted form of aFile --ちがうならフルパスで
			end if
		end repeat
		set file_path_org to my as_join(" ", file_path_org)
		
	else --処理ファイルはひとつだけ
		set aFile to (POSIX path of ((item 1 of my_files) as alias))
		my violation_name(aFile) --ファイル名の警告
		set file_path to my split_path(aFile) --ファイルパスの分割
		my alert_same_name(dir of file_path & f_name of file_path & ".zip") --同名ファイルの警告
		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 --同じディレクトリに展開するので、ファイル名のみ
	end if
	
	try
		set add_files to do shell script "cd " & dir of file_path & "; zip -rP " & my_password & " " & file_path_zip & " " & file_path_org & " -x '*.DS_Store' '*__MACOSX/'"
		--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
	set the clipboard to my_password --クリップボードにパスワードを保存
	
end open

アプリケーションとしてダウンロードしたい人はこちらから:zip_with_password.app.zip 直

注意:フォルダだけをドラッグ&ドロップして作成したzipファイルは、Finderからアーカイブユーティリティでは伸長できません。

f:id:seuzo:20111030105126p:image

StuffIt Expanderを使うか、ターミナルで展開したいディレクトリにcdしてから

$ unzip -P password hoge.zip

などとしてください。unzipコマンドなら、同名のファイルがあった時も対話的に振る舞いを決定できます。

mmmm 2013/04/06 00:11 いままでいちいちターミナル開いてやってたので本当ーーーに助かります!!
ありがとうございます!!!

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証