actionmailer 2.0.2 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionmailer might be problematic. Click here for more details.

Files changed (42) hide show
  1. data/CHANGELOG +9 -0
  2. data/README +0 -0
  3. data/Rakefile +4 -2
  4. data/lib/action_mailer.rb +0 -0
  5. data/lib/action_mailer/base.rb +4 -1
  6. data/lib/action_mailer/test_case.rb +14 -1
  7. data/lib/action_mailer/vendor.rb +2 -2
  8. data/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb +0 -0
  9. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail.rb +0 -0
  10. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/Makefile +0 -0
  11. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/address.rb +0 -0
  12. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/attachments.rb +0 -0
  13. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/base64.rb +0 -0
  14. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/compat.rb +0 -0
  15. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/config.rb +0 -0
  16. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/core_extensions.rb +0 -0
  17. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/encode.rb +84 -42
  18. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/facade.rb +0 -0
  19. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/header.rb +34 -2
  20. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/info.rb +0 -0
  21. data/lib/action_mailer/vendor/tmail-1.2.1/tmail/interface.rb +1123 -0
  22. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/loader.rb +0 -0
  23. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/mail.rb +46 -1
  24. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/mailbox.rb +3 -3
  25. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/mbox.rb +0 -0
  26. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/net.rb +0 -35
  27. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/obsolete.rb +0 -0
  28. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/parser.rb +0 -0
  29. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/parser.y +0 -0
  30. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/port.rb +0 -0
  31. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/quoting.rb +6 -30
  32. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/scanner.rb +9 -5
  33. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/scanner_r.rb +2 -4
  34. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/stringio.rb +0 -0
  35. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/tmail.rb +0 -0
  36. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/utils.rb +3 -4
  37. data/lib/action_mailer/vendor/{tmail-1.1.0 → tmail-1.2.1}/tmail/version.rb +2 -2
  38. data/lib/action_mailer/version.rb +1 -1
  39. data/test/mail_service_test.rb +3 -2
  40. data/test/test_helper_test.rb +18 -0
  41. metadata +36 -35
  42. data/lib/action_mailer/vendor/tmail-1.1.0/tmail/interface.rb +0 -540
data/CHANGELOG CHANGED
@@ -1,3 +1,12 @@
1
+ *2.0.4* (2nd September 2008)
2
+
3
+ * Less verbose mail logging: just recipients for :info log level; the whole email for :debug only. #8000 [iaddict, Tarmo Tänav]
4
+
5
+ * Updated TMail to version 1.2.1 [raasdnil]
6
+
7
+ * Fixed that you don't have to call super in ActionMailer::TestCase#setup #10406 [jamesgolick]
8
+
9
+
1
10
  *2.0.2* (December 16th, 2007)
2
11
 
3
12
  * Included in Rails 2.0.2
data/README CHANGED
File without changes
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rake/testtask'
4
4
  require 'rake/rdoctask'
5
5
  require 'rake/packagetask'
6
6
  require 'rake/gempackagetask'
7
+ require 'rake/contrib/sshpublisher'
7
8
  require 'rake/contrib/rubyforgepublisher'
8
9
  require File.join(File.dirname(__FILE__), 'lib', 'action_mailer', 'version')
9
10
 
@@ -55,7 +56,7 @@ spec = Gem::Specification.new do |s|
55
56
  s.rubyforge_project = "actionmailer"
56
57
  s.homepage = "http://www.rubyonrails.org"
57
58
 
58
- s.add_dependency('actionpack', '= 2.0.2' + PKG_BUILD)
59
+ s.add_dependency('actionpack', '= 2.0.4' + PKG_BUILD)
59
60
 
60
61
  s.has_rdoc = true
61
62
  s.requirements << 'none'
@@ -76,7 +77,8 @@ end
76
77
 
77
78
  desc "Publish the API documentation"
78
79
  task :pgem => [:package] do
