Class: Mail::Body
Overview
Body
The body is where the text of the email is stored. Mail treats the body as a single object. The body itself has no information about boundaries used in the MIME standard, it just looks at its content as either a single block of text, or (if it is a multipart message) as an array of blocks of text.
A body has to be told to split itself up into a multipart message by calling #split with the correct boundary. This is because the body object has no way of knowing what the correct boundary is for itself (there could be many boundaries in a body in the case of a nested MIME text).
Once split is called, Mail::Body will slice itself up on this boundary, assigning anything that appears before the first part to the preamble, and anything that appears after the closing boundary to the epilogue, then each part gets initialized into a Mail::Part object.
The boundary that is used to split up the Body is also stored in the Body object for use on encoding itself back out to a string. You can overwrite this if it needs to be changed.
On encoding, the body will return the preamble, then each part joined by the boundary, followed by a closing boundary string and then the epilogue.
Instance Method Summary (collapse)
- - (Object) <<(val)
-
- (Object) ==(other)
Matches this body with another body.
-
- (Object) =~(regexp)
Accepts a string and performs a regular expression against the decoded text.
-
- (Object) boundary
Returns the boundary used by the body.
-
- (Object) boundary=(val)
Allows you to change the boundary of this Body object.
- - (Object) charset
- - (Object) charset=(val)
- - (Object) decoded
- - (Boolean) empty?
-
- (Object) encoded(transfer_encoding = '8bit')
Returns a body encoded using transfer_encoding.
- - (Object) encoding(val = nil)
- - (Object) encoding=(val)
-
- (Object) epilogue
Returns the epilogue (any text that is after the last MIME boundary).
-
- (Object) epilogue=(val)
Sets the epilogue to a string (adds text after the last MIME boundary).
- - (Object) get_best_encoding(target)
-
- (Boolean) include?(other)
Accepts anything that responds to #to_s and checks if it's a substring of the decoded text.
-
- (Body) initialize(string = '')
constructor
A new instance of Body.
-
- (Object) match(regexp)
Accepts a string and performs a regular expression against the decoded text.
-
- (Boolean) multipart?
Returns true if there are parts defined in the body.
- - (Boolean) only_us_ascii?
- - (Object) parts
-
- (Object) preamble
Returns the preamble (any text that is before the first MIME boundary).
-
- (Object) preamble=(val)
Sets the preamble to a string (adds text before the first MIME boundary).
-
- (Object) raw_source
Returns the raw source that the body was initialized with, without any tampering.
-
- (Object) set_sort_order(order)
Allows you to set the sort order of the parts, overriding the default sort order.
-
- (Object) sort_parts!
Allows you to sort the parts according to the default sort order, or the sort order you set with :set_sort_order.
- - (Object) split!(boundary)
- - (Object) to_s
Constructor Details
- (Body) initialize(string = '')
A new instance of Body
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/mail/body.rb', line 29 def initialize(string = '') @boundary = nil @preamble = nil @epilogue = nil @charset = nil @part_sort_order = [ "text/plain", "text/enriched", "text/html" ] @parts = Mail::PartsList.new if string.blank? @raw_source = '' else # Do join first incase we have been given an Array in Ruby 1.9 if string.respond_to?(:join) @raw_source = string.join('') elsif string.respond_to?(:to_s) @raw_source = string.to_s else raise "You can only assign a string or an object that responds_to? :join or :to_s to a body." end end @encoding = (only_us_ascii? ? '7bit' : '8bit') set_charset end |
Instance Method Details
- (Object) <<(val)
250 251 252 253 254 255 256 |
# File 'lib/mail/body.rb', line 250 def <<( val ) if @parts @parts << val else @parts = Mail::PartsList.new[val] end end |
- (Object) ==(other)
Matches this body with another body. Also matches the decoded value of this body with a string.
Examples:
body = Mail::Body.new('The body')
body == body #=> true
body = Mail::Body.new('The body')
body == 'The body' #=> true
body = Mail::Body.new("VGhlIGJvZHk=\n")
body.encoding = 'base64'
body == "The body" #=> true
66 67 68 69 70 71 72 |
# File 'lib/mail/body.rb', line 66 def ==(other) if other.class == String self.decoded == other else super end end |
- (Object) =~(regexp)
Accepts a string and performs a regular expression against the decoded text
Examples:
body = Mail::Body.new('The body')
body =~ /The/ #=> 0
body = Mail::Body.new("VGhlIGJvZHk=\n")
body.encoding = 'base64'
body =~ /The/ #=> 0
84 85 86 |
# File 'lib/mail/body.rb', line 84 def =~(regexp) self.decoded =~ regexp end |
- (Object) boundary
Returns the boundary used by the body
237 238 239 |
# File 'lib/mail/body.rb', line 237 def boundary @boundary end |
- (Object) boundary=(val)
Allows you to change the boundary of this Body object
242 243 244 |
# File 'lib/mail/body.rb', line 242 def boundary=( val ) @boundary = val end |
- (Object) charset
187 188 189 |
# File 'lib/mail/body.rb', line 187 def charset @charset end |
- (Object) charset=(val)
191 192 193 |
# File 'lib/mail/body.rb', line 191 def charset=( val ) @charset = val end |
- (Object) decoded
175 176 177 178 179 180 181 |
# File 'lib/mail/body.rb', line 175 def decoded if !Encodings.defined?(encoding) raise UnknownEncodingType, "Don't know how to decode #{encoding}, please call #encoded and decode it yourself." else Encodings.get_encoding(encoding).decode(raw_source) end end |
- (Boolean) empty?
273 274 275 |
# File 'lib/mail/body.rb', line 273 def empty? !!raw_source.to_s.empty? end |
- (Object) encoded(transfer_encoding = '8bit')
Returns a body encoded using transfer_encoding. Multipart always uses an identiy encoding (i.e. no encoding). Calling this directly is not a good idea, but supported for compatibility TODO: Validate that preamble and epilogue are valid for requested encoding
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/mail/body.rb', line 150 def encoded(transfer_encoding = '8bit') if multipart? self.sort_parts! encoded_parts = parts.map { |p| p.encoded } ([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s else be = get_best_encoding(transfer_encoding) dec = Mail::Encodings::get_encoding(encoding) enc = Mail::Encodings::get_encoding(be) if transfer_encoding == encoding and dec.nil? # Cannot decode, so skip normalization raw_source else # Decode then encode to normalize and allow transforming # from base64 to Q-P and vice versa decoded = dec.decode(raw_source) if defined?(Encoding) && charset && charset != "US-ASCII" decoded.encode!(charset) decoded.force_encoding('BINARY') unless Encoding.find(charset).ascii_compatible? end enc.encode(decoded) end end end |
- (Object) encoding(val = nil)
195 196 197 198 199 200 201 |
# File 'lib/mail/body.rb', line 195 def encoding(val = nil) if val self.encoding = val else @encoding end end |
- (Object) encoding=(val)
203 204 205 206 207 208 209 |
# File 'lib/mail/body.rb', line 203 def encoding=( val ) @encoding = if val == "text" || val.blank? (only_us_ascii? ? '7bit' : '8bit') else val end end |
- (Object) epilogue
Returns the epilogue (any text that is after the last MIME boundary)
222 223 224 |
# File 'lib/mail/body.rb', line 222 def epilogue @epilogue end |
- (Object) epilogue=(val)
Sets the epilogue to a string (adds text after the last MIME boundary)
227 228 229 |
# File 'lib/mail/body.rb', line 227 def epilogue=( val ) @epilogue = val end |
- (Object) get_best_encoding(target)
141 142 143 144 |
# File 'lib/mail/body.rb', line 141 def get_best_encoding(target) target_encoding = Mail::Encodings.get_encoding(target) target_encoding.get_best_compatible(encoding, raw_source) end |
- (Boolean) include?(other)
Accepts anything that responds to #to_s and checks if it's a substring of the decoded text
Examples:
body = Mail::Body.new('The body')
body.include?('The') #=> true
body = Mail::Body.new("VGhlIGJvZHk=\n")
body.encoding = 'base64'
body.include?('The') #=> true
112 113 114 |
# File 'lib/mail/body.rb', line 112 def include?(other) self.decoded.include?(other.to_s) end |
- (Object) match(regexp)
Accepts a string and performs a regular expression against the decoded text
Examples:
body = Mail::Body.new('The body')
body.match(/The/) #=> #<MatchData "The">
body = Mail::Body.new("VGhlIGJvZHk=\n")
body.encoding = 'base64'
body.match(/The/) #=> #<MatchData "The">
98 99 100 |
# File 'lib/mail/body.rb', line 98 def match(regexp) self.decoded.match(regexp) end |
- (Boolean) multipart?
Returns true if there are parts defined in the body
232 233 234 |
# File 'lib/mail/body.rb', line 232 def multipart? true unless parts.empty? end |
- (Boolean) only_us_ascii?
269 270 271 |
# File 'lib/mail/body.rb', line 269 def only_us_ascii? !(raw_source =~ /[^\x01-\x7f]/) end |
- (Object) parts
246 247 248 |
# File 'lib/mail/body.rb', line 246 def parts @parts end |
- (Object) preamble
Returns the preamble (any text that is before the first MIME boundary)
212 213 214 |
# File 'lib/mail/body.rb', line 212 def preamble @preamble end |
- (Object) preamble=(val)
Sets the preamble to a string (adds text before the first MIME boundary)
217 218 219 |
# File 'lib/mail/body.rb', line 217 def preamble=( val ) @preamble = val end |
- (Object) raw_source
Returns the raw source that the body was initialized with, without any tampering
137 138 139 |
# File 'lib/mail/body.rb', line 137 def raw_source @raw_source end |
- (Object) set_sort_order(order)
Allows you to set the sort order of the parts, overriding the default sort order. Defaults to 'text/plain', then 'text/enriched', then 'text/html' with any other content type coming after.
119 120 121 |
# File 'lib/mail/body.rb', line 119 def set_sort_order(order) @part_sort_order = order end |
- (Object) sort_parts!
Allows you to sort the parts according to the default sort order, or the sort order you set with :set_sort_order.
sort_parts! is also called from :encode, so there is no need for you to call this explicitly
127 128 129 130 131 132 133 |
# File 'lib/mail/body.rb', line 127 def sort_parts! @parts.each do |p| p.body.set_sort_order(@part_sort_order) @parts.sort!(@part_sort_order) p.body.sort_parts! end end |
- (Object) split!(boundary)
258 259 260 261 262 263 264 265 266 267 |
# File 'lib/mail/body.rb', line 258 def split!(boundary) self.boundary = boundary parts = raw_source.split(/(?:\A|\r\n)--#{Regexp.escape(boundary)}(?=(?:--)?\s*$)/) # Make the preamble equal to the preamble (if any) self.preamble = parts[0].to_s.strip # Make the epilogue equal to the epilogue (if any) self.epilogue = parts[-1].to_s.sub('--', '').strip parts[1...-1].to_a.each { |part| @parts << Mail::Part.new(part) } self end |
- (Object) to_s
183 184 185 |
# File 'lib/mail/body.rb', line 183 def to_s decoded end |