Skip to content
This repository
Browse code

Starting again on actionmailer integration with mail

  • Loading branch information...
commit 15d7cac282e29f0a8e7b38dade07abb32d97a991 1 parent cbded53
Mikel Lindsaar authored November 12, 2009

Showing 44 changed files with 186 additions and 8,119 deletions. Show diff stats Hide diff stats

  1. 3  actionmailer/lib/action_mailer.rb
  2. 50  actionmailer/lib/action_mailer/base.rb
  3. 3  actionmailer/lib/action_mailer/delivery_method/smtp.rb
  4. 107  actionmailer/lib/action_mailer/part.rb
  5. 55  actionmailer/lib/action_mailer/part_container.rb
  6. 2  actionmailer/lib/action_mailer/test_case.rb
  7. 5  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail.rb
  8. 426  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/address.rb
  9. 46  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/attachments.rb
  10. 46  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/base64.rb
  11. 41  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/compat.rb
  12. 67  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/config.rb
  13. 63  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/core_extensions.rb
  14. 581  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/encode.rb
  15. 960  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/header.rb
  16. 9  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/index.rb
  17. 1,130  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/interface.rb
  18. 3  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/loader.rb
  19. 579  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb
  20. 495  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/mailbox.rb
  21. 6  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/main.rb
  22. 3  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/mbox.rb
  23. 248  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/net.rb
  24. 132  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/obsolete.rb
  25. 1,478  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/parser.rb
  26. 379  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/port.rb
  27. 118  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/quoting.rb
  28. 58  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/require_arch.rb
  29. 49  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/scanner.rb
  30. 261  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/scanner_r.rb
  31. 280  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/stringio.rb
  32. 337  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/utils.rb
  33. 39  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/version.rb
  34. 18  actionmailer/lib/action_mailer/vendor/tmail.rb
  35. 36  actionmailer/lib/action_mailer/vendor/tmail_compat.rb
  36. 6  actionmailer/test/asset_host_test.rb
  37. 2  actionmailer/test/mail_helper_test.rb
  38. 62  actionmailer/test/mail_layout_test.rb
  39. 28  actionmailer/test/mail_render_test.rb
  40. 69  actionmailer/test/mail_service_test.rb
  41. 12  actionmailer/test/quoting_test.rb
  42. 4  actionmailer/test/test_helper_test.rb
  43. 7  actionmailer/test/tmail_test.rb
  44. 2  actionmailer/test/url_test.rb
3  actionmailer/lib/action_mailer.rb
@@ -53,4 +53,5 @@ module Net
53 53
 
54 54
 autoload :MailHelper, 'action_mailer/mail_helper'
55 55
 
56  
-require 'action_mailer/vendor/tmail'
  56
+require '/Users/mikel/ruby_programs/mail/lib/mail'
  57
+require 'action_mailer/vendor/tmail_compat'
50  actionmailer/lib/action_mailer/base.rb
@@ -251,7 +251,7 @@ module ActionMailer #:nodoc:
251 251
   #   and appear last in the mime encoded message. You can also pick a different order from inside a method with
252 252
   #   +implicit_parts_order+.
253 253
   class Base
254  
-    include AdvAttrAccessor, PartContainer, Quoting, Utils
  254
+    include AdvAttrAccessor, Quoting, Utils
255 255
 
256 256
     include AbstractController::RenderingController
257 257
     include AbstractController::LocalizedCache
@@ -366,6 +366,12 @@ def mailer_name(value = nil)
366 366
     # Alias controller_path to mailer_name so render :partial in views work.
367 367
     alias :controller_path :mailer_name
368 368
 
  369
+    def part(params)
  370
+      part = Mail::Part.new(params)
  371
+      yield part
  372
+      self.parts << part
  373
+    end
  374
+
369 375
     class << self
370 376
       attr_writer :mailer_name
371 377
 
@@ -411,7 +417,7 @@ def method_missing(method_symbol, *parameters) #:nodoc:
411 417
       #   end
412 418
       def receive(raw_email)
413 419
         logger.info "Received mail:\n #{raw_email}" unless logger.nil?
414  
-        mail = TMail::Mail.parse(raw_email)
  420
