kbaum-mail 2.1.2.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 (114) hide show
  1. data/CHANGELOG.rdoc +289 -0
  2. data/README.rdoc +575 -0
  3. data/Rakefile +72 -0
  4. data/TODO.rdoc +19 -0
  5. data/lib/mail.rb +113 -0
  6. data/lib/mail/attachments_list.rb +76 -0
  7. data/lib/mail/body.rb +243 -0
  8. data/lib/mail/configuration.rb +69 -0
  9. data/lib/mail/core_extensions/nil.rb +11 -0
  10. data/lib/mail/core_extensions/string.rb +19 -0
  11. data/lib/mail/elements/address.rb +306 -0
  12. data/lib/mail/elements/address_list.rb +74 -0
  13. data/lib/mail/elements/content_disposition_element.rb +30 -0
  14. data/lib/mail/elements/content_location_element.rb +25 -0
  15. data/lib/mail/elements/content_transfer_encoding_element.rb +21 -0
  16. data/lib/mail/elements/content_type_element.rb +35 -0
  17. data/lib/mail/elements/date_time_element.rb +26 -0
  18. data/lib/mail/elements/envelope_from_element.rb +34 -0
  19. data/lib/mail/elements/message_ids_element.rb +29 -0
  20. data/lib/mail/elements/mime_version_element.rb +26 -0
  21. data/lib/mail/elements/phrase_list.rb +21 -0
  22. data/lib/mail/elements/received_element.rb +30 -0
  23. data/lib/mail/encodings/base64.rb +18 -0
  24. data/lib/mail/encodings/encodings.rb +201 -0
  25. data/lib/mail/encodings/quoted_printable.rb +26 -0
  26. data/lib/mail/envelope.rb +35 -0
  27. data/lib/mail/field.rb +219 -0
  28. data/lib/mail/field_list.rb +33 -0
  29. data/lib/mail/fields/bcc_field.rb +53 -0
  30. data/lib/mail/fields/cc_field.rb +52 -0
  31. data/lib/mail/fields/comments_field.rb +41 -0
  32. data/lib/mail/fields/common/address_container.rb +16 -0
  33. data/lib/mail/fields/common/common_address.rb +128 -0
  34. data/lib/mail/fields/common/common_date.rb +51 -0
  35. data/lib/mail/fields/common/common_field.rb +64 -0
  36. data/lib/mail/fields/common/common_message_id.rb +57 -0
  37. data/lib/mail/fields/common/parameter_hash.rb +39 -0
  38. data/lib/mail/fields/content_description_field.rb +19 -0
  39. data/lib/mail/fields/content_disposition_field.rb +60 -0
  40. data/lib/mail/fields/content_id_field.rb +63 -0
  41. data/lib/mail/fields/content_location_field.rb +42 -0
  42. data/lib/mail/fields/content_transfer_encoding_field.rb +45 -0
  43. data/lib/mail/fields/content_type_field.rb +175 -0
  44. data/lib/mail/fields/date_field.rb +53 -0
  45. data/lib/mail/fields/from_field.rb +53 -0
  46. data/lib/mail/fields/in_reply_to_field.rb +52 -0
  47. data/lib/mail/fields/keywords_field.rb +43 -0
  48. data/lib/mail/fields/message_id_field.rb +80 -0
  49. data/lib/mail/fields/mime_version_field.rb +54 -0
  50. data/lib/mail/fields/optional_field.rb +11 -0
  51. data/lib/mail/fields/received_field.rb +62 -0
  52. data/lib/mail/fields/references_field.rb +53 -0
  53. data/lib/mail/fields/reply_to_field.rb +53 -0
  54. data/lib/mail/fields/resent_bcc_field.rb +53 -0
  55. data/lib/mail/fields/resent_cc_field.rb +53 -0
  56. data/lib/mail/fields/resent_date_field.rb +33 -0
  57. data/lib/mail/fields/resent_from_field.rb +53 -0
  58. data/lib/mail/fields/resent_message_id_field.rb +32 -0
  59. data/lib/mail/fields/resent_sender_field.rb +60 -0
  60. data/lib/mail/fields/resent_to_field.rb +53 -0
  61. data/lib/mail/fields/return_path_field.rb +62 -0
  62. data/lib/mail/fields/sender_field.rb +65 -0
  63. data/lib/mail/fields/structured_field.rb +36 -0
  64. data/lib/mail/fields/subject_field.rb +15 -0
  65. data/lib/mail/fields/to_field.rb +53 -0
  66. data/lib/mail/fields/unstructured_field.rb +117 -0
  67. data/lib/mail/header.rb +235 -0
  68. data/lib/mail/mail.rb +194 -0
  69. data/lib/mail/message.rb +1780 -0
  70. data/lib/mail/network/delivery_methods/file_delivery.rb +40 -0
  71. data/lib/mail/network/delivery_methods/sendmail.rb +62 -0
  72. data/lib/mail/network/delivery_methods/smtp.rb +110 -0
  73. data/lib/mail/network/delivery_methods/test_mailer.rb +40 -0
  74. data/lib/mail/network/retriever_methods/imap.rb +31 -0
  75. data/lib/mail/network/retriever_methods/pop3.rb +149 -0
  76. data/lib/mail/parsers/address_lists.rb +61 -0
  77. data/lib/mail/parsers/address_lists.treetop +19 -0
  78. data/lib/mail/parsers/content_disposition.rb +369 -0
  79. data/lib/mail/parsers/content_disposition.treetop +46 -0
  80. data/lib/mail/parsers/content_location.rb +133 -0
  81. data/lib/mail/parsers/content_location.treetop +20 -0
  82. data/lib/mail/parsers/content_transfer_encoding.rb +179 -0
  83. data/lib/mail/parsers/content_transfer_encoding.treetop +25 -0
  84. data/lib/mail/parsers/content_type.rb +512 -0
  85. data/lib/mail/parsers/content_type.treetop +58 -0
  86. data/lib/mail/parsers/date_time.rb +111 -0
  87. data/lib/mail/parsers/date_time.treetop +11 -0
  88. data/lib/mail/parsers/envelope_from.rb +188 -0
  89. data/lib/mail/parsers/envelope_from.treetop +32 -0
  90. data/lib/mail/parsers/message_ids.rb +42 -0
  91. data/lib/mail/parsers/message_ids.treetop +15 -0
  92. data/lib/mail/parsers/mime_version.rb +141 -0
  93. data/lib/mail/parsers/mime_version.treetop +19 -0
  94. data/lib/mail/parsers/phrase_lists.rb +42 -0
  95. data/lib/mail/parsers/phrase_lists.treetop +15 -0
  96. data/lib/mail/parsers/received.rb +68 -0
  97. data/lib/mail/parsers/received.treetop +11 -0
  98. data/lib/mail/parsers/rfc2045.rb +406 -0
  99. data/lib/mail/parsers/rfc2045.treetop +35 -0
  100. data/lib/mail/parsers/rfc2822.rb +5081 -0
  101. data/lib/mail/parsers/rfc2822.treetop +410 -0
  102. data/lib/mail/parsers/rfc2822_obsolete.rb +3607 -0
  103. data/lib/mail/parsers/rfc2822_obsolete.treetop +241 -0
  104. data/lib/mail/part.rb +82 -0
  105. data/lib/mail/parts_list.rb +34 -0
  106. data/lib/mail/patterns.rb +43 -0
  107. data/lib/mail/utilities.rb +163 -0
  108. data/lib/mail/vendor/treetop.rb +4 -0
  109. data/lib/mail/version.rb +10 -0
  110. data/lib/mail/version_specific/ruby_1_8.rb +84 -0
  111. data/lib/mail/version_specific/ruby_1_9.rb +77 -0
  112. data/lib/tasks/corpus.rake +125 -0
  113. data/lib/tasks/treetop.rake +10 -0
  114. metadata +188 -0
