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,109 @@
1
+ # frozen_string_literal: true
2
+ module Mail
3
+ class AttachmentsList < Array
4
+
5
+ def initialize(parts_list)
6
+ @parts_list = parts_list
7
+ @content_disposition_type = 'attachment'
8
+ parts_list.map { |p|
9
+ if p.mime_type == 'message/rfc822'
10
+ parts = []
11
+ parts << p if p.attachment?
12
+ parts.concat Mail.new(p.body.encoded).attachments
13
+ elsif p.parts.empty?
14
+ p if p.attachment?
15
+ else
16
+ p.attachments
17
+ end
18
+ }.flatten.compact.each { |a| self << a }
19
+ self
20
+ end
21
+
22
+ def inline
23
+ @content_disposition_type = 'inline'
24
+ self
25
+ end
26
+
27
+ # Returns the attachment by filename or at index.
28
+ #
29
+ # mail.attachments['test.png'] = File.read('test.png')
30
+ # mail.attachments['test.jpg'] = File.read('test.jpg')
31
+ #
32
+ # mail.attachments['test.png'].filename #=> 'test.png'
33
+ # mail.attachments[1].filename #=> 'test.jpg'
34
+ def [](index_value)
35
+ if index_value.is_a?(Integer)
36
+ self.fetch(index_value)
37
+ else
38
+ self.select { |a| a.filename == index_value }.first
39
+ end
40
+ end
41
+
42
+ def []=(name, value)
43
+ encoded_name = Mail::Encodings.decode_encode name, :encode
44
+ default_values = { :content_type => "#{set_mime_type(name)}; filename=\"#{encoded_name}\"",
45
+ :content_transfer_encoding => "#{guess_encoding}",
46
+ :content_disposition => "#{@content_disposition_type}; filename=\"#{encoded_name}\"" }
47
+
48
+ if value.is_a?(Hash)
49
+ if path = value.delete(:filename)
50
+ value[:content] ||= File.open(path, 'rb') { |f| f.read }
51
+ end
52
+
53
+ default_values[:body] = value.delete(:content) if value[:content]
54
+
55
+ default_values[:body] = value.delete(:data) if value[:data]
56
+
57
+ encoding = value.delete(:transfer_encoding) || value.delete(:encoding)
58
+ if encoding
59
+ if Mail::Encodings.defined? encoding
60
+ default_values[:content_transfer_encoding] = encoding
61
+ else
62
+ raise "Do not know how to handle Content Transfer Encoding #{encoding}, please choose either quoted-printable or base64"
63
+ end
64
+ end
65
+
66
+ if value[:mime_type]
67
+ default_values[:content_type] = value.delete(:mime_type)
68
+ @mime_type = MiniMime.lookup_by_content_type(default_values[:content_type])
69
+ default_values[:content_transfer_encoding] ||= guess_encoding
70
+ end
71
+
72
+ hash = default_values.merge(value)
73
+ else
74
+ default_values[:body] = value
75
+ hash = default_values
76
+ end
77
+
78
+ if hash[:body].respond_to? :force_encoding and hash[:body].respond_to? :valid_encoding?
79
+ if not hash[:body].valid_encoding? and default_values[:content_transfer_encoding].casecmp('binary').zero?
80
+ hash[:body] = hash[:body].dup if hash[:body].frozen?
81
+ hash[:body].force_encoding("BINARY")
82
+ end
83
+ end
84
+
85
+ attachment = Part.new(hash)
86
+ attachment.add_content_id(hash[:content_id])
87
+
88
+ @parts_list << attachment
89
+ end
90
+
91
+ # Uses the mime type to try and guess the encoding, if it is a binary type, or unknown, then we
92
+ # set it to binary, otherwise as set to plain text
93
+ def guess_encoding
94
+ if @mime_type && !@mime_type.binary?
95
+ "7bit"
96
+ else
97
+ "binary"
98
+ end
99
+ end
100
+
101
+ def set_mime_type(filename)
102
+ filename = filename.encode(Encoding::UTF_8) if filename.respond_to?(:encode)
103
+
104
+ @mime_type = MiniMime.lookup_by_filename(filename)
105
+ @mime_type && @mime_type.content_type
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,305 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module Mail
4
+
5
+ # = Body
6
+ #
7
+ # The body is where the text of the email is stored. Mail treats the body
8
+ # as a single object. The body itself has no information about boundaries
9
+ # used in the MIME standard, it just looks at its content as either a single
10
+ # block of text, or (if it is a multipart message) as an array of blocks of text.
11
+ #
12
+ # A body has to be told to split itself up into a multipart message by calling
13
+ # #split with the correct boundary. This is because the body object has no way
14
+ # of knowing what the correct boundary is for itself (there could be many
15
+ # boundaries in a body in the case of a nested MIME text).
16
+ #
17
+ # Once split is called, Mail::Body will slice itself up on this boundary,
18
+ # assigning anything that appears before the first part to the preamble, and
19
+ # anything that appears after the closing boundary to the epilogue, then
20
+ # each part gets initialized into a Mail::Part object.
21
+ #
22
+ # The boundary that is used to split up the Body is also stored in the Body
23
+ # object for use on encoding itself back out to a string. You can
24
+ # overwrite this if it needs to be changed.
25
+ #
26
+ # On encoding, the body will return the preamble, then each part joined by
27
+ # the boundary, followed by a closing boundary string and then the epilogue.
28
+ class Body
29
+
30
+ def initialize(string = '')
31
+ @boundary = nil
32
+ @preamble = nil
33
+ @epilogue = nil
34
+ @charset = nil
35
+ @part_sort_order = [ "text/plain", "text/enriched", "text/html", "multipart/alternative" ]
36
+ @parts = Mail::PartsList.new
37
+ if Utilities.blank?(string)
38
+ @raw_source = ''
39
+ else
40
+ # Do join first incase we have been given an Array in Ruby 1.9
41
+ if string.respond_to?(:join)
42
+ @raw_source = string.join('')
43
+ elsif string.respond_to?(:to_s)
44
+ @raw_source = string.to_s
45
+ else
46
+ raise "You can only assign a string or an object that responds_to? :join or :to_s to a body."
47
+ end
48
+ end
49
+ @encoding = default_encoding
50
+ set_charset
51
+ end
52
+
53
+ def init_with(coder)
54
+ coder.map.each { |k, v| instance_variable_set(:"@#{k}", v) }
55
+ @parts = Mail::PartsList.new(coder['parts'])
56
+ end
57
+
58
+ # Matches this body with another body. Also matches the decoded value of this
59
+ # body with a string.
60
+ #
61
+ # Examples:
62
+ #
63
+ # body = Mail::Body.new('The body')
64
+ # body == body #=> true
65
+ #
66
+ # body = Mail::Body.new('The body')
67
+ # body == 'The body' #=> true
68
+ #
69
+ # body = Mail::Body.new("VGhlIGJvZHk=\n")
70
+ # body.encoding = 'base64'
71
+ # body == "The body" #=> true
72
+ def ==(other)
73
+ if other.class == String
74
+ self.decoded == other
75
+ else
76
+ super
77
+ end
78
+ end
79
+
80
+ # Accepts a string and performs a regular expression against the decoded text
81
+ #
82
+ # Examples:
83
+ #
84
+ # body = Mail::Body.new('The body')
85
+ # body =~ /The/ #=> 0
86
+ #
87
+ # body = Mail::Body.new("VGhlIGJvZHk=\n")
88
+ # body.encoding = 'base64'
89
+ # body =~ /The/ #=> 0
90
+ def =~(regexp)
91
+ self.decoded =~ regexp
92
+ end
93
+
94
+ # Accepts a string and performs a regular expression against the decoded text
95
+ #
96
+ # Examples:
97
+ #
98
+ # body = Mail::Body.new('The body')
99
+ # body.match(/The/) #=> #<MatchData "The">
100
+ #
101
+ # body = Mail::Body.new("VGhlIGJvZHk=\n")
102
+ # body.encoding = 'base64'
103
+ # body.match(/The/) #=> #<MatchData "The">
104
+ def match(regexp)
105
+ self.decoded.match(regexp)
106
+ end
107
+
108
+ # Accepts anything that responds to #to_s and checks if it's a substring of the decoded text
109
+ #
110
+ # Examples:
111
+ #
112
+ # body = Mail::Body.new('The body')
113
+ # body.include?('The') #=> true
114
+ #
115
+ # body = Mail::Body.new("VGhlIGJvZHk=\n")
116
+ # body.encoding = 'base64'
117
+ # body.include?('The') #=> true
118
+ def include?(other)
119
+ self.decoded.include?(other.to_s)
120
+ end
121
+
122
+ # Allows you to set the sort order of the parts, overriding the default sort order.
123
+ # Defaults to 'text/plain', then 'text/enriched', then 'text/html', then 'multipart/alternative'
124
+ # with any other content type coming after.
125
+ def set_sort_order(order)
126
+ @part_sort_order = order
127
+ end
128
+
129
+ # Allows you to sort the parts according to the default sort order, or the sort order you
130
+ # set with :set_sort_order.
131
+ #
132
+ # sort_parts! is also called from :encode, so there is no need for you to call this explicitly
133
+ def sort_parts!
134
+ @parts.each do |p|
135
+ p.body.set_sort_order(@part_sort_order)
136
+ p.body.sort_parts!
137
+ end
138
+ @parts.sort!(@part_sort_order)
139
+ end
140
+
141
+ def negotiate_best_encoding(message_encoding, allowed_encodings = nil)
142
+ Mail::Encodings::TransferEncoding.negotiate(message_encoding, encoding, raw_source, allowed_encodings)
143
+ end
144
+
145
+ # Returns a body encoded using transfer_encoding. Multipart always uses an
146
+ # identiy encoding (i.e. no encoding).
147
+ # Calling this directly is not a good idea, but supported for compatibility
148
+ # TODO: Validate that preamble and epilogue are valid for requested encoding
149
+ def encoded(transfer_encoding = nil)
150
+ if multipart?
151
+ self.sort_parts!
152
+ encoded_parts = parts.map { |p| p.encoded }
153
+ ([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s
154
+ else
155
+ dec = Mail::Encodings.get_encoding(encoding)
156
+ enc =
157
+ if Utilities.blank?(transfer_encoding)
158
+ dec
159
+ else
160
+ negotiate_best_encoding(transfer_encoding)
161
+ end
162
+
163
+ if dec.nil?
164
+ # Cannot decode, so skip normalization
165
+ raw_source
166
+ else
167
+ # Decode then encode to normalize and allow transforming
168
+ # from base64 to Q-P and vice versa
169
+ decoded = dec.decode(raw_source)
170
+ if defined?(Encoding) && charset && charset != "US-ASCII"
171
+ decoded = decoded.encode(charset)
172
+ decoded.force_encoding('BINARY') unless Encoding.find(charset).ascii_compatible?
173
+ end
174
+ enc.encode(decoded)
175
+ end
176
+ end
177
+ end
178
+
179
+ def decoded
180
+ if !Encodings.defined?(encoding)
181
+ raise UnknownEncodingType, "Don't know how to decode #{encoding}, please call #encoded and decode it yourself."
182
+ else
183
+ Encodings.get_encoding(encoding).decode(raw_source)
184
+ end
185
+ end
186
+
187
+ def to_s
188
+ decoded
189
+ end
190
+
191
+ def encoding(val = nil)
192
+ if val
193
+ self.encoding = val
194
+ else
195
+ @encoding
196
+ end
197
+ end
198
+
199
+ def encoding=( val )
200
+ @encoding =
201
+ if val == "text" || Utilities.blank?(val)
202
+ default_encoding
203
+ else
204
+ val
205
+ end
206
+ end
207
+
208
+ # Returns the raw source that the body was initialized with, without
209
+ # any tampering
210
+ attr_reader :raw_source
211
+
212
+ # Returns parts of the body
213
+ attr_reader :parts
214
+
215
+ # Returns and sets the original character encoding
216
+ attr_accessor :charset
217
+
218
+ # Returns and sets the preamble as a string (any text that is before the first MIME boundary)
219
+ attr_accessor :preamble
220
+
221
+ # Returns and sets the epilogue as a string (any text that is after the last MIME boundary)
222
+ attr_accessor :epilogue
223
+
224
+ # Returns and sets the boundary used by the body
225
+ # Allows you to change the boundary of this Body object
226
+ attr_accessor :boundary
227
+
228
+ # Returns true if there are parts defined in the body
229
+ def multipart?
230
+ true unless parts.empty?
231
+ end
232
+
233
+ def <<( val )
234
+ if @parts
235
+ @parts << val
236
+ else
237
+ @parts = Mail::PartsList.new[val]
238
+ end
239
+ end
240
+
241
+ def split!(boundary)
242
+ self.boundary = boundary
243
+ parts = extract_parts
244
+
245
+ # Make the preamble equal to the preamble (if any)
246
+ self.preamble = parts[0].to_s.strip
247
+ # Make the epilogue equal to the epilogue (if any)
248
+ self.epilogue = parts[-1].to_s.strip
249
+ parts[1...-1].to_a.each { |part| @parts << Mail::Part.new(part) }
250
+ self
251
+ end
252
+
253
+ def ascii_only?
254
+ unless defined? @ascii_only
255
+ @ascii_only = raw_source.ascii_only?
256
+ end
257
+ @ascii_only
258
+ end
259
+
260
+ def empty?
261
+ !!raw_source.to_s.empty?
262
+ end
263
+
264
+ def default_encoding
265
+ ascii_only? ? '7bit' : '8bit'
266
+ end
267
+
268
+ private
269
+
270
+ # split parts by boundary, ignore first part if empty, append final part when closing boundary was missing
271
+ def extract_parts
272
+ parts_regex = /
273
+ (?: # non-capturing group
274
+ \A | # start of string OR
275
+ \r?\n # line break with optional CR
276
+ )
277
+ (
278
+ --#{Regexp.escape(boundary || "")} # boundary delimiter
279
+ (?:--)? # with non-capturing optional closing
280
+ )
281
+ (?=\s*$) # lookahead matching zero or more spaces followed by line-ending
282
+ /x
283
+ parts = raw_source.split(parts_regex).each_slice(2).to_a
284
+ parts.each_with_index { |(part, _), index| parts.delete_at(index) if index > 0 && Utilities.blank?(part) }
285
+
286
+ if parts.size > 1
287
+ final_separator = parts[-2][1]
288
+ parts << [""] if final_separator != "--#{boundary}--"
289
+ end
290
+ parts.map(&:first)
291
+ end
292
+
293
+ def crlf_boundary
294
+ "\r\n--#{boundary}\r\n"
295
+ end
296
+
297
+ def end_boundary
298
+ "\r\n--#{boundary}--\r\n"
299
+ end
300
+
301
+ def set_charset
302
+ @charset = ascii_only? ? 'US-ASCII' : nil
303
+ end
304
+ end
305
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # Thanks to Nicolas Fouché for this wrapper
5
+ #
6
+ require 'singleton'
7
+
8
+ module Mail
9
+
10
+ # The Configuration class is a Singleton used to hold the default
11
+ # configuration for all Mail objects.
12
+ #
13
+ # Each new mail object gets a copy of these values at initialization
14
+ # which can be overwritten on a per mail object basis.
15
+ class Configuration
16
+ include Singleton
17
+
18
+ def initialize
19
+ @delivery_method = nil
20
+ @retriever_method = nil
21
+ super
22
+ end
23
+
24
+ def delivery_method(method = nil, settings = {})
25
+ return @delivery_method if @delivery_method && method.nil?
26
+ @delivery_method = lookup_delivery_method(method).new(settings)
27
+ end
28
+
29
+ def lookup_delivery_method(method)
30
+ case method.is_a?(String) ? method.to_sym : method
31
+ when nil
32
+ Mail::SMTP
33
+ when :smtp
34
+ Mail::SMTP
35
+ when :sendmail
36
+ Mail::Sendmail
37
+ when :exim
38
+ Mail::Exim
39
+ when :file
40
+ Mail::FileDelivery
41
+ when :smtp_connection
42
+ Mail::SMTPConnection
43
+ when :test
44
+ Mail::TestMailer
45
+ when :logger
46
+ Mail::LoggerDelivery
47
+ else
48
+ method
49
+ end
50
+ end
51
+
52
+ def retriever_method(method = nil, settings = {})
53
+ return @retriever_method if @retriever_method && method.nil?
54
+ @retriever_method = lookup_retriever_method(method).new(settings)
55
+ end
56
+
57
+ def lookup_retriever_method(method)
58
+ case method
59
+ when nil
60
+ Mail::POP3
61
+ when :pop3
62
+ Mail::POP3
63
+ when :imap
64
+ Mail::IMAP
65
+ when :test
66
+ Mail::TestRetriever
67
+ else
68
+ method
69
+ end
70
+ end
71
+
72
+ def param_encode_language(value = nil)
73
+ value ? @encode_language = value : @encode_language ||= 'en'
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: us-ascii
2
+ # frozen_string_literal: true
3
+ module Mail
4
+ module Constants
5
+ white_space = %Q|\x9\x20|
6
+ text = %Q|\x1-\x8\xB\xC\xE-\x7f|
7
+ field_name = %Q|\x21-\x39\x3b-\x7e|
8
+ qp_safe = %Q|\x20-\x3c\x3e-\x7e|
9
+
10
+ aspecial = %Q|()<>[]:;@\\,."| # RFC5322
11
+ tspecial = %Q|()<>@,;:\\"/[]?=| # RFC2045
12
+ sp = %Q| |
13
+ control = %Q|\x00-\x1f\x7f-\xff|
14
+
15
+ if control.respond_to?(:force_encoding)
16
+ control = control.dup.force_encoding(Encoding::BINARY)
17
+ end
18
+
19
+ LAX_CRLF = /\r?\n/
20
+ WSP = /[#{white_space}]/
21
+ FWS = /#{LAX_CRLF}#{WSP}*/
22
+ UNFOLD_WS = /#{LAX_CRLF}(#{WSP})/m
23
+ TEXT = /[#{text}]/ # + obs-text
24
+ FIELD_NAME = /[#{field_name}]+/
25
+ FIELD_PREFIX = /\A(#{FIELD_NAME})/
26
+ FIELD_BODY = /.+/m
27
+ FIELD_LINE = /^[#{field_name}]+:\s*.+$/
28
+ FIELD_SPLIT = /^(#{FIELD_NAME})\s*:\s*(#{FIELD_BODY})?$/
29
+ HEADER_LINE = /^([#{field_name}]+:\s*.+)$/
30
+ HEADER_SPLIT = /#{LAX_CRLF}(?!#{WSP})/
31
+
32
+ QP_UNSAFE = /[^#{qp_safe}]/
33
+ QP_SAFE = /[#{qp_safe}]/
34
+ CONTROL_CHAR = /[#{control}]/n
35
+ ATOM_UNSAFE = /[#{Regexp.quote aspecial}#{control}#{sp}]/n
36
+ PHRASE_UNSAFE = /[#{Regexp.quote aspecial}#{control}]/n
37
+ TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{sp}]/n
38
+
39
+ ENCODED_VALUE = %r{
40
+ \=\? # literal =?
41
+ ([^?]+) #
42
+ \? # literal ?
43
+ ([QB]) # either a "Q" or a "B"
44
+ \? # literal ?
45
+ .*? # lazily match all characters
46
+ \?\= # literal ?=
47
+ }mix # m is multi-line, i is case-insensitive, x is free-spacing
48
+
49
+ FULL_ENCODED_VALUE = %r{ # Identical to ENCODED_VALUE but captures the whole rather than components of
50
+ (
51
+ \=\? # literal =?
52
+ [^?]+ #
53
+ \? # literal ?
54
+ [QB] # either a "Q" or a "B"
55
+ \? # literal ?
56
+ .*? # lazily match all characters
57
+ \?\= # literal ?=
58
+ )
59
+ }mix # m is multi-line, i is case-insensitive, x is free-spacing
60
+
61
+ EMPTY = ''
62
+ SPACE = ' '
63
+ UNDERSCORE = '_'
64
+ HYPHEN = '-'
65
+ COLON = ':'
66
+ ASTERISK = '*'
67
+ CRLF = "\r\n"
68
+ CR = "\r"
69
+ LF = "\n"
70
+ CR_ENCODED = "=0D"
71
+ LF_ENCODED = "=0A"
72
+ CAPITAL_M = 'M'
73
+ EQUAL_LF = "=\n"
74
+ NULL_SENDER = '<>'
75
+
76
+ Q_VALUES = ['Q','q']
77
+ B_VALUES = ['B','b']
78
+ end
79
+ end