Google Desktop で howm の検索を(一部)高速化
4年程 howm を愛用している。
howm ファイルは1日1ファイルベースで、いまや1000個弱に近づいた。
ここ最近は、C-c , g や C-c , s での全文検索があまりに遅くて耐え難い。
遅いといっても10秒ちょっと待てば結果が出るのだが、多用するにはストレスが溜まる。
マシンのスペックを上げればいいのかもしれないが (現在 Pen4 3.2GHz, 1GB RAM)、
そう簡単にもいかないのが不況下の職場の辛いところ。
そんなときこそソフトウェアによる高速化だ!
まずは howm-view-use-grep を t にして、
検索を cygwin の grep にやらせてみたけど、全然早くならねー
元々の fake-grep との違いがほとんど感じられない。これはだめだ。
もう少し調べてみると、namazu だの rast だのを導入すると早くなるっぽい。
けど、面倒そう。(ちゃんと調べてないので本当は簡単かも)
そこで、かなり昔から話題になっていた Google Desktop を導入してみた。
Google Desktop を grep 風に扱うための gdsgrep.rb なんてのもあるみたいだし、
これを howm から外部 grep として使わせれば楽勝!第三部完!
なんて軽い気持ちで取りくんでみたが、楽勝ではなかった。
まず、Google Desktop の検索は正規表現とか無理。(ですよね?)
さらに、ファイル内のキーワード出現位置(行数)とか教えてくれない。
これじゃ grep としての機能を果たせないよー
ということでメタヒューリスティック的に(合ってる?)
Google Desktop でファイル検索範囲を絞り込んでから、
普通に grep で検索をかけるので攻めてみた。
結果、正規表現は使えないけど、たいていの検索ではかなりの高速化が達成できたので、
以下に elisp を公開します。
たまに結果を取りこぼしたりしてるみたいだけど、
そこら辺はメタヒューリスティック(合ってる?)ということでご愛嬌
ちなみに Windows で Meadow 3 でしか試してません。
ブログのタイトル通り、何がおきても一切保証しません。
dolist のあたりとかぐちゃぐちゃですが気にしません。
2010-10-24 追記
上の記事は howm ファイルが Google デスクトップによって全文検索されることを前提として書いていますが、デフォルトの設定ではそうはならないかもしれません。
うまくいかない場合、howm ファイルの拡張子を .txt 等の全文検索対象拡張子に変えるか、Google デスクトップに Larry's Any Text File Indexer 拡張(テキストファイル全般を全文検索の対象にする拡張)をインストールする等してみてください。
;;; howm-gds.el --- howm with Google Desktop ;; Copyright (C) 2009 ;; Author: yamdan <yamdan@gmail.com> ;; Keywords: howm, gds ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Commentary: ;; Setup: ;; ;; Install Google Desktop, and add to your .emacs: ;; ;; (require 'howm-gds) ;; (setq howm-gds-search-default-dir "c:\\path\\to\\howm") ;; ;; * edit "c:\\path\\to\\howm" to your howm directory. ;; ;;; Code: (require 'howm) (defvar howm-gds-search-url (if (functionp 'mw32-registry-get) (car-safe (mw32-registry-get "HKEY_CURRENT_USER\\Software\\Google\\Google Desktop\\API""search_url")))) (defvar howm-gds-search-default-dir "c:\\path\\to\\howm") (defvar howm-gds-search-max-num 1000) (defvar howm-gds-switch-original nil) ; for debug (defun howm-gds-call-view-search (regexp fixed-p &optional emacs-regexp) (let ((hilit (if emacs-regexp `((,emacs-regexp . howm-view-hilit-face)) nil))) (howm-view-search-folder regexp (howm-gds-search-path-folder regexp) ; 検索範囲を GDS で絞込 nil nil fixed-p hilit) (howm-record-view-window-configuration))) (defun howm-gds-list-reminder (types name) (let* ((r (howm-reminder-regexp types)) (rg (howm-reminder-regexp-grep types)) (summarizer (howm-reminder-summarizer r t)) (folder (howm-reminder-search-path-folder))) (howm-view-search-folder rg (howm-gds-search-path-folder rg) name summarizer) (howm-list-exclude) (howm-reminder-add-font-lock) (howm-mode-add-font-lock) (let ((action-lock-default-rules (howm-action-lock-reminder-forward-rules t))) (action-lock-mode)))) (defun howm-gds-search-path-folder (regexp) (if howm-gds-switch-original (howm-search-path-folder) (let ((files (howm-gds-search-filepath regexp))) (if files (howm-make-folder:files files) (howm-search-path-folder) ; GDS による絞込に失敗したら、通常の検索範囲を設定 )))) (defun howm-gds-search-filepath (regexp &optional dir) (let* ((dir (or dir howm-gds-search-default-dir)) (query (howm-gds-url-encode-string regexp 'utf-8)) (in-dir (howm-gds-url-encode-string dir 'utf-8)) (buf (url-retrieve-synchronously (concat howm-gds-search-url "&ie=utf-8" "&adv=1" "&has=" query "&type=cat_files" "&num=" (number-to-string howm-gds-search-max-num) "&in=" in-dir "&under=on" "&format=xml"))) filepath-list) (save-excursion (set-buffer buf) (let* ((results-set (xml-parse-region (point-min) (point-max)))) (dolist (results-elt results-set) (and (listp results-elt) (equal (car results-elt) 'results) (dolist (result-elt (xml-node-children results-elt)) (and (listp result-elt) (equal (car result-elt) 'result) (let* ((url-elt (assoc 'url (xml-node-children result-elt))) (url (and (listp url-elt) (car-safe (xml-node-children url-elt))))) (and url (add-to-list 'filepath-list url))))))))) filepath-list)) ;; refer to w3m-url-encode-string (in w3m.el) (defun howm-gds-url-encode-string (str &optional coding) (mapconcat (lambda (ch) (cond ((eq ch ?\n) ; newline "%0D%0A") ((string-match "[-a-zA-Z0-9_:/.]" (char-to-string ch)) ; xxx? (char-to-string ch)) ; printable ((char-equal ch ?\x20) ; space "+") (t (format "%%%02X" ch)))) ; escape ;; Coerce a string into a list of chars. (append (encode-coding-string (or str "") (or coding 'iso-2022-jp)) nil) "")) (defalias 'howm-call-view-search 'howm-gds-call-view-search) (defalias 'howm-list-reminder 'howm-gds-list-reminder) (provide 'howm-gds) ;;; howm-gds.el ends here
おっと wanderlust と gmail の悪口はそこまでだ
久しぶりに wanderlust で gmail を読もうとしたら、
Cannot open: elmo-network-initialize-session
なんてエラーが表示され、メールが取得できなくなってしまっていた。
色々調べる内に、原因と対策が判明したので、以下に記録する。
以下のページがとても役に立った。感謝します。
[riwablo: さくらインターネットとimapとopensslとwl]
http://riwablo.blogspot.com/2008/04/imapopensslwl.html
原因
imap.gmail.com へ SSL/TLS で接続する際、
imap.gmail.com のサーバ証明書の検証に失敗するため、
wanderlust (elmo) がセッション確立の途中でエラーを吐いて終了する。
サーバ証明書の検証に失敗してしまうのは、
証明書の発行者 (issuer) である "Equifax Secure Certificate Agency" のルート証明書が、
openssl から利用できていないため。
対策(1) (推奨)
openssl 用証明書ストア (ディレクトリ) の準備
openssl が証明書を読みにいくディレクトリを用意する。
bash-3.2$ mkdir -m 744 -p ~/.w3/certs bash-3.2$
ルート証明書の取得
openssl s_client で imap.gmail.com:993 へ接続してみると、
imap.gmail.com のサーバ証明書は Equifax Secure Certificate Agency によって
発行されていることが分かる。
bash-3.2$ openssl s_client -host imap.gmail.com -port 993 CONNECTED(00000006) depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com i:/C=US/O=Google Inc/CN=Google Internet Authority 1 s:/C=US/O=Google Inc/CN=Google Internet Authority i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority (以下略)
Equifax Secure Certificate Agency のルート証明書は、
firefox の証明書ストアなどに入っているので、そこから取得する。
環境設定→詳細→暗号化→証明書を表示...
で表示される証明書のリストから
"Equifax" の "Equifax Secure CA" をクリックし、
"書き出す..." ボタンをクリック。
ファイル形式は PEM を選択し、
上で作った ~/.w3/certs ディレクトリへ保存する。
シンボリックリンクの生成
openssl が適切に証明書を選択できるように、
subject のハッシュ値に ".0" を付加したシンボリックリンクを作る。
といってもやるのはコマンド c_rehash を実行するだけ。
bash-3.2$ c_rehash ~/.w3/certs bash-3.2$
これで ~/.w3/certs 内に証明書へのシンボリックリンクが作られる。
bash-3.2$ ls -l ~/.w3/certs total 16 lrwxr-xr-x 1 yamdan staff 19 4 7 00:09 594f1775.0 -> EquifaxSecureCA.pem -rw-r--r--@ 1 yamdan staff 1162 4 7 00:06 EquifaxSecureCA.pem
.wl の編集
.wl へ以下を追記する。
;; SSL/TLS 用証明書ストアのパス (setq ssl-certificate-directory "/Users/yamdan/.w3/certs")
ここでは必ず絶対パスを指定すること。
"~/.w3/certs" のような指定をするとディレクトリの読み込みに失敗する。
(ssl.el の内部では、openssl の実行に
start-process-shell-command ではなく start-process を利用しており、
シェルによる引数の展開 "~/.w3/certs" --> "/Users/yamdan/.w3/certs"
が行われないため)
完了
以上で imap.gmail.com への接続に成功するはず。
.wl は最終的に以下のようになる。
;; IMAP サーバの設定 (setq elmo-imap4-default-server "imap.gmail.com") (setq elmo-imap4-default-user "xxxxxxxxxxxx@gmail.com") (setq elmo-imap4-default-authenticate-type 'clear) (setq elmo-imap4-default-port '993) (setq elmo-imap4-default-stream-type 'ssl) (setq elmo-imap4-use-modified-utf7 t) ;; SMTP サーバの設定 (setq wl-smtp-connection-type 'starttls) (setq wl-smtp-posting-port 587) (setq wl-smtp-authenticate-type "plain") (setq wl-smtp-posting-user "xxxxxxxxxxxxx") (setq wl-smtp-posting-server "smtp.gmail.com") ;; SSL/TLS 用証明書ストアのパス (setq ssl-certificate-directory "/Users/yamdan/.w3/certs")
対策(2) (非推奨)
上の手順の代わりに、
(setq ssl-certificate-verification-policy 1)
のように、ssl-certificate-verification-policy の値に 0 以外を与えても、エラーが抑制される。
証明書の検証に失敗しているのには変わらないはずなんだが、
この挙動の違いはなんなのだろう?
ssl.el の中を見ると、ssl-certificate-verification-policy の値は、
openssl s_client の -verify オプションの値として利用されるようだ。
そしてどうも openssl s_client は
「-verify 0 オプションを付加したときだけ」
証明書検証失敗時の出力が変化するようだ。
bash-3.2$ openssl s_client -host imap.gmail.com -port 993 -verify 0 -CApath ~/.w3/certs verify depth is 0 CONNECTED(00000003) depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=20:unable to get local issuer certificate verify return:0 49965:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed:s3_clnt.c:983:
-verify 0 オプションを付加したときだけは、
openssl s_client は error を吐いて途中終了する。
この error が ssl.el 経由で elmo へ伝わり、
Cannot open: elmo-network-initialize-session
のエラー出力へ繋がっていたようだ。
一方、-verify オプションを付加しない場合や、付加しても 0 以外の値を与えた場合には、
証明書検証に失敗しようが問答無用で、セッションの確立までは進んでしまう。
bash-3.2$ openssl s_client -host imap.gmail.com -port 993 -verify 1 -CApath ~/.w3/certs verify depth is 1 CONNECTED(00000003) depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=20:unable to get local issuer certificate verify return:1 depth=1 /C=US/O=Google Inc/CN=Google Internet Authority verify error:num=27:certificate not trusted verify return:1 depth=0 /C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com verify return:1 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com i:/C=US/O=Google Inc/CN=Google Internet Authority 1 s:/C=US/O=Google Inc/CN=Google Internet Authority i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority --- Server certificate -----BEGIN CERTIFICATE----- MIIDLzCCApigAwIBAgIKKNVg8QAAAAAHfzANBgkqhkiG9w0BAQUFADBGMQswCQYD VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu dGVybmV0IEF1dGhvcml0eTAeFw0wOTAzMTIyMDIzNDFaFw0xMDAzMTIyMDMzNDFa MGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRcwFQYDVQQDEw5pbWFw LmdtYWlsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo1cDhDhgSN3M 9Do6D459nSNxZW1fTPJV5rmJctt12zZwDTBbHqWlZsK1ZvcV1ngj1nYgZ7RXZmgC sxEUSK/sw+/5Otl6BpK3OLFZI5U/FmMUTssG588Hsl21SBxeK7RoAgxxM2vB2Jgi 3KH+E13mlgUXlCyrehnbbTlwEosURyUCAwEAAaOCAQAwgf0wHQYDVR0OBBYEFNiX w7Ps6PWzF80VrxYbz63ucVArMB8GA1UdIwQYMBaAFL/AMOv1QxE+Z7qekfv8atrj axIkMEYGA1UdHwQ/MD0wO6A5oDeGNWh0dHA6Ly9jcmwuZXh0Lmdvb2dsZS5jb20v R29vZ2xlSW50ZXJuZXRBdXRob3JpdHkuY3JsMFAGCCsGAQUFBwEBBEQwQjBABggr BgEFBQcwAoY0aHR0cDovL2NhLmV4dC5nb29nbGUuY29tL0dvb2dsZUludGVybmV0 QXV0aG9yaXR5LmNydDAhBgkrBgEEAYI3FAIEFB4SAFcAZQBiAFMAZQByAHYAZQBy MA0GCSqGSIb3DQEBBQUAA4GBALo7fCzccb+0OeU+iGPJ/CEynTIegiqt/OkZPP4P aVy7a0MjwK7mDDYpMMu10r4oYSM8iI1BN2iIXRFDkuogp48yeh8P3In1A332XdW3 UoaoIhI8DunLXgfBEr2/TPUHtXDfJumu+wCojdjT2ywwud1hY8LSRR2zv27FWEAD OaRh -----END CERTIFICATE----- subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com issuer=/C=US/O=Google Inc/CN=Google Internet Authority --- No client certificate CA names sent --- SSL handshake has read 1660 bytes and written 306 bytes --- New, TLSv1/SSLv3, Cipher is RC4-MD5 Server public key is 1024 bit Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : RC4-MD5 Session-ID: xxxxxxxx Session-ID-ctx: Master-Key: xxxxxxxx Key-Arg : None Start Time: 1241109692 Timeout : 300 (sec) Verify return code: 27 (certificate not trusted) --- * OK Gimap ready for requests from xxx.xxx.xxx.xxx
途中で verify error とか certificate not trusted とか出てるけど、
セッションは確立する。
elmo や wanderlust はこれをエラーと認識できないようだ。
ちなみに openssl のバージョンは 0.9.8i です。
bash-3.2$ openssl version OpenSSL 0.9.8i 15 Sep 2008
meadow 3 の python-mode
デフォルトのpython-modeだと、どうも補完がうまくいかない。
http://www.emacswiki.org/cgi-bin/wiki/PythonMode#toc2
に、
The version in Emacs 22 has a bunch of problems. Use * http://www.loveshack.ukfsn.org/emacs/python.el It requires * http://www.loveshack.ukfsn.org/emacs/emacs.py and * http://www.loveshack.ukfsn.org/emacs/sym-comp.el
とあるので、それぞれダウンロードして、
python.el を %MEADOW%\lisp\progmodes 下へ、
emacs.py を %MEADOW%\etc 下へ、
sym-comp.el を %MEADOW%\lisp 下へ、
それぞれコピーしたら解決した。
sym-comp.el は site-lisp の方がいいのかな?
比較
月に約186,667パケット以上使うのであれば「新つなぎ放題」
186,667パケット=約22.8MB
パケット従量は0.0105円/パケットで、1MBあたり約86円