2007年04月14日

Wanderlust (MH形式) から Thunderbird (mbox形式) へのメールデータ移行するrubyスクリプト

Wanderlust (MH形式) から Thunderbird (mbox形式) へのメールデータ移行するrubyスクリプト

使い方



mhdir2mbox.rbをダウンロード

~/Mail/Wanderlust/FolderA をThunderbirdのFolderAにコピーするには、

コマンドラインから、cygwinのbashなら

cd ~/Mail/Wanderlust
mhdir2mbox.rb -d ~/Mail/Thunderbird/ FolderA

を実行すると ~/Mail/Thunderbird/FolderA というファイルができ、
Thunderbirdのローカルフォルダ下に「FolderA」が出現する。
引数に与えたディレクトリの構成をターゲット以下に作成するので、フルパスでは書かないで下さい。


いろいろ調整したかったので、Wanderlust側は再帰的には探しに行かない。いっぺんにやるには、

cd ~/Mail/Wanderlust && find -type d -print0 |xargs -0 mhdir2mbox.rb -d ~/Mail/Thunderbird

みたいな感じでたぶんOK。

Thunderbird側からこのディレクトリをローカルフォルダとして設定。
account.GIF

数千メールあると初回のThunderbird起動時に読み込みに失敗することがあった。いちど削除してコピーし直したらうまくいった。




動機



Google Desktopでメールを検索したくなったのだが、今のところWanderlustでこれを実現する方法は無さそう。

Wanderlustにメーラとしての不満は殆ど無いが、日本語添付ファイルでトラブることがたまにあるので、別系統も用意できると安心。

*データ形式

Wanderlustはmh形式でこれは、1ファイル1メール、フォルダがメーラ上の振り分け対象フォルダと対応。ファイルシステム上の効率は悪そうだが何と言っても分かりやすい。

Google Desktop Searchもこれをサポートしてくれていたら何も問題無かったのに。

一方、Thunderbirdはmbox形式で、ググってみると

行頭が「From 」(フロム+スペース)で始まる行が区切りになるらしい。何と分かり難いことか。本文に「From 」が出てきてしまったら「> From 」とする、つまり 「>」を挿入するのがエスケープ方法だと。

これは面倒臭いので、各メールの間に
「From -」
みたいな行を挟めば何とかなる、というか何とかなった。


これも真面目に対応しました。

フォルダ形式



Wanderlustでフォルダを3階層ぐらいに管理していたので、これもそのまま再現したい。例えば

c:\home\Mail\WL

がメールフォルダの根っこでその下に適宜整理してることにする。


+-home-+-Mail-+-WL-----+-10仕事-+-Aプロジェクト
| |
| +-報告書
| |
| +-プレゼン
|
+-20事務-+-出張


Thunderbirdでは、「アカウント設定」メニュー内に「ローカルフォルダ」なる設定項目があり、ここが保存フォルダになっているようだ。

これを例えば

c:\home\Mail\Thunderbird

をメールフォルダの根っこにして、その下にメーラから見ると同じフォルダ構成にしたい。手動で試すと判るが、フォルダとしては


+-home-+-Mail-+-Tunderbird-+-10仕事.sbd-+-Aプロジェクト
| |
| +-報告書
| |
| +-プレゼン
+-10仕事
|
+-20事務.sbd-+-出張


ツリーのノード、中間フォルダは,「フォルダ名+.sbd」というディレクトリ、ツリーの葉っぱに相当するのは「フォルダ名」のファイルで、これがmbox形式である。さらに中間のノードにもメールを格納できてこれは、そのフォルダと同じレイヤ(フォルダの中じゃなくて並んで存在する)のファイルである。


したがって、Wanderlustのフォルダは、「フォルダ名.sbd」という名前でフォルダを作り、MHフォルダの中のメールファイル「0,1,2,3,4,...」は「From -」という行を挿入しながら結合して、「Wanderlustのフォルダ名」というひとつの「ファイル」にすれば良い。

さらに「フォルダ名.sbd」を作成して、「フォルダ名」というファイルが無い場合、つまりフォルダの中にフォルダしか無い場合は同名のダミーのファイル(空でOK)が必要。

フォルダを作成後、Thunderbirdを起動し直せばめでたく認識。

== さらに修正(2008/03/20) ==

高村さんにトラックバック頂いた通り不具合があり、反映しました。

