[mew-dist 29226] 受け取った暗号化 Zip の内容を Mew のメッセージバッファに表示する
Kiyoto Hamano
kiyoto at example.com
2010年 5月 13日 (木) 19:11:20 JST
濱野と申します。
暗号化 Zip ファイルでメール本文をやり取りする事があり、その内容を
Mew のメッセージバッファで見たいと考え、添付の elisp を作成して使っ
ています。今回、Zip の暗号化機能が搭載されたとあり、問題点は数多く
残ってはおりますが、思い切って投稿してみます。
主な機能は、以下の通りです。
メールに添付された暗号化 Zip ファイルを裏で zip コマンドを使用し
て解凍し、解凍したファイルの内容をメッセージバッファに表示する。
解凍後のファイルが複数あれば、その中からどのファイルをメッセージ
バッファに表示するかを選択し、選択したファイルを表示する。
利点は、端末に戻ってパスワードを入力して Zip ファイルを解凍、そして閲覧、
という動作を Emacs 内で完結できる点です。
現状はらんでいる主な問題点は、以下の通りです。
* Mew 6.3 と Mew 4.2 でのみしか動かない。
* パスワードを間違えた事を検知できない。
* パスワードを間違って記憶させると、クリアするコマンドが無い。
* このディレクトリでは、このパスワードのような組み合わせができない。
* などなど
よろしければ、どうぞ。
--
HAMANO Kiyoto
kiyoto at example.com
-------------- next part --------------
;; -*- Coding:iso-2022-jp; Mode:Emacs-lisp -*-
;; version: 0.4
;; created by HAMANO Kiyoto <kiyoto at example.com>
;; 概要:
;;
;; パスワードつき Zip で圧縮されたメッセージを Mew の *Mew message* バッ
;; ファに表示する。
;;
;; (*) まだバグが多々あると思われます。
;;
;;
;; 使用法:
;;
;; load-path の通ったディレクトリにこのファイルを置き、.emacs に以下の
;; 設定を足す。
;;
;; (require 'mew-dispzip)
;; ;; summary-mode で C-cy でを押す事でzipファイルを解凍し、表示する
;; (add-hook
;; 'mew-summary-mode-hook
;; (lambda ()
;; (define-key mew-summary-mode-map "\C-cy"
;; 'mew-dispzip-summary-execute-command)))
;;
;; C-cy を押すのは、# で作られた文字で大きく Binary と書かれているバッ
;; ファ(*Mew summary*)が表示されている状態で行う。解凍したファイルが 1
;; つのみならば、ただちにそのファイルを表示し、複数ファイルの場合は、
;; どのファイルを表示するかを選択する。
;;
;;
;; 設定:
;;
;; * パスワードの保存
;; パスワードを入力したくない場合は、mew-dispzip-unzip-password にパス
;; ワードを設定する。
;;
;; (setq mew-dispzip-unzip-password "hogehoge")
;;
;; * 一度パスワードを入力したら、キャッシュする
;; パスワードを一度入力したら、上記 mew-dispzip-unzip-password に保存
;; したい場合、mew-dispzip-unzip-password-caching を t にする。
;; (.emacs にパスワードを書きたくない場合)
;;
;; (setq mew-dispzip-unzip-password-caching t)
;;
;; * 展開した zip ファイルの内容を保存するディレクトリを変更する
;; 解凍した zip ファイルの内容を置くディレクトリを変更する場合、
;; mew-dispzip-save-dir の値を変更する。
;; (注) このディレクトリを作成する際、パーミッションの設定は特に行うよ
;; うにしていない。
;;
;; ;; mew-dispzip-directory-clear 関数でクリアするとこのディレクトリ以
;; ;; 下の内容がまるごと削除される可能性があるので、他にファイルのある
;; ;; ディレクトリを指定してはいけない。
;; (setq mew-dispzip-save-dir "/home/foo/.archive")
;;
;; * 展開した zip ファイルの内容を保存しない
;; 毎回 zip ファイルを解凍し、解凍し終わったら、作成したディレクトリ・
;; ファイルを削除するようにする。
;;
;; (setq mew-dispzip-unzip-caching nil)
;;
;;
;; 必要物:
;;
;; * unzip コマンド
;; * mew
;;
;;
;; TODO:
;;
;; * *Mew message* バッファに表示するファイルが txt であるかどうかを確
;; 認する(現在は確認せず insert している)。
;; * Mail のあるディレクトリ毎に使用するパスワードを変える仕組み(不要?)
;; * 入力した password があっていたかどうかの確認処理
;; * 難しいならば、password のキャッシュを削除する処理
;; * 別のディレクトリへzipファイルを見たメールを移動した場合の考慮
;; * 毎回 unzip するオプションを追加した
;; * その場合、mew-dispzip-save-dir に指定されたディレクトリを毎度
;; 削除する。
;; * コメントの追加
;; * 関数名・変数名の修正
;; * だいたい行った
;;
;; ChangeLog:
;;
;; 0.4: Emacs 23.1 + Mew 6.3 暫定対応
;;
;; テスト環境:
;;
;; * emacs 23.1 + mew 6.3
;;
(require 'mew)
;; Variables:
(defvar mew-dispzip-unzip-command "unzip")
(defvar mew-dispzip-unzip-options '("-o"
(concat "-P" mew-dispzip-unzip-password)
(concat "-d" mew-dispzip-save-dir)))
(defvar mew-dispzip-unzip-password nil)
(defvar mew-dispzip-unzip-password-caching nil)
(defvar mew-dispzip-save-dir (concat (getenv "HOME")
"/"
".mew-dispzip-archive")
"*Zip ファイルを解凍した内容が収められるディレクトリ。
`mew-dispzip-unzip-caching' が nil のとき、このディレクトリは、解
凍の都度削除されるので、解凍した Zip ファイル以外に内容があるディ
レクトリを指定してはいけない。")
(defvar mew-dispzip-unzip-caching t)
;; Functions:
(defun mew-dispzip-directory-clear (&optional dir no-confirm)
(interactive)
(let* ((d (if dir
dir
mew-dispzip-save-dir))
(files (mew-dispzip-directory-files d t)))
(when (or no-confirm
(yes-or-no-p (format "Delete the dir %s (yes/no):"
d)))
(message "Delete files...")
(dolist (i files)
(setq i (format "%s/%s" d i))
(cond
((file-directory-p i)
(delete-directory i))
(t
(delete-file i))))
(delete-directory d)
(message "Delete files...done"))))
(defun mew-dispzip-directory-files (dir &optional include-directory)
(let ((mew-dispzip-directory-files-internal
'(lambda (din &optional subdir)
(let ((d din))
(if subdir
(progn
(setq d (concat d "/" subdir))
(if include-directory
(setq files (cons (format "%s/" subdir)
files)))))
(dolist (i (directory-files d))
(cond
((file-directory-p (concat d "/" i))
(unless (or (member i '("." "..")))
(funcall mew-dispzip-directory-files-internal
din
(concat subdir "/" i))))
(t
(cond
(subdir
(setq files (cons (format "%s/%s" subdir i)
files)))
(t
(setq files (cons (format "%s" i)
files))))))))))
files)
(funcall mew-dispzip-directory-files-internal dir)
files))
(defun mew-dispzip-summary-concat-options ()
(let ((password (if mew-dispzip-unzip-password
mew-dispzip-unzip-password
(read-passwd "Password: "))))
(when (and mew-dispzip-unzip-password-caching
(null mew-dispzip-unzip-password))
;; set password to global
(setq mew-dispzip-unzip-password password))
(let ((optstring "")
;; set password to local
(mew-dispzip-unzip-password password))
(dolist (i mew-dispzip-unzip-options)
(cond
((and (listp i)
(symbolp (car i)))
(setq optstring (concat optstring " " (eval i))))
(t
(setq optstring (concat optstring " " i)))))
optstring)))
;; for mew 6.3
(defun my-mew-dispzip-summary-execute-external (program options)
(mew-summary-msg-or-part
(let* ((fld (mew-summary-folder-name))
(msg (mew-summary-message-number2))
(nums (mew-syntax-nums))
(cache (mew-cache-hit fld msg 'must-hit))
(syntax (mew-cache-decode-syntax cache))
(stx (mew-syntax-get-entry syntax nums))
(ctl (mew-syntax-get-ct stx))
(ct (mew-syntax-get-value ctl 'cap))
(win (selected-window))
(begin (mew-syntax-get-begin stx))
(end (mew-syntax-get-end stx))
(params (mew-syntax-get-params ctl))
(cdpl (mew-syntax-get-cdp stx))
(fname (mew-syntax-get-filename cdpl ctl)))
(mew-summary-toggle-disp-msg 'on)
(mew-window-configure 'message)
;; message buffer
(unwind-protect
(mew-elet
;; nil or t
(mew-summary-execute-program
program ct ctl cache begin end params fname options t)
(mew-summary-display-postscript 'no-hook))
(select-window win)))))
(defun mew-dispzip-summary-execute-command (&optional arg)
"zip ファイルを解凍し、*Mew message* バッファに表示する。一度解凍し
たファイルは、mew-dispzip-save-dir にキャッシュされ、以後、そのファイルが使
われる。unzip し直したい場合は、前置引数(C-u など)をつけてこの関数を実
行する。"
(interactive "P")
(let* ((num (mew-summary-message-number2))
(dir (substring (mew-summary-folder-name) 1))
(mew-dispzip-save-dir
(concat mew-dispzip-save-dir
(unless (equal "/"
(substring mew-dispzip-save-dir
(1- (length mew-dispzip-save-dir))))
"/")
dir
"/"
num))
filenum
selected)
;; clear unzip cache
(when (and (null mew-dispzip-unzip-caching)
(file-exists-p mew-dispzip-save-dir))
(mew-dispzip-directory-clear mew-dispzip-save-dir t)
(message "")) ; clear minibuffer
;; directory don't exist.
(unless (file-exists-p mew-dispzip-save-dir)
(make-directory mew-dispzip-save-dir t)
(unless (file-exists-p mew-dispzip-save-dir)
(error "make-directory")))
;; do unzip
(when (or arg
(= 2 (length (directory-files mew-dispzip-save-dir))))
(when (and num dir mew-dispzip-save-dir)
(mew-summary-msg-or-part
(cond
((string= mew-version-number "4.2")
(mew-summary-execute-base
nil
mew-dispzip-unzip-command
(delete "" (mew-split-quoted (mew-dispzip-summary-concat-options)
mew-sp
?\"
?\"))))
((string= mew-version-number "6.3")
(my-mew-dispzip-summary-execute-external
mew-dispzip-unzip-command
(delete "" (mew-split-quoted (mew-dispzip-summary-concat-options)
mew-sp
?\"
?\"))))))
(sit-for 0.1))) ; force sync...
;; select file
(setq filenum (length (mew-dispzip-directory-files mew-dispzip-save-dir)))
(when (> filenum 0)
(setq selected
(cond
((= filenum 1)
(car (nthcdr 2 (directory-files mew-dispzip-save-dir))))
(t
(completing-read
"Select File: "
(mapcar 'list
(mew-dispzip-directory-files mew-dispzip-save-dir))
nil
t))))
;; display selected file to *Mew message* buffer.
(let ((cwin (get-buffer-window (current-buffer)))
(mwin (get-buffer-window (mew-buffer-message))))
(when mwin
(select-window mwin)
(unwind-protect
(progn
(setq buffer-read-only nil)
(erase-buffer)
(mew-message-clear-end-of)
(insert (with-current-buffer (find-file-noselect
(concat mew-dispzip-save-dir
"/"
selected))
(buffer-string)))
(mew-message-set-end-of)
(goto-char (point-min)))
(progn (setq buffer-read-only t)
(select-window cwin)))))
;; clear unzip cache
(when (and (null mew-dispzip-unzip-caching)
(file-exists-p mew-dispzip-save-dir))
(mew-dispzip-directory-clear mew-dispzip-save-dir t)
(message ""))))) ; clear minibuffer
(provide 'mew-dispzip)
;; mew-dispzip.el ends here
Mew-dist メーリングリストの案内