# net/pop.rb

## このライブラリについて

メールを受信するためのプロトコル POP3 (Post Office Protocol version 3) を 扱うライブラリです。POP3 の実装は [RFC1939] <URL:http://www.ietf.org/rfc/rfc1939.txt> に基いています。

## 使用例

### メールの受信

以下のコードは、メールを受信してファイル 'inbox/1' 'inbox/2'... に 書きこみ、サーバ上からメールを消します。pop3.server.address は適宜 読みかえてください。

    require 'net/pop'

    pop = Net::POP3.new( 'pop3.server.address', 110 )
    pop.start( 'YourAccount', 'YourPassword' )          ###
    if pop.mails.empty? then
      puts 'no mail.'
    else
      i = 0
      pop.each_mail do |m|   # or "pop.mails.each ..."
        File.open( 'inbox/' + i.to_s, 'w' ) {|f|
          f.write m.pop
        }
        m.delete
        i += 1
      end
      puts "#{pop.mails.size} mails popped."
    end
    pop.finish                                           ###

POP サーバはネットワークのむこうに存在するので、なにか仕事をさせる にはその前に開始手続きを、終わったら終了手続きを、行わなければいけ ません。それを行うのが Net::POP3#start と #finish で、POP3 オブジェクト はその二つのメソッドの間でだけ有効になります。

サーバ上のメールは POPMail オブジェクトとして表現されており、この オブジェクトのメソッドを呼ぶことでメールを取ってきたり消したりする ことができます。POP3#mails はこの POPMail オブジェクトの配列であり、 POP3#each_mail はさらに mails.each のショートカットです。

### 短くする

上の例はあえて省略や短縮用メソッドを避けたためにかなり冗長です。 まず、ブロック付きの Net::POP3.start を使うことで POP3.new #start #finish を併合できます。

    require 'net/pop'

    Net::POP3.start( 'pop3.server.address', 110,
                     'YourAccount', 'YourPassword' ){|pop|
      if pop.mails.empty? then
        puts 'no mail.'
      else
        i = 0
        pop.each_mail do |m|   # or "pop.mails.each ..."
          File.open( 'inbox/' + i.to_s, 'w' ) {|f|
            f.write m.pop
          }
          m.delete
          i += 1
        end
        puts "#{pop.mails.size} mails popped."
      end
    }

POP3#delete_all を使うとさらに #each_mail と m.delete を 併合できます。

    require 'net/pop'

    Net::POP3.start( 'pop3.server.address', 110,
                  'YourAccount', 'YourPassword' ) {|pop|
      if pop.mails.empty? then
        puts 'no mail.'
      else
        i = 0
        pop.delete_all do |m|
          File.open( 'inbox/' + i.to_s, 'w' ) {|f|
            f.write m.pop
          }
          i += 1
        end
      end
    }

クラスメソッドの POP3.delete_all を使うとさらに短くなります。

    require 'net/pop'

    i = 0
    Net::POP3.delete_all( 'pop3.server.address', 110,
                          'YourAccount', 'YourPassword' ) do |m|
      File.open( 'inbox/' + i.to_s, 'w' ) {|f|
          f.write m.pop
      }
      i += 1
    end

### ファイルに直接書く

これまでの例では m.pop の部分でメールをひとつの文字列として うけとっていましたが、たとえば 3MB くらいある巨大なメールの場合は これではまずい場合があります。そのような場合は以下のように m.pop に File オブジェクトを与える手が使えます。

    require 'net/pop'
    Net::POP3.delete_all( 'pop3.server.address', 110,
                          'YourAccount', 'YourPassword' ) do |m|
      File.open( 'inbox', 'w' ) {|f|
          m.pop f   ####
      }
    end

### APOP

Net::POP3 クラスのかわりに Net::APOP クラスを使うと、認証時に APOP を 使うようになります。また動的にノーマル POP と APOP を選択するには、 以下のように Net::POP3.APOP() メソッドを使うのが便利です。

    require 'net/pop'

    # use APOP authentication if $isapop == true
    pop = Net::POP3.APOP($isapop).new( 'apop.server.address', 110 )
    pop.start( YourAccount', 'YourPassword' ) {|pop|
        # Rest code is same.
    }

この方法はクラス自体を変えるので、クラスメソッドの start や foreach、 delete_all、auth_only なども APOP とともに使えます。

## Net::POP3 class

### クラスメソッド

new( address, port = 110, apop = false )

  Net::POP3 オブジェクトを生成します。まだ接続はしません。 apop が真のときは APOP 認証を行うオブジェクトを生成します。

start( address, port = 110, account, password )
start( address, port = 110, account, password ) {|pop| .... }

  address の port 番ポートに接続し、アカウント account パスワード password で POP ログインします。第二引数 port に nil を渡すと POP3 のデフォルトポート(110)を使います。

      Net::POP3.start( addr, port, account, password ) {|pop|
        pop.each_mail do |m|
          file.write m.pop
          m.delete
        end
      }

