actionmailer 2.0.5 → 2.1.0

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 (73) hide show
  1. data/CHANGELOG +2 -5
  2. data/MIT-LICENSE +1 -1
  3. data/README +14 -10
  4. data/Rakefile +3 -4
  5. data/lib/action_mailer.rb +1 -1
  6. data/lib/action_mailer/adv_attr_accessor.rb +1 -1
  7. data/lib/action_mailer/base.rb +140 -100
  8. data/lib/action_mailer/helpers.rb +7 -7
  9. data/lib/action_mailer/part.rb +2 -2
  10. data/lib/action_mailer/quoting.rb +3 -1
  11. data/lib/action_mailer/test_case.rb +14 -22
  12. data/lib/action_mailer/vendor.rb +2 -2
  13. data/lib/action_mailer/vendor/text-format-0.6.3/text/format.rb +0 -0
  14. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail.rb +1 -0
  15. data/lib/action_mailer/vendor/tmail-1.2.3/tmail/address.rb +426 -0
  16. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/attachments.rb +2 -3
  17. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/base64.rb +4 -10
  18. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/compat.rb +8 -6
  19. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/config.rb +2 -6
  20. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/core_extensions.rb +14 -18
  21. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/encode.rb +77 -19
  22. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/header.rb +7 -10
  23. data/lib/action_mailer/vendor/tmail-1.2.3/tmail/index.rb +9 -0
  24. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/interface.rb +20 -13
  25. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/loader.rb +2 -0
  26. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/mail.rb +97 -26
  27. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/mailbox.rb +70 -10
  28. data/lib/action_mailer/vendor/tmail-1.2.3/tmail/main.rb +6 -0
  29. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/mbox.rb +2 -0
  30. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/net.rb +16 -15
  31. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/obsolete.rb +7 -12
  32. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/parser.rb +1 -0
  33. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/port.rb +0 -0
  34. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/quoting.rb +0 -0
  35. data/lib/action_mailer/vendor/tmail-1.2.3/tmail/require_arch.rb +58 -0
  36. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/scanner.rb +3 -1
  37. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/scanner_r.rb +15 -15
  38. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/stringio.rb +1 -0
  39. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/utils.rb +89 -32
  40. data/lib/action_mailer/vendor/{tmail-1.2.1 → tmail-1.2.3}/tmail/version.rb +4 -3
  41. data/lib/action_mailer/version.rb +2 -2
  42. data/test/delivery_method_test.rb +1 -1
  43. data/test/mail_helper_test.rb +1 -1
  44. data/test/mail_render_test.rb +1 -1
  45. data/test/mail_service_test.rb +48 -9
  46. data/test/quoting_test.rb +19 -32
  47. data/test/test_helper_test.rb +3 -9
  48. data/test/tmail_test.rb +1 -1
  49. data/test/url_test.rb +2 -2
  50. metadata +33 -53
  51. data/lib/action_mailer/vendor/tmail-1.2.1/tmail/Makefile +0 -19
  52. data/lib/action_mailer/vendor/tmail-1.2.1/tmail/address.rb +0 -245
  53. data/lib/action_mailer/vendor/tmail-1.2.1/tmail/facade.rb +0 -552
  54. data/lib/action_mailer/vendor/tmail-1.2.1/tmail/info.rb +0 -35
  55. data/lib/action_mailer/vendor/tmail-1.2.1/tmail/parser.y +0 -381
  56. data/lib/action_mailer/vendor/tmail-1.2.1/tmail/tmail.rb +0 -1
  57. data/test/fixtures/first_mailer/share.rhtml +0 -0
  58. data/test/fixtures/helper_mailer/use_example_helper.rhtml +0 -0
  59. data/test/fixtures/helper_mailer/use_helper.rhtml +0 -0
  60. data/test/fixtures/helper_mailer/use_helper_method.rhtml +0 -0
  61. data/test/fixtures/helper_mailer/use_mail_helper.rhtml +0 -0
  62. data/test/fixtures/path.with.dots/funky_path_mailer/multipart_with_template_path_with_dots.rhtml +0 -0
  63. data/test/fixtures/path.with.dots/multipart_with_template_path_with_dots.rhtml +0 -0
  64. data/test/fixtures/raw_base64_decoded_string +0 -0
  65. data/test/fixtures/raw_base64_encoded_string +0 -1
  66. data/test/fixtures/second_mailer/share.rhtml +0 -0
  67. data/test/fixtures/templates/signed_up.rhtml +0 -0
  68. data/test/fixtures/test_mailer/implicitly_multipart_example.ignored.rhtml +0 -0
  69. data/test/fixtures/test_mailer/implicitly_multipart_example.text.html.rhtml +0 -0
  70. data/test/fixtures/test_mailer/implicitly_multipart_example.text.plain.rhtml +0 -0
  71. data/test/fixtures/test_mailer/implicitly_multipart_example.text.yaml.rhtml +0 -0
  72. data/test/fixtures/test_mailer/signed_up.rhtml +0 -0
  73. data/test/fixtures/test_mailer/signed_up_with_url.rhtml +0 -0
