mail-portertech 2.6.2.edge
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +753 -0
- data/CONTRIBUTING.md +60 -0
- data/Dependencies.txt +2 -0
- data/Gemfile +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +683 -0
- data/Rakefile +29 -0
- data/TODO.rdoc +9 -0
- data/lib/mail.rb +91 -0
- data/lib/mail/attachments_list.rb +104 -0
- data/lib/mail/body.rb +291 -0
- data/lib/mail/check_delivery_params.rb +20 -0
- data/lib/mail/configuration.rb +75 -0
- data/lib/mail/core_extensions/nil.rb +19 -0
- data/lib/mail/core_extensions/object.rb +13 -0
- data/lib/mail/core_extensions/smtp.rb +24 -0
- data/lib/mail/core_extensions/string.rb +43 -0
- data/lib/mail/core_extensions/string/access.rb +145 -0
- data/lib/mail/core_extensions/string/multibyte.rb +78 -0
- data/lib/mail/elements.rb +14 -0
- data/lib/mail/elements/address.rb +270 -0
- data/lib/mail/elements/address_list.rb +51 -0
- data/lib/mail/elements/content_disposition_element.rb +26 -0
- data/lib/mail/elements/content_location_element.rb +21 -0
- data/lib/mail/elements/content_transfer_encoding_element.rb +17 -0
- data/lib/mail/elements/content_type_element.rb +31 -0
- data/lib/mail/elements/date_time_element.rb +22 -0
- data/lib/mail/elements/envelope_from_element.rb +39 -0
- data/lib/mail/elements/message_ids_element.rb +24 -0
- data/lib/mail/elements/mime_version_element.rb +22 -0
- data/lib/mail/elements/phrase_list.rb +16 -0
- data/lib/mail/elements/received_element.rb +26 -0
- data/lib/mail/encodings.rb +304 -0
- data/lib/mail/encodings/7bit.rb +31 -0
- data/lib/mail/encodings/8bit.rb +31 -0
- data/lib/mail/encodings/base64.rb +33 -0
- data/lib/mail/encodings/binary.rb +31 -0
- data/lib/mail/encodings/quoted_printable.rb +39 -0
- data/lib/mail/encodings/transfer_encoding.rb +58 -0
- data/lib/mail/envelope.rb +30 -0
- data/lib/mail/field.rb +247 -0
- data/lib/mail/field_list.rb +33 -0
- data/lib/mail/fields.rb +35 -0
- data/lib/mail/fields/bcc_field.rb +56 -0
- data/lib/mail/fields/cc_field.rb +55 -0
- data/lib/mail/fields/comments_field.rb +41 -0
- data/lib/mail/fields/common/address_container.rb +16 -0
- data/lib/mail/fields/common/common_address.rb +135 -0
- data/lib/mail/fields/common/common_date.rb +35 -0
- data/lib/mail/fields/common/common_field.rb +57 -0
- data/lib/mail/fields/common/common_message_id.rb +48 -0
- data/lib/mail/fields/common/parameter_hash.rb +58 -0
- data/lib/mail/fields/content_description_field.rb +19 -0
- data/lib/mail/fields/content_disposition_field.rb +70 -0
- data/lib/mail/fields/content_id_field.rb +62 -0
- data/lib/mail/fields/content_location_field.rb +42 -0
- data/lib/mail/fields/content_transfer_encoding_field.rb +44 -0
- data/lib/mail/fields/content_type_field.rb +201 -0
- data/lib/mail/fields/date_field.rb +57 -0
- data/lib/mail/fields/from_field.rb +55 -0
- data/lib/mail/fields/in_reply_to_field.rb +56 -0
- data/lib/mail/fields/keywords_field.rb +44 -0
- data/lib/mail/fields/message_id_field.rb +82 -0
- data/lib/mail/fields/mime_version_field.rb +53 -0
- data/lib/mail/fields/optional_field.rb +13 -0
- data/lib/mail/fields/received_field.rb +75 -0
- data/lib/mail/fields/references_field.rb +56 -0
- data/lib/mail/fields/reply_to_field.rb +55 -0
- data/lib/mail/fields/resent_bcc_field.rb +55 -0
- data/lib/mail/fields/resent_cc_field.rb +55 -0
- data/lib/mail/fields/resent_date_field.rb +35 -0
- data/lib/mail/fields/resent_from_field.rb +55 -0
- data/lib/mail/fields/resent_message_id_field.rb +34 -0
- data/lib/mail/fields/resent_sender_field.rb +62 -0
- data/lib/mail/fields/resent_to_field.rb +55 -0
- data/lib/mail/fields/return_path_field.rb +65 -0
- data/lib/mail/fields/sender_field.rb +67 -0
- data/lib/mail/fields/structured_field.rb +51 -0
- data/lib/mail/fields/subject_field.rb +16 -0
- data/lib/mail/fields/to_field.rb +55 -0
- data/lib/mail/fields/unstructured_field.rb +204 -0
- data/lib/mail/header.rb +274 -0
- data/lib/mail/indifferent_hash.rb +146 -0
- data/lib/mail/mail.rb +267 -0
- data/lib/mail/matchers/has_sent_mail.rb +157 -0
- data/lib/mail/message.rb +2160 -0
- data/lib/mail/multibyte.rb +42 -0
- data/lib/mail/multibyte/chars.rb +474 -0
- data/lib/mail/multibyte/exceptions.rb +8 -0
- data/lib/mail/multibyte/unicode.rb +400 -0
- data/lib/mail/multibyte/utils.rb +60 -0
- data/lib/mail/network.rb +14 -0
- data/lib/mail/network/delivery_methods/exim.rb +52 -0
- data/lib/mail/network/delivery_methods/file_delivery.rb +45 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +89 -0
- data/lib/mail/network/delivery_methods/smtp.rb +142 -0
- data/lib/mail/network/delivery_methods/smtp_connection.rb +61 -0
- data/lib/mail/network/delivery_methods/test_mailer.rb +44 -0
- data/lib/mail/network/retriever_methods/base.rb +63 -0
- data/lib/mail/network/retriever_methods/imap.rb +173 -0
- data/lib/mail/network/retriever_methods/pop3.rb +140 -0
- data/lib/mail/network/retriever_methods/test_retriever.rb +43 -0
- data/lib/mail/parsers.rb +26 -0
- data/lib/mail/parsers/address_lists_parser.rb +132 -0
- data/lib/mail/parsers/content_disposition_parser.rb +67 -0
- data/lib/mail/parsers/content_location_parser.rb +35 -0
- data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
- data/lib/mail/parsers/content_type_parser.rb +64 -0
- data/lib/mail/parsers/date_time_parser.rb +36 -0
- data/lib/mail/parsers/envelope_from_parser.rb +45 -0
- data/lib/mail/parsers/message_ids_parser.rb +39 -0
- data/lib/mail/parsers/mime_version_parser.rb +41 -0
- data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
- data/lib/mail/parsers/ragel.rb +17 -0
- data/lib/mail/parsers/ragel/common.rl +184 -0
- data/lib/mail/parsers/ragel/date_time.rl +30 -0
- data/lib/mail/parsers/ragel/parser_info.rb +61 -0
- data/lib/mail/parsers/ragel/ruby.rb +39 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
- data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
- data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
- data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
- data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
- data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
- data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
- data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
- data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
- data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
- data/lib/mail/parsers/received_parser.rb +47 -0
- data/lib/mail/part.rb +120 -0
- data/lib/mail/parts_list.rb +57 -0
- data/lib/mail/patterns.rb +37 -0
- data/lib/mail/utilities.rb +225 -0
- data/lib/mail/values/unicode_tables.dat +0 -0
- data/lib/mail/version.rb +4 -0
- data/lib/mail/version_specific/ruby_1_8.rb +119 -0
- data/lib/mail/version_specific/ruby_1_9.rb +159 -0
- metadata +276 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
|
5
|
+
class Retriever
|
6
|
+
|
7
|
+
# Get the oldest received email(s)
|
8
|
+
#
|
9
|
+
# Possible options:
|
10
|
+
# count: number of emails to retrieve. The default value is 1.
|
11
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
12
|
+
#
|
13
|
+
def first(options = {}, &block)
|
14
|
+
options ||= {}
|
15
|
+
options[:what] = :first
|
16
|
+
options[:count] ||= 1
|
17
|
+
find(options, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Get the most recent received email(s)
|
21
|
+
#
|
22
|
+
# Possible options:
|
23
|
+
# count: number of emails to retrieve. The default value is 1.
|
24
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
25
|
+
#
|
26
|
+
def last(options = {}, &block)
|
27
|
+
options ||= {}
|
28
|
+
options[:what] = :last
|
29
|
+
options[:count] ||= 1
|
30
|
+
find(options, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Get all emails.
|
34
|
+
#
|
35
|
+
# Possible options:
|
36
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
37
|
+
#
|
38
|
+
def all(options = {}, &block)
|
39
|
+
options ||= {}
|
40
|
+
options[:count] = :all
|
41
|
+
find(options, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Find emails in the mailbox, and then deletes them. Without any options, the
|
45
|
+
# five last received emails are returned.
|
46
|
+
#
|
47
|
+
# Possible options:
|
48
|
+
# what: last or first emails. The default is :first.
|
49
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
50
|
+
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
51
|
+
# instance of Message, not an array of Message instances.
|
52
|
+
# delete_after_find: flag for whether to delete each retreived email after find. Default
|
53
|
+
# is true. Call #find if you would like this to default to false.
|
54
|
+
#
|
55
|
+
def find_and_delete(options = {}, &block)
|
56
|
+
options ||= {}
|
57
|
+
options[:delete_after_find] ||= true
|
58
|
+
find(options, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
# The IMAP retriever allows to get the last, first or all emails from a IMAP server.
|
5
|
+
# Each email retrieved (RFC2822) is given as an instance of +Message+.
|
6
|
+
#
|
7
|
+
# While being retrieved, emails can be yielded if a block is given.
|
8
|
+
#
|
9
|
+
# === Example of retrieving Emails from GMail:
|
10
|
+
#
|
11
|
+
# Mail.defaults do
|
12
|
+
# retriever_method :imap, { :address => "imap.googlemail.com",
|
13
|
+
# :port => 993,
|
14
|
+
# :user_name => '<username>',
|
15
|
+
# :password => '<password>',
|
16
|
+
# :enable_ssl => true }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Mail.all #=> Returns an array of all emails
|
20
|
+
# Mail.first #=> Returns the first unread email
|
21
|
+
# Mail.last #=> Returns the last unread email
|
22
|
+
#
|
23
|
+
# You can also pass options into Mail.find to locate an email in your imap mailbox
|
24
|
+
# with the following options:
|
25
|
+
#
|
26
|
+
# mailbox: name of the mailbox used for email retrieval. The default is 'INBOX'.
|
27
|
+
# what: last or first emails. The default is :first.
|
28
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
29
|
+
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
30
|
+
# instance of Message, not an array of Message instances.
|
31
|
+
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
32
|
+
# or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
|
33
|
+
# The default is 'ALL'
|
34
|
+
#
|
35
|
+
# Mail.find(:what => :first, :count => 10, :order => :asc, :keys=>'ALL')
|
36
|
+
# #=> Returns the first 10 emails in ascending order
|
37
|
+
#
|
38
|
+
class IMAP < Retriever
|
39
|
+
require 'net/imap' unless defined?(Net::IMAP)
|
40
|
+
|
41
|
+
def initialize(values)
|
42
|
+
self.settings = { :address => "localhost",
|
43
|
+
:port => 143,
|
44
|
+
:user_name => nil,
|
45
|
+
:password => nil,
|
46
|
+
:authentication => nil,
|
47
|
+
:enable_ssl => false }.merge!(values)
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor :settings
|
51
|
+
|
52
|
+
# Find emails in a IMAP mailbox. Without any options, the 10 last received emails are returned.
|
53
|
+
#
|
54
|
+
# Possible options:
|
55
|
+
# mailbox: mailbox to search the email(s) in. The default is 'INBOX'.
|
56
|
+
# what: last or first emails. The default is :first.
|
57
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
58
|
+
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
59
|
+
# instance of Message, not an array of Message instances.
|
60
|
+
# read_only: will ensure that no writes are made to the inbox during the session. Specifically, if this is
|
61
|
+
# set to true, the code will use the EXAMINE command to retrieve the mail. If set to false, which
|
62
|
+
# is the default, a SELECT command will be used to retrieve the mail
|
63
|
+
# This is helpful when you don't want your messages to be set to read automatically. Default is false.
|
64
|
+
# delete_after_find: flag for whether to delete each retreived email after find. Default
|
65
|
+
# is false. Use #find_and_delete if you would like this to default to true.
|
66
|
+
# keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
|
67
|
+
# or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
|
68
|
+
# The default is 'ALL'
|
69
|
+
#
|
70
|
+
def find(options={}, &block)
|
71
|
+
options = validate_options(options)
|
72
|
+
|
73
|
+
start do |imap|
|
74
|
+
options[:read_only] ? imap.examine(options[:mailbox]) : imap.select(options[:mailbox])
|
75
|
+
|
76
|
+
uids = imap.uid_search(options[:keys])
|
77
|
+
uids.reverse! if options[:what].to_sym == :last
|
78
|
+
uids = uids.first(options[:count]) if options[:count].is_a?(Integer)
|
79
|
+
uids.reverse! if (options[:what].to_sym == :last && options[:order].to_sym == :asc) ||
|
80
|
+
(options[:what].to_sym != :last && options[:order].to_sym == :desc)
|
81
|
+
|
82
|
+
if block_given?
|
83
|
+
uids.each do |uid|
|
84
|
+
uid = options[:uid].to_i unless options[:uid].nil?
|
85
|
+
fetchdata = imap.uid_fetch(uid, ['RFC822'])[0]
|
86
|
+
new_message = Mail.new(fetchdata.attr['RFC822'])
|
87
|
+
new_message.mark_for_delete = true if options[:delete_after_find]
|
88
|
+
if block.arity == 3
|
89
|
+
yield new_message, imap, uid
|
90
|
+
else
|
91
|
+
yield new_message
|
92
|
+
end
|
93
|
+
imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find] && new_message.is_marked_for_delete?
|
94
|
+
break unless options[:uid].nil?
|
95
|
+
end
|
96
|
+
imap.expunge if options[:delete_after_find]
|
97
|
+
else
|
98
|
+
emails = []
|
99
|
+
uids.each do |uid|
|
100
|
+
uid = options[:uid].to_i unless options[:uid].nil?
|
101
|
+
fetchdata = imap.uid_fetch(uid, ['RFC822'])[0]
|
102
|
+
emails << Mail.new(fetchdata.attr['RFC822'])
|
103
|
+
imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find]
|
104
|
+
break unless options[:uid].nil?
|
105
|
+
end
|
106
|
+
imap.expunge if options[:delete_after_find]
|
107
|
+
emails.size == 1 && options[:count] == 1 ? emails.first : emails
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Delete all emails from a IMAP mailbox
|
113
|
+
def delete_all(mailbox='INBOX')
|
114
|
+
mailbox ||= 'INBOX'
|
115
|
+
mailbox = Net::IMAP.encode_utf7(mailbox)
|
116
|
+
|
117
|
+
start do |imap|
|
118
|
+
imap.uid_search(['ALL']).each do |uid|
|
119
|
+
imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED])
|
120
|
+
end
|
121
|
+
imap.expunge
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns the connection object of the retrievable (IMAP or POP3)
|
126
|
+
def connection(&block)
|
127
|
+
raise ArgumentError.new('Mail::Retrievable#connection takes a block') unless block_given?
|
128
|
+
|
129
|
+
start do |imap|
|
130
|
+
yield imap
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
# Set default options
|
137
|
+
def validate_options(options)
|
138
|
+
options ||= {}
|
139
|
+
options[:mailbox] ||= 'INBOX'
|
140
|
+
options[:count] ||= 10
|
141
|
+
options[:order] ||= :asc
|
142
|
+
options[:what] ||= :first
|
143
|
+
options[:keys] ||= 'ALL'
|
144
|
+
options[:uid] ||= nil
|
145
|
+
options[:delete_after_find] ||= false
|
146
|
+
options[:mailbox] = Net::IMAP.encode_utf7(options[:mailbox])
|
147
|
+
options[:read_only] ||= false
|
148
|
+
|
149
|
+
options
|
150
|
+
end
|
151
|
+
|
152
|
+
# Start an IMAP session and ensures that it will be closed in any case.
|
153
|
+
def start(config=Mail::Configuration.instance, &block)
|
154
|
+
raise ArgumentError.new("Mail::Retrievable#imap_start takes a block") unless block_given?
|
155
|
+
|
156
|
+
imap = Net::IMAP.new(settings[:address], settings[:port], settings[:enable_ssl], nil, false)
|
157
|
+
if settings[:authentication].nil?
|
158
|
+
imap.login(settings[:user_name], settings[:password])
|
159
|
+
else
|
160
|
+
# Note that Net::IMAP#authenticate('LOGIN', ...) is not equal with Net::IMAP#login(...)!
|
161
|
+
# (see also http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/net/imap/rdoc/classes/Net/IMAP.html#M000718)
|
162
|
+
imap.authenticate(settings[:authentication], settings[:user_name], settings[:password])
|
163
|
+
end
|
164
|
+
|
165
|
+
yield imap
|
166
|
+
ensure
|
167
|
+
if defined?(imap) && imap && !imap.disconnected?
|
168
|
+
imap.disconnect
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
# The Pop3 retriever allows to get the last, first or all emails from a POP3 server.
|
5
|
+
# Each email retrieved (RFC2822) is given as an instance of +Message+.
|
6
|
+
#
|
7
|
+
# While being retrieved, emails can be yielded if a block is given.
|
8
|
+
#
|
9
|
+
# === Example of retrieving Emails from GMail:
|
10
|
+
#
|
11
|
+
# Mail.defaults do
|
12
|
+
# retriever_method :pop3, { :address => "pop.gmail.com",
|
13
|
+
# :port => 995,
|
14
|
+
# :user_name => '<username>',
|
15
|
+
# :password => '<password>',
|
16
|
+
# :enable_ssl => true }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Mail.all #=> Returns an array of all emails
|
20
|
+
# Mail.first #=> Returns the first unread email
|
21
|
+
# Mail.last #=> Returns the last unread email
|
22
|
+
#
|
23
|
+
# You can also pass options into Mail.find to locate an email in your pop mailbox
|
24
|
+
# with the following options:
|
25
|
+
#
|
26
|
+
# what: last or first emails. The default is :first.
|
27
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
28
|
+
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
29
|
+
# instance of Message, not an array of Message instances.
|
30
|
+
#
|
31
|
+
# Mail.find(:what => :first, :count => 10, :order => :asc)
|
32
|
+
# #=> Returns the first 10 emails in ascending order
|
33
|
+
#
|
34
|
+
class POP3 < Retriever
|
35
|
+
require 'net/pop' unless defined?(Net::POP)
|
36
|
+
|
37
|
+
def initialize(values)
|
38
|
+
self.settings = { :address => "localhost",
|
39
|
+
:port => 110,
|
40
|
+
:user_name => nil,
|
41
|
+
:password => nil,
|
42
|
+
:authentication => nil,
|
43
|
+
:enable_ssl => false }.merge!(values)
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_accessor :settings
|
47
|
+
|
48
|
+
# Find emails in a POP3 mailbox. Without any options, the 5 last received emails are returned.
|
49
|
+
#
|
50
|
+
# Possible options:
|
51
|
+
# what: last or first emails. The default is :first.
|
52
|
+
# order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
|
53
|
+
# count: number of emails to retrieve. The default value is 10. A value of 1 returns an
|
54
|
+
# instance of Message, not an array of Message instances.
|
55
|
+
# delete_after_find: flag for whether to delete each retreived email after find. Default
|
56
|
+
# is false. Use #find_and_delete if you would like this to default to true.
|
57
|
+
#
|
58
|
+
def find(options = {}, &block)
|
59
|
+
options = validate_options(options)
|
60
|
+
|
61
|
+
start do |pop3|
|
62
|
+
mails = pop3.mails
|
63
|
+
pop3.reset # Clears all "deleted" marks. This prevents non-explicit/accidental deletions due to server settings.
|
64
|
+
mails.sort! { |m1, m2| m2.number <=> m1.number } if options[:what] == :last
|
65
|
+
mails = mails.first(options[:count]) if options[:count].is_a? Integer
|
66
|
+
|
67
|
+
if options[:what].to_sym == :last && options[:order].to_sym == :desc ||
|
68
|
+
options[:what].to_sym == :first && options[:order].to_sym == :asc ||
|
69
|
+
mails.reverse!
|
70
|
+
end
|
71
|
+
|
72
|
+
if block_given?
|
73
|
+
mails.each do |mail|
|
74
|
+
new_message = Mail.new(mail.pop)
|
75
|
+
new_message.mark_for_delete = true if options[:delete_after_find]
|
76
|
+
yield new_message
|
77
|
+
mail.delete if options[:delete_after_find] && new_message.is_marked_for_delete? # Delete if still marked for delete
|
78
|
+
end
|
79
|
+
else
|
80
|
+
emails = []
|
81
|
+
mails.each do |mail|
|
82
|
+
emails << Mail.new(mail.pop)
|
83
|
+
mail.delete if options[:delete_after_find]
|
84
|
+
end
|
85
|
+
emails.size == 1 && options[:count] == 1 ? emails.first : emails
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Delete all emails from a POP3 server
|
92
|
+
def delete_all
|
93
|
+
start do |pop3|
|
94
|
+
unless pop3.mails.empty?
|
95
|
+
pop3.delete_all
|
96
|
+
pop3.finish
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns the connection object of the retrievable (IMAP or POP3)
|
102
|
+
def connection(&block)
|
103
|
+
raise ArgumentError.new('Mail::Retrievable#connection takes a block') unless block_given?
|
104
|
+
|
105
|
+
start do |pop3|
|
106
|
+
yield pop3
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
# Set default options
|
113
|
+
def validate_options(options)
|
114
|
+
options ||= {}
|
115
|
+
options[:count] ||= 10
|
116
|
+
options[:order] ||= :asc
|
117
|
+
options[:what] ||= :first
|
118
|
+
options[:delete_after_find] ||= false
|
119
|
+
options
|
120
|
+
end
|
121
|
+
|
122
|
+
# Start a POP3 session and ensure that it will be closed in any case. Any messages
|
123
|
+
# marked for deletion via #find_and_delete or with the :delete_after_find option
|
124
|
+
# will be deleted when the session is closed.
|
125
|
+
def start(config = Configuration.instance, &block)
|
126
|
+
raise ArgumentError.new("Mail::Retrievable#pop3_start takes a block") unless block_given?
|
127
|
+
|
128
|
+
pop3 = Net::POP3.new(settings[:address], settings[:port], false)
|
129
|
+
pop3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) if settings[:enable_ssl]
|
130
|
+
pop3.start(settings[:user_name], settings[:password])
|
131
|
+
|
132
|
+
yield pop3
|
133
|
+
ensure
|
134
|
+
if defined?(pop3) && pop3 && pop3.started?
|
135
|
+
pop3.finish
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Mail
|
4
|
+
|
5
|
+
class TestRetriever < Retriever
|
6
|
+
|
7
|
+
def self.emails
|
8
|
+
@@emails
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.emails=(val)
|
12
|
+
@@emails = val
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(values)
|
16
|
+
@@emails = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(options = {}, &block)
|
20
|
+
options[:count] ||= :all
|
21
|
+
options[:order] ||= :asc
|
22
|
+
options[:what] ||= :first
|
23
|
+
emails_index = (0...@@emails.size).to_a
|
24
|
+
emails_index.reverse! if options[:what] == :last
|
25
|
+
emails_index = case count = options[:count]
|
26
|
+
when :all then emails_index
|
27
|
+
when Fixnum then emails_index[0, count]
|
28
|
+
else
|
29
|
+
raise 'Invalid count option value: ' + count.inspect
|
30
|
+
end
|
31
|
+
if options[:what] == :last && options[:order] == :asc || options[:what] == :first && options[:order] == :desc
|
32
|
+
emails_index.reverse!
|
33
|
+
end
|
34
|
+
emails_index.each { |idx| @@emails[idx].mark_for_delete = true } if options[:delete_after_find]
|
35
|
+
emails = emails_index.map { |idx| @@emails[idx] }
|
36
|
+
emails.each { |email| yield email } if block_given?
|
37
|
+
@@emails.reject!(&:is_marked_for_delete?) if options[:delete_after_find]
|
38
|
+
emails.size == 1 && options[:count] == 1 ? emails.first : emails
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/mail/parsers.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Mail
|
2
|
+
module Parsers
|
3
|
+
|
4
|
+
# Low-level ragel based parsers
|
5
|
+
require 'mail/parsers/ragel'
|
6
|
+
|
7
|
+
AddressListStruct = Struct.new(:addresses, :group_names, :error)
|
8
|
+
AddressStruct = Struct.new(:raw, :domain, :comments, :local,
|
9
|
+
:obs_domain_list, :display_name, :group, :error)
|
10
|
+
ContentDispositionStruct = Struct.new(:disposition_type, :parameters, :error)
|
11
|
+
ContentLocationStruct = Struct.new(:location, :error)
|
12
|
+
ContentTransferEncodingStruct = Struct.new(:encoding, :error)
|
13
|
+
ContentTypeStruct = Struct.new(:main_type, :sub_type, :parameters, :error)
|
14
|
+
DateTimeStruct = Struct.new(:date_string, :time_string, :error)
|
15
|
+
EnvelopeFromStruct = Struct.new(:address, :ctime_date, :error)
|
16
|
+
MessageIdsStruct = Struct.new(:message_ids, :error)
|
17
|
+
MimeVersionStruct = Struct.new(:major, :minor, :error)
|
18
|
+
PhraseListsStruct = Struct.new(:phrases, :error)
|
19
|
+
ReceivedStruct = Struct.new(:date, :time, :info, :error)
|
20
|
+
|
21
|
+
require 'mail/parsers/ragel/parser_info'
|
22
|
+
Ragel::FIELD_PARSERS.each do |field_parser|
|
23
|
+
require "mail/parsers/#{field_parser}_parser"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|