hakeの日記

Windows環境でプログラミングの勉強をしています。

net/pop - メールの受信

Rubyの勉強
pop/apopサーバーに接続してメールを取って来る。下のサンプルではyahooメールにアクセスして各メールのunique-idとヘッダと本文10行をファイルに保存。文字コードはJIS。タイトルのデコードはNKFで実施、オプションはBだと思ったらNだった、この辺は良くわかっていないです。

追記

nkfのオプションがmBで上手くいかなかったのは、=?ISO-2022-JP?B?……?=という風にデーコード文字列の両端に識別用?の文字が付加していたためでした。これを除去したらmBでデコードできました。ちなみにヘッダにある日本語はSubject以外も同じエンコードを行う模様。


unique-idがわかるのでヘッダだけリストアップして必要なメールだけ取って来るなんていう処理も比較的簡単にできそうですね。


マニュアル:http://www.ruby-lang.org/ja/man/?cmd=view;name=net%2Fpop

require 'net/pop'
require 'nkf'

POPSERVER = 'pop.mail.yahoo.co.jp'
PORT      = 110
ACCOUNT   = 'user_name'
PASSWARD  = 'passward'

is_apop = false   # APOPならばtrueにする
INBOX   = 'F:/inbox'

pop = Net::POP3::APOP(is_apop).new( POPSERVER, PORT )
pop.start( ACCOUNT, PASSWARD ) do |pop|
  if pop.mails.empty? then
    puts 'no mail.'
  else
    pop.each_mail do |m|
      File.open( INBOX , 'a' ) do |f|
        f.puts "unique_id = " + m.unique_id
        f.puts 
        #h = m.header         # ヘッダのみ
        h = m.top(10)         # ヘッダ+本文(10行)
        flag_subj = false     # Subject: 処理中
        subject = ""
        h.each_line("\n") do |line|
          line.chomp!
          # Subjectのデコード  エンコードされたブロックが複数個ある場合に改行されてる?
          # 本文がJISだったのでタイトルも合わせる
          if flag_subj && /^ / =~ line
            subject << line.lstrip.gsub(/(\=\?.*?\?\=)/){|base| NKF.nkf('-mNj', base)}
          elsif /^Subject:/ =~ line
            subject = line.gsub(/(\=\?.*?\?\=)/){|base| NKF.nkf('-mNj', base)}
            flag_subj = true
          else
            f.puts subject if flag_subj
            f.puts line
            flag_subj = false
          end
        end
        f.puts '---------------------------------------------------'
      end
      # m.delete        # サーバーから削除
    end
  end
end