Protocol
This library provides functionality for retrieving email via POP3, the Post Office Protocol version 3. For details of POP3, see [RFC1939] (www.ietf.org/rfc/rfc1939.txt).
This example retrieves messages from the server and deletes them on the server.
Messages are written to files named 'inbox/1', 'inbox/2', .… Replace 'pop.example.com' with your POP3 server address, and 'YourAccount' and 'YourPassword' with the appropriate account details.
require 'net/pop' pop = Net::POP3.new('pop.example.com') pop.start('YourAccount', 'YourPassword') # (1) if pop.mails.empty? puts 'No mail.' else i = 0 pop.each_mail do |m| # or "pop.mails.each ..." # (2) File.open("inbox/#{i}", 'w') do |f| f.write m.pop end m.delete i += 1 end puts "#{pop.mails.size} mails popped." end pop.finish # (3)
Call Net::POP3#start and start POP session.
Access messages by using Net::POP3#each_mail and/or Net::POP3#mails.
Close POP session by calling Net::POP3#finish or use the block form of start.
The example above is very verbose. You can shorten the code by using some utility methods. First, the block form of Net::POP3.start can be used instead of Net::POP3.new, Net::POP3#start and Net::POP3#finish.
require 'net/pop' Net::POP3.start('pop.example.com', 110, 'YourAccount', 'YourPassword') do |pop| if pop.mails.empty? puts 'No mail.' else i = 0 pop.each_mail do |m| # or "pop.mails.each ..." File.open("inbox/#{i}", 'w') do |f| f.write m.pop end m.delete i += 1 end puts "#{pop.mails.size} mails popped." end end
Net::POP3#delete_all is an alternative for each_mail and delete.
require 'net/pop' Net::POP3.start('pop.example.com', 110, 'YourAccount', 'YourPassword') do |pop| if pop.mails.empty? puts 'No mail.' else i = 1 pop.delete_all do |m| File.open("inbox/#{i}", 'w') do |f| f.write m.pop end i += 1 end end end
And here is an even shorter example.
require 'net/pop' i = 0 Net::POP3.delete_all('pop.example.com', 110, 'YourAccount', 'YourPassword') do |m| File.open("inbox/#{i}", 'w') do |f| f.write m.pop end i += 1 end
All the examples above get each message as one big string. This example avoids this.
require 'net/pop' i = 1 Net::POP3.delete_all('pop.example.com', 110, 'YourAccount', 'YourPassword') do |m| File.open("inbox/#{i}", 'w') do |f| m.pop do |chunk| # get a message little by little. f.write chunk end i += 1 end end
The net/pop library supports APOP authentication. To use APOP, use the Net::APOP class instead of the Net::POP3 class. You can use the utility method, Net::POP3.APOP(). For example:
require 'net/pop'
# Use APOP authentication if $isapop == true
pop = Net::POP3.APOP($is_apop).new('apop.example.com', 110)
pop.start(YourAccount', 'YourPassword') do |pop|
# Rest of the code is the same.
end
If your POP server provides UIDL functionality, you can grab only selected mails from the POP server. e.g.
def need_pop?( id ) # determine if we need pop this mail... end Net::POP3.start('pop.example.com', 110, 'Your account', 'Your password') do |pop| pop.mails.select { |m| need_pop?(m.unique_id) }.each do |m| do_something(m.pop) end end
The Net::POPMail#unique_id method returns the unique-id of the message as a String. Normally the unique-id is a hash of the message.
Seconds to wait until a connection is opened. If the POP3 object cannot open a connection within this time, it raises a TimeoutError exception.
Seconds to wait until reading one block (by one read(1) call). If the POP3 object cannot complete a read() within this time, it raises a TimeoutError exception.
Opens a POP3 session, attempts authentication, and quits.
This method raises POPAuthenticationError if authentication fails.
Net::POP3.auth_only('pop.example.com', 110, 'YourAccount', 'YourPassword')
Net::POP3.auth_only('pop.example.com', 110, 'YourAccount', 'YourPassword', true)
# File net/pop.rb, line 290
def POP3.auth_only( address, port = nil,
account = nil, password = nil,
isapop = false )
new(address, port, isapop).auth_only account, password
end
The default port for POP3 connections, port 110
# File net/pop.rb, line 200
def POP3.default_port
110
end
Starts a POP3 session and deletes all messages on the server. If a block is given, each POPMail object is yielded to it before being deleted.
This method raises a POPAuthenticationError if authentication fails.
Net::POP3.delete_all('pop.example.com', 110, 'YourAccount', 'YourPassword') do |m| file.write m.pop end
# File net/pop.rb, line 268
def POP3.delete_all( address, port = nil,
account = nil, password = nil,
isapop = false, &block )
start(address, port, account, password, isapop) {|pop|
pop.delete_all(&block)
}
end
Starts a POP3 session and iterates over each POPMail object, yielding it to the
block. This method is equivalent to:
Net::POP3.start(address, port, account, password) do |pop| pop.each_mail do |m| yield m end end
This method raises a POPAuthenticationError if authentication fails.
Net::POP3.foreach('pop.example.com', 110, 'YourAccount', 'YourPassword') do |m| file.write m.pop m.delete if $DELETE end
# File net/pop.rb, line 247
def POP3.foreach( address, port = nil,
account = nil, password = nil,
isapop = false, &block ) # :yields: message
start(address, port, account, password, isapop) {|pop|
pop.each_mail(&block)
}
end
Creates a new POP3 object.
address is the hostname or ip address of your POP3 server.
The optional port is the port to connect to; it defaults to
110.
The optional isapop specifies whether this connection is going
to use APOP authentication; it defaults to
false.
This method does not open the TCP connection.
# File net/pop.rb, line 342
def initialize( addr, port = nil, isapop = false )
@address = addr
@port = port || self.class.default_port
@apop = isapop
@command = nil
@socket = nil
@started = false
@open_timeout = 30
@read_timeout = 60
@debug_output = nil
@mails = nil
@n_mails = nil
@n_bytes = nil
end
Creates a new POP3 object and open the connection. Equivalent to
Net::POP3.new(address, port, isapop).start(account, password)
If block is provided, yields the newly-opened POP3 object to it, and automatically closes it at the
end of the session.
Net::POP3.start(addr, port, account, password) do |pop| pop.each_mail do |m| file.write m.pop m.delete end end
# File net/pop.rb, line 326
def POP3.start( address, port = nil,
account = nil, password = nil,
isapop = false, &block ) # :yield: pop
new(address, port, isapop).start(account, password, &block)
end
Does this instance use APOP authentication?
# File net/pop.rb, line 360
def apop?
@apop
end
Starts a pop3 session, attempts authentication, and quits. This method must not be called while POP3 session is opened. This method raises POPAuthenticationError if authentication fails.
# File net/pop.rb, line 299
def auth_only( account, password )
raise IOError, 'opening previously opened POP session' if started?
start(account, password) {
;
}
end
Deletes all messages on the server.
If called with a block, yields each message in turn before deleting it.
n = 1 pop.delete_all do |m| File.open("inbox/#{n}") do |f| f.write m.pop end n += 1 end
This method raises a POPError if an error occurs.
# File net/pop.rb, line 551
def delete_all # :yield: message
mails().each do |m|
yield m if block_given?
m.delete unless m.deleted?
end
end
Yields each message to the passed-in block in turn. Equivalent to:
pop3.mails.each do |popmail| .... end
This method raises a POPError if an error occurs.
# File net/pop.rb, line 529
def each_mail( &block ) # :yield: message
mails().each(&block)
end
Finishes a POP3 session and closes TCP connection.
# File net/pop.rb, line 458
def finish
raise IOError, 'POP session not yet started' unless started?
do_finish
end
Provide human-readable stringification of class state.
# File net/pop.rb, line 365
def inspect
"#<#{self.class} #{@address}:#{@port} open=#{@started}>"
end
Returns an array of Net::POPMail objects, representing all the messages on the server. This array is renewed when the session restarts; otherwise, it is fetched from the server the first time this method is called (directly or indirectly) and cached.
This method raises a POPError if an error occurs.
# File net/pop.rb, line 507
def mails
return @mails.dup if @mails
if n_mails() == 0
# some popd raises error for LIST on the empty mailbox.
@mails = []
return []
end
@mails = command().list.map {|num, size|
POPMail.new(num, size, self, command())
}
@mails.dup
end
Returns the total size in bytes of all the messages on the POP server.
# File net/pop.rb, line 495
def n_bytes
return @n_bytes if @n_bytes
@n_mails, @n_bytes = command().stat
@n_bytes
end
Returns the number of messages on the POP server.
# File net/pop.rb, line 488
def n_mails
return @n_mails if @n_mails
@n_mails, @n_bytes = command().stat
@n_mails
end
Set the read timeout.
# File net/pop.rb, line 403
def read_timeout=( sec )
@command.socket.read_timeout = sec if @command
@read_timeout = sec
end
Resets the session. This clears all “deleted” marks from messages.
This method raises a POPError if an error occurs.
# File net/pop.rb, line 561
def reset
command().rset
mails().each do |m|
m.instance_eval {
@deleted = false
}
end
end
WARNING: This method causes a serious security hole. Use this method only for debugging.
Set an output stream for debugging.
pop = Net::POP.new(addr, port) pop.set_debug_output $stderr pop.start(account, passwd) do |pop| .... end
# File net/pop.rb, line 382
def set_debug_output( arg )
@debug_output = arg
end
Starts a POP3 session.
When called with block, gives a POP3 object to the block and closes the session after block call finishes.
This method raises a POPAuthenticationError if authentication fails.
# File net/pop.rb, line 421
def start( account, password ) # :yield: pop
raise IOError, 'POP session already started' if @started
if block_given?
begin
do_start account, password
return yield(self)
ensure
do_finish
end
else
do_start account, password
return self
end
end