+        mail = Mail.parse(raw_email)
415 421
         mail.base64_decode
416 422
         new.receive(mail)
417 423
       end
@@ -456,7 +462,7 @@ def initialize(method_name=nil, *parameters) #:nodoc:
456 462
     end
457 463
 
458 464
     # Initialize the mailer via the given +method_name+. The body will be
459  
-    # rendered and a new TMail::Mail object created.
  465
+    # rendered and a new Mail object created.
460 466
     def create!(method_name, *parameters) #:nodoc:
461 467
       initialize_defaults(method_name)
462 468
       __send__(method_name, *parameters)
@@ -472,7 +478,7 @@ def create!(method_name, *parameters) #:nodoc:
472 478
       @mail = create_mail
473 479
     end
474 480
 
475  
-    # Delivers a TMail::Mail object. By default, it delivers the cached mail
  481
+    # Delivers a Mail object. By default, it delivers the cached mail
476 482
     # object (from the <tt>create!</tt> method). If no cached mail object exists, and
477 483
     # no alternate has been given as the parameter, this will fail.
478 484
     def deliver!(mail = @mail)
@@ -520,18 +526,18 @@ def create_parts
520 526
         super # Run deprecation hooks
521 527
 
522 528
         if String === response_body
523  
-          @parts.unshift Part.new(
524  
-            :content_type => "text/plain",
525  
-            :disposition => "inline",
526  
-            :charset => charset,
  529
+          @parts.unshift Mail::Part.new(
  530
+            :content_type => ["text", "plain", {:charset => charset}],
  531
+            :content_disposition => "inline",
527 532
             :body => response_body
528 533
           )
529 534
         else
530 535
           self.class.template_root.find_all(@template, {}, mailer_name).each do |template|
531  
-            @parts << Part.new(
532  
-              :content_type => template.mime_type ? template.mime_type.to_s : "text/plain",
533  
-              :disposition => "inline",
534  
-              :charset => charset,
  536
+            ct = template.mime_type ? template.mime_type.to_s : "text/plain"
  537
+            main_type, sub_type = ct.split("/")
  538
+            @parts << Mail::Part.new(
  539
+              :content_type => [main_type, sub_type, {:charset => charset}],
  540
+              :content_disposition => "inline",
535 541
               :body => render_to_body(:_template => template)
536 542
             )
537 543
           end
@@ -551,8 +557,8 @@ def sort_parts(parts, order = [])
551 557
         order = order.collect { |s| s.downcase }
552 558
 
553 559
         parts = parts.sort do |a, b|
554  
-          a_ct = a.content_type.downcase
555  
-          b_ct = b.content_type.downcase
  560
+          a_ct = a.content_type.content_type.downcase
  561
+          b_ct = b.content_type.content_type.downcase
556 562
 
557 563
           a_in = order.include? a_ct
558 564
           b_in = order.include? b_ct
@@ -577,7 +583,7 @@ def sort_parts(parts, order = [])
577 583
       end
578 584
 
579 585
       def create_mail
580  
-        m = TMail::Mail.new
  586
+        m = Mail.new
581 587
 
582 588
         m.subject,     = quote_any_if_necessary(charset, subject)
583 589
         m.to, m.from   = quote_any_address_if_necessary(charset, recipients, from)
@@ -599,7 +605,7 @@ def create_mail
599 605
           m.body = normalize_new_lines(@parts.first.body)
600 606
         else
601 607
           @parts.each do |p|
602  
-            part = (TMail::Mail === p ? p : p.to_mail(self))
  608
+            part = (Mail === p ? p : p.to_mail(self))
603 609
             m.parts << part
604 610
           end
605 611
 
@@ -612,5 +618,17 @@ def create_mail
612 618
         @mail = m
613 619
       end
614 620
 
  621
+      def parse_content_type(defaults=nil)
  622
+        if content_type.blank? 
  623
+          return defaults                                                ? 
  624
+            [ defaults.content_type, { 'charset' => defaults.charset } ] : 
  625
+            [ nil, {} ] 
  626
+        end 
  627
+        ctype, *attrs = content_type.split(/;\s*/)
  628
+        attrs = attrs.inject({}) { |h,s| k,v = s.split(/=/, 2); h[k] = v; h }
  629
+        [ctype, {"charset" => charset || defaults && defaults.charset}.merge(attrs)]
  630
+      end
  631
+
  632
+
615 633
   end
616 634
 end
3  actionmailer/lib/action_mailer/delivery_method/smtp.rb
@@ -15,8 +15,7 @@ class Smtp < Method
15 15
 
16 16
       def perform_delivery(mail)
17 17
         destinations = mail.destinations
18  
-        mail.ready_to_send
19  
-        sender = (mail['return-path'] && mail['return-path'].spec) || mail['from']
  18
+        sender = (mail['return-path'] && mail['return-path'].address) || mail['from']
20 19
 
21 20
         smtp = Net::SMTP.new(settings[:address], settings[:port])
22 21
         smtp.enable_starttls_auto if settings[:enable_starttls_auto] && smtp.respond_to?(:enable_starttls_auto)
107  actionmailer/lib/action_mailer/part.rb
... ...
@@ -1,107 +0,0 @@
1  
-module ActionMailer
2  
-  # Represents a subpart of an email message. It shares many similar
3  
-  # attributes of ActionMailer::Base.  Although you can create parts manually
4  
-  # and add them to the +parts+ list of the mailer, it is easier
5  
-  # to use the helper methods in ActionMailer::PartContainer.
6  
-  class Part
7  
-    include AdvAttrAccessor, PartContainer, Utils
8  
-
9  
-    # Represents the body of the part, as a string. This should not be a
10  
-    # Hash (like ActionMailer::Base), but if you want a template to be rendered
11  
-    # into the body of a subpart you can do it with the mailer's +render+ method
12  
-    # and assign the result here.
13  
-    adv_attr_accessor :body
14  
-    
15  
-    # Specify the charset for this subpart. By default, it will be the charset
16  
-    # of the containing part or mailer.
17  
-    adv_attr_accessor :charset
18  
-    
19  
-    # The content disposition of this part, typically either "inline" or
20  
-    # "attachment".
21  
-    adv_attr_accessor :content_disposition
22  
-    
23  
-    # The content type of the part.
24  
-    adv_attr_accessor :content_type
25  
-    
26  
-    # The filename to use for this subpart (usually for attachments).
27  
-    adv_attr_accessor :filename
28  
-    
29  
-    # Accessor for specifying additional headers to include with this part.
30  
-    adv_attr_accessor :headers
31  
-    
32  
-    # The transfer encoding to use for this subpart, like "base64" or
33  
-    # "quoted-printable".
34  
-    adv_attr_accessor :transfer_encoding
35  
-
36  
-    # Create a new part from the given +params+ hash. The valid params keys
37  
-    # correspond to the accessors.
38  
-    def initialize(params)
39  
-      @content_type = params[:content_type]
40  
-      @content_disposition = params[:disposition] || "inline"
41  
-      @charset = params[:charset]
42  
-      @body = params[:body]
43  
-      @filename = params[:filename]
44  
-      @transfer_encoding = params[:transfer_encoding] || "quoted-printable"
45  
-      @headers = params[:headers] || {}
46  
-      @parts = []
47  
-    end
48  
-
49  
-    # Convert the part to a mail object which can be included in the parts
50  
-    # list of another mail object.
51  
-    def to_mail(defaults)
52  
-      part = TMail::Mail.new
53  
-
54  
-      real_content_type, ctype_attrs = parse_content_type(defaults)
55  
-
56  
-      if @parts.empty?
57  
-        part.content_transfer_encoding = transfer_encoding || "quoted-printable"
58  
-        case (transfer_encoding || "").downcase
59  
-          when "base64" then
60  
-            part.body = TMail::Base64.folding_encode(body)
61  
-          when "quoted-printable"
62  
-            part.body = [normalize_new_lines(body)].pack("M*")
63  
-          else
64  
-            part.body = body
65  
-        end
66  
-
67  
-        # Always set the content_type after setting the body and or parts!
68  
-        # Also don't set filename and name when there is none (like in
69  
-        # non-attachment parts)
70  
-        if content_disposition == "attachment"
71  
-          ctype_attrs.delete "charset"
72  
-          part.set_content_type(real_content_type, nil,
73  
-            squish("name" => filename).merge(ctype_attrs))
74  
-          part.set_content_disposition(content_disposition,
75  
-            squish("filename" => filename).merge(ctype_attrs))
76  
-        else
77  
-          part.set_content_type(real_content_type, nil, ctype_attrs)
78  
-          part.set_content_disposition(content_disposition) 
79  
-        end        
80  
-      else
81  
-        if String === body
82  
-          @parts.unshift Part.new(:charset => charset, :body => @body, :content_type => 'text/plain')
83  
-          @body = nil
84  
-        end
85  
-          
86  
-        @parts.each do |p|
87  
-          prt = (TMail::Mail === p ? p : p.to_mail(defaults))
88  
-          part.parts << prt
89  
-        end
90  
-        
91  
-        if real_content_type =~ /multipart/
92  
-          ctype_attrs.delete 'charset'
93  
-          part.set_content_type(real_content_type, nil, ctype_attrs)
94  
-        end
95  
-      end
96  
-
97  
-      headers.each { |k,v| part[k] = v }
98  
-
99  
-      part
100  
-    end
101  
-
102  
-    private
103  
-      def squish(values={})
104  
-        values.delete_if { |k,v| v.nil? }
105  
-      end
106  
-  end
107  
-end
55  actionmailer/lib/action_mailer/part_container.rb
... ...
@@ -1,55 +0,0 @@
1  
-module ActionMailer
2  
-  # Accessors and helpers that ActionMailer::Base and ActionMailer::Part have
3  
-  # in common. Using these helpers you can easily add subparts or attachments
4  
-  # to your message:
5  
-  #
6  
-  #   def my_mail_message(...)
7  
-  #     ...
8  
-  #     part "text/plain" do |p|
9  
-  #       p.body "hello, world"
10  
-  #       p.transfer_encoding "base64"
11  
-  #     end
12  
-  #
13  
-  #     attachment "image/jpg" do |a|
14  
-  #       a.body = File.read("hello.jpg")
15  
-  #       a.filename = "hello.jpg"
16  
-  #     end
17  
-  #   end
18  
-  module PartContainer
19  
-    # The list of subparts of this container
20  
-    attr_reader :parts
21  
-
22  
-    # Add a part to a multipart message, with the given content-type. The
23  
-    # part itself is yielded to the block so that other properties (charset,
24  
-    # body, headers, etc.) can be set on it.
25  
-    def part(params)
26  
-      params = {:content_type => params} if String === params
27  
-      part = Part.new(params)
28  
-      yield part if block_given?
29  
-      @parts << part
30  
-    end
31  
-
32  
-    # Add an attachment to a multipart message. This is simply a part with the
33  
-    # content-disposition set to "attachment".
34  
-    def attachment(params, &block)
35  
-      params = { :content_type => params } if String === params
36  
-      params = { :disposition => "attachment",
37  
-                 :transfer_encoding => "base64" }.merge(params)
38  
-      part(params, &block)
39  
-    end
40  
-
41  
-    private
42  
-    
43  
-      def parse_content_type(defaults=nil)
44  
-        if content_type.blank? 
45  
-          return defaults                                                ? 
46  
-            [ defaults.content_type, { 'charset' => defaults.charset } ] : 
47  
-            [ nil, {} ] 
48  
-        end 
49  
-        ctype, *attrs = content_type.split(/;\s*/)
50  
-        attrs = attrs.inject({}) { |h,s| k,v = s.split(/=/, 2); h[k] = v; h }
51  
-        [ctype, {"charset" => charset || defaults && defaults.charset}.merge(attrs)]
52  
-      end
53  
-
54  
-  end
55  
-end
2  actionmailer/lib/action_mailer/test_case.rb
@@ -43,7 +43,7 @@ def initialize_test_deliveries
43 43
       end
44 44
 
45 45
       def set_expected_mail
46  
-        @expected = TMail::Mail.new
  46
+        @expected = Mail.new
47 47
         @expected.set_content_type "text", "plain", { "charset" => charset }
48 48
         @expected.mime_version = '1.0'
49 49
       end
5  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail.rb
... ...
@@ -1,5 +0,0 @@
1  
-require 'tmail/version'
2  
-require 'tmail/mail'
3  
-require 'tmail/mailbox'
4  
-require 'tmail/core_extensions'
5  
-require 'tmail/net'
426  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/address.rb
... ...
@@ -1,426 +0,0 @@
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 themselves.  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 becoming <@@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
46  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/attachments.rb
... ...
@@ -1,46 +0,0 @@
1  
-=begin rdoc
2  
-
3  
-= Attachment handling file
4  
-
5  
-=end
6  
-
7  
-require 'stringio'
8  
-
9  
-module TMail
10  
-  class Attachment < StringIO
11  
-    attr_accessor :original_filename, :content_type
12  
-  end
13  
-
14  
-  class Mail
15  
-    def has_attachments?
16  
-      multipart? && parts.any? { |part| attachment?(part) }
17  
-    end
18  
-
19  
-    def attachment?(part)
20  
-      part.disposition_is_attachment? || part.content_type_is_text?
21  
-    end
22  
-
23  
-    def attachments
24  
-      if multipart?
25  
-        parts.collect { |part| 
26  
-          if part.multipart?
27  
-            part.attachments
28  
-          elsif attachment?(part)
29  
-            content   = part.body # unquoted automatically by TMail#body
30  
-            file_name = (part['content-location'] &&
31  
-                          part['content-location'].body) ||
32  
-                        part.sub_header("content-type", "name") ||
33  
-                        part.sub_header("content-disposition", "filename")
34  
-            
35  
-            next if file_name.blank? || content.blank?
36  
-            
37  
-            attachment = Attachment.new(content)
38  
-            attachment.original_filename = file_name.strip
39  
-            attachment.content_type = part.content_type
40  
-            attachment
41  
-          end
42  
-        }.flatten.compact
43  
-      end      
44  
-    end
45  
-  end
46  
-end
46  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/base64.rb
... ...
@@ -1,46 +0,0 @@
1  
-#--
2  
-#   Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
3  
-#
4  
-#   Permission is hereby granted, free of charge, to any person obtaining
5  
-#   a copy of this software and associated documentation files (the
6  
-#   "Software"), to deal in the Software without restriction, including
7  
-#   without limitation the rights to use, copy, modify, merge, publish,
8  
-#   distribute, sublicense, and/or sell copies of the Software, and to
9  
-#   permit persons to whom the Software is furnished to do so, subject to
10  
-#   the following conditions:
11  
-#
12  
-#   The above copyright notice and this permission notice shall be
13  
-#   included in all copies or substantial portions of the Software.
14  
-#
15  
-#   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  
-#   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  
-#   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  
-#   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19  
-#   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20  
-#   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  
-#   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  
-#
23  
-#   Note: Originally licensed under LGPL v2+. Using MIT license for Rails
24  
-#   with permission of Minero Aoki.
25  
-#++
26  
-#:stopdoc:
27  
-module TMail
28  
-  module Base64
29  
-
30  
-    module_function
31  
-
32  
-    def folding_encode( str, eol = "\n", limit = 60 )
33  
-      [str].pack('m')
34  
-    end
35  
-
36  
-    def encode( str )
37  
-      [str].pack('m').tr( "\r\n", '' )
38  
-    end
39  
-
40  
-    def decode( str, strict = false )
41  
-      str.unpack('m').first
42  
-    end
43  
-
44  
-  end
45  
-end
46  
-#:startdoc:
41  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/compat.rb
... ...
@@ -1,41 +0,0 @@
1  
-#:stopdoc:
2  
-unless Enumerable.method_defined?(:map) 
3  
-  module Enumerable #:nodoc:
4  
-    alias map collect
5  
-  end
6  
-end
7  
-
8  
-unless Enumerable.method_defined?(:select)
9  
-  module Enumerable #:nodoc:
10  
-    alias select find_all
11  
-  end
12  
-end
13  
-
14  
-unless Enumerable.method_defined?(:reject)
15  
-  module Enumerable #:nodoc:
16  
-    def reject
17  
-      result = []
18  
-      each do |i|
19  
-        result.push i unless yield(i)
20  
-      end
21  
-      result
22  
-    end
23  
-  end
24  
-end
25  
-
26  
-unless Enumerable.method_defined?(:sort_by)
27  
-  module Enumerable #:nodoc:
28  
-    def sort_by
29  
-      map {|i| [yield(i), i] }.sort.map {|val, i| i }
30  
-    end
31  
-  end
32  
-end
33  
-
34  
-unless File.respond_to?(:read)
35  
-  def File.read(fname) #:nodoc:
36  
-    File.open(fname) {|f|
37  
-      return f.read
38  
-    }
39  
-  end
40  
-end
41  
-#:startdoc:
67  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/config.rb
... ...
@@ -1,67 +0,0 @@
1  
-#--
2  
-# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
3  
-#
4  
-# Permission is hereby granted, free of charge, to any person obtaining
5  
-# a copy of this software and associated documentation files (the
6  
-# "Software"), to deal in the Software without restriction, including
7  
-# without limitation the rights to use, copy, modify, merge, publish,
8  
-# distribute, sublicense, and/or sell copies of the Software, and to
9  
-# permit persons to whom the Software is furnished to do so, subject to
10  
-# the following conditions:
11  
-#
12  
-# The above copyright notice and this permission notice shall be
13  
-# included in all copies or substantial portions of the Software.
14  
-#
15  
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19  
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20  
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21  
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  
-#
23  
-# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
24  
-# with permission of Minero Aoki.
25  
-#++
26  
-#:stopdoc:
27  
-module TMail
28  
-
29  
-  class Config
30  
-
31  
-    def initialize( strict )
32  
-      @strict_parse = strict
33  
-      @strict_base64decode = strict
34  
-    end
35  
-
36  
-    def strict_parse?
37  
-      @strict_parse
38  
-    end
39  
-
40  
-    attr_writer :strict_parse
41  
-
42  
-    def strict_base64decode?
43  
-      @strict_base64decode
44  
-    end
45  
-
46  
-    attr_writer :strict_base64decode
47  
-
48  
-    def new_body_port( mail )
49  
-      StringPort.new
50  
-    end
51  
-
52  
-    alias new_preamble_port  new_body_port
53  
-    alias new_part_port      new_body_port
54  
-  
55  
-  end
56  
-
57  
-  DEFAULT_CONFIG        = Config.new(false)
58  
-  DEFAULT_STRICT_CONFIG = Config.new(true)
59  
-
60  
-  def Config.to_config( arg )
61  
-    return DEFAULT_STRICT_CONFIG if arg == true
62  
-    return DEFAULT_CONFIG        if arg == false
63  
-    arg or DEFAULT_CONFIG
64  
-  end
65  
-
66  
-end
67  
-#:startdoc:
63  actionmailer/lib/action_mailer/vendor/tmail-1.2.3/tmail/core_extensions.rb
... ...
@@ -1,63 +0,0 @@
1  
-#:stopdoc:
2  
-unless Object.respond_to?(:blank?)
3  
-  class Object
4  
-    # Check first to see if we are in a Rails environment, no need to 
5  
-    # define these methods if we are
6  
-
7  
-    # An object is blank if it's nil, empty, or a whitespace string.
8  
-    # For example, "", "   ", nil, [], and {} are blank.
9  
-    #
10  
-    # This simplifies
11  
-    #   if !address.nil? && !address.empty?
12  
-    # to
13  
-    #   if !address.blank?
14  
-    def blank?
15  
-      if respond_to?(:empty?) && respond_to?(:strip)
16  
-        empty? or strip.empty?
17  
-      elsif respond_to?(:empty?)
18  
-        empty?
19  
-      else
20  
-        !self
21  
-      end
22  
-    end
23  
-  end
24  
-
25  
-  class NilClass
26  
-    def blank?
27  
-      true
28  
-    end
29  
-  end
30  
-
31  
-  class FalseClass
32  
-    def blank?
33  
-      true
34  
-    end
35