OSDN Git Service

Rails 2.3.11
[redminele/redminele.git] / ruby / lib / ruby / gems / 1.8 / gems / actionmailer-2.3.5 / lib / action_mailer / vendor / tmail-1.2.3 / tmail / mail.rb
diff --git a/ruby/lib/ruby/gems/1.8/gems/actionmailer-2.3.5/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb b/ruby/lib/ruby/gems/1.8/gems/actionmailer-2.3.5/lib/action_mailer/vendor/tmail-1.2.3/tmail/mail.rb
deleted file mode 100644 (file)
index c3a8803..0000000
+++ /dev/null
@@ -1,578 +0,0 @@
-=begin rdoc
-
-= Mail class
-
-=end
-#--
-# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
-# with permission of Minero Aoki.
-#++
-
-
-require 'tmail/interface'
-require 'tmail/encode'
-require 'tmail/header'
-require 'tmail/port'
-require 'tmail/config'
-require 'tmail/utils'
-require 'tmail/attachments'
-require 'tmail/quoting'
-require 'socket'
-
-module TMail
-
-  # == Mail Class
-  # 
-  # Accessing a TMail object done via the TMail::Mail class.  As email can be fairly complex
-  # creatures, you will find a large amount of accessor and setter methods in this class!
-  # 
-  # Most of the below methods handle the header, in fact, what TMail does best is handle the
-  # header of the email object.  There are only a few methods that deal directly with the body
-  # of the email, such as base64_encode and base64_decode.
-  # 
-  # === Using TMail inside your code
-  # 
-  # The usual way is to install the gem (see the {README}[link:/README] on how to do this) and
-  # then put at the top of your class:
-  # 
-  #  require 'tmail'
-  # 
-  # You can then create a new TMail object in your code with:
-  # 
-  #  @email = TMail::Mail.new
-  # 
-  # Or if you have an email as a string, you can initialize a new TMail::Mail object and get it
-  # to parse that string for you like so:
-  # 
-  #  @email = TMail::Mail.parse(email_text)
-  # 
-  # You can also read a single email off the disk, for example:
-  # 
-  #  @email = TMail::Mail.load('filename.txt')
-  # 
-  # Also, you can read a mailbox (usual unix mbox format) and end up with an array of TMail
-  # objects by doing something like this:
-  # 
-  #  # Note, we pass true as the last variable to open the mailbox read only
-  #  mailbox = TMail::UNIXMbox.new("mailbox", nil, true)
-  #  @emails = []
-  #  mailbox.each_port { |m| @emails << TMail::Mail.new(m) }
-  #
-  class Mail
-
-    class << self
-      
-      # Opens an email that has been saved out as a file by itself.
-      # 
-      # This function will read a file non-destructively and then parse
-      # the contents and return a TMail::Mail object.
-      # 
-      # Does not handle multiple email mailboxes (like a unix mbox) for that
-      # use the TMail::UNIXMbox class.
-      # 
-      # Example:
-      #  mail = TMail::Mail.load('filename')
-      # 
-      def load( fname )
-        new(FilePort.new(fname))
-      end
-
-      alias load_from load
-      alias loadfrom load
-      
-      # Parses an email from the supplied string and returns a TMail::Mail
-      # object.
-      # 
-      # Example:
-      #  require 'rubygems'; require 'tmail'
-      #  email_string =<<HEREDOC
-      #  To: mikel@lindsaar.net
-      #  From: mikel@me.com
-      #  Subject: This is a short Email
-      #  
-      #  Hello there Mikel!
-      #  
-      #  HEREDOC
-      #  mail = TMail::Mail.parse(email_string)
-      #  #=> #<TMail::Mail port=#<TMail::StringPort:id=0xa30ac0> bodyport=nil>
-      #  mail.body
-      #  #=> "Hello there Mikel!\n\n"
-      def parse( str )
-        new(StringPort.new(str))
-      end
-
-    end
-
-    def initialize( port = nil, conf = DEFAULT_CONFIG ) #:nodoc:
-      @port = port || StringPort.new
-      @config = Config.to_config(conf)
-
-      @header      = {}
-      @body_port   = nil
-      @body_parsed = false
-      @epilogue    = ''
-      @parts       = []
-
-      @port.ropen {|f|
-          parse_header f
-          parse_body f unless @port.reproducible?
-      }
-    end
-
-    # Provides access to the port this email is using to hold it's data
-    # 
-    # Example:
-    #  mail = TMail::Mail.parse(email_string)
-    #  mail.port
-    #  #=> #<TMail::StringPort:id=0xa2c952>
-    attr_reader :port
-
-    def inspect
-      "\#<#{self.class} port=#{@port.inspect} bodyport=#{@body_port.inspect}>"
-    end
-
-    #
-    # to_s interfaces
-    #
-
-    public
-
-    include StrategyInterface
-
-    def write_back( eol = "\n", charset = 'e' )
-      parse_body
-      @port.wopen {|stream| encoded eol, charset, stream }
-    end
-
-    def accept( strategy )
-      with_multipart_encoding(strategy) {
-          ordered_each do |name, field|
-            next if field.empty?
-            strategy.header_name canonical(name)
-            field.accept strategy
-            strategy.puts
-          end
-          strategy.puts
-          body_port().ropen {|r|
-              strategy.write r.read
-          }
-      }
-    end
-
-    private
-
-    def canonical( name )
-      name.split(/-/).map {|s| s.capitalize }.join('-')
-    end
-
-    def with_multipart_encoding( strategy )
-      if parts().empty?    # DO NOT USE @parts
-        yield
-
-      else
-        bound = ::TMail.new_boundary
-        if @header.key? 'content-type'
-          @header['content-type'].params['boundary'] = bound
-        else
-          store 'Content-Type', %<multipart/mixed; boundary="#{bound}">
-        end
-
-        yield
-
-        parts().each do |tm|
-          strategy.puts
-          strategy.puts '--' + bound
-          tm.accept strategy
-        end
-        strategy.puts
-        strategy.puts '--' + bound + '--'
-        strategy.write epilogue()
-      end
-    end
-
-    ###
-    ### header
-    ###
-
-    public
-
-    ALLOW_MULTIPLE = {
-      'received'          => true,
-      'resent-date'       => true,
-      'resent-from'       => true,
-      'resent-sender'     => true,
-      'resent-to'         => true,
-      'resent-cc'         => true,
-      'resent-bcc'        => true,
-      'resent-message-id' => true,
-      'comments'          => true,
-      'keywords'          => true
-    }
-    USE_ARRAY = ALLOW_MULTIPLE
-
-    def header
-      @header.dup
-    end
-
-    # Returns a TMail::AddressHeader object of the field you are querying.
-    # Examples:
-    #  @mail['from']  #=> #<TMail::AddressHeader "mikel@test.com.au">
-    #  @mail['to']    #=> #<TMail::AddressHeader "mikel@test.com.au">
-    #
-    # You can get the string value of this by passing "to_s" to the query:
-    # Example:
-    #  @mail['to'].to_s #=> "mikel@test.com.au"
-    def []( key )
-      @header[key.downcase]
-    end
-
-    def sub_header(key, param)
-      (hdr = self[key]) ? hdr[param] : nil
-    end
-
-    alias fetch []
-
-    # Allows you to set or delete TMail header objects at will.
-    # Examples:
-    #  @mail = TMail::Mail.new
-    #  @mail['to'].to_s       # => 'mikel@test.com.au'
-    #  @mail['to'] = 'mikel@elsewhere.org'
-    #  @mail['to'].to_s       # => 'mikel@elsewhere.org'
-    #  @mail.encoded          # => "To: mikel@elsewhere.org\r\n\r\n"
-    #  @mail['to'] = nil
-    #  @mail['to'].to_s       # => nil
-    #  @mail.encoded          # => "\r\n"
-    # 
-    # Note: setting mail[] = nil actually deletes the header field in question from the object,
-    # it does not just set the value of the hash to nil
-    def []=( key, val )
-      dkey = key.downcase
-
-      if val.nil?
-        @header.delete dkey
-        return nil
-      end
-
-      case val
-      when String
-        header = new_hf(key, val)
-      when HeaderField
-        ;
-      when Array
-        ALLOW_MULTIPLE.include? dkey or
-                raise ArgumentError, "#{key}: Header must not be multiple"
-        @header[dkey] = val
-        return val
-      else
-        header = new_hf(key, val.to_s)
-      end
-      if ALLOW_MULTIPLE.include? dkey
-        (@header[dkey] ||= []).push header
-      else
-        @header[dkey] = header
-      end
-
-      val
-    end
-
-    alias store []=
-    
-    # Allows you to loop through each header in the TMail::Mail object in a block
-    # Example:
-    #   @mail['to'] = 'mikel@elsewhere.org'
-    #   @mail['from'] = 'me@me.com'
-    #   @mail.each_header { |k,v| puts "#{k} = #{v}" }
-    #   # => from = me@me.com
-    #   # => to = mikel@elsewhere.org
-    def each_header
-      @header.each do |key, val|
-        [val].flatten.each {|v| yield key, v }
-      end
-    end
-
-    alias each_pair each_header
-
-    def each_header_name( &block )
-      @header.each_key(&block)
-    end
-
-    alias each_key each_header_name
-
-    def each_field( &block )
-      @header.values.flatten.each(&block)
-    end
-
-    alias each_value each_field
-
-    FIELD_ORDER = %w(
-      return-path received
-      resent-date resent-from resent-sender resent-to
-      resent-cc resent-bcc resent-message-id
-      date from sender reply-to to cc bcc
-      message-id in-reply-to references
-      subject comments keywords
-      mime-version content-type content-transfer-encoding
-      content-disposition content-description
-    )
-
-    def ordered_each
-      list = @header.keys
-      FIELD_ORDER.each do |name|
-        if list.delete(name)
-          [@header[name]].flatten.each {|v| yield name, v }
-        end
-      end
-      list.each do |name|
-        [@header[name]].flatten.each {|v| yield name, v }
-      end
-    end
-
-    def clear
-      @header.clear
-    end
-
-    def delete( key )
-      @header.delete key.downcase
-    end
-
-    def delete_if
-      @header.delete_if do |key,val|
-        if Array === val
-          val.delete_if {|v| yield key, v }
-          val.empty?
-        else
-          yield key, val
-        end
-      end
-    end
-
-    def keys
-      @header.keys
-    end
-
-    def key?( key )
-      @header.key? key.downcase
-    end
-
-    def values_at( *args )
-      args.map {|k| @header[k.downcase] }.flatten
-    end
-
-    alias indexes values_at
-    alias indices values_at
-
-    private
-
-    def parse_header( f )
-      name = field = nil
-      unixfrom = nil
-
-      while line = f.gets
-        case line
-        when /\A[ \t]/             # continue from prev line
-          raise SyntaxError, 'mail is began by space' unless field
-          field << ' ' << line.strip
-
-        when /\A([^\: \t]+):\s*/   # new header line
-          add_hf name, field if field
-          name = $1
-          field = $' #.strip
-
-        when /\A\-*\s*\z/          # end of header
-          add_hf name, field if field
-          name = field = nil
-          break
-
-        when /\AFrom (\S+)/
-          unixfrom = $1
-
-        when /^charset=.*/
-
-        else
-          raise SyntaxError, "wrong mail header: '#{line.inspect}'"
-        end
-      end
-      add_hf name, field if name
-
-      if unixfrom
-        add_hf 'Return-Path', "<#{unixfrom}>" unless @header['return-path']
-      end
-    end
-
-    def add_hf( name, field )
-      key = name.downcase
-      field = new_hf(name, field)
-
-      if ALLOW_MULTIPLE.include? key
-        (@header[key] ||= []).push field
-      else
-        @header[key] = field
-      end
-    end
-
-    def new_hf( name, field )
-      HeaderField.new(name, field, @config)
-    end
-
-    ###
-    ### body
-    ###
-
-    public
-
-    def body_port
-      parse_body
-      @body_port
-    end
-
-    def each( &block )
-      body_port().ropen {|f| f.each(&block) }
-    end
-
-    def quoted_body
-      body_port.ropen {|f| return f.read }
-    end
-
-    def quoted_body= str
-      body_port.wopen { |f| f.write str }
-      str
-    end
-
-    def body=( str )
-      # Sets the body of the email to a new (encoded) string.
-      # 
-      # We also reparses the email if the body is ever reassigned, this is a performance hit, however when
-      # you assign the body, you usually want to be able to make sure that you can access the attachments etc.
-      # 
-      # Usage:
-      # 
-      #  mail.body = "Hello, this is\nthe body text"
-      #  # => "Hello, this is\nthe body"
-      #  mail.body
-      #  # => "Hello, this is\nthe body"
-      @body_parsed = false
-      parse_body(StringInput.new(str))
-      parse_body
-      @body_port.wopen {|f| f.write str }
-      str
-    end
-
-    alias preamble  quoted_body
-    alias preamble= quoted_body=
-
-    def epilogue
-      parse_body
-      @epilogue.dup
-    end
-
-    def epilogue=( str )
-      parse_body
-      @epilogue = str
-      str
-    end
-
-    def parts
-      parse_body
-      @parts
-    end
-    
-    def each_part( &block )
-      parts().each(&block)
-    end
-    
-    # Returns true if the content type of this part of the email is
-    # a disposition attachment
-    def disposition_is_attachment?
-      (self['content-disposition'] && self['content-disposition'].disposition == "attachment")
-    end
-
-    # Returns true if this part's content main type is text, else returns false.
-    # By main type is meant "text/plain" is text.  "text/html" is text
-    def content_type_is_text?
-      self.header['content-type'] && (self.header['content-type'].main_type != "text")
-    end
-
-    private
-
-    def parse_body( f = nil )
-      return if @body_parsed
-      if f
-        parse_body_0 f
-      else
-        @port.ropen {|f|
-            skip_header f
-            parse_body_0 f
-        }
-      end
-      @body_parsed = true
-    end
-
-    def skip_header( f )
-      while line = f.gets
-        return if /\A[\r\n]*\z/ === line
-      end
-    end
-
-    def parse_body_0( f )
-      if multipart?
-        read_multipart f
-      else
-        @body_port = @config.new_body_port(self)
-        @body_port.wopen {|w|
-            w.write f.read
-        }
-      end
-    end
-    
-    def read_multipart( src )
-      bound = @header['content-type'].params['boundary']
-      is_sep = /\A--#{Regexp.quote bound}(?:--)?[ \t]*(?:\n|\r\n|\r)/
-      lastbound = "--#{bound}--"
-
-      ports = [ @config.new_preamble_port(self) ]
-      begin
-        f = ports.last.wopen
-        while line = src.gets
-          if is_sep === line
-            f.close
-            break if line.strip == lastbound
-            ports.push @config.new_part_port(self)
-            f = ports.last.wopen
-          else
-            f << line
-          end
-        end
-        @epilogue = (src.read || '')
-      ensure
-        f.close if f and not f.closed?
-      end
-
-      @body_port = ports.shift
-      @parts = ports.map {|p| self.class.new(p, @config) }
-    end
-
-  end   # class Mail
-
-end   # module TMail