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.
Files changed (153) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.rdoc +753 -0
  3. data/CONTRIBUTING.md +60 -0
  4. data/Dependencies.txt +2 -0
  5. data/Gemfile +15 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +683 -0
  8. data/Rakefile +29 -0
  9. data/TODO.rdoc +9 -0
  10. data/lib/mail.rb +91 -0
  11. data/lib/mail/attachments_list.rb +104 -0
  12. data/lib/mail/body.rb +291 -0
  13. data/lib/mail/check_delivery_params.rb +20 -0
  14. data/lib/mail/configuration.rb +75 -0
  15. data/lib/mail/core_extensions/nil.rb +19 -0
  16. data/lib/mail/core_extensions/object.rb +13 -0
  17. data/lib/mail/core_extensions/smtp.rb +24 -0
  18. data/lib/mail/core_extensions/string.rb +43 -0
  19. data/lib/mail/core_extensions/string/access.rb +145 -0
  20. data/lib/mail/core_extensions/string/multibyte.rb +78 -0
  21. data/lib/mail/elements.rb +14 -0
  22. data/lib/mail/elements/address.rb +270 -0
  23. data/lib/mail/elements/address_list.rb +51 -0
  24. data/lib/mail/elements/content_disposition_element.rb +26 -0
  25. data/lib/mail/elements/content_location_element.rb +21 -0
  26. data/lib/mail/elements/content_transfer_encoding_element.rb +17 -0
  27. data/lib/mail/elements/content_type_element.rb +31 -0
  28. data/lib/mail/elements/date_time_element.rb +22 -0
  29. data/lib/mail/elements/envelope_from_element.rb +39 -0
  30. data/lib/mail/elements/message_ids_element.rb +24 -0
  31. data/lib/mail/elements/mime_version_element.rb +22 -0
  32. data/lib/mail/elements/phrase_list.rb +16 -0
  33. data/lib/mail/elements/received_element.rb +26 -0
  34. data/lib/mail/encodings.rb +304 -0
  35. data/lib/mail/encodings/7bit.rb +31 -0
  36. data/lib/mail/encodings/8bit.rb +31 -0
  37. data/lib/mail/encodings/base64.rb +33 -0
  38. data/lib/mail/encodings/binary.rb +31 -0
  39. data/lib/mail/encodings/quoted_printable.rb +39 -0
  40. data/lib/mail/encodings/transfer_encoding.rb +58 -0
  41. data/lib/mail/envelope.rb +30 -0
  42. data/lib/mail/field.rb +247 -0
  43. data/lib/mail/field_list.rb +33 -0
  44. data/lib/mail/fields.rb +35 -0
  45. data/lib/mail/fields/bcc_field.rb +56 -0
  46. data/lib/mail/fields/cc_field.rb +55 -0
  47. data/lib/mail/fields/comments_field.rb +41 -0
  48. data/lib/mail/fields/common/address_container.rb +16 -0
  49. data/lib/mail/fields/common/common_address.rb +135 -0
  50. data/lib/mail/fields/common/common_date.rb +35 -0
  51. data/lib/mail/fields/common/common_field.rb +57 -0
  52. data/lib/mail/fields/common/common_message_id.rb +48 -0
  53. data/lib/mail/fields/common/parameter_hash.rb +58 -0
  54. data/lib/mail/fields/content_description_field.rb +19 -0
  55. data/lib/mail/fields/content_disposition_field.rb +70 -0
  56. data/lib/mail/fields/content_id_field.rb +62 -0
  57. data/lib/mail/fields/content_location_field.rb +42 -0
  58. data/lib/mail/fields/content_transfer_encoding_field.rb +44 -0
  59. data/lib/mail/fields/content_type_field.rb +201 -0
  60. data/lib/mail/fields/date_field.rb +57 -0
  61. data/lib/mail/fields/from_field.rb +55 -0
  62. data/lib/mail/fields/in_reply_to_field.rb +56 -0
  63. data/lib/mail/fields/keywords_field.rb +44 -0
  64. data/lib/mail/fields/message_id_field.rb +82 -0
  65. data/lib/mail/fields/mime_version_field.rb +53 -0
  66. data/lib/mail/fields/optional_field.rb +13 -0
  67. data/lib/mail/fields/received_field.rb +75 -0
  68. data/lib/mail/fields/references_field.rb +56 -0
  69. data/lib/mail/fields/reply_to_field.rb +55 -0
  70. data/lib/mail/fields/resent_bcc_field.rb +55 -0
  71. data/lib/mail/fields/resent_cc_field.rb +55 -0
  72. data/lib/mail/fields/resent_date_field.rb +35 -0
  73. data/lib/mail/fields/resent_from_field.rb +55 -0
  74. data/lib/mail/fields/resent_message_id_field.rb +34 -0
  75. data/lib/mail/fields/resent_sender_field.rb +62 -0
  76. data/lib/mail/fields/resent_to_field.rb +55 -0
  77. data/lib/mail/fields/return_path_field.rb +65 -0
  78. data/lib/mail/fields/sender_field.rb +67 -0
  79. data/lib/mail/fields/structured_field.rb +51 -0
  80. data/lib/mail/fields/subject_field.rb +16 -0
  81. data/lib/mail/fields/to_field.rb +55 -0
  82. data/lib/mail/fields/unstructured_field.rb +204 -0
  83. data/lib/mail/header.rb +274 -0
  84. data/lib/mail/indifferent_hash.rb +146 -0
  85. data/lib/mail/mail.rb +267 -0
  86. data/lib/mail/matchers/has_sent_mail.rb +157 -0
  87. data/lib/mail/message.rb +2160 -0
  88. data/lib/mail/multibyte.rb +42 -0
  89. data/lib/mail/multibyte/chars.rb +474 -0
  90. data/lib/mail/multibyte/exceptions.rb +8 -0
  91. data/lib/mail/multibyte/unicode.rb +400 -0
  92. data/lib/mail/multibyte/utils.rb +60 -0
  93. data/lib/mail/network.rb +14 -0
  94. data/lib/mail/network/delivery_methods/exim.rb +52 -0
  95. data/lib/mail/network/delivery_methods/file_delivery.rb +45 -0
  96. data/lib/mail/network/delivery_methods/sendmail.rb +89 -0
  97. data/lib/mail/network/delivery_methods/smtp.rb +142 -0
  98. data/lib/mail/network/delivery_methods/smtp_connection.rb +61 -0
  99. data/lib/mail/network/delivery_methods/test_mailer.rb +44 -0
  100. data/lib/mail/network/retriever_methods/base.rb +63 -0
  101. data/lib/mail/network/retriever_methods/imap.rb +173 -0
  102. data/lib/mail/network/retriever_methods/pop3.rb +140 -0
  103. data/lib/mail/network/retriever_methods/test_retriever.rb +43 -0
  104. data/lib/mail/parsers.rb +26 -0
  105. data/lib/mail/parsers/address_lists_parser.rb +132 -0
  106. data/lib/mail/parsers/content_disposition_parser.rb +67 -0
  107. data/lib/mail/parsers/content_location_parser.rb +35 -0
  108. data/lib/mail/parsers/content_transfer_encoding_parser.rb +33 -0
  109. data/lib/mail/parsers/content_type_parser.rb +64 -0
  110. data/lib/mail/parsers/date_time_parser.rb +36 -0
  111. data/lib/mail/parsers/envelope_from_parser.rb +45 -0
  112. data/lib/mail/parsers/message_ids_parser.rb +39 -0
  113. data/lib/mail/parsers/mime_version_parser.rb +41 -0
  114. data/lib/mail/parsers/phrase_lists_parser.rb +33 -0
  115. data/lib/mail/parsers/ragel.rb +17 -0
  116. data/lib/mail/parsers/ragel/common.rl +184 -0
  117. data/lib/mail/parsers/ragel/date_time.rl +30 -0
  118. data/lib/mail/parsers/ragel/parser_info.rb +61 -0
  119. data/lib/mail/parsers/ragel/ruby.rb +39 -0
  120. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +14864 -0
  121. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +37 -0
  122. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +751 -0
  123. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +37 -0
  124. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +614 -0
  125. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +37 -0
  126. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +447 -0
  127. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +37 -0
  128. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +825 -0
  129. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +37 -0
  130. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +817 -0
  131. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +37 -0
  132. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +2129 -0
  133. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +37 -0
  134. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +1570 -0
  135. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +37 -0
  136. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +440 -0
  137. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +37 -0
  138. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +564 -0
  139. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +37 -0
  140. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +51 -0
  141. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +5144 -0
  142. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +37 -0
  143. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +37 -0
  144. data/lib/mail/parsers/received_parser.rb +47 -0
  145. data/lib/mail/part.rb +120 -0
  146. data/lib/mail/parts_list.rb +57 -0
  147. data/lib/mail/patterns.rb +37 -0
  148. data/lib/mail/utilities.rb +225 -0
  149. data/lib/mail/values/unicode_tables.dat +0 -0
  150. data/lib/mail/version.rb +4 -0
  151. data/lib/mail/version_specific/ruby_1_8.rb +119 -0
  152. data/lib/mail/version_specific/ruby_1_9.rb +159 -0
  153. 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
@@ -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