Class: Mail::Body

Inherits:
Object
  • Object
show all
Defined in:
lib/mail/body.rb

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 it’s content as either a single block of text, or (if it is a multipart message) as an array of blocks o 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

Constructor Details

#initialize(string = '') ⇒ Body

Returns 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
# File 'lib/mail/body.rb', line 29

def initialize(string = '')
  @boundary = nil
  @preamble = nil
  @epilogue = 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 = nil
  set_charset
end

Instance Method Details

#<<(val) ⇒ Object



206
207
208
209
210
211
212
# File 'lib/mail/body.rb', line 206

def <<( val )
  if @parts
    @parts << val
  else
    @parts = Mail::PartsList.new[val]
  end
end

#==(other) ⇒ Object

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


65
66
67
68
69
70
71
# File 'lib/mail/body.rb', line 65

def ==(other)
  if other.class == String
    self.decoded == other
  else
    super
  end
end

#=~(regexp) ⇒ Object

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


83
84
85
# File 'lib/mail/body.rb', line 83

def =~(regexp)
  self.decoded =~ regexp
end

#boundaryObject

Returns the boundary used by the body



193
194
195
# File 'lib/mail/body.rb', line 193

def boundary
  @boundary
end

#boundary=(val) ⇒ Object

Allows you to change the boundary of this Body object



198
199
200
# File 'lib/mail/body.rb', line 198

def boundary=( val )
  @boundary = val
end

#charsetObject



151
152
153
# File 'lib/mail/body.rb', line 151

def charset
  @charset
end

#charset=(val) ⇒ Object



155
156
157
# File 'lib/mail/body.rb', line 155

def charset=( val )
  @charset = val
end

#decodedObject



139
140
141
142
143
144
145
# File 'lib/mail/body.rb', line 139

def decoded
  if encoding.nil? || !Encodings.defined?(encoding)
    raw_source.to_lf
  else
    Encodings.get_encoding(encoding).decode(raw_source)
  end
end

#encodedObject

Returns a US-ASCII 7-bit compliant body. Right now just returns the raw source. Need to implement



129
130
131
132
133
134
135
136
137
# File 'lib/mail/body.rb', line 129

def encoded
  if multipart?
    self.sort_parts!
    encoded_parts = parts.map { |p| p.encoded }
    ([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s
  else
    raw_source.to_crlf
  end
end

#encodingObject



159
160
161
# File 'lib/mail/body.rb', line 159

def encoding
  @encoding
end

#encoding=(val) ⇒ Object



163
164
165
# File 'lib/mail/body.rb', line 163

def encoding=( val )
  @encoding = val
end

#epilogueObject

Returns the epilogue (any text that is after the last MIME boundary)



178
179
180
# File 'lib/mail/body.rb', line 178

def epilogue
  @epilogue
end

#epilogue=(val) ⇒ Object

Sets the epilogue to a string (adds text after the last mime boundary)



183
184
185
# File 'lib/mail/body.rb', line 183

def epilogue=( val )
  @epilogue = val
end

#match(regexp) ⇒ Object

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">


97
98
99
# File 'lib/mail/body.rb', line 97

def match(regexp)
  self.decoded.match(regexp)
end

#multipart?Boolean

Returns true if there are parts defined in the body

Returns:

  • (Boolean)


188
189
190
# File 'lib/mail/body.rb', line 188

def multipart?
  true unless parts.empty?
end

#only_us_ascii?Boolean

Returns:

  • (Boolean)


225
226
227
# File 'lib/mail/body.rb', line 225

def only_us_ascii?
  !!raw_source.to_s.ascii_only?
end

#partsObject



202
203
204
# File 'lib/mail/body.rb', line 202

def parts
  @parts
end

#preambleObject

Returns the preamble (any text that is before the first MIME boundary)



168
169
170
# File 'lib/mail/body.rb', line 168

def preamble
  @preamble
end

#preamble=(val) ⇒ Object

Sets the preamble to a string (adds text before the first mime boundary)



173
174
175
# File 'lib/mail/body.rb', line 173

def preamble=( val )
  @preamble = val
end

#raw_sourceObject

Returns the raw source that the body was initialized with, without any tampering



123
124
125
# File 'lib/mail/body.rb', line 123

def raw_source
  @raw_source
end

#set_sort_order(order) ⇒ Object

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.



104
105
106
# File 'lib/mail/body.rb', line 104

def set_sort_order(order)
  @part_sort_order = order
end

#sort_parts!Object

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



112
113
114
115
116
117
118
119
# File 'lib/mail/body.rb', line 112

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
#      @parts.sort!(@part_sort_order)
end

#split!(boundary) ⇒ Object



214
215
216
217
218
219
220
221
222
223
# File 'lib/mail/body.rb', line 214

def split!(boundary)
  self.boundary = boundary
  parts = raw_source.split("--#{boundary}")
  # 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

#to_sObject



147
148
149
# File 'lib/mail/body.rb', line 147

def to_s
  decoded
end