nano-fast-tool 0.0.1

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 (138) hide show
  1. checksums.yaml +7 -0
  2. data/mail-2.9.1/MIT-LICENSE +20 -0
  3. data/mail-2.9.1/README.md +771 -0
  4. data/mail-2.9.1/lib/mail/attachments_list.rb +109 -0
  5. data/mail-2.9.1/lib/mail/body.rb +305 -0
  6. data/mail-2.9.1/lib/mail/configuration.rb +78 -0
  7. data/mail-2.9.1/lib/mail/constants.rb +79 -0
  8. data/mail-2.9.1/lib/mail/elements/address.rb +258 -0
  9. data/mail-2.9.1/lib/mail/elements/address_list.rb +34 -0
  10. data/mail-2.9.1/lib/mail/elements/content_disposition_element.rb +20 -0
  11. data/mail-2.9.1/lib/mail/elements/content_location_element.rb +17 -0
  12. data/mail-2.9.1/lib/mail/elements/content_transfer_encoding_element.rb +13 -0
  13. data/mail-2.9.1/lib/mail/elements/content_type_element.rb +25 -0
  14. data/mail-2.9.1/lib/mail/elements/date_time_element.rb +15 -0
  15. data/mail-2.9.1/lib/mail/elements/envelope_from_element.rb +39 -0
  16. data/mail-2.9.1/lib/mail/elements/message_ids_element.rb +31 -0
  17. data/mail-2.9.1/lib/mail/elements/mime_version_element.rb +15 -0
  18. data/mail-2.9.1/lib/mail/elements/phrase_list.rb +19 -0
  19. data/mail-2.9.1/lib/mail/elements/received_element.rb +35 -0
  20. data/mail-2.9.1/lib/mail/elements.rb +15 -0
  21. data/mail-2.9.1/lib/mail/encodings/7bit.rb +27 -0
  22. data/mail-2.9.1/lib/mail/encodings/8bit.rb +18 -0
  23. data/mail-2.9.1/lib/mail/encodings/base64.rb +38 -0
  24. data/mail-2.9.1/lib/mail/encodings/binary.rb +13 -0
  25. data/mail-2.9.1/lib/mail/encodings/identity.rb +24 -0
  26. data/mail-2.9.1/lib/mail/encodings/quoted_printable.rb +45 -0
  27. data/mail-2.9.1/lib/mail/encodings/transfer_encoding.rb +77 -0
  28. data/mail-2.9.1/lib/mail/encodings/unix_to_unix.rb +20 -0
  29. data/mail-2.9.1/lib/mail/encodings.rb +314 -0
  30. data/mail-2.9.1/lib/mail/envelope.rb +28 -0
  31. data/mail-2.9.1/lib/mail/field.rb +313 -0
  32. data/mail-2.9.1/lib/mail/field_list.rb +87 -0
  33. data/mail-2.9.1/lib/mail/fields/bcc_field.rb +49 -0
  34. data/mail-2.9.1/lib/mail/fields/cc_field.rb +33 -0
  35. data/mail-2.9.1/lib/mail/fields/comments_field.rb +31 -0
  36. data/mail-2.9.1/lib/mail/fields/common_address_field.rb +162 -0
  37. data/mail-2.9.1/lib/mail/fields/common_date_field.rb +56 -0
  38. data/mail-2.9.1/lib/mail/fields/common_field.rb +77 -0
  39. data/mail-2.9.1/lib/mail/fields/common_message_id_field.rb +41 -0
  40. data/mail-2.9.1/lib/mail/fields/content_description_field.rb +12 -0
  41. data/mail-2.9.1/lib/mail/fields/content_disposition_field.rb +44 -0
  42. data/mail-2.9.1/lib/mail/fields/content_id_field.rb +35 -0
  43. data/mail-2.9.1/lib/mail/fields/content_location_field.rb +28 -0
  44. data/mail-2.9.1/lib/mail/fields/content_transfer_encoding_field.rb +44 -0
  45. data/mail-2.9.1/lib/mail/fields/content_type_field.rb +171 -0
  46. data/mail-2.9.1/lib/mail/fields/date_field.rb +28 -0
  47. data/mail-2.9.1/lib/mail/fields/from_field.rb +33 -0
  48. data/mail-2.9.1/lib/mail/fields/in_reply_to_field.rb +45 -0
  49. data/mail-2.9.1/lib/mail/fields/keywords_field.rb +30 -0
  50. data/mail-2.9.1/lib/mail/fields/message_id_field.rb +36 -0
  51. data/mail-2.9.1/lib/mail/fields/mime_version_field.rb +42 -0
  52. data/mail-2.9.1/lib/mail/fields/named_structured_field.rb +10 -0
  53. data/mail-2.9.1/lib/mail/fields/named_unstructured_field.rb +10 -0
  54. data/mail-2.9.1/lib/mail/fields/optional_field.rb +15 -0
  55. data/mail-2.9.1/lib/mail/fields/parameter_hash.rb +61 -0
  56. data/mail-2.9.1/lib/mail/fields/received_field.rb +61 -0
  57. data/mail-2.9.1/lib/mail/fields/references_field.rb +42 -0
  58. data/mail-2.9.1/lib/mail/fields/reply_to_field.rb +33 -0
  59. data/mail-2.9.1/lib/mail/fields/resent_bcc_field.rb +33 -0
  60. data/mail-2.9.1/lib/mail/fields/resent_cc_field.rb +33 -0
  61. data/mail-2.9.1/lib/mail/fields/resent_date_field.rb +10 -0
  62. data/mail-2.9.1/lib/mail/fields/resent_from_field.rb +33 -0
  63. data/mail-2.9.1/lib/mail/fields/resent_message_id_field.rb +10 -0
  64. data/mail-2.9.1/lib/mail/fields/resent_sender_field.rb +32 -0
  65. data/mail-2.9.1/lib/mail/fields/resent_to_field.rb +33 -0
  66. data/mail-2.9.1/lib/mail/fields/return_path_field.rb +60 -0
  67. data/mail-2.9.1/lib/mail/fields/sender_field.rb +45 -0
  68. data/mail-2.9.1/lib/mail/fields/structured_field.rb +24 -0
  69. data/mail-2.9.1/lib/mail/fields/subject_field.rb +14 -0
  70. data/mail-2.9.1/lib/mail/fields/to_field.rb +33 -0
  71. data/mail-2.9.1/lib/mail/fields/unstructured_field.rb +189 -0
  72. data/mail-2.9.1/lib/mail/fields.rb +45 -0
  73. data/mail-2.9.1/lib/mail/header.rb +237 -0
  74. data/mail-2.9.1/lib/mail/indifferent_hash.rb +147 -0
  75. data/mail-2.9.1/lib/mail/mail.rb +267 -0
  76. data/mail-2.9.1/lib/mail/matchers/attachment_matchers.rb +44 -0
  77. data/mail-2.9.1/lib/mail/matchers/has_sent_mail.rb +201 -0
  78. data/mail-2.9.1/lib/mail/message.rb +2159 -0
  79. data/mail-2.9.1/lib/mail/multibyte/chars.rb +318 -0
  80. data/mail-2.9.1/lib/mail/multibyte/unicode.rb +405 -0
  81. data/mail-2.9.1/lib/mail/multibyte/utils.rb +44 -0
  82. data/mail-2.9.1/lib/mail/multibyte.rb +82 -0
  83. data/mail-2.9.1/lib/mail/network/delivery_methods/exim.rb +50 -0
  84. data/mail-2.9.1/lib/mail/network/delivery_methods/file_delivery.rb +43 -0
  85. data/mail-2.9.1/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  86. data/mail-2.9.1/lib/mail/network/delivery_methods/sendmail.rb +87 -0
  87. data/mail-2.9.1/lib/mail/network/delivery_methods/smtp.rb +200 -0
  88. data/mail-2.9.1/lib/mail/network/delivery_methods/smtp_connection.rb +57 -0
  89. data/mail-2.9.1/lib/mail/network/delivery_methods/test_mailer.rb +44 -0
  90. data/mail-2.9.1/lib/mail/network/retriever_methods/base.rb +64 -0
  91. data/mail-2.9.1/lib/mail/network/retriever_methods/imap.rb +190 -0
  92. data/mail-2.9.1/lib/mail/network/retriever_methods/pop3.rb +143 -0
  93. data/mail-2.9.1/lib/mail/network/retriever_methods/test_retriever.rb +45 -0
  94. data/mail-2.9.1/lib/mail/network.rb +16 -0
  95. data/mail-2.9.1/lib/mail/parser_tools.rb +15 -0
  96. data/mail-2.9.1/lib/mail/parsers/address_lists_parser.rb +33245 -0
  97. data/mail-2.9.1/lib/mail/parsers/address_lists_parser.rl +183 -0
  98. data/mail-2.9.1/lib/mail/parsers/content_disposition_parser.rb +904 -0
  99. data/mail-2.9.1/lib/mail/parsers/content_disposition_parser.rl +93 -0
  100. data/mail-2.9.1/lib/mail/parsers/content_location_parser.rb +825 -0
  101. data/mail-2.9.1/lib/mail/parsers/content_location_parser.rl +82 -0
  102. data/mail-2.9.1/lib/mail/parsers/content_transfer_encoding_parser.rb +525 -0
  103. data/mail-2.9.1/lib/mail/parsers/content_transfer_encoding_parser.rl +75 -0
  104. data/mail-2.9.1/lib/mail/parsers/content_type_parser.rb +1051 -0
  105. data/mail-2.9.1/lib/mail/parsers/content_type_parser.rl +94 -0
  106. data/mail-2.9.1/lib/mail/parsers/date_time_parser.rb +894 -0
  107. data/mail-2.9.1/lib/mail/parsers/date_time_parser.rl +73 -0
  108. data/mail-2.9.1/lib/mail/parsers/envelope_from_parser.rb +3678 -0
  109. data/mail-2.9.1/lib/mail/parsers/envelope_from_parser.rl +93 -0
  110. data/mail-2.9.1/lib/mail/parsers/message_ids_parser.rb +5164 -0
  111. data/mail-2.9.1/lib/mail/parsers/message_ids_parser.rl +97 -0
  112. data/mail-2.9.1/lib/mail/parsers/mime_version_parser.rb +516 -0
  113. data/mail-2.9.1/lib/mail/parsers/mime_version_parser.rl +72 -0
  114. data/mail-2.9.1/lib/mail/parsers/phrase_lists_parser.rb +887 -0
  115. data/mail-2.9.1/lib/mail/parsers/phrase_lists_parser.rl +94 -0
  116. data/mail-2.9.1/lib/mail/parsers/received_parser.rb +8785 -0
  117. data/mail-2.9.1/lib/mail/parsers/received_parser.rl +95 -0
  118. data/mail-2.9.1/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  119. data/mail-2.9.1/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  120. data/mail-2.9.1/lib/mail/parsers/rfc2045_mime.rl +16 -0
  121. data/mail-2.9.1/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  122. data/mail-2.9.1/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  123. data/mail-2.9.1/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  124. data/mail-2.9.1/lib/mail/parsers/rfc5322.rl +74 -0
  125. data/mail-2.9.1/lib/mail/parsers/rfc5322_address.rl +72 -0
  126. data/mail-2.9.1/lib/mail/parsers/rfc5322_date_time.rl +37 -0
  127. data/mail-2.9.1/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  128. data/mail-2.9.1/lib/mail/parsers.rb +13 -0
  129. data/mail-2.9.1/lib/mail/part.rb +119 -0
  130. data/mail-2.9.1/lib/mail/parts_list.rb +131 -0
  131. data/mail-2.9.1/lib/mail/smtp_envelope.rb +57 -0
  132. data/mail-2.9.1/lib/mail/utilities.rb +576 -0
  133. data/mail-2.9.1/lib/mail/values/unicode_tables.dat +0 -0
  134. data/mail-2.9.1/lib/mail/version.rb +17 -0
  135. data/mail-2.9.1/lib/mail/yaml.rb +30 -0
  136. data/mail-2.9.1/lib/mail.rb +65 -0
  137. data/nano-fast-tool.gemspec +12 -0
  138. metadata +177 -0
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+ require 'mail/smtp_envelope'
3
+
4
+ module Mail
5
+ # A delivery method implementation which sends via sendmail.
6
+ #
7
+ # To use this, first find out where the sendmail binary is on your computer,
8
+ # if you are on a mac or unix box, it is usually in /usr/sbin/sendmail, this will
9
+ # be your sendmail location.
10
+ #
11
+ # Mail.defaults do
12
+ # delivery_method :sendmail
13
+ # end
14
+ #
15
+ # Or if your sendmail binary is not at '/usr/sbin/sendmail'
16
+ #
17
+ # Mail.defaults do
18
+ # delivery_method :sendmail, :location => '/absolute/path/to/your/sendmail'
19
+ # end
20
+ #
21
+ # Then just deliver the email as normal:
22
+ #
23
+ # Mail.deliver do
24
+ # to 'mikel@test.lindsaar.net'
25
+ # from 'ada@test.lindsaar.net'
26
+ # subject 'testing sendmail'
27
+ # body 'testing sendmail'
28
+ # end
29
+ #
30
+ # Or by calling deliver on a Mail message
31
+ #
32
+ # mail = Mail.new do
33
+ # to 'mikel@test.lindsaar.net'
34
+ # from 'ada@test.lindsaar.net'
35
+ # subject 'testing sendmail'
36
+ # body 'testing sendmail'
37
+ # end
38
+ #
39
+ # mail.deliver!
40
+ class Sendmail
41
+ DEFAULTS = {
42
+ :location => '/usr/sbin/sendmail',
43
+ :arguments => %w[ -i ]
44
+ }
45
+
46
+ attr_accessor :settings
47
+
48
+ class DeliveryError < StandardError
49
+ end
50
+
51
+ def initialize(values)
52
+ self.settings = self.class::DEFAULTS.merge(values)
53
+ raise ArgumentError, ":arguments expected to be an Array of individual string args" if settings[:arguments].is_a?(String)
54
+ end
55
+
56
+ def destinations_for(envelope)
57
+ envelope.to
58
+ end
59
+
60
+ def deliver!(mail)
61
+ envelope = Mail::SmtpEnvelope.new(mail)
62
+
63
+ command = [settings[:location]]
64
+ command.concat Array(settings[:arguments])
65
+ command.concat [ '-f', envelope.from ] if envelope.from
66
+
67
+ if destinations = destinations_for(envelope)
68
+ command.push '--'
69
+ command.concat destinations
70
+ end
71
+
72
+ popen(command) do |io|
73
+ io.puts ::Mail::Utilities.binary_unsafe_to_lf(envelope.message)
74
+ io.flush
75
+ end
76
+ end
77
+
78
+ private
79
+ def popen(command, &block)
80
+ IO.popen(command, 'w+', :err => :out, &block).tap do
81
+ if $?.exitstatus != 0
82
+ raise DeliveryError, "Delivery failed with exitstatus #{$?.exitstatus}: #{command.inspect}"
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+ require 'mail/smtp_envelope'
3
+
4
+ module Mail
5
+ # == Sending Email with SMTP
6
+ #
7
+ # Mail allows you to send emails using SMTP. This is done by wrapping Net::SMTP in
8
+ # an easy to use manner.
9
+ #
10
+ # === Sending via SMTP server on Localhost
11
+ #
12
+ # Sending locally (to a postfix or sendmail server running on localhost) requires
13
+ # no special setup. Just to Mail.deliver &block or message.deliver! and it will
14
+ # be sent in this method.
15
+ #
16
+ # === Sending via MobileMe
17
+ #
18
+ # Mail.defaults do
19
+ # delivery_method :smtp, { :address => "smtp.me.com",
20
+ # :port => 587,
21
+ # :domain => 'your.host.name',
22
+ # :user_name => '<username>',
23
+ # :password => '<password>',
24
+ # :authentication => 'plain',
25
+ # :enable_starttls => :auto }
26
+ # end
27
+ #
28
+ # === Sending via GMail
29
+ #
30
+ # Mail.defaults do
31
+ # delivery_method :smtp, { :address => "smtp.gmail.com",
32
+ # :port => 587,
33
+ # :domain => 'your.host.name',
34
+ # :user_name => '<username>',
35
+ # :password => '<password>',
36
+ # :authentication => 'plain',
37
+ # :enable_starttls => :auto }
38
+ # end
39
+ #
40
+ # === Configuring TLS/SSL and STARTTLS
41
+ #
42
+ # A few remarks:
43
+ # - when enabling `tls` (or `ssl`), setting (truthy values for) either `enable_starttls` or `enable_starttls_auto` will raise an ArgumentError as TLS and STARTTLS are mutually exclusive.
44
+ # - to configure STARTTLS, use the `enable_starttls`-flag (instead of a combination of `enable_starttls` and `enable_starttls_auto`). Acceptable values are `:always`, `:auto` and `false`.
45
+ # - when providing a truthy value for `enable_starttls`, the `enable_starttls_auto`-flag will be ignored.
46
+ # - when none of `tls`, `ssl`, `enable_starttls` or `enable_starttls_auto` is set, the fallback will be `enable_starttls` `:auto`.
47
+ #
48
+ # === Certificate verification
49
+ #
50
+ # When using TLS, some mail servers provide certificates that are self-signed
51
+ # or whose names do not exactly match the hostname given in the address.
52
+ # OpenSSL will reject these by default. The best remedy is to use the correct
53
+ # hostname or update the certificate authorities trusted by your ruby. If
54
+ # that isn't possible, you can control this behavior with
55
+ # an :openssl_verify_mode setting. Its value may be either an OpenSSL
56
+ # verify mode constant (OpenSSL::SSL::VERIFY_NONE, OpenSSL::SSL::VERIFY_PEER),
57
+ # or a string containing the name of an OpenSSL verify mode (none, peer).
58
+ #
59
+ # === Others
60
+ #
61
+ # Feel free to send me other examples that were tricky
62
+ #
63
+ # === Delivering the email
64
+ #
65
+ # Once you have the settings right, sending the email is done by:
66
+ #
67
+ # Mail.deliver do
68
+ # to 'mikel@test.lindsaar.net'
69
+ # from 'ada@test.lindsaar.net'
70
+ # subject 'testing sendmail'
71
+ # body 'testing sendmail'
72
+ # end
73
+ #
74
+ # Or by calling deliver on a Mail message
75
+ #
76
+ # mail = Mail.new do
77
+ # to 'mikel@test.lindsaar.net'
78
+ # from 'ada@test.lindsaar.net'
79
+ # subject 'testing sendmail'
80
+ # body 'testing sendmail'
81
+ # end
82
+ #
83
+ # mail.deliver!
84
+ class SMTP
85
+ attr_accessor :settings
86
+
87
+ DEFAULTS = {
88
+ :address => 'localhost',
89
+ :port => 25,
90
+ :domain => 'localhost.localdomain',
91
+ :user_name => nil,
92
+ :password => nil,
93
+ :authentication => nil,
94
+ :enable_starttls => nil,
95
+ :enable_starttls_auto => nil,
96
+ :openssl_verify_mode => nil,
97
+ :ssl => nil,
98
+ :tls => nil,
99
+ :open_timeout => 5,
100
+ :read_timeout => 5
101
+ }
102
+
103
+ def initialize(values)
104
+ self.settings = DEFAULTS.merge(values)
105
+ end
106
+
107
+ def deliver!(mail)
108
+ response = start_smtp_session do |smtp|
109
+ Mail::SMTPConnection.new(:connection => smtp, :return_response => true).deliver!(mail)
110
+ end
111
+
112
+ settings[:return_response] ? response : self
113
+ end
114
+
115
+ private
116
+ # `k` is said to be provided when `settings` has a non-nil value for `k`.
117
+ def setting_provided?(k)
118
+ !settings[k].nil?
119
+ end
120
+
121
+ # Yields one of `:always`, `:auto` or `false` based on `enable_starttls` and `enable_starttls_auto` flags.
122
+ # Yields `false` when `smtp_tls?`.
123
+ # Else defaults to `:auto` when neither `enable_starttls*` flag is provided.
124
+ # Providing a truthy value for `enable_starttls` will ignore `enable_starttls_auto`.
125
+ def smtp_starttls
126
+ return false if smtp_tls?
127
+
128
+ if setting_provided?(:enable_starttls) && settings[:enable_starttls]
129
+ # enable_starttls: provided and truthy
130
+ case settings[:enable_starttls]
131
+ when :auto then :auto
132
+ when :always then :always
133
+ else
134
+ :always
135
+ end
136
+ else
137
+ # enable_starttls: not provided or false
138
+ if setting_provided?(:enable_starttls_auto)
139
+ settings[:enable_starttls_auto] ? :auto : false
140
+ else
141
+ # enable_starttls_auto: not provided
142
+ # enable_starttls: when provided then false
143
+ # use :auto when neither enable_starttls* provided
144
+ setting_provided?(:enable_starttls) ? false : :auto
145
+ end
146
+ end
147
+ end
148
+
149
+ def smtp_tls?
150
+ (setting_provided?(:tls) && settings[:tls]) || (setting_provided?(:ssl) && settings[:ssl])
151
+ end
152
+
153
+ def start_smtp_session(&block)
154
+ build_smtp_session.start(settings[:domain], settings[:user_name], settings[:password], settings[:authentication], &block)
155
+ end
156
+
157
+ def build_smtp_session
158
+ if smtp_tls? && (settings[:enable_starttls] || settings[:enable_starttls_auto])
159
+ raise ArgumentError, ":enable_starttls and :tls are mutually exclusive. Set :tls if you're on an SMTPS connection. Set :enable_starttls if you're on an SMTP connection and using STARTTLS for secure TLS upgrade."
160
+ end
161
+
162
+ Net::SMTP.new(settings[:address], settings[:port]).tap do |smtp|
163
+ if smtp_tls?
164
+ smtp.disable_starttls
165
+ smtp.enable_tls(ssl_context)
166
+ else
167
+ smtp.disable_tls
168
+
169
+ case smtp_starttls
170
+ when :always
171
+ smtp.enable_starttls(ssl_context)
172
+ when :auto
173
+ smtp.enable_starttls_auto(ssl_context)
174
+ else
175
+ smtp.disable_starttls
176
+ end
177
+ end
178
+
179
+ smtp.open_timeout = settings[:open_timeout] if settings[:open_timeout]
180
+ smtp.read_timeout = settings[:read_timeout] if settings[:read_timeout]
181
+ end
182
+ end
183
+
184
+ # Allow SSL context to be configured via settings, for Ruby >= 1.9
185
+ # Just returns openssl verify mode for Ruby 1.8.x
186
+ def ssl_context
187
+ openssl_verify_mode = settings[:openssl_verify_mode]
188
+
189
+ if openssl_verify_mode.kind_of?(String)
190
+ openssl_verify_mode = OpenSSL::SSL.const_get("VERIFY_#{openssl_verify_mode.upcase}")
191
+ end
192
+
193
+ context = Net::SMTP.default_ssl_context
194
+ context.verify_mode = openssl_verify_mode if openssl_verify_mode
195
+ context.ca_path = settings[:ca_path] if settings[:ca_path]
196
+ context.ca_file = settings[:ca_file] if settings[:ca_file]
197
+ context
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+ require 'mail/smtp_envelope'
3
+
4
+ module Mail
5
+ # == Sending Email with SMTP
6
+ #
7
+ # Mail allows you to send emails using an open SMTP connection. This is done by
8
+ # passing a created Net::SMTP object. This way we can get better performance to
9
+ # our local mail server by reducing the number of connections at any one time.
10
+ #
11
+ # === Sending via SMTP server on Localhost
12
+ #
13
+ # To send mail open a connection with Net::Smtp using any options you like
14
+ # === Delivering the email
15
+ #
16
+ # Once you have the settings right, sending the email is done by:
17
+ #
18
+ # smtp_conn = Net::SMTP.start(settings[:address], settings[:port])
19
+ # Mail.defaults do
20
+ # delivery_method :smtp_connection, { :connection => smtp_conn }
21
+ # end
22
+ #
23
+ # Mail.deliver do
24
+ # to 'mikel@test.lindsaar.net'
25
+ # from 'ada@test.lindsaar.net'
26
+ # subject 'testing sendmail'
27
+ # body 'testing sendmail'
28
+ # end
29
+ #
30
+ # Or by calling deliver on a Mail message
31
+ #
32
+ # mail = Mail.new do
33
+ # to 'mikel@test.lindsaar.net'
34
+ # from 'ada@test.lindsaar.net'
35
+ # subject 'testing sendmail'
36
+ # body 'testing sendmail'
37
+ # end
38
+ #
39
+ # mail.deliver!
40
+ class SMTPConnection
41
+ attr_accessor :smtp, :settings
42
+
43
+ def initialize(values)
44
+ raise ArgumentError.new('A Net::SMTP object is required for this delivery method') if values[:connection].nil?
45
+ self.smtp = values[:connection]
46
+ self.settings = values
47
+ end
48
+
49
+ # Send the message via SMTP.
50
+ # The from and to attributes are optional. If not set, they are retrieve from the Message.
51
+ def deliver!(mail)
52
+ envelope = Mail::SmtpEnvelope.new(mail)
53
+ response = smtp.sendmail(envelope.message, envelope.from, envelope.to)
54
+ settings[:return_response] ? response : self
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ require 'mail/smtp_envelope'
3
+
4
+ module Mail
5
+ # The TestMailer is a bare bones mailer that does nothing. It is useful
6
+ # when you are testing.
7
+ #
8
+ # It also provides a template of the minimum methods you require to implement
9
+ # if you want to make a custom mailer for Mail
10
+ class TestMailer
11
+ # Provides a store of all the emails sent with the TestMailer so you can check them.
12
+ def self.deliveries
13
+ @@deliveries ||= []
14
+ end
15
+
16
+ # Allows you to over write the default deliveries store from an array to some
17
+ # other object. If you just want to clear the store,
18
+ # call TestMailer.deliveries.clear.
19
+ #
20
+ # If you place another object here, please make sure it responds to:
21
+ #
22
+ # * << (message)
23
+ # * clear
24
+ # * length
25
+ # * size
26
+ # * and other common Array methods
27
+ def self.deliveries=(val)
28
+ @@deliveries = val
29
+ end
30
+
31
+ attr_accessor :settings
32
+
33
+ def initialize(values)
34
+ @settings = values.dup
35
+ end
36
+
37
+ def deliver!(mail)
38
+ # Create the envelope to validate it
39
+ Mail::SmtpEnvelope.new(mail)
40
+
41
+ Mail::TestMailer.deliveries << mail
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Mail
5
+
6
+ class Retriever
7
+
8
+ # Get the oldest received email(s)
9
+ #
10
+ # Possible options:
11
+ # count: number of emails to retrieve. The default value is 1.
12
+ # order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
13
+ #
14
+ def first(options = nil, &block)
15
+ options = options ? Hash[options] : {}
16
+ options[:what] = :first
17
+ options[:count] ||= 1
18
+ find(options, &block)
19
+ end
20
+
21
+ # Get the most recent received email(s)
22
+ #
23
+ # Possible options:
24
+ # count: number of emails to retrieve. The default value is 1.
25
+ # order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
26
+ #
27
+ def last(options = nil, &block)
28
+ options = options ? Hash[options] : {}
29
+ options[:what] = :last
30
+ options[:count] ||= 1
31
+ find(options, &block)
32
+ end
33
+
34
+ # Get all emails.
35
+ #
36
+ # Possible options:
37
+ # order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
38
+ #
39
+ def all(options = nil, &block)
40
+ options = options ? Hash[options] : {}
41
+ options[:count] = :all
42
+ find(options, &block)
43
+ end
44
+
45
+ # Find emails in the mailbox, and then deletes them. Without any options, the
46
+ # five last received emails are returned.
47
+ #
48
+ # Possible options:
49
+ # what: last or first emails. The default is :first.
50
+ # order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
51
+ # count: number of emails to retrieve. The default value is 10. A value of 1 returns an
52
+ # instance of Message, not an array of Message instances.
53
+ # delete_after_find: flag for whether to delete each retreived email after find. Default
54
+ # is true. Call #find if you would like this to default to false.
55
+ #
56
+ def find_and_delete(options = nil, &block)
57
+ options = options ? Hash[options] : {}
58
+ options[:delete_after_find] ||= true
59
+ find(options, &block)
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,190 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module Mail
5
+ # The IMAP retriever allows to get the last, first or all emails from a IMAP server.
6
+ # Each email retrieved (RFC2822) is given as an instance of +Message+.
7
+ #
8
+ # While being retrieved, emails can be yielded if a block is given.
9
+ #
10
+ # === Example of retrieving Emails from GMail:
11
+ #
12
+ # Mail.defaults do
13
+ # retriever_method :imap, { :address => "imap.googlemail.com",
14
+ # :port => 993,
15
+ # :user_name => '<username>',
16
+ # :password => '<password>',
17
+ # :enable_ssl => true }
18
+ # end
19
+ #
20
+ # Mail.all #=> Returns an array of all emails
21
+ # Mail.first #=> Returns the first unread email
22
+ # Mail.last #=> Returns the last unread email
23
+ #
24
+ # You can also pass options into Mail.find to locate an email in your imap mailbox
25
+ # with the following options:
26
+ #
27
+ # mailbox: name of the mailbox used for email retrieval. The default is 'INBOX'.
28
+ # what: last or first emails. The default is :first.
29
+ # order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
30
+ # count: number of emails to retrieve. The default value is 10. A value of 1 returns an
31
+ # instance of Message, not an array of Message instances.
32
+ # keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
33
+ # or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
34
+ # The default is 'ALL'
35
+ #
36
+ # Mail.find(:what => :first, :count => 10, :order => :asc, :keys=>'ALL')
37
+ # #=> Returns the first 10 emails in ascending order
38
+ #
39
+ class IMAP < Retriever
40
+ require 'net/imap' unless defined?(Net::IMAP)
41
+
42
+ def initialize(values)
43
+ self.settings = { :address => "localhost",
44
+ :port => 143,
45
+ :user_name => nil,
46
+ :password => nil,
47
+ :authentication => nil,
48
+ :enable_ssl => false,
49
+ :enable_starttls => false }.merge!(values)
50
+ end
51
+
52
+ attr_accessor :settings
53
+
54
+ # Find emails in a IMAP mailbox. Without any options, the 10 last received emails are returned.
55
+ #
56
+ # Possible options:
57
+ # mailbox: mailbox to search the email(s) in. The default is 'INBOX'.
58
+ # what: last or first emails. The default is :first.
59
+ # order: order of emails returned. Possible values are :asc or :desc. Default value is :asc.
60
+ # count: number of emails to retrieve. The default value is 10. A value of 1 returns an
61
+ # instance of Message, not an array of Message instances.
62
+ # read_only: will ensure that no writes are made to the inbox during the session. Specifically, if this is
63
+ # set to true, the code will use the EXAMINE command to retrieve the mail. If set to false, which
64
+ # is the default, a SELECT command will be used to retrieve the mail
65
+ # This is helpful when you don't want your messages to be set to read automatically. Default is false.
66
+ # delete_after_find: flag for whether to delete each retreived email after find. Default
67
+ # is false. Use #find_and_delete if you would like this to default to true.
68
+ # keys: are passed as criteria to the SEARCH command. They can either be a string holding the entire search string,
69
+ # or a single-dimension array of search keywords and arguments. Refer to [IMAP] section 6.4.4 for a full list
70
+ # The default is 'ALL'
71
+ # search_charset: charset to pass to IMAP server search. Omitted by default. Example: 'UTF-8' or 'ASCII'.
72
+ #
73
+ def find(options=nil, &block)
74
+ options = validate_options(options)
75
+
76
+ start do |imap|
77
+ options[:read_only] ? imap.examine(options[:mailbox]) : imap.select(options[:mailbox])
78
+
79
+ uids = imap.uid_search(options[:keys], options[:search_charset])
80
+ .to_a # older net-imap may return nil, newer may return ESearchResult struct
81
+ .sort # RFC3501 does _not_ require UIDs to be returned in order
82
+ uids.reverse! if options[:what].to_sym == :last
83
+ uids = uids.first(options[:count]) if options[:count].is_a?(Integer)
84
+ uids.reverse! if (options[:what].to_sym == :last && options[:order].to_sym == :asc) ||
85
+ (options[:what].to_sym != :last && options[:order].to_sym == :desc)
86
+
87
+ if block_given?
88
+ uids.each do |uid|
89
+ uid = options[:uid].to_i unless options[:uid].nil?
90
+ fetchdata = imap.uid_fetch(uid, ['RFC822', 'FLAGS'])[0]
91
+ new_message = Mail.new(fetchdata.attr['RFC822'])
92
+ new_message.mark_for_delete = true if options[:delete_after_find]
93
+
94
+ if block.arity == 4
95
+ yield new_message, imap, uid, fetchdata.attr['FLAGS']
96
+ elsif block.arity == 3
97
+ yield new_message, imap, uid
98
+ else
99
+ yield new_message
100
+ end
101
+
102
+ imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find] && new_message.is_marked_for_delete?
103
+ break unless options[:uid].nil?
104
+ end
105
+ imap.expunge if options[:delete_after_find]
106
+ else
107
+ emails = []
108
+ uids.each do |uid|
109
+ uid = options[:uid].to_i unless options[:uid].nil?
110
+ fetchdata = imap.uid_fetch(uid, ['RFC822'])[0]
111
+ emails << Mail.new(fetchdata.attr['RFC822'])
112
+ imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED]) if options[:delete_after_find]
113
+ break unless options[:uid].nil?
114
+ end
115
+ imap.expunge if options[:delete_after_find]
116
+ emails.size == 1 && options[:count] == 1 ? emails.first : emails
117
+ end
118
+ end
119
+ end
120
+
121
+ # Delete all emails from a IMAP mailbox
122
+ def delete_all(mailbox='INBOX')
123
+ mailbox ||= 'INBOX'
124
+ mailbox = Net::IMAP.encode_utf7(mailbox)
125
+
126
+ start do |imap|
127
+ imap.select(mailbox)
128
+ imap.uid_search(['ALL']).each do |uid|
129
+ imap.uid_store(uid, "+FLAGS", [Net::IMAP::DELETED])
130
+ end
131
+ imap.expunge
132
+ end
133
+ end
134
+
135
+ # Returns the connection object of the retrievable (IMAP or POP3)
136
+ def connection(&block)
137
+ raise ArgumentError.new('Mail::Retrievable#connection takes a block') unless block_given?
138
+
139
+ start do |imap|
140
+ yield imap
141
+ end
142
+ end
143
+
144
+ private
145
+
146
+ # Set default options
147
+ def validate_options(options)
148
+ options = options ? Hash[options] : {}
149
+ options[:mailbox] ||= 'INBOX'
150
+ options[:count] ||= 10
151
+ options[:order] ||= :asc
152
+ options[:what] ||= :first
153
+ options[:keys] ||= 'ALL'
154
+ options[:uid] ||= nil
155
+ options[:delete_after_find] ||= false
156
+ options[:mailbox] = Net::IMAP.encode_utf7(options[:mailbox])
157
+ options[:read_only] ||= false
158
+
159
+ options
160
+ end
161
+
162
+ # Start an IMAP session and ensures that it will be closed in any case.
163
+ def start(config=Mail::Configuration.instance, &block)
164
+ raise ArgumentError.new("Mail::Retrievable#imap_start takes a block") unless block_given?
165
+
166
+ if settings[:enable_starttls] && settings[:enable_ssl]
167
+ raise ArgumentError, ":enable_starttls and :enable_ssl are mutually exclusive. Set :enable_ssl if you're on an IMAPS connection. Set :enable_starttls if you're on an IMAP connection and using STARTTLS for secure TLS upgrade."
168
+ end
169
+
170
+ imap = Net::IMAP.new(settings[:address], settings[:port], settings[:enable_ssl], nil, false)
171
+
172
+ imap.starttls if settings[:enable_starttls]
173
+
174
+ if settings[:authentication].nil?
175
+ imap.login(settings[:user_name], settings[:password])
176
+ else
177
+ # Note that Net::IMAP#authenticate('LOGIN', ...) is not equal with Net::IMAP#login(...)!
178
+ # (see also http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/net/imap/rdoc/classes/Net/IMAP.html#M000718)
179
+ imap.authenticate(settings[:authentication], settings[:user_name], settings[:password])
180
+ end
181
+
182
+ yield imap
183
+ ensure
184
+ if defined?(imap) && imap && !imap.disconnected?
185
+ imap.disconnect
186
+ end
187
+ end
188
+
189
+ end
190
+ end