mhdir2mbox.rbを修正した。83行目を
text.sub!(/\AFrom - /,'>From - ')
から
text.sub!(/\A(>*)From /,'\1>From ')
とするだけ。多分これでOK。


ご指摘ありがとうございました。




posted by fn23 at 18:59| Comment(2) | TrackBack(3) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2007年02月28日

elmo-split で日本語文字を含むパターンを使う

会社での普段のメールの読み書きはWanderlustを使っているのだが、いつからか elmo-split で日本語を含むルールが不調だった。

日本語を含むルールが書けないと、例えばSubjectに「未承諾広告」を含むもの、が指定できなかったりして不便。

GTDっぽくinboxを半自動処理するためにも振り分けルールを賢くするのは結構大事。

elmo-split.el を一行変更することで実現できた。副作用はありそう、特に複数のmultibyte文字を混在するとき(日本語とハングルとか)だが、個人的には日本語さえOKならそれでいいことにした。

問題だったこと



elmo-split-ruleのパターンに日本語を指定してもパターンマッチしてくれなくなった。昔のバージョンのWanderlustではマッチしてたのに。。

修正点



elmo-split.el の一時バッファを (set-buffer-multibyte nil) していたのを"t" に変更する。 Wanderlust-MLのログを見ると、ハングルとの混在のときの問題(?)とやらの対策のようであるが、ボクはmultibyte文字は日本語しか使わないので結果オーライ。

できるようになったこと



以下のような日本語を含む振り分けルールが書けるようになった。


(setq elmo-split-rule
'(
;; SPAM
((spam-p) "+spam")
;; 太郎
( (match from "太郎")
"+Log/70人/太郎")
( (or (match Subject "未承諾広告")
(match from "senden.*shop\\.co\\.jp")
)
"+Log/90DM・案内" )
;; ML
( (match Subject "\\[XX-ML")
"+Log/91ML")
)
)
)


修正パッチ