@@ -22,7 +22,7 @@ module ActionMailer
22
22
 
23
23
  module ClassMethods
24
24
  # Makes all the (instance) methods in the helper module available to templates rendered through this controller.
25
- # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
25
+ # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
26
26
  # available to the templates.
27
27
  def add_template_helper(helper_module) #:nodoc:
28
28
  master_helper_module.module_eval "include #{helper_module}"
@@ -34,7 +34,7 @@ module ActionMailer
34
34
  # helper FooHelper
35
35
  # includes FooHelper in the template class.
36
36
  # helper { def foo() "#{bar} is the very best" end }
37
- # evaluates the block in the template class, adding method #foo.
37
+ # evaluates the block in the template class, adding method +foo+.
38
38
  # helper(:three, BlindHelper) { def mice() 'mice' end }
39
39
  # does all three.
40
40
  def helper(*args, &block)
@@ -45,7 +45,7 @@ module ActionMailer
45
45
  when String, Symbol
46
46
  file_name = arg.to_s.underscore + '_helper'
47
47
  class_name = file_name.camelize
48
-
48
+
49
49
  begin
50
50
  require_dependency(file_name)
51
51
  rescue LoadError => load_error
@@ -87,17 +87,17 @@ module ActionMailer
87
87
  attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
88
88
  end
89
89
 
90
- private
90
+ private
91
91
  def inherited_with_helper(child)
92
92
  inherited_without_helper(child)
93
93
  begin
94
94
  child.master_helper_module = Module.new
95
95
  child.master_helper_module.send! :include, master_helper_module
96
- child.helper child.name.underscore
96
+ child.helper child.name.to_s.underscore
97
97
  rescue MissingSourceFile => e
98
- raise unless e.is_missing?("helpers/#{child.name.underscore}_helper")
98
+ raise unless e.is_missing?("helpers/#{child.name.to_s.underscore}_helper")
99
99
  end
100
- end
100
+ end
101
101
  end
102
102
 
103
103
  private
@@ -5,7 +5,7 @@ require 'action_mailer/utils'
5
5
  module ActionMailer
6
6
  # Represents a subpart of an email message. It shares many similar
7
7
  # attributes of ActionMailer::Base. Although you can create parts manually
8
- # and add them to the #parts list of the mailer, it is easier
8
+ # and add them to the +parts+ list of the mailer, it is easier
9
9
  # to use the helper methods in ActionMailer::PartContainer.
10
10
  class Part
11
11
  include ActionMailer::AdvAttrAccessor
@@ -13,7 +13,7 @@ module ActionMailer
13
13
 
14
14
  # Represents the body of the part, as a string. This should not be a
15
15
  # Hash (like ActionMailer::Base), but if you want a template to be rendered
16
- # into the body of a subpart you can do it with the mailer's #render method
16
+ # into the body of a subpart you can do it with the mailer's +render+ method
17
17
  # and assign the result here.
18
18
  adv_attr_accessor :body
19
19
 
@@ -24,6 +24,8 @@ module ActionMailer
24
24
 