79
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
80
+ Rake::SshFilePublisher.new("david@greed.loudthinking.com", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
81
+ `ssh david@greed.loudthinking.com '/u/sites/gems/gemupdate.sh'`
80
82
  end
81
83
 
82
84
  desc "Publish the API documentation"
File without changes
@@ -463,7 +463,10 @@ module ActionMailer #:nodoc:
463
463
  # no alternate has been given as the parameter, this will fail.
464
464
  def deliver!(mail = @mail)
465
465
  raise "no mail object available for delivery!" unless mail
466
- logger.info "Sent mail:\n #{mail.encoded}" unless logger.nil?
466
+ unless logger.nil?
467
+ logger.info "Sent mail to #{recipients.to_a.join(', ')}"
468
+ logger.debug "\n#{mail.encoded}"
469
+ end
467
470
 
468
471
  begin
469
472
  __send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
@@ -33,7 +33,7 @@ module ActionMailer
33
33
  end
34
34
  end
35
35
 
36
- def setup
36
+ def setup_with_mailer
37
37
  ActionMailer::Base.delivery_method = :test
38
38
  ActionMailer::Base.perform_deliveries = true
39
39
  ActionMailer::Base.deliveries = []
@@ -42,6 +42,19 @@ module ActionMailer
42
42
  @expected.set_content_type "text", "plain", { "charset" => charset }
43
43
  @expected.mime_version = '1.0'
44
44
  end
45
+ alias_method :setup, :setup_with_mailer
46
+
47
+ def self.method_added(method)
48
+ if method.to_s == 'setup'
49
+ unless method_defined?(:setup_without_mailer)
50
+ alias_method :setup_without_mailer, :setup
51
+ define_method(:setup) do
52
+ setup_with_mailer
53
+ setup_without_mailer
54
+ end
55
+ end
56
+ end
57
+ end
45
58
 
46
59
  private
47
60
  def charset
@@ -2,9 +2,9 @@
2
2
  require 'rubygems'
3
3
 
4
4
  begin
5
- gem 'tmail', '~> 1.1.0'
5
+ gem 'tmail', '~> 1.2.1'
6
6
  rescue Gem::LoadError
7
- $:.unshift "#{File.dirname(__FILE__)}/vendor/tmail-1.1.0"
7
+ $:.unshift "#{File.dirname(__FILE__)}/vendor/tmail-1.2.1"
8
8
  end
9
9
 
10
10
  begin
@@ -1,36 +1,35 @@
1
- =begin rdoc
2
-
3
- = Text Encoding class
4
-
5
- =end
6
- #--
7
- # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
1
+ # = TITLE:
2
+ #
3
+ # Text Encoding class
4
+ #
5
+ # = COPYRIGHT:
8
6
  #
9
- # Permission is hereby granted, free of charge, to any person obtaining
10
- # a copy of this software and associated documentation files (the
11
- # "Software"), to deal in the Software without restriction, including
12
- # without limitation the rights to use, copy, modify, merge, publish,
13
- # distribute, sublicense, and/or sell copies of the Software, and to
14
- # permit persons to whom the Software is furnished to do so, subject to
15
- # the following conditions:
7
+ # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
16
8
  #
17
- # The above copyright notice and this permission notice shall be
18
- # included in all copies or substantial portions of the Software.
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
19
16
  #
20
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
27
19
  #
28
- # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
29
- # with permission of Minero Aoki.
30
- #++
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
29
+ # with permission of Minero Aoki.
31
30
 
32
31
  require 'nkf'
33
- require 'tmail/base64.rb'
32
+ require 'tmail/base64'
34
33
  require 'tmail/stringio'
35
34
  require 'tmail/utils'
36
35
 
@@ -52,25 +51,25 @@ module TMail
52
51
  end
53
52
  end
54
53
  module_function :create_dest
55
-
54
+
56
55
  def encoded( eol = "\r\n", charset = 'j', dest = nil )
57
56
  accept_strategy Encoder, eol, charset, dest
58
57
  end
59
-
58
+
60
59
  def decoded( eol = "\n", charset = 'e', dest = nil )
61
60
  # Turn the E-Mail into a string and return it with all
62
61
  # encoded characters decoded. alias for to_s
63
62
  accept_strategy Decoder, eol, charset, dest
64
63
  end
65
-
64
+
66
65
  alias to_s decoded
67
-
66
+
68
67
  def accept_strategy( klass, eol, charset, dest = nil )
69
68
  dest ||= ''
70
69
  accept klass.new( create_dest(dest), charset, eol )
71
70
  dest
72
71
  end
73
-
72
+
74
73
  end
75
74
 
76
75
 
@@ -121,7 +120,7 @@ module TMail
121
120
  def header_body( str )
122
121
  @f << decode(str)
123
122
  end
124
-
123
+
125
124
  def space
126
125
  @f << ' '
127
126
  end
@@ -131,7 +130,7 @@ module TMail
131
130
  def lwsp( str )
132
131
  @f << str
133
132
  end
134
-
133
+
135
134
  def meta( str )
136
135
  @f << str
137
136
  end
@@ -182,7 +181,8 @@ module TMail
182
181
  end
183
182
 
184
183
  SPACER = "\t"
185
- MAX_LINE_LEN = 70
184
+ MAX_LINE_LEN = 78
185
+ RFC_2822_MAX_LENGTH = 998
186
186
 
187
187
  OPTIONS = {
188
188
  'EUC' => '-Ej -m0',
@@ -202,7 +202,7 @@ module TMail
202
202
  def preserve_quotes=( bool )
203
203
  @preserve_quotes
204
204
  end
205
-
205
+
206
206
  def preserve_quotes
207
207
  @preserve_quotes
208
208
  end
@@ -378,7 +378,7 @@ module TMail
378
378
  i += 1
379
379
  end
380
380
  end
381
-
381
+
382
382
  METHOD_ID = {
383
383
  ?j => :extract_J,
384
384
  ?e => :extract_E,
@@ -451,31 +451,73 @@ module TMail
451
451
  # puts '---- lwsp -------------------------------------'
452
452
  # puts "+ #{lwsp.inspect}"
453
453
  fold if restsize() <= 0
454
- flush
454
+ flush(@folded)
455
455
  @lwsp = lwsp
456
456
  end
457
457
 
458
- def flush
458
+ def flush(folded = false)
459
459
  # puts '---- flush ----'
460
460
  # puts "spc >>>#{@lwsp.inspect}<<<"
461
461
  # puts "txt >>>#{@text.inspect}<<<"
462
462
  @f << @lwsp << @text
463
- @curlen += (@lwsp.size + @text.size)
463
+ if folded
464
+ @curlen = 0
465
+ else
466
+ @curlen += (@lwsp.size + @text.size)
467
+ end
464
468
  @text = ''
465
469
  @lwsp = ''
466
470
  end
467
471
 
468
472
  def fold
469
473
  # puts '---- fold ----'
470
- @f << @eol
474
+ unless @f.string =~ /^.*?:$/
475
+ @f << @eol
476
+ @lwsp = SPACER
477
+ else
478
+ fold_header
479
+ @folded = true
480
+ end
471
481
  @curlen = 0
472
- @lwsp = SPACER
482
+ end
483
+
484
+ def fold_header
485
+ # Called because line is too long - so we need to wrap.
486
+ # First look for whitespace in the text
487
+ # if it has text, fold there
488
+ # check the remaining text, if too long, fold again
489
+ # if it doesn't, then don't fold unless the line goes beyond 998 chars
490
+
491
+ # Check the text to see if there is whitespace, or if not
492
+ @wrapped_text = []
493
+ until @text == ''
494
+ fold_the_string
495
+ end
496
+ @text = @wrapped_text.join("#{@eol}#{SPACER}")
497
+ end
498
+
499
+ def fold_the_string
500
+ whitespace_location = @text =~ /\s/ || @text.length
501
+ # Is the location of the whitespace shorter than the RCF_2822_MAX_LENGTH?
502
+ # if there is no whitespace in the string, then this
503
+ unless mazsize(whitespace_location) <= 0
504
+ @wrapped_text << @text.slice!(0...whitespace_location)
505
+ # If it is not less, we have to wrap it destructively
506
+ else
507
+ slice_point = RFC_2822_MAX_LENGTH - @curlen - @lwsp.length
508
+ @wrapped_text << @text.slice!(0...slice_point)
509
+ end
473
510
  end
474
511
 
475
512
  def restsize
476
513
  MAX_LINE_LEN - (@curlen + @lwsp.size + @text.size)
477
514
  end
478
515
 
516
+ def mazsize(whitespace_location)
517
+ # Per RFC2822, the maximum length of a line is 998 chars
518
+ RFC_2822_MAX_LENGTH - (@curlen + @lwsp.size + whitespace_location)
519
+ end
520
+
479
521
  end
480
522
 
481
523
  end # module TMail
@@ -54,8 +54,40 @@ module TMail
54
54
  klass.newobj body, conf
55
55
  end
56
56
 
57
+ # Returns a HeaderField object matching the header you specify in the "name" param.
58
+ # Requires an initialized TMail::Port to be passed in.
59
+ #
60
+ # The method searches the header of the Port you pass into it to find a match on
61
+ # the header line you pass. Once a match is found, it will unwrap the matching line
62
+ # as needed to return an initialized HeaderField object.
63
+ #
64
+ # If you want to get the Envelope sender of the email object, pass in "EnvelopeSender",
65
+ # if you want the From address of the email itself, pass in 'From'.
66
+ #
67
+ # This is because a mailbox doesn't have the : after the From that designates the
68
+ # beginning of the envelope sender (which can be different to the from address of
69
+ # the emial)
70
+ #
71
+ # Other fields can be passed as normal, "Reply-To", "Received" etc.
72
+ #
73
+ # Note: Change of behaviour in 1.2.1 => returns nil if it does not find the specified
74
+ # header field, otherwise returns an instantiated object of the correct header class
75
+ #
76
+ # For example:
77
+ # port = TMail::FilePort.new("/test/fixtures/raw_email_simple")
78
+ # h = TMail::HeaderField.new_from_port(port, "From")
79
+ # h.addrs.to_s #=> "Mikel Lindsaar <mikel@nowhere.com>"
80
+ # h = TMail::HeaderField.new_from_port(port, "EvelopeSender")
81
+ # h.addrs.to_s #=> "mike@anotherplace.com.au"
82
+ # h = TMail::HeaderField.new_from_port(port, "SomeWeirdHeaderField")
83
+ # h #=> nil
57
84
  def new_from_port( port, name, conf = DEFAULT_CONFIG )
58
- re = Regep.new('\A(' + Regexp.quote(name) + '):', 'i')
85
+ if name == "EnvelopeSender"
86
+ name = "From"
87
+ re = Regexp.new('\A(From) ', 'i')
88
+ else
89
+ re = Regexp.new('\A(' + Regexp.quote(name) + '):', 'i')
90
+ end
59
91
  str = nil
60
92
  port.ropen {|f|
61
93
  f.each do |line|
@@ -66,7 +98,7 @@ module TMail
66
98
  end
67
99
  end
68
100
  }
69
- new(name, str, Config.to_config(conf))
101
+ new(name, str, Config.to_config(conf)) if str
70
102
  end
71
103
 
72
104
  def internal_new( name, conf )
@@ -0,0 +1,1123 @@
1
+ =begin rdoc
2
+
3
+ = interface.rb Provides an interface to the TMail object
4
+
5
+ =end
6
+ #--
7
+ # Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ # Note: Originally licensed under LGPL v2+. Using MIT license for Rails
29
+ # with permission of Minero Aoki.
30
+ #++
31
+
32
+ # TMail::Mail objects get accessed primarily through the methods in this file.
33
+ #
34
+ #
35
+
36
+ require 'tmail/utils'
37
+
38
+ module TMail
39
+
40
+ class Mail
41
+
42
+ # Allows you to query the mail object with a string to get the contents
43
+ # of the field you want.
44
+ #
45
+ # Returns a string of the exact contnts of the field
46
+ #
47
+ # mail.from = "mikel <mikel@lindsaar.net>"
48
+ # mail.header_string("From") #=> "mikel <mikel@lindsaar.net>"
49
+ def header_string( name, default = nil )
50
+ h = @header[name.downcase] or return default
51
+ h.to_s
52
+ end
53
+
54
+ #:stopdoc:
55
+ #--
56
+ #== Attributes
57
+
58
+ include TextUtils
59
+
60
+ def set_string_array_attr( key, strs )
61
+ strs.flatten!
62
+ if strs.empty?
63
+ @header.delete key.downcase
64
+ else
65
+ store key, strs.join(', ')
66
+ end
67
+ strs
68
+ end
69
+ private :set_string_array_attr
70
+
71
+ def set_string_attr( key, str )
72
+ if str
73
+ store key, str
74
+ else
75
+ @header.delete key.downcase
76
+ end
77
+ str
78
+ end
79
+ private :set_string_attr
80
+
81
+ def set_addrfield( name, arg )
82
+ if arg
83
+ h = HeaderField.internal_new(name, @config)
84
+ h.addrs.replace [arg].flatten
85
+ @header[name] = h
86
+ else
87
+ @header.delete name
88
+ end
89
+ arg
90
+ end
91
+ private :set_addrfield
92
+
93
+ def addrs2specs( addrs )
94
+ return nil unless addrs
95
+ list = addrs.map {|addr|
96
+ if addr.address_group?
97
+ then addr.map {|a| a.spec }
98
+ else addr.spec
99
+ end
100
+ }.flatten
101
+ return nil if list.empty?
102
+ list
103
+ end
104
+ private :addrs2specs
105
+
106
+ #:startdoc:
107
+
108
+ #== Date and Time methods
109
+
110
+ # Returns the date of the email message as per the "date" header value or returns
111
+ # nil by default (if no date field exists).
112
+ #
113
+ # You can also pass whatever default you want into this method and it will return
114
+ # that instead of nil if there is no date already set.
115
+ def date( default = nil )
116
+ if h = @header['date']
117
+ h.date
118
+ else
119
+ default
120
+ end
121
+ end
122
+
123
+ # Destructively sets the date of the mail object with the passed Time instance,
124
+ # returns a Time instance set to the date/time of the mail
125
+ #
126
+ # Example:
127
+ #
128
+ # now = Time.now
129
+ # mail.date = now
130
+ # mail.date #=> Sat Nov 03 18:47:50 +1100 2007
131
+ # mail.date.class #=> Time
132
+ def date=( time )
133
+ if time
134
+ store 'Date', time2str(time)
135
+ else
136
+ @header.delete 'date'
137
+ end
138
+ time
139
+ end
140
+
141
+ # Returns the time of the mail message formatted to your taste using a
142
+ # strftime format string. If no date set returns nil by default or whatever value
143
+ # you pass as the second optional parameter.
144
+ #
145
+ # time = Time.now # (on Nov 16 2007)
146
+ # mail.date = time
147
+ # mail.strftime("%D") #=> "11/16/07"
148
+ def strftime( fmt, default = nil )
149
+ if t = date
150
+ t.strftime(fmt)
151
+ else
152
+ default
153
+ end
154
+ end
155
+
156
+ #== Destination methods
157
+
158
+ # Return a TMail::Addresses instance for each entry in the "To:" field of the mail object header.
159
+ #
160
+ # If the "To:" field does not exist, will return nil by default or the value you
161
+ # pass as the optional parameter.
162
+ #
163
+ # Example:
164
+ #
165
+ # mail = TMail::Mail.new
166
+ # mail.to_addrs #=> nil
167
+ # mail.to_addrs([]) #=> []
168
+ # mail.to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
169
+ # mail.to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
170
+ def to_addrs( default = nil )
171
+ if h = @header['to']
172
+ h.addrs
173
+ else
174
+ default
175
+ end
176
+ end
177
+
178
+ # Return a TMail::Addresses instance for each entry in the "Cc:" field of the mail object header.
179
+ #
180
+ # If the "Cc:" field does not exist, will return nil by default or the value you
181
+ # pass as the optional parameter.
182
+ #
183
+ # Example:
184
+ #
185
+ # mail = TMail::Mail.new
186
+ # mail.cc_addrs #=> nil
187
+ # mail.cc_addrs([]) #=> []
188
+ # mail.cc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
189
+ # mail.cc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
190
+ def cc_addrs( default = nil )
191
+ if h = @header['cc']
192
+ h.addrs
193
+ else
194
+ default
195
+ end
196
+ end
197
+
198
+ # Return a TMail::Addresses instance for each entry in the "Bcc:" field of the mail object header.
199
+ #
200
+ # If the "Bcc:" field does not exist, will return nil by default or the value you
201
+ # pass as the optional parameter.
202
+ #
203
+ # Example:
204
+ #
205
+ # mail = TMail::Mail.new
206
+ # mail.bcc_addrs #=> nil
207
+ # mail.bcc_addrs([]) #=> []
208
+ # mail.bcc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
209
+ # mail.bcc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
210
+ def bcc_addrs( default = nil )
211
+ if h = @header['bcc']
212
+ h.addrs
213
+ else
214
+ default
215
+ end
216
+ end
217
+
218
+ # Destructively set the to field of the "To:" header to equal the passed in string.
219
+ #
220
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
221
+ # object before assigning it to the mail message.
222
+ #
223
+ # Example:
224
+ #
225
+ # mail = TMail::Mail.new
226
+ # mail.to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
227
+ # mail.to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
228
+ def to_addrs=( arg )
229
+ set_addrfield 'to', arg
230
+ end
231
+
232
+ # Destructively set the to field of the "Cc:" header to equal the passed in string.
233
+ #
234
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
235
+ # object before assigning it to the mail message.
236
+ #
237
+ # Example:
238
+ #
239
+ # mail = TMail::Mail.new
240
+ # mail.cc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
241
+ # mail.cc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
242
+ def cc_addrs=( arg )
243
+ set_addrfield 'cc', arg
244
+ end
245
+
246
+ # Destructively set the to field of the "Bcc:" header to equal the passed in string.
247
+ #
248
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
249
+ # object before assigning it to the mail message.
250
+ #
251
+ # Example:
252
+ #
253
+ # mail = TMail::Mail.new
254
+ # mail.bcc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
255
+ # mail.bcc_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
256
+ def bcc_addrs=( arg )
257
+ set_addrfield 'bcc', arg
258
+ end
259
+
260
+ # Returns who the email is to as an Array of email addresses as opposed to an Array of
261
+ # TMail::Address objects which is what Mail#to_addrs returns
262
+ #
263
+ # Example:
264
+ #
265
+ # mail = TMail::Mail.new
266
+ # mail.to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
267
+ # mail.to #=> ["mikel@me.org", "mikel@you.org"]
268
+ def to( default = nil )
269
+ addrs2specs(to_addrs(nil)) || default
270
+ end
271
+
272
+ # Returns who the email cc'd as an Array of email addresses as opposed to an Array of
273
+ # TMail::Address objects which is what Mail#to_addrs returns
274
+ #
275
+ # Example:
276
+ #
277
+ # mail = TMail::Mail.new
278
+ # mail.cc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
279
+ # mail.cc #=> ["mikel@me.org", "mikel@you.org"]
280
+ def cc( default = nil )
281
+ addrs2specs(cc_addrs(nil)) || default
282
+ end
283
+
284
+ # Returns who the email bcc'd as an Array of email addresses as opposed to an Array of
285
+ # TMail::Address objects which is what Mail#to_addrs returns
286
+ #
287
+ # Example:
288
+ #
289
+ # mail = TMail::Mail.new
290
+ # mail.bcc = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
291
+ # mail.bcc #=> ["mikel@me.org", "mikel@you.org"]
292
+ def bcc( default = nil )
293
+ addrs2specs(bcc_addrs(nil)) || default
294
+ end
295
+
296
+ # Destructively sets the "To:" field to the passed array of strings (which should be valid
297
+ # email addresses)
298
+ #
299
+ # Example:
300
+ #
301
+ # mail = TMail::Mail.new
302
+ # mail.to = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
303
+ # mail.to #=> ["mikel@abc.org", "mikel@xyz.org"]
304
+ # mail['to'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
305
+ def to=( *strs )
306
+ set_string_array_attr 'To', strs
307
+ end
308
+
309
+ # Destructively sets the "Cc:" field to the passed array of strings (which should be valid
310
+ # email addresses)
311
+ #
312
+ # Example:
313
+ #
314
+ # mail = TMail::Mail.new
315
+ # mail.cc = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
316
+ # mail.cc #=> ["mikel@abc.org", "mikel@xyz.org"]
317
+ # mail['cc'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
318
+ def cc=( *strs )
319
+ set_string_array_attr 'Cc', strs
320
+ end
321
+
322
+ # Destructively sets the "Bcc:" field to the passed array of strings (which should be valid
323
+ # email addresses)
324
+ #
325
+ # Example:
326
+ #
327
+ # mail = TMail::Mail.new
328
+ # mail.bcc = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
329
+ # mail.bcc #=> ["mikel@abc.org", "mikel@xyz.org"]
330
+ # mail['bcc'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
331
+ def bcc=( *strs )
332
+ set_string_array_attr 'Bcc', strs
333
+ end
334
+
335
+ #== Originator methods
336
+
337
+ # Return a TMail::Addresses instance for each entry in the "From:" field of the mail object header.
338
+ #
339
+ # If the "From:" field does not exist, will return nil by default or the value you
340
+ # pass as the optional parameter.
341
+ #
342
+ # Example:
343
+ #
344
+ # mail = TMail::Mail.new
345
+ # mail.from_addrs #=> nil
346
+ # mail.from_addrs([]) #=> []
347
+ # mail.from = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
348
+ # mail.from_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
349
+ def from_addrs( default = nil )
350
+ if h = @header['from']
351
+ h.addrs
352
+ else
353
+ default
354
+ end
355
+ end
356
+
357
+ # Destructively set the to value of the "From:" header to equal the passed in string.
358
+ #
359
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
360
+ # object before assigning it to the mail message.
361
+ #
362
+ # Example:
363
+ #
364
+ # mail = TMail::Mail.new
365
+ # mail.from_addrs = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
366
+ # mail.from_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
367
+ def from_addrs=( arg )
368
+ set_addrfield 'from', arg
369
+ end
370
+
371
+ # Returns who the email is from as an Array of email address strings instead to an Array of
372
+ # TMail::Address objects which is what Mail#from_addrs returns
373
+ #
374
+ # Example:
375
+ #
376
+ # mail = TMail::Mail.new
377
+ # mail.from = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
378
+ # mail.from #=> ["mikel@me.org", "mikel@you.org"]
379
+ def from( default = nil )
380
+ addrs2specs(from_addrs(nil)) || default
381
+ end
382
+
383
+ # Destructively sets the "From:" field to the passed array of strings (which should be valid
384
+ # email addresses)
385
+ #
386
+ # Example:
387
+ #
388
+ # mail = TMail::Mail.new
389
+ # mail.from = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
390
+ # mail.from #=> ["mikel@abc.org", "mikel@xyz.org"]
391
+ # mail['from'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
392
+ def from=( *strs )
393
+ set_string_array_attr 'From', strs
394
+ end
395
+
396
+ # Returns the "friendly" human readable part of the address
397
+ #
398
+ # Example:
399
+ #
400
+ # mail = TMail::Mail.new
401
+ # mail.from = "Mikel Lindsaar <mikel@abc.com>"
402
+ # mail.friendly_from #=> "Mikel Lindsaar"
403
+ def friendly_from( default = nil )
404
+ h = @header['from']
405
+ a, = h.addrs
406
+ return default unless a
407
+ return a.phrase if a.phrase
408
+ return h.comments.join(' ') unless h.comments.empty?
409
+ a.spec
410
+ end
411
+
412
+ # Return a TMail::Addresses instance for each entry in the "Reply-To:" field of the mail object header.
413
+ #
414
+ # If the "Reply-To:" field does not exist, will return nil by default or the value you
415
+ # pass as the optional parameter.
416
+ #
417
+ # Example:
418
+ #
419
+ # mail = TMail::Mail.new
420
+ # mail.reply_to_addrs #=> nil
421
+ # mail.reply_to_addrs([]) #=> []
422
+ # mail.reply_to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
423
+ # mail.reply_to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
424
+ def reply_to_addrs( default = nil )
425
+ if h = @header['reply-to']
426
+ h.addrs.blank? ? default : h.addrs
427
+ else
428
+ default
429
+ end
430
+ end
431
+
432
+ # Destructively set the to value of the "Reply-To:" header to equal the passed in argument.
433
+ #
434
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
435
+ # object before assigning it to the mail message.
436
+ #
437
+ # Example:
438
+ #
439
+ # mail = TMail::Mail.new
440
+ # mail.reply_to_addrs = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
441
+ # mail.reply_to_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
442
+ def reply_to_addrs=( arg )
443
+ set_addrfield 'reply-to', arg
444
+ end
445
+
446
+ # Returns who the email is from as an Array of email address strings instead to an Array of
447
+ # TMail::Address objects which is what Mail#reply_to_addrs returns
448
+ #
449
+ # Example:
450
+ #
451
+ # mail = TMail::Mail.new
452
+ # mail.reply_to = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
453
+ # mail.reply_to #=> ["mikel@me.org", "mikel@you.org"]
454
+ def reply_to( default = nil )
455
+ addrs2specs(reply_to_addrs(nil)) || default
456
+ end
457
+
458
+ # Destructively sets the "Reply-To:" field to the passed array of strings (which should be valid
459
+ # email addresses)
460
+ #
461
+ # Example:
462
+ #
463
+ # mail = TMail::Mail.new
464
+ # mail.reply_to = ["mikel@abc.com", "Mikel <mikel@xyz.com>"]
465
+ # mail.reply_to #=> ["mikel@abc.org", "mikel@xyz.org"]
466
+ # mail['reply_to'].to_s #=> "mikel@abc.com, Mikel <mikel@xyz.com>"
467
+ def reply_to=( *strs )
468
+ set_string_array_attr 'Reply-To', strs
469
+ end
470
+
471
+ # Return a TMail::Addresses instance of the "Sender:" field of the mail object header.
472
+ #
473
+ # If the "Sender:" field does not exist, will return nil by default or the value you
474
+ # pass as the optional parameter.
475
+ #
476
+ # Example:
477
+ #
478
+ # mail = TMail::Mail.new
479
+ # mail.sender #=> nil
480
+ # mail.sender([]) #=> []
481
+ # mail.sender = "Mikel <mikel@me.org>"
482
+ # mail.reply_to_addrs #=> [#<TMail::Address mikel@me.org>]
483
+ def sender_addr( default = nil )
484
+ f = @header['sender'] or return default
485
+ f.addr or return default
486
+ end
487
+
488
+ # Destructively set the to value of the "Sender:" header to equal the passed in argument.
489
+ #
490
+ # TMail will parse your contents and turn each valid email address into a TMail::Address
491
+ # object before assigning it to the mail message.
492
+ #
493
+ # Example:
494
+ #
495
+ # mail = TMail::Mail.new
496
+ # mail.sender_addrs = "Mikel <mikel@me.org>, another Mikel <mikel@you.org>"
497
+ # mail.sender_addrs #=> [#<TMail::Address mikel@me.org>, #<TMail::Address mikel@you.org>]
498
+ def sender_addr=( addr )
499
+ if addr
500
+ h = HeaderField.internal_new('sender', @config)
501
+ h.addr = addr
502
+ @header['sender'] = h
503
+ else
504
+ @header.delete 'sender'
505
+ end
506
+ addr
507
+ end
508
+
509
+ # Returns who the sender of this mail is as string instead to an Array of
510
+ # TMail::Address objects which is what Mail#sender_addr returns
511
+ #
512
+ # Example:
513
+ #
514
+ # mail = TMail::Mail.new
515
+ # mail.sender = "Mikel <mikel@me.org>"
516
+ # mail.sender #=> "mikel@me.org"
517
+ def sender( default = nil )
518
+ f = @header['sender'] or return default
519
+ a = f.addr or return default
520
+ a.spec
521
+ end
522
+
523
+ # Destructively sets the "Sender:" field to the passed string (which should be a valid
524
+ # email address)
525
+ #
526
+ # Example:
527
+ #
528
+ # mail = TMail::Mail.new
529
+ # mail.sender = "mikel@abc.com"
530
+ # mail.sender #=> "mikel@abc.org"
531
+ # mail['sender'].to_s #=> "mikel@abc.com"
532
+ def sender=( str )
533
+ set_string_attr 'Sender', str
534
+ end
535
+
536
+ #== Subject methods
537
+
538
+ # Returns the subject of the mail instance.
539
+ #
540
+ # If the subject field does not exist, returns nil by default or you can pass in as
541
+ # the parameter for what you want the default value to be.
542
+ #
543
+ # Example:
544
+ #
545
+ # mail = TMail::Mail.new
546
+ # mail.subject #=> nil
547
+ # mail.subject("") #=> ""
548
+ # mail.subject = "Hello"
549
+ # mail.subject #=> "Hello"
550
+ def subject( default = nil )
551
+ if h = @header['subject']
552
+ h.body
553
+ else
554
+ default
555
+ end
556
+ end
557
+ alias quoted_subject subject
558
+
559
+ # Destructively sets the passed string as the subject of the mail message.
560
+ #
561
+ # Example
562
+ #
563
+ # mail = TMail::Mail.new
564
+ # mail.subject #=> "This subject"
565
+ # mail.subject = "Another subject"
566
+ # mail.subject #=> "Another subject"
567
+ def subject=( str )
568
+ set_string_attr 'Subject', str
569
+ end
570
+
571
+ #== Message Identity & Threading Methods
572
+
573
+ # Returns the message ID for this mail object instance.
574
+ #
575
+ # If the message_id field does not exist, returns nil by default or you can pass in as
576
+ # the parameter for what you want the default value to be.
577
+ #
578
+ # Example:
579
+ #
580
+ # mail = TMail::Mail.new
581
+ # mail.message_id #=> nil
582
+ # mail.message_id(TMail.new_message_id) #=> "<47404c5326d9c_2ad4fbb80161@baci.local.tmail>"
583
+ # mail.message_id = TMail.new_message_id
584
+ # mail.message_id #=> "<47404c5326d9c_2ad4fbb80161@baci.local.tmail>"
585
+ def message_id( default = nil )
586
+ if h = @header['message-id']
587
+ h.id || default
588
+ else
589
+ default
590
+ end
591
+ end
592
+
593
+ # Destructively sets the message ID of the mail object instance to the passed in string
594
+ #
595
+ # Example:
596
+ #
597
+ # mail = TMail::Mail.new
598
+ # mail.message_id = "this_is_my_badly_formatted_message_id"
599
+ # mail.message_id #=> "this_is_my_badly_formatted_message_id"
600
+ def message_id=( str )
601
+ set_string_attr 'Message-Id', str
602
+ end
603
+
604
+ # Returns the "In-Reply-To:" field contents as an array of this mail instance if it exists
605
+ #
606
+ # If the in_reply_to field does not exist, returns nil by default or you can pass in as
607
+ # the parameter for what you want the default value to be.
608
+ #
609
+ # Example:
610
+ #
611
+ # mail = TMail::Mail.new
612
+ # mail.in_reply_to #=> nil
613
+ # mail.in_reply_to([]) #=> []
614
+ # TMail::Mail.load("../test/fixtures/raw_email_reply")
615
+ # mail.in_reply_to #=> ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
616
+ def in_reply_to( default = nil )
617
+ if h = @header['in-reply-to']
618
+ h.ids
619
+ else
620
+ default
621
+ end
622
+ end
623
+
624
+ # Destructively sets the value of the "In-Reply-To:" field of an email.
625
+ #
626
+ # Accepts an array of a single string of a message id
627
+ #
628
+ # Example:
629
+ #
630
+ # mail = TMail::Mail.new
631
+ # mail.in_reply_to = ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
632
+ # mail.in_reply_to #=> ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
633
+ def in_reply_to=( *idstrs )
634
+ set_string_array_attr 'In-Reply-To', idstrs
635
+ end
636
+
637
+ # Returns the references of this email (prior messages relating to this message)
638
+ # as an array of message ID strings. Useful when you are trying to thread an
639
+ # email.
640
+ #
641
+ # If the references field does not exist, returns nil by default or you can pass in as
642
+ # the parameter for what you want the default value to be.
643
+ #
644
+ # Example:
645
+ #
646
+ # mail = TMail::Mail.new
647
+ # mail.references #=> nil
648
+ # mail.references([]) #=> []
649
+ # mail = TMail::Mail.load("../test/fixtures/raw_email_reply")
650
+ # mail.references #=> ["<473FF3B8.9020707@xxx.org>", "<348F04F142D69C21-291E56D292BC@xxxx.net>"]
651
+ def references( default = nil )
652
+ if h = @header['references']
653
+ h.refs
654
+ else
655
+ default
656
+ end
657
+ end
658
+
659
+ # Destructively sets the value of the "References:" field of an email.
660
+ #
661
+ # Accepts an array of strings of message IDs
662
+ #
663
+ # Example:
664
+ #
665
+ # mail = TMail::Mail.new
666
+ # mail.references = ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
667
+ # mail.references #=> ["<348F04F142D69C21-291E56D292BC@xxxx.net>"]
668
+ def references=( *strs )
669
+ set_string_array_attr 'References', strs
670
+ end
671
+
672
+ #== MIME header methods
673
+
674
+ # Returns the listed MIME version of this email from the "Mime-Version:" header field
675
+ #
676
+ # If the mime_version field does not exist, returns nil by default or you can pass in as
677
+ # the parameter for what you want the default value to be.
678
+ #
679
+ # Example:
680
+ #
681
+ # mail = TMail::Mail.new
682
+ # mail.mime_version #=> nil
683
+ # mail.mime_version([]) #=> []
684
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
685
+ # mail.mime_version #=> "1.0"
686
+ def mime_version( default = nil )
687
+ if h = @header['mime-version']
688
+ h.version || default
689
+ else
690
+ default
691
+ end
692
+ end
693
+
694
+ def mime_version=( m, opt = nil )
695
+ if opt
696
+ if h = @header['mime-version']
697
+ h.major = m
698
+ h.minor = opt
699
+ else
700
+ store 'Mime-Version', "#{m}.#{opt}"
701
+ end
702
+ else
703
+ store 'Mime-Version', m
704
+ end
705
+ m
706
+ end
707
+
708
+ # Returns the current "Content-Type" of the mail instance.
709
+ #
710
+ # If the content_type field does not exist, returns nil by default or you can pass in as
711
+ # the parameter for what you want the default value to be.
712
+ #
713
+ # Example:
714
+ #
715
+ # mail = TMail::Mail.new
716
+ # mail.content_type #=> nil
717
+ # mail.content_type([]) #=> []
718
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
719
+ # mail.content_type #=> "text/plain"
720
+ def content_type( default = nil )
721
+ if h = @header['content-type']
722
+ h.content_type || default
723
+ else
724
+ default
725
+ end
726
+ end
727
+
728
+ # Returns the current main type of the "Content-Type" of the mail instance.
729
+ #
730
+ # If the content_type field does not exist, returns nil by default or you can pass in as
731
+ # the parameter for what you want the default value to be.
732
+ #
733
+ # Example:
734
+ #
735
+ # mail = TMail::Mail.new
736
+ # mail.main_type #=> nil
737
+ # mail.main_type([]) #=> []
738
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
739
+ # mail.main_type #=> "text"
740
+ def main_type( default = nil )
741
+ if h = @header['content-type']
742
+ h.main_type || default
743
+ else
744
+ default
745
+ end
746
+ end
747
+
748
+ # Returns the current sub type of the "Content-Type" of the mail instance.
749
+ #
750
+ # If the content_type field does not exist, returns nil by default or you can pass in as
751
+ # the parameter for what you want the default value to be.
752
+ #
753
+ # Example:
754
+ #
755
+ # mail = TMail::Mail.new
756
+ # mail.sub_type #=> nil
757
+ # mail.sub_type([]) #=> []
758
+ # mail = TMail::Mail.load("../test/fixtures/raw_email")
759
+ # mail.sub_type #=> "plain"
760
+ def sub_type( default = nil )
761
+ if h = @header['content-type']
762
+ h.sub_type || default
763
+ else
764
+ default
765
+ end
766
+ end
767
+
768
+ # Destructively sets the "Content-Type:" header field of this mail object
769
+ #
770
+ # Allows you to set the main type, sub type as well as parameters to the field.
771
+ # The main type and sub type need to be a string.
772
+ #
773
+ # The optional params hash can be passed with keys as symbols and values as a string,
774
+ # or strings as keys and values.
775
+ #
776
+ # Example:
777
+ #
778
+ # mail = TMail::Mail.new
779
+ # mail.set_content_type("text", "plain")
780
+ # mail.to_s #=> "Content-Type: text/plain\n\n"
781
+ #
782
+ # mail.set_content_type("text", "plain", {:charset => "EUC-KR", :format => "flowed"})
783
+ # mail.to_s #=> "Content-Type: text/plain; charset=EUC-KR; format=flowed\n\n"
784
+ #
785
+ # mail.set_content_type("text", "plain", {"charset" => "EUC-KR", "format" => "flowed"})
786
+ # mail.to_s #=> "Content-Type: text/plain; charset=EUC-KR; format=flowed\n\n"
787
+ def set_content_type( str, sub = nil, param = nil )
788
+ if sub
789
+ main, sub = str, sub
790
+ else
791
+ main, sub = str.split(%r</>, 2)
792
+ raise ArgumentError, "sub type missing: #{str.inspect}" unless sub
793
+ end
794
+ if h = @header['content-type']
795
+ h.main_type = main
796
+ h.sub_type = sub
797
+ h.params.clear
798
+ else
799
+ store 'Content-Type', "#{main}/#{sub}"
800
+ end
801
+ @header['content-type'].params.replace param if param
802
+ str
803
+ end
804
+
805
+ alias content_type= set_content_type
806
+
807
+ # Returns the named type parameter as a string, from the "Content-Type:" header.
808
+ #
809
+ # Example:
810
+ #
811
+ # mail = TMail::Mail.new
812
+ # mail.type_param("charset") #=> nil
813
+ # mail.type_param("charset", []) #=> []
814
+ # mail.set_content_type("text", "plain", {:charset => "EUC-KR", :format => "flowed"})
815
+ # mail.type_param("charset") #=> "EUC-KR"
816
+ # mail.type_param("format") #=> "flowed"
817
+ def type_param( name, default = nil )
818
+ if h = @header['content-type']
819
+ h[name] || default
820
+ else
821
+ default
822
+ end
823
+ end
824
+
825
+ # Returns the character set of the email. Returns nil if no encoding set or returns
826
+ # whatever default you pass as a parameter - note passing the parameter does NOT change
827
+ # the mail object in any way.
828
+ #
829
+ # Example:
830
+ #
831
+ # mail = TMail::Mail.load("path_to/utf8_email")
832
+ # mail.charset #=> "UTF-8"
833
+ #
834
+ # mail = TMail::Mail.new
835
+ # mail.charset #=> nil
836
+ # mail.charset("US-ASCII") #=> "US-ASCII"
837
+ def charset( default = nil )
838
+ if h = @header['content-type']
839
+ h['charset'] or default
840
+ else
841
+ default
842
+ end
843
+ end
844
+
845
+ # Destructively sets the character set used by this mail object to the passed string, you
846
+ # should note though that this does nothing to the mail body, just changes the header
847
+ # value, you will need to transliterate the body as well to match whatever you put
848
+ # in this header value if you are changing character sets.
849
+ #
850
+ # Example:
851
+ #
852
+ # mail = TMail::Mail.new
853
+ # mail.charset #=> nil
854
+ # mail.charset = "UTF-8"
855
+ # mail.charset #=> "UTF-8"
856
+ def charset=( str )
857
+ if str
858
+ if h = @header[ 'content-type' ]
859
+ h['charset'] = str
860
+ else
861
+ store 'Content-Type', "text/plain; charset=#{str}"
862
+ end
863
+ end
864
+ str
865
+ end
866
+
867
+ # Returns the transfer encoding of the email. Returns nil if no encoding set or returns
868
+ # whatever default you pass as a parameter - note passing the parameter does NOT change
869
+ # the mail object in any way.
870
+ #
871
+ # Example:
872
+ #
873
+ # mail = TMail::Mail.load("path_to/base64_encoded_email")
874
+ # mail.transfer_encoding #=> "base64"
875
+ #
876
+ # mail = TMail::Mail.new
877
+ # mail.transfer_encoding #=> nil
878
+ # mail.transfer_encoding("base64") #=> "base64"
879
+ def transfer_encoding( default = nil )
880
+ if h = @header['content-transfer-encoding']
881
+ h.encoding || default
882
+ else
883
+ default
884
+ end
885
+ end
886
+
887
+ # Destructively sets the transfer encoding of the mail object to the passed string, you
888
+ # should note though that this does nothing to the mail body, just changes the header
889
+ # value, you will need to encode or decode the body as well to match whatever you put
890
+ # in this header value.
891
+ #
892
+ # Example:
893
+ #
894
+ # mail = TMail::Mail.new
895
+ # mail.transfer_encoding #=> nil
896
+ # mail.transfer_encoding = "base64"
897
+ # mail.transfer_encoding #=> "base64"
898
+ def transfer_encoding=( str )
899
+ set_string_attr 'Content-Transfer-Encoding', str
900
+ end
901
+
902
+ alias encoding transfer_encoding
903
+ alias encoding= transfer_encoding=
904
+ alias content_transfer_encoding transfer_encoding
905
+ alias content_transfer_encoding= transfer_encoding=
906
+
907
+ # Returns the content-disposition of the mail object, returns nil or the passed
908
+ # default value if given
909
+ #
910
+ # Example:
911
+ #
912
+ # mail = TMail::Mail.load("path_to/raw_mail_with_attachment")
913
+ # mail.disposition #=> "attachment"
914
+ #
915
+ # mail = TMail::Mail.load("path_to/plain_simple_email")
916
+ # mail.disposition #=> nil
917
+ # mail.disposition(false) #=> false
918
+ def disposition( default = nil )
919
+ if h = @header['content-disposition']
920
+ h.disposition || default
921
+ else
922
+ default
923
+ end
924
+ end
925
+
926
+ alias content_disposition disposition
927
+
928
+ # Allows you to set the content-disposition of the mail object. Accepts a type
929
+ # and a hash of parameters.
930
+ #
931
+ # Example:
932
+ #
933
+ # mail.set_disposition("attachment", {:filename => "test.rb"})
934
+ # mail.disposition #=> "attachment"
935
+ # mail['content-disposition'].to_s #=> "attachment; filename=test.rb"
936
+ def set_disposition( str, params = nil )
937
+ if h = @header['content-disposition']
938
+ h.disposition = str
939
+ h.params.clear
940
+ else
941
+ store('Content-Disposition', str)
942
+ h = @header['content-disposition']
943
+ end
944
+ h.params.replace params if params
945
+ end
946
+
947
+ alias disposition= set_disposition
948
+ alias set_content_disposition set_disposition
949
+ alias content_disposition= set_disposition
950
+
951
+ # Returns the value of a parameter in an existing content-disposition header
952
+ #
953
+ # Example:
954
+ #
955
+ # mail.set_disposition("attachment", {:filename => "test.rb"})
956
+ # mail['content-disposition'].to_s #=> "attachment; filename=test.rb"
957
+ # mail.disposition_param("filename") #=> "test.rb"
958
+ # mail.disposition_param("missing_param_key") #=> nil
959
+ # mail.disposition_param("missing_param_key", false) #=> false
960
+ # mail.disposition_param("missing_param_key", "Nothing to see here") #=> "Nothing to see here"
961
+ def disposition_param( name, default = nil )
962
+ if h = @header['content-disposition']
963
+ h[name] || default
964
+ else
965
+ default
966
+ end
967
+ end
968
+
969
+ # Destructively convert the Mail object's body into a Base64 encoded email
970
+ # returning the modified Mail object
971
+ def base64_encode!
972
+ store 'Content-Transfer-Encoding', 'Base64'
973
+ self.body = Base64.folding_encode(self.body)
974
+ end
975
+
976
+ # ==Depreciation warning
977
+ # base64_encode will return the body encoded, not modify the message body in
978
+ # future versions of TMail
979
+ alias :base64_encode :base64_encode!
980
+
981
+ # Destructively convert the Mail object's body into a Base64 decoded email
982
+ # returning the modified Mail object
983
+ def base64_decode!
984
+ if /base64/i === self.transfer_encoding('')
985
+ store 'Content-Transfer-Encoding', '8bit'
986
+ self.body = Base64.decode(self.body, @config.strict_base64decode?)
987
+ end
988
+ end
989
+
990
+ # ==Depreciation warning
991
+ # base64_decode will return the body decoded, not modify the message body in
992
+ # future versions of TMail
993
+ alias :base64_decode :base64_decode!
994
+
995
+ # Returns an array of each destination in the email message including to: cc: or bcc:
996
+ #
997
+ # Example:
998
+ #
999
+ # mail.to = "Mikel <mikel@lindsaar.net>"
1000
+ # mail.cc = "Trans <t@t.com>"
1001
+ # mail.bcc = "bob <bob@me.com>"
1002
+ # mail.destinations #=> ["mikel@lindsaar.net", "t@t.com", "bob@me.com"]
1003
+ def destinations( default = nil )
1004
+ ret = []
1005
+ %w( to cc bcc ).each do |nm|
1006
+ if h = @header[nm]
1007
+ h.addrs.each {|i| ret.push i.address }
1008
+ end
1009
+ end
1010
+ ret.empty? ? default : ret
1011
+ end
1012
+
1013
+ # Yields a block of destination, yielding each as a string.
1014
+ # (from the destinations example)
1015
+ # mail.each_destination { |d| puts "#{d.class}: #{d}" }
1016
+ # String: mikel@lindsaar.net
1017
+ # String: t@t.com
1018
+ # String: bob@me.com
1019
+ def each_destination( &block )
1020
+ destinations([]).each do |i|
1021
+ if Address === i
1022
+ yield i
1023
+ else
1024
+ i.each(&block)
1025
+ end
1026
+ end
1027
+ end
1028
+
1029
+ alias each_dest each_destination
1030
+
1031
+ # Returns an array of reply to addresses that the Mail object has,
1032
+ # or if the Mail message has no reply-to, returns an array of the
1033
+ # Mail objects from addresses. Else returns the default which can
1034
+ # either be passed as a parameter or defaults to nil
1035
+ #
1036
+ # Example:
1037
+ # mail.from = "Mikel <mikel@lindsaar.net>"
1038
+ # mail.reply_to = nil
1039
+ # mail.reply_addresses #=> [""]
1040
+ #
1041
+ def reply_addresses( default = nil )
1042
+ reply_to_addrs(nil) or from_addrs(nil) or default
1043
+ end
1044
+
1045
+ # Returns the "sender" field as an array -> useful to find out who to
1046
+ # send an error email to.
1047
+ def error_reply_addresses( default = nil )
1048
+ if s = sender(nil)
1049
+ [s]
1050
+ else
1051
+ from_addrs(default)
1052
+ end
1053
+ end
1054
+
1055
+ # Returns true if the Mail object is a multipart message
1056
+ def multipart?
1057
+ main_type('').downcase == 'multipart'
1058
+ end
1059
+
1060
+ # Creates a new email in reply to self. Sets the In-Reply-To and
1061
+ # References headers for you automagically.
1062
+ #
1063
+ # Example:
1064
+ # mail = TMail::Mail.load("my_email")
1065
+ # reply_email = mail.create_reply
1066
+ # reply_email.class #=> TMail::Mail
1067
+ # reply_email.references #=> ["<d3b8cf8e49f04480850c28713a1f473e@lindsaar.net>"]
1068
+ # reply_email.in_reply_to #=> ["<d3b8cf8e49f04480850c28713a1f473e@lindsaar.net>"]
1069
+ def create_reply
1070
+ setup_reply create_empty_mail()
1071
+ end
1072
+
1073
+ # Creates a new email in reply to self. Sets the In-Reply-To and
1074
+ # References headers for you automagically.
1075
+ #
1076
+ # Example:
1077
+ # mail = TMail::Mail.load("my_email")
1078
+ # forward_email = mail.create_forward
1079
+ # forward_email.class #=> TMail::Mail
1080
+ # forward_email.content_type #=> "multipart/mixed"
1081
+ # forward_email.body #=> "Attachment: (unnamed)"
1082
+ # forward_email.encoded #=> Returns the original email as a MIME attachment
1083
+ def create_forward
1084
+ setup_forward create_empty_mail()
1085
+ end
1086
+
1087
+ #:stopdoc:
1088
+ private
1089
+
1090
+ def create_empty_mail
1091
+ self.class.new(StringPort.new(''), @config)
1092
+ end
1093
+
1094
+ def setup_reply( mail )
1095
+ if tmp = reply_addresses(nil)
1096
+ mail.to_addrs = tmp
1097
+ end
1098
+
1099
+ mid = message_id(nil)
1100
+ tmp = references(nil) || []
1101
+ tmp.push mid if mid
1102
+ mail.in_reply_to = [mid] if mid
1103
+ mail.references = tmp unless tmp.empty?
1104
+ mail.subject = 'Re: ' + subject('').sub(/\A(?:\[[^\]]+\])?(?:\s*Re:)*\s*/i, '')
1105
+ mail.mime_version = '1.0'
1106
+ mail
1107
+ end
1108
+
1109
+ def setup_forward( mail )
1110
+ m = Mail.new(StringPort.new(''))
1111
+ m.body = decoded
1112
+ m.set_content_type 'message', 'rfc822'
1113
+ m.encoding = encoding('7bit')
1114
+ mail.parts.push m
1115
+ # call encoded to reparse the message
1116
+ mail.encoded
1117
+ mail
1118
+ end
1119
+
1120
+ #:startdoc:
1121
+ end # class Mail
1122
+
1123
+ end # module TMail