@@ -0,0 +1,72 @@
1
+ environment = File.expand_path('../../vendor/gems/environment')
2
+ if File.exist?("#{environment}.rb")
3
+ require environment
4
+ end
5
+
6
+ require 'rake/rdoctask'
7
+ require 'rake/gempackagetask'
8
+ require 'rake/testtask'
9
+ require 'spec/rake/spectask'
10
+ require 'cucumber/rake/task'
11
+ require 'bundler'
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = "kbaum-mail"
15
+ s.version = "2.1.2.1"
16
+ s.author = "Mike Lindsaar"
17
+ s.email = "raasdnil@gmail.com"
18
+ s.homepage = "http://github.com/mikel/mail"
19
+ s.description = "A really Ruby Mail handler."
20
+ s.summary = "Mail provides a nice Ruby DSL for making, sending and reading emails."
21
+
22
+ s.platform = Gem::Platform::RUBY
23
+ s.has_rdoc = true
24
+ s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "TODO.rdoc"]
25
+
26
+ s.add_dependency('activesupport', ">= 2.3.4")
27
+ s.add_dependency('mime-types')
28
+
29
+ s.require_path = 'lib'
30
+ s.files = %w(README.rdoc Rakefile TODO.rdoc) + Dir.glob("lib/**/*")
31
+ end
32
+
33
+ Rake::GemPackageTask.new(spec) do |pkg|
34
+ pkg.gem_spec = spec
35
+ end
36
+
37
+ task :default => :spec
38
+ Cucumber::Rake::Task.new do |t|
39
+ t.cucumber_opts = "spec/features --format pretty"
40
+ end
41
+
42
+ Spec::Rake::SpecTask.new(:rcov) do |t|
43
+ t.spec_files = FileList['test/**/tc_*.rb', 'spec/**/*_spec.rb']
44
+ t.rcov = true
45
+ t.rcov_opts = t.rcov_opts << ['--exclude', '/Library,/opt,/System']
46
+ end
47
+
48
+ Spec::Rake::SpecTask.new(:spec) do |t|
49
+ t.warning = true
50
+ t.spec_files = FileList['spec/**/*_spec.rb']
51
+ t.spec_opts = %w(--backtrace --diff --color)
52
+ t.libs << "#{File.dirname(__FILE__)}/spec"
53
+ t.libs << "#{File.dirname(__FILE__)}/spec/mail"
54
+ end
55
+
56
+ Rake::TestTask.new(:test) do |t|
57
+ t.libs << 'test'
58
+ t.pattern = 'test/**/tc_*.rb'
59
+ t.verbose = true
60
+ t.warning = false
61
+ end
62
+
63
+ Rake::RDocTask.new(:rdoc) do |rdoc|
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = 'Mail'
66
+ rdoc.options << '--line-numbers' << '--inline-source'
67
+ rdoc.rdoc_files.include('README')
68
+ rdoc.rdoc_files.include('lib/**/*.rb')
69
+ end
70
+
71
+ # load custom rake tasks
72
+ Dir["#{File.dirname(__FILE__)}/lib/tasks/**/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,19 @@
1
+ == Not really in any order:
2
+
3
+ * Make body, part, field, header, message all responding correctly to :encoded
4
+ and :decoded messages. And remove ":to_s" as a method on these
5
+ classes. Encoded needs to return the field, encoded, ready to send in the
6
+ mail system, that is, US-ASCII. Decoded needs to return the field decoded ready to
7
+ view. :to_s is (unfortunately) ambiguous in this case. Maybe return a warning
8
+ with :to_s and say "please use encoded or decoded instead" or :to_s returns
9
+ "Showing you the encoded view by default, call :decoded to see the decoded view"
10
+
11
+ * Refactor out the multibyte and string handling. Make ActiveSupport a dependancy
12
+
13
+ * Clean up the relationship between message, parts and bodies. Need to make sure
14
+ once parsed, that a body knows what encoding it is, for example.
15
+
16
+ * Cleanup the treetop parsers......... do I _really_ need that many entrance files?
17
+
18
+ * Simplify the relationship of Headers and Fields. Doing too much of the Field work
19
+ in the Header class on instantiating fields. Header should just say "Field, do it!"
@@ -0,0 +1,113 @@
1
+ # encoding: utf-8
2
+ module Mail # :doc:
3
+
4
+ require 'date'
5
+
6
+ require 'active_support'
7
+
8
+ # Have to handle ActiveSupport 2.3 and 3.0
9
+ # Following two lines make sure that HashWithIndifferentAccess is available
10
+ # regardless of having activesupport 3 or 2.3 loaded
11
+ require 'active_support/core_ext/hash/indifferent_access'
12
+
13
+ require 'mail/vendor/treetop'
14
+
15
+ require 'uri'
16
+ require 'net/smtp'
17
+ require 'mime/types'
18
+
19
+ if RUBY_VERSION <= '1.8.6'
20
+ begin
21
+ require 'tlsmail'
22
+ rescue LoadError
23
+ raise "You need to install tlsmail if you are using ruby <= 1.8.6"
24
+ end
25
+ end
26
+
27
+ if RUBY_VERSION >= "1.9.1"
28
+ require 'mail/version_specific/ruby_1_9.rb'
29
+ RubyVer = Mail::Ruby19
30
+ else
31
+ require 'mail/version_specific/ruby_1_8.rb'
32
+ RubyVer = Mail::Ruby18
33
+ end
34
+
35
+ require 'mail/version'
36
+
37
+ begin
38
+ require 'active_support/core_ext/object/blank'
39
+ rescue LoadError
40
+ # Unneeded for Active Support <= 3.0.pre
41
+ end
42
+
43
+ require 'mail/core_extensions/nil'
44
+ require 'mail/core_extensions/string'
45
+
46
+ require 'mail/patterns'
47
+ require 'mail/utilities'
48
+ require 'mail/configuration'
49
+ require 'mail/network/delivery_methods/smtp'
50
+ require 'mail/network/delivery_methods/file_delivery'
51
+ require 'mail/network/delivery_methods/sendmail'
52
+ require 'mail/network/delivery_methods/test_mailer'
53
+ require 'mail/network/retriever_methods/pop3'
54
+ require 'mail/network/retriever_methods/imap'
55
+
56
+ require 'mail/message'
57
+ require 'mail/part'
58
+ require 'mail/header'
59
+ require 'mail/parts_list'
60
+ require 'mail/attachments_list'
61
+ require 'mail/body'
62
+ require 'mail/field'
63
+ require 'mail/field_list'
64
+
65
+ # Load in all common header fields modules
66
+ require 'mail/fields/common/address_container'
67
+ require 'mail/fields/common/common_address'
68
+ require 'mail/fields/common/common_date'
69
+ require 'mail/fields/common/common_field'
70
+ require 'mail/fields/common/common_message_id'
71
+ require 'mail/fields/common/parameter_hash'
72
+
73
+ require 'mail/fields/structured_field'
74
+ require 'mail/fields/unstructured_field'
75
+ require 'mail/envelope'
76
+
77
+ parsers = %w[ rfc2822_obsolete rfc2822 address_lists phrase_lists
78
+ date_time received message_ids envelope_from rfc2045
79
+ mime_version content_type content_disposition
80
+ content_transfer_encoding content_location ]
81
+
82
+ parsers.each do |parser|
83
+ begin
84
+ # Try requiring the pre-compiled ruby version first
85
+ require "mail/parsers/#{parser}"
86
+ rescue LoadError
87
+ # Otherwise, get treetop to compile and load it
88
+ Treetop.load("mail/parsers/#{parser}")
89
+ end
90
+ end
91
+
92
+ # Load in all header field elements
93
+ elems = Dir.glob(File.join(File.dirname(__FILE__), 'mail', 'elements', '*.rb'))
94
+ elems.each do |elem|
95
+ require "mail/elements/#{File.basename(elem, '.rb')}"
96
+ end
97
+
98
+ # Load in all header fields
99
+ fields = Dir.glob(File.join(File.dirname(__FILE__), 'mail', 'fields', '*.rb'))
100
+ fields.each do |field|
101
+ require "mail/fields/#{File.basename(field, '.rb')}"
102
+ end
103
+
104
+ # Load in all transfer encodings
105
+ elems = Dir.glob(File.join(File.dirname(__FILE__), 'mail', 'encodings', '*.rb'))
106
+ elems.each do |elem|
107
+ require "mail/encodings/#{File.basename(elem, '.rb')}"
108
+ end
109
+
110
+ # Finally... require all the Mail.methods
111
+ require File.join('mail', 'mail')
112
+
113
+ end
@@ -0,0 +1,76 @@
1
+ module Mail
2
+ class AttachmentsList < Array
3
+
4
+ def initialize(parts_list)
5
+ @parts_list = parts_list
6
+ parts_list.map { |p|
7
+ if p.parts.empty?
8
+ p if p.attachment?
9
+ else
10
+ p.attachments
11
+ end
12
+ }.flatten.compact.each { |a| self << a }
13
+ self
14
+ end
15
+
16
+ # Returns the attachment by filename or at index.
17
+ #
18
+ # mail.attachments['test.png'] = File.read('test.png')
19
+ # mail.attachments['test.jpg'] = File.read('test.jpg')
20
+ #
21
+ # mail.attachments['test.png'].filename #=> 'test.png'
22
+ # mail.attachments[1].filename #=> 'test.jpg'
23
+ def [](index_value)
24
+ if index_value.is_a?(Fixnum)
25
+ self.fetch(index_value)
26
+ else
27
+ self.select { |a| a.filename == index_value }.first
28
+ end
29
+ end
30
+
31
+ def []=(name, value)
32
+ default_values = { :content_type => "#{set_mime_type(name)}; filename=\"#{name}\"",
33
+ :content_transfer_encoding => 'Base64',
34
+ :content_disposition => "attachment; filename=\"#{name}\"" }
35
+
36
+ if value.is_a?(Hash)
37
+
38
+ default_values[:body] = value.delete(:content) if value[:content]
39
+
40
+ default_values[:body] = value.delete(:data) if value[:data]
41
+
42
+ # Only force encode base64 if the user has not specified an encoding
43
+ if value[:transfer_encoding]
44
+ default_values[:content_transfer_encoding] = value.delete(:transfer_encoding)
45
+ elsif value[:encoding]
46
+ default_values[:content_transfer_encoding] = value.delete(:encoding)
47
+ else
48
+ default_values[:body] = Mail::Encodings::Base64.encode(default_values[:body])
49
+ end
50
+
51
+ if value[:mime_type]
52
+ default_values[:content_type] = value.delete(:mime_type)
53
+ end
54
+
55
+ hash = default_values.merge(value)
56
+ else
57
+ default_values[:body] = Mail::Encodings::Base64.encode(value)
58
+ hash = default_values
59
+ end
60
+
61
+ @parts_list << Part.new(hash)
62
+ end
63
+
64
+ def set_mime_type(filename)
65
+ # Have to do this because MIME::Types is not Ruby 1.9 safe yet
66
+ if RUBY_VERSION >= '1.9'
67
+ new_file = String.new(filename).force_encoding(Encoding::BINARY)
68
+ ext = new_file.split('.'.force_encoding(Encoding::BINARY)).last
69
+ filename = "file.#{ext}".force_encoding('US-ASCII')
70
+ end
71
+ @mime_type = MIME::Types.type_for(filename).first
72
+ end
73
+
74
+ end
75
+ end
76
+
@@ -0,0 +1,243 @@
1
+ # encoding: utf-8
2
+ module Mail
3
+
4
+ # = Body
5
+ #
6
+ # The body is where the text of the email is stored. Mail treats the body
7
+ # as a single object. The body itself has no information about boundaries
8
+ # used in the MIME standard, it just looks at it's content as either a single
9
+ # block of text, or (if it is a multipart message) as an array of blocks o text.
10
+ #
11
+ # A body has to be told to split itself up into a multipart message by calling
12
+ # #split with the correct boundary. This is because the body object has no way
13
+ # of knowing what the correct boundary is for itself (there could be many
14
+ # boundaries in a body in the case of a nested MIME text).
15
+ #
16
+ # Once split is called, Mail::Body will slice itself up on this boundary,
17
+ # assigning anything that appears before the first part to the preamble, and
18
+ # anything that appears after the closing boundary to the epilogue, then
19
+ # each part gets initialized into a Mail::Part object.
20
+ #
21
+ # The boundary that is used to split up the Body is also stored in the Body
22
+ # object for use on encoding itself back out to a string. You can
23
+ # overwrite this if it needs to be changed.
24
+ #
25
+ # On encoding, the body will return the preamble, then each part joined by
26
+ # the boundary, followed by a closing boundary string and then the epilogue.
27
+ class Body
28
+
29
+ def initialize(string = '')
30
+ @boundary = nil
31
+ @preamble = nil
32
+ @epilogue = nil
33
+ @part_sort_order = [ "text/plain", "text/enriched", "text/html" ]
34
+ @parts = Mail::PartsList.new
35
+ if string.blank?
36
+ @raw_source = ''
37
+ else
38
+ # Do join first incase we have been given an Array in Ruby 1.9
39
+ if string.respond_to?(:join)
40
+ @raw_source = string.join('')
41
+ elsif string.respond_to?(:to_s)
42
+ @raw_source = string.to_s
43
+ else
44
+ raise "You can only assign a string or an object that responds_to? :join or :to_s to a body."
45
+ end
46
+ end
47
+ @encoding = nil
48
+ set_charset
49
+ end
50
+
51
+ # Matches this body with another body. Also matches the decoded value of this
52
+ # body with a string.
53
+ #
54
+ # Examples:
55
+ #
56
+ # body = Mail::Body.new('The body')
57
+ # body == body #=> true
58
+ #
59
+ # body = Mail::Body.new('The body')
60
+ # body == 'The body' #=> true
61
+ #
62
+ # body = Mail::Body.new("VGhlIGJvZHk=\n")
63
+ # body.encoding = 'base64'
64
+ # body == "The body" #=> true
65
+ def ==(other)
66
+ if other.class == String
67
+ self.decoded == other
68
+ else
69
+ super
70
+ end
71
+ end
72
+
73
+ # Accepts a string and performs a regular expression against the decoded text
74
+ #
75
+ # Examples:
76
+ #
77
+ # body = Mail::Body.new('The body')
78
+ # body =~ /The/ #=> 0
79
+ #
80
+ # body = Mail::Body.new("VGhlIGJvZHk=\n")
81
+ # body.encoding = 'base64'
82
+ # body =~ /The/ #=> 0
83
+ def =~(regexp)
84
+ self.decoded =~ regexp
85
+ end
86
+
87
+ # Accepts a string and performs a regular expression against the decoded text
88
+ #
89
+ # Examples:
90
+ #
91
+ # body = Mail::Body.new('The body')
92
+ # body.match(/The/) #=> #<MatchData "The">
93
+ #
94
+ # body = Mail::Body.new("VGhlIGJvZHk=\n")
95
+ # body.encoding = 'base64'
96
+ # body.match(/The/) #=> #<MatchData "The">
97
+ def match(regexp)
98
+ self.decoded.match(regexp)
99
+ end
100
+
101
+ # Allows you to set the sort order of the parts, overriding the default sort order.
102
+ # Defaults to 'text/plain', then 'text/enriched', then 'text/html' with any other content
103
+ # type coming after.
104
+ def set_sort_order(order)
105
+ @part_sort_order = order
106
+ end
107
+
108
+ # Allows you to sort the parts according to the default sort order, or the sort order you
109
+ # set with :set_sort_order.
110
+ #
111
+ # sort_parts! is also called from :encode, so there is no need for you to call this explicitly
112
+ def sort_parts!
113
+ @parts.each do |p|
114
+ p.body.set_sort_order(@part_sort_order)
115
+ @parts.sort!(@part_sort_order)
116
+ p.body.sort_parts!
117
+ end
118
+ # @parts.sort!(@part_sort_order)
119
+ end
120
+
121
+ # Returns the raw source that the body was initialized with, without
122
+ # any tampering
123
+ def raw_source
124
+ @raw_source
125
+ end
126
+
127
+ # Returns a US-ASCII 7-bit compliant body. Right now just returns the
128
+ # raw source. Need to implement
129
+ def encoded
130
+ if multipart?
131
+ self.sort_parts!
132
+ encoded_parts = parts.map { |p| p.encoded }
133
+ ([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s
134
+ else
135
+ raw_source.to_crlf
136
+ end
137
+ end
138
+
139
+ def decoded
140
+ if encoding.nil? || !Encodings.defined?(encoding)
141
+ raw_source.to_lf
142
+ else
143
+ Encodings.get_encoding(encoding).decode(raw_source)
144
+ end
145
+ end
146
+
147
+ def to_s
148
+ decoded
149
+ end
150
+
151
+ def charset
152
+ @charset
153
+ end
154
+
155
+ def charset=( val )
156
+ @charset = val
157
+ end
158
+
159
+ def encoding
160
+ @encoding
161
+ end
162
+
163
+ def encoding=( val )
164
+ @encoding = val
165
+ end
166
+
167
+ # Returns the preamble (any text that is before the first MIME boundary)
168
+ def preamble
169
+ @preamble
170
+ end
171
+
172
+ # Sets the preamble to a string (adds text before the first mime boundary)
173
+ def preamble=( val )
174
+ @preamble = val
175
+ end
176
+
177
+ # Returns the epilogue (any text that is after the last MIME boundary)
178
+ def epilogue
179
+ @epilogue
180
+ end
181
+
182
+ # Sets the epilogue to a string (adds text after the last mime boundary)
183
+ def epilogue=( val )
184
+ @epilogue = val
185
+ end
186
+
187
+ # Returns true if there are parts defined in the body
188
+ def multipart?
189
+ true unless parts.empty?
190
+ end
191
+
192
+ # Returns the boundary used by the body
193
+ def boundary
194
+ @boundary
195
+ end
196
+
197
+ # Allows you to change the boundary of this Body object
198
+ def boundary=( val )
199
+ @boundary = val
200
+ end
201
+
202
+ def parts
203
+ @parts
204
+ end
205
+
206
+ def <<( val )
207
+ if @parts
208
+ @parts << val
209
+ else
210
+ @parts = Mail::PartsList.new[val]
211
+ end
212
+ end
213
+
214
+ def split!(boundary)
215
+ self.boundary = boundary
216
+ parts = raw_source.split("--#{boundary}")
217
+ # Make the preamble equal to the preamble (if any)
218
+ self.preamble = parts[0].to_s.strip
219
+ # Make the epilogue equal to the epilogue (if any)
220
+ self.epilogue = parts[-1].to_s.sub('--', '').strip
221
+ parts[1...-1].to_a.each { |part| @parts << Mail::Part.new(part) }
222
+ self
223
+ end
224
+
225
+ def only_us_ascii?
226
+ !!raw_source.to_s.ascii_only?
227
+ end
228
+
229
+ private
230
+
231
+ def crlf_boundary
232
+ "\r\n\r\n--#{boundary}\r\n"
233
+ end
234
+
235
+ def end_boundary
236
+ "\r\n\r\n--#{boundary}--\r\n"
237
+ end
238
+
239
+ def set_charset
240
+ raw_source.ascii_only? ? @charset = 'US-ASCII' : @charset = nil
241
+ end
242
+ end
243
+ end