25
25
  # Quote the given text if it contains any "illegal" characters
26
26
  def quote_if_necessary(text, charset)
27
+ text = text.dup.force_encoding(Encoding::ASCII_8BIT) if text.respond_to?(:force_encoding)
28
+
27
29
  (text =~ CHARS_NEEDING_QUOTING) ?
28
30
  quoted_printable(text, charset) :
29
31
  text
@@ -38,7 +40,7 @@ module ActionMailer
38
40
  # regular email address, or it can be a phrase followed by an address in
39
41
  # brackets. The phrase is the only part that will be quoted, and only if
40
42
  # it needs to be. This allows extended characters to be used in the
41
- # "to", "from", "cc", and "bcc" headers.
43
+ # "to", "from", "cc", "bcc" and "reply-to" headers.
42
44
  def quote_address_if_necessary(address, charset)
43
45
  if Array === address
44
46
  address.map { |a| quote_address_if_necessary(a, charset) }
@@ -8,11 +8,13 @@ module ActionMailer
8
8
  "test case definition"
9
9
  end
10
10
  end
11
- # New Test Super class for forward compatibility.
12
- # To override
11
+
13
12
  class TestCase < ActiveSupport::TestCase
14
13
  include ActionMailer::Quoting
15
14
 
15
+ setup :initialize_test_deliveries
16
+ setup :set_expected_mail
17
+
16
18
  class << self
17
19
  def tests(mailer)
18
20
  write_inheritable_attribute(:mailer_class, mailer)
@@ -33,28 +35,18 @@ module ActionMailer
33
35
  end
34
36
  end
35
37
 
36
- def setup_with_mailer
37
- ActionMailer::Base.delivery_method = :test
38
- ActionMailer::Base.perform_deliveries = true
39
- ActionMailer::Base.deliveries = []
40
-
41
- @expected = TMail::Mail.new
42
- @expected.set_content_type "text", "plain", { "charset" => charset }
43
- @expected.mime_version = '1.0'
44
- end
45
- alias_method :setup, :setup_with_mailer
38
+ protected
39
+ def initialize_test_deliveries
40
+ ActionMailer::Base.delivery_method = :test
41
+ ActionMailer::Base.perform_deliveries = true
42
+ ActionMailer::Base.deliveries = []
43
+ end
46
44
 
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
45
+ def set_expected_mail
46
+ @expected = TMail::Mail.new
47
+ @expected.set_content_type "text", "plain", { "charset" => charset }
48
+ @expected.mime_version = '1.0'
56
49
  end
57
- end
58
50
 
59
51
  private
60
52
  def charset
@@ -2,9 +2,9 @@
2
2
  require 'rubygems'
3
3
 
4
4
  begin
5
- gem 'tmail', '~> 1.2.1'
5
+ gem 'tmail', '~> 1.2.3'
6
6
  rescue Gem::LoadError
7
- $:.unshift "#{File.dirname(__FILE__)}/vendor/tmail-1.2.1"
7
+ $:.unshift "#{File.dirname(__FILE__)}/vendor/tmail-1.2.3"
8
8
  end
9
9
 
10
10
  begin
@@ -2,3 +2,4 @@ require 'tmail/version'
2
2
  require 'tmail/mail'
3
3
  require 'tmail/mailbox'
4
4
  require 'tmail/core_extensions'