APOP( is_apop )

  bool が真なら Net::APOP クラス、偽なら Net::POP3 クラスを返します。 以下の例のように使ってください。

      # example 1
      pop = Net::POP3::APOP($isapop).new( addr, port )

      # example 2
      Net::POP3::APOP($isapop).start( addr, port ) {|pop|
          ....
      }

foreach( address, port = 110, account, password ) {|mail| .... }

  POP セッションを開き、サーバ上のすべてのメールに対して繰り返します。 以下と同じです。

      Net::POP3.start( address, port, account, password ) {|pop|
        pop.each_mail do |m|
          yield m
        end
      }

      # example
      Net::POP3.foreach( 'your.pop.server', 110,
                         'YourAccount', 'YourPassword' ) do |m|
        file.write m.pop
        m.delete if $DELETE
      end

delete_all( address, port = 110, account, password )
delete_all( address, port = 110, account, password ) {|mail| .... }

  POP セッションを開き、サーバ上のメールをすべて削除します。 ブロックが与えられた時は削除する前にブロックにそのメールを 渡します。以下と同じです。

      # example
      Net::POP3.delete_all( addr, nil, 'YourAccount', 'YourPassword' ) do |m|
        m.pop file
      end

auth_only( address, port = 110, account, password )

  POP セッションを開き認証だけを行って接続を切ります。 POP before SMTP 専用です。

      # example
      Net::POP3.auth_only( 'your.pop3.server',
                           nil,     # using default (110)
                           'YourAccount',
                           'YourPassword' )

### メソッド

start( account, password )
start( account, password ) {|pop| .... }

  リモートホストとの接続を開始し、アカウントに account、 パスワードに password を使って POP ログインします。

active?

  POP3 セッションが開始されていたら真。

address

  接続するアドレス

port

  接続するポート番号

open_timeout
open_timeout=(n)

  接続時に待つ最大秒数。この秒数たってもコネクションが 開かなければ例外 TimeoutError を発生します。

read_timeout
read_timeout=(n)

  読みこみ (read(1) 一回) でブロックしてよい最大秒数。 この秒数たっても読みこめなければ例外 TimeoutError を発生します。

finish

  POP3 セッションを終了します。セッション開始前にこのメソッドが 呼ばれた場合は例外 IOError を発生します。

mails

  Net::POPMail オブジェクトの配列をかえします。 この配列はセッションを開始したときに自動的に更新されます。

each_mail {|popmail| .... }
each {|popmail| .... }

  pop3.mails.each と同じです。

delete_all
delete_all {|popmail| .... }

  サーバ上のメールを全て消去します。 ブロックを与えられたときは消去する前にその POPMail オブジェクトを ブロックに渡します。

      # example
      n = 1
      pop.delete_all do |m|
        File.open("inbox/#{n}") {|f| f.write m.pop }
        n += 1
      end

auth_only( account, password )

  POP セッションを開き認証だけを行って接続を切ります。 POP before SMTP 専用です。

      # example
      pop = Net::POP3.new( 'your.pop3.server' )
      pop.auth_only 'YourAccount', 'YourPassword'

reset

  セッションをリセットします。 具体的には POPMail#delete で消したメールが全て復活します。 (POP3 ではメール一個だけを復活する方法はありません)

## Net::APOP

このクラスでは新しいメソッドは導入していません。 認証方式が APOP に変わるだけです。

### スーパークラス

Net::POP3

## Net::POPMail

POP サーバー上のメール一通を抽象的に表現するクラス。 メールの取得や消去といった操作をカプセル化します。

### メソッド

pop( dest = '' )

  メールを受信して dest に << メソッドを使って書きこみます。 dest を返します。

      # example
      allmails = nil
      POP3.start( 'your.pop3.server', 110,
                  'YourAccount, 'YourPassword' ) {|pop|
          allmails = pop.mails.collect {|popmail| popmail.pop }
      }

pop {|str| .... }

  メールの文字列を少しづつ読みこみ、順次ブロックに与えます。

      # example
      POP3.start( 'localhost', 110 ) {|pop3|
        pop3.each_mail do |m|
          m.pop do |str|
            # do anything
          end
        end
      }

header

  ヘッダだけを受信して文字列で返します。

top( lines )

  メールヘッダと lines 行ぶんの本文を取得し文字列で返します。

delete

  サーバ上からメールを削除します。

size

  メールのサイズ (単位はバイト) をかえします。

deleted?

  メールがサーバ上で消去されているとき真。消去してしまったら POP3#reset を使う以外に復活する方法はありません。

unique_id

  メールに対して振られた、サーバ上で一意な識別子（UIDL）をかえします。 number と違い、接続しなおしても変化しません。

reverse link: [添付ライブラリ]