[ruby-list:37639] Re: net/pop.rbにUIDLコマンドでMessage-Idのリストを取得するメソッド

From: とみたまさひろ <tommy@...>
Date: 2003-05-01 14:53:30 UTC
List: ruby-list #37639
とみたです。

On Thu, 1 May 2003 13:22:01 +0900
"Keisuke Minami" <keisuke@rccn.com> wrote:

> POP3プロトコルの仕様上、メールの一覧を取得するのに無駄が多いのはしょうがないのですが、
> 特定のひとつのメールだけを取り出すには、UIDLとRETRを組み合わせるだけで
> うまく行くと思ったのです。
	〜〜
> POP3コマンドのコマンドの直接呼び出し用の
> 低レベルインターフェースの実装だけでも
> 十分事足りるかもしれないです。

私には Ruby 添付の net/pop は高機能すぎて使いづらかったので、自作の簡
単なものを良く使ってます。

こんな感じ。

	pop = POP::new(hostname, username, password)
	pop.list	# => ["1 1234","2 5678",...]
	pop.uidl	# => ["1 uid-1","2 uid-2",..]
	pop.uidl 2	# => "2 uid-2"
	pop.retr 1	# => header + body
	pop.top 1, 0	# => header
	pop.quit

よろしければどうぞ :-)

-- 
とみたまさひろ <tommy@tmtm.org>

Attachments (1)

pop.rb (1.52 KB, text/x-ruby)
require 'socket'

class POPError < StandardError
end

class POP
  def initialize(server, user, pass, port=110)
    @sock = TCPSocket::new(server, port || 110)
    wait_ok
    @sock.print "USER #{user}\r\n"
    wait_ok
    @sock.print "PASS #{pass}\r\n"
    wait_ok
  end

  def uidl(n=nil)
    if n then
      @sock.print "UIDL #{n}\r\n"
      r = wait_ok
      return r[4..-1]
    else
      @sock.print "UIDL\r\n"
      wait_ok
      return wait_p.split /\r\n/
    end
  end

  def list(n=nil)
    if n then
      @sock.print "LIST #{n}\r\n"
      r = wait_ok
      return r[4..-1]
    else
      @sock.print "LIST\r\n"
      wait_ok
      return wait_p.split /\r\n/
    end
  end

  def retr(n, &block)
    @sock.print "RETR #{n}\r\n"
    wait_ok
    wait_p &block
  end

  def top(n, l, &block)
    @sock.print "TOP #{n} #{l}\r\n"
    wait_ok
    wait_p &block
  end

  def dele(n)
    @sock.print "DELE #{n}\r\n"
    wait_ok
  end

  def quit()
    @sock.print "QUIT\r\n"
    wait_ok
    @sock.close
  end

  def wait_ok()
    loop do
      r = @sock.gets
      if r == nil then
	raise POPError, 'disconnected by server'
      end
      r = r.chomp.sub(/\r$/,'')
      if r =~ /^\+OK/ then return r end
      raise POPError, r
    end
  end

  def wait_p(&block)
    ret = ''
    loop do
      r = @sock.gets
      if r == nil then
	raise POPError, 'disconnected by server'
      end
      if r == ".\r\n" then return ret end
      r[0,2] = '.' if r[0,2] == '..'
      if block then
	block.call r
      else
	ret << r
      end
    end
    ret
  end

end

In This Thread