Class | Net::POP3 |
In: |
lib/net/pop.rb
|
Parent: | 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)
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 POP3.new, POP3#start and 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
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 POPMail#unique_id() method returns the unique-id of the message as a String. Normally the unique-id is a hash of the message.
Revision | = | %q$Revision: 16193 $.split[1] |
address | [R] | The address to connect to. |
open_timeout | [RW] | Seconds to wait until a connection is opened. If the POP3 object cannot open a connection within this time, it raises a TimeoutError exception. |
read_timeout | [R] | 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. |
Returns the APOP class if isapop is true; otherwise, returns the POP class. For example:
# Example 1 pop = Net::POP3::APOP($is_apop).new(addr, port) # Example 2 Net::POP3::APOP($is_apop).start(addr, port) do |pop| .... end
# File lib/net/pop.rb, line 238 238: def POP3.APOP(isapop) 239: isapop ? APOP : POP3 240: end
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 lib/net/pop.rb, line 305 305: def POP3.auth_only(address, port = nil, 306: account = nil, password = nil, 307: isapop = false) 308: new(address, port, isapop).auth_only account, password 309: end
# File lib/net/pop.rb, line 370 370: def POP3.certs 371: return @ssl_params[:ca_file] || @ssl_params[:ca_path] 372: end
# File lib/net/pop.rb, line 336 336: def POP3.create_ssl_params(verify_or_params = {}, certs = nil) 337: begin 338: params = verify_or_params.to_hash 339: rescue NoMethodError 340: params = {} 341: params[:verify_mode] = verify_or_params 342: if certs 343: if File.file?(certs) 344: params[:ca_file] = certs 345: elsif File.directory?(certs) 346: params[:ca_path] = certs 347: end 348: end 349: end 350: return params 351: 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 lib/net/pop.rb, line 283 283: def POP3.delete_all(address, port = nil, 284: account = nil, password = nil, 285: isapop = false, &block) 286: start(address, port, account, password, isapop) {|pop| 287: pop.delete_all(&block) 288: } 289: 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 lib/net/pop.rb, line 262 262: def POP3.foreach(address, port = nil, 263: account = nil, password = nil, 264: isapop = false, &block) # :yields: message 265: start(address, port, account, password, isapop) {|pop| 266: pop.each_mail(&block) 267: } 268: end
address is the hostname or ip address of your POP3 server.
The optional port is the port to connect to.
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 lib/net/pop.rb, line 410 410: def initialize(addr, port = nil, isapop = false) 411: @address = addr 412: @ssl_params = POP3.ssl_params 413: @port = port 414: @apop = isapop 415: 416: @command = nil 417: @socket = nil 418: @started = false 419: @open_timeout = 30 420: @read_timeout = 60 421: @debug_output = nil 422: 423: @mails = nil 424: @n_mails = nil 425: @n_bytes = nil 426: 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 lib/net/pop.rb, line 394 394: def POP3.start(address, port = nil, 395: account = nil, password = nil, 396: isapop = false, &block) # :yield: pop 397: new(address, port, isapop).start(account, password, &block) 398: 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 lib/net/pop.rb, line 314 314: def auth_only(account, password) 315: raise IOError, 'opening previously opened POP session' if started? 316: start(account, password) { 317: ; 318: } 319: 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 lib/net/pop.rb, line 666 666: def delete_all # :yield: message 667: mails().each do |m| 668: yield m if block_given? 669: m.delete unless m.deleted? 670: end 671: end
Enables SSL for this instance. Must be called before the connection is established to have any effect. +params[:port]+ is port to establish the SSL connection on; Defaults to 995. params (except :port) is passed to OpenSSL::SSLContext#set_params.
# File lib/net/pop.rb, line 445 445: def enable_ssl(verify_or_params = {}, certs = nil, port = nil) 446: begin 447: @ssl_params = verify_or_params.to_hash.dup 448: @port = @ssl_params.delete(:port) || @port 449: rescue NoMethodError 450: @ssl_params = POP3.create_ssl_params(verify_or_params, certs) 451: @port = port || @port 452: end 453: end
Provide human-readable stringification of class state.
# File lib/net/pop.rb, line 460 460: def inspect 461: "#<#{self.class} #{@address}:#{@port} open=#{@started}>" 462: end
# File lib/net/pop.rb, line 691 691: def logging(msg) 692: @debug_output << msg + "\n" if @debug_output 693: 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 lib/net/pop.rb, line 622 622: def mails 623: return @mails.dup if @mails 624: if n_mails() == 0 625: # some popd raises error for LIST on the empty mailbox. 626: @mails = [] 627: return [] 628: end 629: 630: @mails = command().list.map {|num, size| 631: POPMail.new(num, size, self, command()) 632: } 633: @mails.dup 634: end
Returns the total size in bytes of all the messages on the POP server.
# File lib/net/pop.rb, line 610 610: def n_bytes 611: return @n_bytes if @n_bytes 612: @n_mails, @n_bytes = command().stat 613: @n_bytes 614: end
Returns the number of messages on the POP server.
# File lib/net/pop.rb, line 603 603: def n_mails 604: return @n_mails if @n_mails 605: @n_mails, @n_bytes = command().stat 606: @n_mails 607: 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 lib/net/pop.rb, line 477 477: def set_debug_output(arg) 478: @debug_output = arg 479: 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 lib/net/pop.rb, line 518 518: def start(account, password) # :yield: pop 519: raise IOError, 'POP session already started' if @started 520: if block_given? 521: begin 522: do_start account, password 523: return yield(self) 524: ensure 525: do_finish 526: end 527: else 528: do_start account, password 529: return self 530: end 531: end
does this instance use SSL?
# File lib/net/pop.rb, line 434 434: def use_ssl? 435: return !@ssl_params.nil? 436: end
# File lib/net/pop.rb, line 591 591: def command 592: raise IOError, 'POP session not opened yet' \ 593: if not @socket or @socket.closed? 594: @command 595: end
# File lib/net/pop.rb, line 578 578: def do_finish 579: @mails = nil 580: @n_mails = nil 581: @n_bytes = nil 582: @command.quit if @command 583: ensure 584: @started = false 585: @command = nil 586: @socket.close if @socket and not @socket.closed? 587: @socket = nil 588: end
# File lib/net/pop.rb, line 533 533: def do_start(account, password) 534: s = timeout(@open_timeout) { TCPSocket.open(@address, port) } 535: if use_ssl? 536: raise 'openssl library not installed' unless defined?(OpenSSL) 537: context = OpenSSL::SSL::SSLContext.new 538: context.set_params(@ssl_params) 539: s = OpenSSL::SSL::SSLSocket.new(s, context) 540: s.sync_close = true 541: s.connect 542: if context.verify_mode != OpenSSL::SSL::VERIFY_NONE 543: s.post_connection_check(@address) 544: end 545: end 546: @socket = InternetMessageIO.new(s) 547: logging "POP session started: #{@address}:#{@port} (#{@apop ? 'APOP' : 'POP'})" 548: @socket.read_timeout = @read_timeout 549: @socket.debug_output = @debug_output 550: on_connect 551: @command = POP3Command.new(@socket) 552: if apop? 553: @command.apop account, password 554: else 555: @command.auth account, password 556: end 557: @started = true 558: ensure 559: # Authentication failed, clean up connection. 560: unless @started 561: s.close if s and not s.closed? 562: @socket = nil 563: @command = nil 564: end 565: end