LaterMail いろいろと修正
Hit Me Laterにインスパイアされた、とってもシンプルなリマインダーツール『Later Mail』 | IDEA*IDEA で取り上げていただいたおかげで、たくさんの方が http://lm.5-55.jp/ を使ってくださっています。ありがとうございます。
で、いろいろな方がいろいろな環境からメールを送ってこられるので、エラーになるケースもちらほら見受けられます。現象が確認でき次第、修正していますので、エラーが返ってきた方は、info@5-55.jp へメールいただけると助かります。
以下はエラー報告いただいたケースで解決したものです。(たぶん解決したんじゃないかなというものも含みます)
ケース1:docomo の携帯
"Message-Id:"ヘッダが "Message-ID:"になっていたため、正規表現でマッチせず、エラーになっていました。
正規表現のマッチングに「大文字小文字を区別しない」オプション(/i)を付けたので、解決済みです。
ケース2:MacOSXのMail
"Date:"ヘッダの形式が "2008年8月28日 5:02:54:JST"という形式だったので、そのまま Time.parse に食わせていたため、エラーになっていました。
NKF で UTF-8 に変換してから "年月日"を "/"に変換して、Time.parse に通すようにしたので、このケースは解決済みです。(たぶん。確認待ち)
追記:MacOSXのMailの場合、"Date:"ヘッダ形式云々より、"Message-Id:"ヘッダのあとに"Date:"ヘッダがくるため、ファイルを書こうとしたとき Dateが未定義になっていました。
"Message-Id:"ヘッダ受信時点で Dateが未定義だったら現在時刻を使用するように修正したため、解決済みです。("Date:"自体使わない方がいいかも)
ケース3:Au(ezweb) の携帯
"Date:"ヘッダ自体を送ってこなかったため、"Date:"ヘッダが付かないケースは現在時刻を採用するように修正しました。このケースは解決済みです。(たぶん。確認待ち)
ケース4:Softbank(vodafone.ne.jp) の携帯
Postfix が「No recipient addresses found in message header」というエラーを吐いているので、ヘッダから送り先の抽出ができないといっているんだと思うんですが、原因不明。
とりあえずとれる対策として、"From "、"Return-Path:"、"Sender:"にメールアドレスがあって、"To:"がなかった場合は、そのメールアドレスを"To:"とするようにしてみました。
誰かが vodafone.ne.jp から使ってくれるのの確認待ちです。
latermail.rb
公開してたった1日、2日でずいぶん修正してしまったので、一応いまのところの最新ソースを貼り付けておきます。
"Message-Id:"をファイル名にしようとしてずいぶん無理をしているような気がするのと、メールの遅延などを考慮して "Date:"を使ったほうがいいなと思っていたんですが、最近はそんなにひどい遅延にお目にかかったことがないから、いっそ使わないで受信時刻をそのまま使ったほうがすっきりするかもと思っているので、そのうち、また書き直すかもしれません。
require 'time' require 'nkf' class LaterMail # ファイル名(時刻+Message-Id)が決まるまで、@bufに溜めておく def initialize(mdir = '') @dir = mdir @buf = Array.new end # 0 - 24 --> 指定時間をプラス # sunday - saturday --> 次の指定曜日までの日数をプラス(曜日以外は入ってこないが、入ってきてもプラスしないだけ) def add(dt, to) week = { 'sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6 } t = Time.parse(NKF.nkf('-Jw -xm0', dt).gsub(/[年月日]/,'/')) if to if to =~ /\d/ t += to.to_i * 3600 elsif week[to] t += ]/).each { |wd| return wd if wd.include?('@') } nil end def write ct = 0 from = to = boundary = dt = nil from_write = to_write = tf = false io = nil while line = gets if boundary && line.include?("--#{boundary}") if (ct += 1) == 2 io.puts commercial(to) end end if (mail = get_mail(line">*1 user = mail.split('@')[0] end case line when /^From /i, /^Return-Path:/i, /^Sender:/i from = mail @buf << line when /^X-Original-To:/i to = user @buf << "X-Original-To: #{from}" when /for\s*<.*@5-55\.jp>/i to = user @buf << line when /^Delivered-To:/i to = user when /^Date:/i dt = add(line, to) @buf << "Date: #{dt.to_s}" when /^From:/i from_write = true @buf << from_message when /^To:/i to_write = tf = true @buf << "To: #{from}" when /^Content-Type: multipart/i boundary = line.split('"')[1] @buf << line when /^Message-Id:/i @buf << from_message if !from_write && from @buf << "To: #{from}" if !to_write @buf << line dt = add(Time.now.to_s, to) unless dt io = open("#{@dir}#{dt.strftime('%Y%m%d%H%M%S')}.#{user}", "w") @buf.each { |bf| io.puts bf } else if tf next if line =~ /^\s/ tf = false end if io io.puts line else @buf << line end end end unless boundary io.puts commercial(to) end end end if __FILE__ == $0 # cat mail > ruby latermail.rb lmail = LaterMail.new("/home/hml/Maildir/tmp/") lmail.write end
*1:6 - t.wday + week[to]) % 7 + 1) * 3600 * 24
t = Time.mktime(t.year, t.month, t.day, 7)
end
end
t
end
def from_message
"From: LaterMail