5
+ require 'tmail/net'
@@ -0,0 +1,426 @@
1
+ =begin rdoc
2
+
3
+ = Address handling class
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
+ require 'tmail/encode'
33
+ require 'tmail/parser'
34
+
35
+
36
+ module TMail
37
+
38
+ # = Class Address
39
+ #
40
+ # Provides a complete handling library for email addresses. Can parse a string of an
41
+ # address directly or take in preformatted addresses themseleves. Allows you to add
42
+ # and remove phrases from the front of the address and provides a compare function for
43
+ # email addresses.
44
+ #
45
+ # == Parsing and Handling a Valid Address:
46
+ #
47
+ # Just pass the email address in as a string to Address.parse:
48
+ #
49
+ # email = TMail::Address.parse('Mikel Lindsaar <mikel@lindsaar.net>)
50
+ # #=> #<TMail::Address mikel@lindsaar.net>
51
+ # email.address
52
+ # #=> "mikel@lindsaar.net"
53
+ # email.local
54
+ # #=> "mikel"
55
+ # email.domain
56
+ # #=> "lindsaar.net"
57
+ # email.name # Aliased as phrase as well
58
+ # #=> "Mikel Lindsaar"
59
+ #
60
+ # == Detecting an Invalid Address
61
+ #
62
+ # If you want to check the syntactical validity of an email address, just pass it to
63
+ # Address.parse and catch any SyntaxError:
64
+ #
65
+ # begin
66
+ # TMail::Mail.parse("mikel 2@@@@@ me .com")
67
+ # rescue TMail::SyntaxError
68
+ # puts("Invalid Email Address Detected")
69
+ # else
70
+ # puts("Address is valid")
71
+ # end
72
+ # #=> "Invalid Email Address Detected"
73
+ class Address
74
+
75
+ include TextUtils #:nodoc:
76
+
77
+ # Sometimes you need to parse an address, TMail can do it for you and provide you with
78
+ # a fairly robust method of detecting a valid address.
79
+ #
80
+ # Takes in a string, returns a TMail::Address object.
81
+ #
82
+ # Raises a TMail::SyntaxError on invalid email format
83
+ def Address.parse( str )
84
+ Parser.parse :ADDRESS, special_quote_address(str)
85
+ end
86
+
87
+ def Address.special_quote_address(str) #:nodoc:
88
+ # Takes a string which is an address and adds quotation marks to special
89
+ # edge case methods that the RACC parser can not handle.
90
+ #
91
+ # Right now just handles two edge cases:
92
+ #
93
+ # Full stop as the last character of the display name:
94
+ # Mikel L. <mikel@me.com>
95
+ # Returns:
96
+ # "Mikel L." <mikel@me.com>
97
+ #
98
+ # Unquoted @ symbol in the display name:
99
+ # mikel@me.com <mikel@me.com>
100
+ # Returns:
101
+ # "mikel@me.com" <mikel@me.com>
102
+ #
103
+ # Any other address not matching these patterns just gets returned as is.
104
+ case
105
+ # This handles the missing "" in an older version of Apple Mail.app
106
+ # around the display name when the display name contains a '@'
107
+ # like 'mikel@me.com <mikel@me.com>'
108
+ # Just quotes it to: '"mikel@me.com" <mikel@me.com>'
109
+ when str =~ /\A([^"].+@.+[^"])\s(<.*?>)\Z/
110
+ return "\"#{$1}\" #{$2}"
111
+ # This handles cases where 'Mikel A. <mikel@me.com>' which is a trailing
112
+ # full stop before the address section. Just quotes it to
113
+ # '"Mikel A. <mikel@me.com>"
114
+ when str =~ /\A(.*?\.)\s(<.*?>)\Z/
115
+ return "\"#{$1}\" #{$2}"
116
+ else
117
+ str
118
+ end
119
+ end
120
+
121
+ def address_group? #:nodoc:
122
+ false
123
+ end
124
+
125
+ # Address.new(local, domain)
126
+ #
127
+ # Accepts:
128
+ #
129
+ # * local - Left of the at symbol
130
+ #
131
+ # * domain - Array of the domain split at the periods.
132
+ #
133
+ # For example:
134
+ #
135
+ # Address.new("mikel", ["lindsaar", "net"])
136
+ # #=> "#<TMail::Address mikel@lindsaar.net>"
137
+ def initialize( local, domain )
138
+ if domain
139
+ domain.each do |s|
140
+ raise SyntaxError, 'empty word in domain' if s.empty?
141
+ end
142
+ end
143
+
144
+ # This is to catch an unquoted "@" symbol in the local part of the
145
+ # address. Handles addresses like <"@"@me.com> and makes sure they
146
+ # stay like <"@"@me.com> (previously were becomming <@@me.com>)
147
+ if local && (local.join == '@' || local.join =~ /\A[^"].*?@.*?[^"]\Z/)
148
+ @local = "\"#{local.join}\""
149
+ else
150
+ @local = local
151
+ end
152
+
153
+ @domain = domain
154
+ @name = nil
155
+ @routes = []
156
+ end
157
+
158
+ # Provides the name or 'phrase' of the email address.
159
+ #
160
+ # For Example:
161
+ #
162
+ # email = TMail::Address.parse("Mikel Lindsaar <mikel@lindsaar.net>")
163
+ # email.name
164
+ # #=> "Mikel Lindsaar"
165
+ def name
166
+ @name
167
+ end
168
+
169
+ # Setter method for the name or phrase of the email
170
+ #
171
+ # For Example:
172
+ #
173
+ # email = TMail::Address.parse("mikel@lindsaar.net")
174
+ # email.name
175
+ # #=> nil
176
+ # email.name = "Mikel Lindsaar"
177
+ # email.to_s
178
+ # #=> "Mikel Lindsaar <mikel@me.com>"
179
+ def name=( str )
180
+ @name = str
181
+ @name = nil if str and str.empty?
182
+ end
183
+
184
+ #:stopdoc:
185
+ alias phrase name
186
+ alias phrase= name=
187
+ #:startdoc:
188
+
189
+ # This is still here from RFC 822, and is now obsolete per RFC2822 Section 4.
190
+ #
191
+ # "When interpreting addresses, the route portion SHOULD be ignored."
192
+ #
193
+ # It is still here, so you can access it.
194
+ #
195
+ # Routes return the route portion at the front of the email address, if any.
196
+ #
197
+ # For Example:
198
+ # email = TMail::Address.parse( "<@sa,@another:Mikel@me.com>")
199
+ # => #<TMail::Address Mikel@me.com>
200
+ # email.to_s
201
+ # => "<@sa,@another:Mikel@me.com>"
202
+ # email.routes
203
+ # => ["sa", "another"]
204
+ def routes
205
+ @routes
206
+ end
207
+
208
+ def inspect #:nodoc:
209
+ "#<#{self.class} #{address()}>"
210
+ end
211
+
212
+ # Returns the local part of the email address
213
+ #
214
+ # For Example:
215
+ #
216
+ # email = TMail::Address.parse("mikel@lindsaar.net")
217
+ # email.local
218
+ # #=> "mikel"
219
+ def local
220
+ return nil unless @local
221
+ return '""' if @local.size == 1 and @local[0].empty?
222
+ # Check to see if it is an array before trying to map it
223
+ if @local.respond_to?(:map)
224
+ @local.map {|i| quote_atom(i) }.join('.')
225
+ else
226
+ quote_atom(@local)
227
+ end
228
+ end
229
+
230
+ # Returns the domain part of the email address
231
+ #
232
+ # For Example:
233
+ #
234
+ # email = TMail::Address.parse("mikel@lindsaar.net")
235
+ # email.local
236
+ # #=> "lindsaar.net"
237
+ def domain
238
+ return nil unless @domain
239
+ join_domain(@domain)
240
+ end
241
+
242
+ # Returns the full specific address itself
243
+ #
244
+ # For Example:
245
+ #
246
+ # email = TMail::Address.parse("mikel@lindsaar.net")
247
+ # email.address
248
+ # #=> "mikel@lindsaar.net"
249
+ def spec
250
+ s = self.local
251
+ d = self.domain
252
+ if s and d
253
+ s + '@' + d
254
+ else
255
+ s
256
+ end
257
+ end
258
+
259
+ alias address spec
260
+
261
+ # Provides == function to the email. Only checks the actual address
262
+ # and ignores the name/phrase component
263
+ #
264
+ # For Example
265
+ #
266
+ # addr1 = TMail::Address.parse("My Address <mikel@lindsaar.net>")
267
+ # #=> "#<TMail::Address mikel@lindsaar.net>"
268
+ # addr2 = TMail::Address.parse("Another <mikel@lindsaar.net>")
269
+ # #=> "#<TMail::Address mikel@lindsaar.net>"
270
+ # addr1 == addr2
271
+ # #=> true
272
+ def ==( other )
273
+ other.respond_to? :spec and self.spec == other.spec
274
+ end
275
+
276
+ alias eql? ==
277
+
278
+ # Provides a unique hash value for this record against the local and domain
279
+ # parts, ignores the name/phrase value
280
+ #
281
+ # email = TMail::Address.parse("mikel@lindsaar.net")
282
+ # email.hash
283
+ # #=> 18767598
284
+ def hash
285
+ @local.hash ^ @domain.hash
286
+ end
287
+
288
+ # Duplicates a TMail::Address object returning the duplicate
289
+ #
290
+ # addr1 = TMail::Address.parse("mikel@lindsaar.net")
291
+ # addr2 = addr1.dup
292
+ # addr1.id == addr2.id
293
+ # #=> false
294
+ def dup
295
+ obj = self.class.new(@local.dup, @domain.dup)
296
+ obj.name = @name.dup if @name
297
+ obj.routes.replace @routes
298
+ obj
299
+ end
300
+
301
+ include StrategyInterface #:nodoc:
302
+
303
+ def accept( strategy, dummy1 = nil, dummy2 = nil ) #:nodoc:
304
+ unless @local
305
+ strategy.meta '<>' # empty return-path
306
+ return
307
+ end
308
+
309
+ spec_p = (not @name and @routes.empty?)
310
+ if @name
311
+ strategy.phrase @name
312
+ strategy.space
313
+ end
314
+ tmp = spec_p ? '' : '<'
315
+ unless @routes.empty?
316
+ tmp << @routes.map {|i| '@' + i }.join(',') << ':'
317
+ end
318
+ tmp << self.spec
319
+ tmp << '>' unless spec_p
320
+ strategy.meta tmp
321
+ strategy.lwsp ''
322
+ end
323
+
324
+ end
325
+
326
+
327
+ class AddressGroup
328
+
329
+ include Enumerable
330
+
331
+ def address_group?
332
+ true
333
+ end
334
+
335
+ def initialize( name, addrs )
336
+ @name = name
337
+ @addresses = addrs
338
+ end
339
+
340
+ attr_reader :name
341
+
342
+ def ==( other )
343
+ other.respond_to? :to_a and @addresses == other.to_a
344
+ end
345
+
346
+ alias eql? ==
347
+
348
+ def hash
349
+ map {|i| i.hash }.hash
350
+ end
351
+
352
+ def []( idx )
353
+ @addresses[idx]
354
+ end
355
+
356
+ def size
357
+ @addresses.size
358
+ end
359
+
360
+ def empty?
361
+ @addresses.empty?
362
+ end
363
+
364
+ def each( &block )
365
+ @addresses.each(&block)
366
+ end
367
+
368
+ def to_a
369
+ @addresses.dup
370
+ end
371
+
372
+ alias to_ary to_a
373
+
374
+ def include?( a )
375
+ @addresses.include? a
376
+ end
377
+
378
+ def flatten
379
+ set = []
380
+ @addresses.each do |a|
381
+ if a.respond_to? :flatten
382
+ set.concat a.flatten
383
+ else
384
+ set.push a
385
+ end
386
+ end
387
+ set
388
+ end
389
+
390
+ def each_address( &block )
391
+ flatten.each(&block)
392
+ end
393
+
394
+ def add( a )
395
+ @addresses.push a
396
+ end
397
+
398
+ alias push add
399
+
400
+ def delete( a )
401
+ @addresses.delete a
402
+ end
403
+
404
+ include StrategyInterface
405
+
406
+ def accept( strategy, dummy1 = nil, dummy2 = nil )
407
+ strategy.phrase @name
408
+ strategy.meta ':'
409
+ strategy.space
410
+ first = true
411
+ each do |mbox|
412
+ if first
413
+ first = false
414
+ else
415
+ strategy.meta ','
416
+ end
417
+ strategy.space
418
+ mbox.accept strategy
419
+ end
420
+ strategy.meta ';'
421
+ strategy.lwsp ''
422
+ end
423
+
424
+ end
425
+
426
+ end # module TMail