--- elmo-split.el 2007-02-27 20:41:20.640625000 +0900
+++ elmo-split.el~ 2006-10-31 21:47:29.000000000 +0900
@@ -327,8 +327,7 @@
(elmo-with-progress-display (elmo-split (length msgs)) "Splitting messages"
(unwind-protect
(with-temp-buffer
- (set-buffer-multibyte nil)
+ (set-buffer-multibyte t)
(dolist (msg msgs)
(erase-buffer)
(when (ignore-errors
posted by fn23 at 00:52| Comment(0) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2006年10月30日

Greasemonkeyをいじってみた

Greasemonkeyをいじってみた。
結構いろいろできそうなので、もうちょっと遊んでみる事にする。

続きを読む
ラベル:Firefox greasemonkey
posted by fn23 at 01:56| Comment(0) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2006年10月28日

OP25B後の自宅サーバのメール対策(解決)

先日から国内の各プロバイダがOP25B (Outbound Port 25 Blocking) を始めました。その影響で我が家の自宅サーバからメールが送信できなくなっていましたが、対策できたのでその方法をご紹介します。

うちではフリーのダイナミックDNSに登録しており、自宅用のメールアドレスを
使っていました。

ダイナミックDNSからもらったドメイン名 = myhost.dydns.org
使っていたメールアドレス = mymail@myhost.dydns.org

このアドレスに来たメールを gmail に転送していたのですが、2006年9月末か
らこれができなくなっていました。

契約しているプロバイダはBではじまる大手プロバイダで、OP25Bによって行わ
れた制限は具体的には、プロバイダ外部インターネットへの25番ポートへの接
続を禁止、プロバイダのsmtpサーバの利用を許可するが、送信アドレスはプロバイダの自ドメインに限る、というものです。

このため、一般的なOP25B対策である、

relayhost=smtp.myprovider.ne.jp

だけでは、送信者が不正ということで、

553 Invalid sender address (in reply to MAIL FROM command))


のエラーが出ていました。

これを回避するためには、自サーバで中継する際に送信者を書き換えれば良い
わけですが、本当に送信者を書き換えてしまうとメールとして役に立ちません。
(誰から来たのか分からないんじゃ意味がない。)

ところが、プロバイダがチェックしているのは、Envelop From と呼ばれる情報
で、これはメール内容に記述された送信者「ではなく」メール配送エージェント同士でやりとりするコマンド上での送信者なのです。メール内容に傷を付けずにEnvelope Fromだけを書き換えれば、ほぼ所期の目的が達成できます。

ちなみに、メール内記述の送信者とEnvelope Fromが異るのはMLなどでもある状
態で、異るから即違反という訳ではないようです。(全く問題無い訳でもなさそうな気もしますが。)

まあ、プロバイダには、所期の目的であるスパム防止、メール流量を常識の範囲に抑えることを自分ルールとして管理することでいいかな、と思ってます。

その設定を以下に示します。私が使っているのは Ubuntu Linux 上の postfix
ですので、その例です。



凡例


DNSからもらったドメイン名 : myhost.dydns.org
自宅内でのサーバ機名 : myserver
プロバイダのsmtpサーバ名: smtp.myprovider.ne.jp
プロバイダのsmtp認証アカウント: myaccount@myprovider.ne.jp
プロバイダのsmtp認証パスワード: mypasswd
転送元(自作の)メールアドレス : mailname@myhost.dydns.org
転送先メールアドレス : mygmailaccount@gmail.com

転送元メールアドレス(家族分) : mywife@myhost.dydns.org
転送したいメールアドレス(家族分) : mywife@yahoo.co.jp



$ sudo vi main.cf

myorigin = myhost.dydns.org
mydomain = myhost.dydns.org
sender_canonical_maps = regexp:/etc/postfix/sender_rx

# プロバイダのsmtp認証を有効にする
smtp_sasl_auth_enable = yes
# IDとパスワードの対をファイル/etc/postfix/isp_passwdに登録
smtp_sasl_password_maps = hash:/etc/postfix/isp_passwd
# anonymous認証を許可しない
smtp_sasl_security_options = noanonymous
# ホスト名
myhostname = myserver.myhost.dydns.org
mydestination = myhost.dydns.org, myserver, localhost.localdomain, , localhost
# プロバイダのメールサーバ名
relayhost = [smtp.myprovider.ne.jp]:587
# ローカルネットワークの指定
mynetworks = 192.168.1.0/24, 127.0.0.0/8


$ sudo vi isp_passwd

smtp.myprovider.ne.jp myaccount@myprovider.ne.jp:mypasswd

保存した後にdb作成
$ sudo postmap /etc/postfix/isp_passwd

/etc/postfix/isp_passwd.dbができる

Envelope Fromを全てプロバイダからもらった正規メールアドレスに変換
$ sudo vi sender_rx
/^.*$/ myaccount@myprovider.ne.jp


転送先を指定

$ sudo vi /etc/aliases

root: myname
nickname: myname
mailname: mygmailaccount@gmail.com
mywife: mywife@yahoo.co.jp
mywife-docomo: mywife@docomo.ne.jp


dbの作成
$ sudo newaliases
/etc/aliases.dbができる

設定の反映
$ sudo /etc/init.d/postfix restart


これで、自宅サーバ運用のメールをメールサービスに転送することができるはずです。もちろん自宅サーバでimapやpopを運用すれば、転送に悩まずに使えるわけですが。

この際ちゃんとPostfixのことを調べたい方には、やはりOreillyがお奨めです。


Ubuntu全般ならwebでも本でもいろいろありますが、1冊あると安心できる方には
posted by fn23 at 02:09| Comment(2) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2006年03月04日

org-mode:meadowで表編集、日本語文字で崩れないためのパッチ

org-modeはoutline-modeにさらに手を入れたようなmodeでGTDに使っている人もいるようだ。

試しに使ってみたところ、tableが賢くて驚き。org-modeの本筋ではないかもしれないが便利。表形式にメモを取るだけのためについついExcel開いたりするものだが、これがemacsでできる。

それは良いのだが、meadowでorg-modeを使うと日本語で表が崩れる。オリジナルのorg-modeは日本語文字もascii 文字も一文字と数えていたので、こんな感じ。

----
| adkfjk | jkja | kjkdjkj | にほんご | |
| 012 | 343 | 34343 | 343 | 1 |
----

文字列長を length でなく string-width で数えるように修正するといい感じ。

----
| adkfjk | jkja | kjkdjkj | にほんご | |
| 012 | 343 | 34343 | 343 | 1 |
----

以下のパッチでセルが揃うようになった。


diff -BbwuE "c:/meadow/lisp/textmodes/org.el~" "c:/meadow/lisp/textmodes/org.el"
--- c:/meadow/lisp/textmodes/org.el~ 2005-12-15 00:06:31.001000000 +0900
+++ c:/meadow/lisp/textmodes/org.el 2006-03-03 10:30:05.468750000 +0900
@@ -6528,7 +6528,7 @@
(while (< (setq i (1+ i)) maxfields) ;; Loop over all columns
(setq column (mapcar (lambda (x) (or (nth i x) "")) fields))
;; maximum length
- (push (apply 'max 1 (mapcar 'length column)) lengths)
+ (push (apply 'max 1 (mapcar 'string-width column)) lengths)
;; compute the fraction stepwise, ignoring empty fields
(setq cnt 0 frac 0.0)
(mapcar




posted by fn23 at 02:32| Comment(2) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2006年02月11日

Thunderbird1.5 POP3タイムアウト頻発 boot.iniに/usepmtimerで解決

Thunderbirdをバージョン1.5に上げたらPOP3のタイムアウトが頻発して困っていたのが解決。Picasa2の具合も良くなったような気がする。

初めはSymantec AntiVirusとの相性かと思い、一生懸命Symantecのナレッジベースを調べたりググッたりしたが分からず。

(もじら組)[IMAP] デュアルコアのPC上でタイムアウトが頻発する で解決。

boot.ini に /usepmtimer を追加することでタイムアウトが起こらなくなった。

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect /usepmtimer


もうひとつの解決策の可能性だったAMDのドライバ AMD Athlon 64 X2 Dual Core Processor Driver for Windows XP and Windows Server 2003 Version (exe) 1.2.2.2 の方は既にインストール済だったので違ったようだ。

嬉しい副作用として、Picasa2で監視フォルダをちゃんと監視してくれてなかったような動作 (、、とでも言えば良いのか) が解決。

マルチコアのタイマ、同期で何か問題があって、ACPIのタイマを使うことで解決できたと推測するが、分散処理とタイマ同期の問題はなかなか再現しないので難しい。

この不具合も何度か試すと動いてしまうので、大騒ぎになってないだけだと思うけど。

PCのメールクライアント程度だからいいようのものの、組み込みシステムでこの手の不具合を出すと被害甚大なのにちっとも再現しなくてハマる、こわいこわい。
posted by fn23 at 01:28| Comment(0) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2006年01月27日

Unisonでファイル同期

unisonはファイル同期ソフト。デスクトップPCとノートPCの同期に使用。
便利なのだが2バイト目が0x5cな文字でコケるのが致命的。「ソフト」とかが駄目なのは痛いのでパッチ。

unison-2.17.1の以下を修正
unison-2.17.1-sjis.patch
日本語フォルダ、日本語ファイル名も行けるようになった。

--- update.ml.orig 2005-08-12 09:26:59.000000000 +0900
+++ update.ml 2006-01-25 21:43:07.859375000 +0900
@@ -1116,7 +1116,7 @@
(* FIX: This should catch all device names (like aux, con, ...). I don't
know what all the possible device names are. *)
Rx.case_insensitive
- (Rx.rx "\\.*|aux|con|lpt1|prn|(.*[\000-\031\\/<>:\"|].*)")
+ (Rx.rx "\\.*|aux|con|lpt1|prn|(.*[\000-\031/<>:\"].*)|((^|(.*[^\x81-\x9f\xe0-\xfc]))[|\\].*)")
let isBadWindowsFilename s =
(* FIX: should also check for a max filename length, not sure how much *)
posted by fn23 at 19:54| Comment(1) | TrackBack(1) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

シェルスクリプトでforループ

C言語のfor文相当

for(i = s; i < max; i++){
...
}

シェル(sh,bash)では以下

i=$s
while [ $i -lt $max ]
do
...
i=`expr $i + 1`
done

---
なんか汚ない。本当にこれしか無いのか?


posted by fn23 at 19:37| Comment(0) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2005年08月09日

すごい勢い(自称)でデバッグ完了

この2週間ものすごい勢いで、設計、コーディング、単体デバッグ、組み込み、実機デバッグとこなし、ようやく終了。

自分でも自信が持てない位タイトなスケジュールだったが、少くともボクの担当部分は無事に完了、結構満足している。あとは問い合わせが少ないことを祈るばかり。

対象は組込みシステムでバリバリのリアルタイム制御なため、頭の中やエディタの中のコードの世界だけではうまくいかず、だいたいいつもハマるのだが、今回はそれもほとんど無かったのが、自分としては満足。

プログラミングの仕事をしていて佳境に入ると、乗ってきた状態になるが、まさにこの状態が10日間ぐらい続いた気がする。最近「フロー(Flow)状態」ということばが流行っているようで、心理学の用語で「一つのことに没頭し、ほとんど瞑想状態になること」が語源らしいが、まさにこれかな、と。

ただ、いつもいつもこんなに猛烈に開発できる訳ではなくて、Joel on Softwareにあった記事「開発者としての自分が生産的にコーディングするのは平均して1日に2、3時間だ」というのに、非常に共感。
あー、ボクだけじゃなかったのね、優秀な人でもそうなのね、と。これを読んでちょっと安心。


Joel on Software:射撃しつつ前進


このまま徐々に夏休み気分に落ちて行って、そのまま夏休みって展開が理想的ではあるが、どうなることやら。
posted by fn23 at 00:11| Comment(0) | TrackBack(1) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2004年07月16日

プログラミング言語の学び方

英語でしゃべらナイトゲストだった中尊寺ゆつこの「大人になってから外国語を学ぶコツ」はそのまま「プログラミング言語を学ぶコツ」に当てはまるなぁ、と思った。

NHK TV「英語でしゃべらナイト」はいつもゲストが面白く、毎週見ている。前回のゲストは漫画家の中尊寺ゆつこさん。漫画家としての人気絶頂期に30代前半でニューヨークに渡った経験を話していた。英語も上手、発音も綺麗だ。

彼女いわく、おとなになってから英語を学ぶ順番は、

1. 文法
2. 単語
3. リスニング
4. 発音

で、巷で言われているような、
(海外に)住めばオッケー、子供のころから始めなきゃ、文法は不要、という風潮はバッサリ否定。

ネイティブのようにしゃべれなくても良い。日本語でしっかりモノを考えられる脳味噌を作るほうが重要、海外に住んでも勉強しなければ上達しない。とのことで、ごもっとも。

プログラミング言語の修得も全く同じだと思う。OJTとか、とにかくコードを書け、とか言われることが多いが、何と言っても、

「1.文法」 だろう。ひとつの言語をマスターした人にとっては他の言語の文法の修得が早いのは確かだが、それは修得スピードが速くなっただけで文法を知らずにマスターできるという意味ではない。

ある種の自慢話のような雰囲気で「文法知らないんだけど書いちゃいました」ってのは、「文法定義を真面目に読まなかったけど、大体分かって、このプログラム書けました。ボクってセンスいいでしょ?」という意味だと思って良い。文法は理解しているのだ。

その上で

「2.単語」に相当するその言語やOSなりの登場人物であるAPIとかライブラリを掴む(暗記する必要は無いけど)。

「3.リスニング」に相当するのは、他人のコードを読むことである。1,2が分からずにやみくもにコードを読んでも自らの血や、肉とすることは無理である。オープンソースのコードを読む、でも良いし、コードレビューに真面目に参加する、でも良い。

「4.発音」最後にとりくむのが、如何に綺麗にコードを書くか、である。これもサボって良い訳ではないが、1,2,3が無いと「どんなコードが綺麗なコードか」の美意識、こだわりをそもそも勘違いする可能性もある。

もちろん、1,2,3,4のいずれのステップもほぼ自動的に理解できてしまうセンスの良い人もいるが、どこかのステップを端折っているわけではない。

中尊寺さんが強調していたように、英語力そのものよりも母国語で如何に語るべきものを持っているかが重要、というのは全くもってその通り。プログラミングでも、「何を作る?」「どのように作る?」が重要なのは言うまでもない。
posted by fn23 at 19:49| Comment(0) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

2004年03月16日

squid cygwin1.5対応

cygwinをアップデートしたらsquidが動かなくなった。

FATAL: setrlimit: RLIMIT_NOFILE: (24) Too many open files

その対応は以下。

cygwin setup.exe でソース込みでダウンロード。
/usr/src/squid-XXX
下のビルドディレクトリ .build/
の中の include/autoconf.h を修正。RLIMIT関係をコメントアウト。

/* Define if you have the setrlimit function. */
/* #define HAVE_SETRLIMIT 1 */

...

/* Define if you have the getrlimit function. */
/* #define HAVE_GETRLIMIT 1 */

これでビルドし直すと、無事起動。
posted by fn23 at 00:00| Comment(0) | TrackBack(0) | ソフトウェア | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は180日以上新しい記事の投稿がないブログに表示されております。