Class TMail::Mail
In: lib/tmail/mail.rb
lib/tmail/net.rb
lib/tmail/obsolete.rb
Parent: Object

facade.rb

Methods

[]   []=   accept   add_date   add_message_id   base64_decode   base64_encode   bcc   bcc=   bcc_addrs   bcc_addrs=   body   body=   body_port   boundary   cc   cc=   cc_addrs   cc_addrs=   charset   charset=   clear   content_disposition   content_disposition=   content_transfer_encoding   content_transfer_encoding=   content_type   content_type=   create_empty_mail   create_forward   create_reply   create_reply   date   date=   delete   delete_if   delete_no_send_fields   destinations   disposition   disposition=   disposition_param   each   each_dest   each_dest   each_destination   each_field   each_header   each_header_name   each_key   each_pair   each_part   each_value   encoding   encoding=   epilogue   epilogue=   error_reply_addresses   fetch   friendly_from   from   from=   from_addr   from_address   from_address=   from_addrs   from_addrs=   from_phrase   has_key?   has_value?   header   header_string   in_reply_to   in_reply_to=   include?   indexes   indices   inspect   key?   keys   load   main_type   message_id   message_id=   mime_encode   mime_encode_binary   mime_encode_multipart   mime_encode_singlepart   mime_encode_text   mime_version   mime_version=   msgid   msgid   msgid=   multipart?   new   ordered_each   parse   parts   preamble   preamble=   ready_to_send   references   references=   reply_addresses   reply_to   reply_to=   reply_to_addrs   reply_to_addrs=   send_text_to   send_to   send_to_0   sender   sender=   sender_addr   sender_addr=   set_content_disposition   set_content_type   set_disposition   setup_forward   setup_reply   store   strftime   sub_type   subject   subject=   to   to=   to_addrs   to_addrs=   transfer_encoding   transfer_encoding=   type_param   value?   values   values_at   write_back  

Included Modules

StrategyInterface TextUtils

Constants

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   Direct Header Access
USE_ARRAY = ALLOW_MULTIPLE
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 )
NOSEND_FIELDS = %w( received bcc )

External Aliases

load -> loadfrom
load -> load_from

Attributes

port  [R] 

Public Class methods

[Source]

# File lib/tmail/obsolete.rb, line 114
  def Mail.boundary
    ::TMail.new_boundary
  end

[Source]

# File lib/tmail/mail.rb, line 24
    def Mail.load(fname)
      new(FilePort.new(fname))
    end

[Source]

# File lib/tmail/obsolete.rb, line 118
  def Mail.msgid
    ::TMail.new_message_id
  end

[Source]

# File lib/tmail/mail.rb, line 32
    def initialize(port = nil, conf = DEFAULT_CONFIG)
      @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

[Source]

# File lib/tmail/mail.rb, line 28
    def Mail.parse(str)
      new(StringPort.new(str))
    end

Public Instance methods

[Source]

# File lib/tmail/mail.rb, line 592
    def [](key)
      @header[key.downcase]
    end

[Source]

# File lib/tmail/mail.rb, line 598
    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
        raise BadMessage, "multiple #{key}: header fields exist"\
            unless ALLOW_MULTIPLE.include?(dkey)
        @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

[Source]

# File lib/tmail/mail.rb, line 69
    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

[Source]

# File lib/tmail/net.rb, line 66
    def add_date
      self.date = Time.now
    end

[Source]

# File lib/tmail/net.rb, line 62
    def add_message_id(fqdn = nil)
      self.message_id = ::TMail::new_msgid(fqdn)
    end

[Source]

# File lib/tmail/mail.rb, line 163
    def base64_decode
      if /base64/i =~ self.transfer_encoding('')
        store 'Content-Transfer-Encoding', '8bit'
        self.body = Base64.decode(self.body, @config.strict_base64decode?)
      end
    end

[Source]

# File lib/tmail/mail.rb, line 158
    def base64_encode
      store 'Content-Transfer-Encoding', 'Base64'
      self.body = Base64.folding_encode(self.body)
    end

[Source]

# File lib/tmail/mail.rb, line 259
    def bcc(default = nil)
      addrs2specs(bcc_addrs(nil)) || default
    end

[Source]

# File lib/tmail/mail.rb, line 271
    def bcc=(*strs)
      set_string_array_attr 'Bcc', strs
    end

[Source]

# File lib/tmail/mail.rb, line 234
    def bcc_addrs(default = nil)
      h = @header['bcc'] or return default
      h.addrs
    end

[Source]

# File lib/tmail/mail.rb, line 247
    def bcc_addrs=(arg)
      set_addrfield 'bcc', arg
    end

[Source]

# File lib/tmail/mail.rb, line 767
    def body
      parse_body
      @body_port.ropen {|f|
        return f.read
      }
    end

[Source]

# File lib/tmail/mail.rb, line 774
    def body=(str)
      parse_body
      @body_port.wopen {|f| f.write str }
      str
    end

Message Body

[Source]

# File lib/tmail/mail.rb, line 758
    def body_port
      parse_body
      @body_port
    end

[Source]

# File lib/tmail/mail.rb, line 255
    def cc(default = nil)
      addrs2specs(cc_addrs(nil)) || default
    end

[Source]

# File lib/tmail/mail.rb, line 267
    def cc=(*strs)
      set_string_array_attr 'Cc', strs
    end

[Source]

# File lib/tmail/mail.rb, line 229
    def cc_addrs(default = nil)
      h = @header['cc'] or return default
      h.addrs
    end

[Source]

# File lib/tmail/mail.rb, line 243
    def cc_addrs=(arg)
      set_addrfield 'cc', arg
    end

[Source]

# File lib/tmail/mail.rb, line 453
    def charset(default = nil)
      h = @header['content-type'] or return default
      h['charset'] || default
    end

[Source]

# File lib/tmail/mail.rb, line 458
    def charset=(str)
      if str
        if h = @header[ 'content-type' ]
          h['charset'] = str
        else
          store 'Content-Type', "text/plain; charset=#{str}"
        end
      end
      str
    end

[Source]

# File lib/tmail/mail.rb, line 671
    def clear
      @header.clear
    end
content_disposition(default = nil)

Alias for disposition

content_disposition=(pos, params = nil)

Alias for set_disposition

content_transfer_encoding(default = nil)

Alias for transfer_encoding

content_transfer_encoding=(str)

Alias for transfer_encoding=

[Source]

# File lib/tmail/mail.rb, line 412
    def content_type(default = nil)
      h = @header['content-type'] or return default
      h.content_type || default
    end
content_type=(str, sub = nil, param = nil)

Alias for set_content_type

[Source]

# File lib/tmail/net.rb, line 110
    def create_empty_mail
      self.class.new(StringPort.new(''), @config)
    end

[Source]

# File lib/tmail/net.rb, line 133
    def create_forward
      setup_forward create_empty_mail()
    end

[Source]

# File lib/tmail/net.rb, line 114
    def create_reply
      setup_reply create_empty_mail()
    end

[Source]

# File lib/tmail/mail.rb, line 174
    def create_reply
      mail = TMail::Mail.new
      mail.subject = 'Re: ' + subject('').sub(/\A(?:\[[^\]]+\])?(?:\s*Re:)*\s*/i, '')
      mail.to_addrs = reply_addresses([])
      mail.in_reply_to = [message_id(nil)].compact
      mail.references = references([]) + [message_id(nil)].compact
      mail.mime_version = '1.0'
      mail
    end

date time

[Source]

# File lib/tmail/mail.rb, line 201
    def date(default = nil)
      h = @header['date'] or return default
      h.date
    end

[Source]

# File lib/tmail/mail.rb, line 206
    def date=(time)
      if time
        store 'Date', time2str(time)
      else
        @header.delete 'date'
      end
      time
    end

[Source]

# File lib/tmail/mail.rb, line 675
    def delete(key)
      @header.delete key.downcase
    end

[Source]

# File lib/tmail/mail.rb, line 679
    def delete_if
      @header.delete_if {|key, val|
        if val.is_a?(Array)
          val.delete_if {|v| yield key, v }
          val.empty?
        else
          yield key, val
        end
      }
    end

[Source]

# File lib/tmail/net.rb, line 55
    def delete_no_send_fields
      NOSEND_FIELDS.each do |nm|
        delete nm
      end
      delete_if {|n,v| v.empty? }
    end

[Source]

# File lib/tmail/mail.rb, line 134
    def destinations(default = nil)
      result = to([]) + cc([]) + bcc([])
      return default if result.empty?
      result
    end

[Source]

# File lib/tmail/mail.rb, line 488
    def disposition(default = nil)
      if h = @header['content-disposition']
        h.disposition || default
      else
        default
      end
    end
disposition=(pos, params = nil)

Alias for set_disposition

[Source]

# File lib/tmail/mail.rb, line 510
    def disposition_param(name, default = nil)
      if h = @header['content-disposition']
        h[name] || default
      else
        default
      end
    end

[Source]

# File lib/tmail/mail.rb, line 763
    def each(&block)
      body_port().ropen {|f| f.each(&block) }
    end
each_dest(&block)

Alias for each_destination

each_dest(&block)

Alias for each_destination

[Source]

# File lib/tmail/mail.rb, line 140
    def each_destination(&block)
      destinations([]).each(&block)
    end

[Source]

# File lib/tmail/mail.rb, line 642
    def each_field(&block)
      @header.values.flatten.each(&block)
    end

[Source]

# File lib/tmail/mail.rb, line 628
    def each_header
      @header.each do |key, val|
        [val].flatten.each {|v| yield key, v }
      end
    end

[Source]

# File lib/tmail/mail.rb, line 636
    def each_header_name(&block)
      @header.each_key(&block)
    end
each_key(&block)

Alias for each_header_name

each_pair()

Alias for each_header

[Source]

# File lib/tmail/mail.rb, line 799
    def each_part(&block)
      parts().each(&block)
    end
each_value(&block)

Alias for each_field

encoding(default = nil)

Alias for transfer_encoding

encoding=(str)

Alias for transfer_encoding=

[Source]

# File lib/tmail/mail.rb, line 783
    def epilogue
      parse_body
      @epilogue.dup
    end

[Source]

# File lib/tmail/mail.rb, line 788
    def epilogue=(str)
      parse_body
      @epilogue = str
      str
    end

[Source]

# File lib/tmail/mail.rb, line 150
    def error_reply_addresses(default = nil)
      if s = sender(nil)
        [s]
      else
        from_addrs(default)
      end
    end
fetch(key)

Alias for #[]

High level utilities

[Source]

# File lib/tmail/mail.rb, line 121
    def friendly_from(default = nil)
      h = @header['from']
      a, = h.addrs
      return default unless a
      return a.phrase if a.phrase
      return h.comments.join(' ') unless h.comments.empty?
      a.spec
    end

[Source]

# File lib/tmail/mail.rb, line 291
    def from(default = nil)
      addrs2specs(from_addrs(nil)) || default
    end

[Source]

# File lib/tmail/mail.rb, line 295
    def from=(*strs)
      set_string_array_attr 'From', strs
    end

[Source]

# File lib/tmail/obsolete.rb, line 46
    def from_addr(default = nil)
      addr, = from_addrs(nil)
      addr || default
    end

[Source]

# File lib/tmail/mail.rb, line 130
    def from_address(default = nil)
      from([]).first || default
    end
from_address=(arg)

Alias for from_addrs=

originator

[Source]

# File lib/tmail/mail.rb, line 279
    def from_addrs(default = nil)
      if h = @header['from']
        h.addrs
      else
        default
      end
    end

[Source]

# File lib/tmail/mail.rb, line 287
    def from_addrs=(arg)
      set_addrfield 'from', arg
    end

[Source]

# File lib/tmail/obsolete.rb, line 53
    def from_phrase(default = nil)
      if a = from_addr(nil)
        a.phrase
      else
        default
      end
    end
has_key?(key)

Alias for key?

has_value?(val)

Alias for value?

[Source]

# File lib/tmail/mail.rb, line 588
    def header
      @header.dup
    end

[Source]

# File lib/tmail/mail.rb, line 192
    def header_string(name, default = nil)
      h = @header[name.downcase] or return default
      h.to_s
    end

[Source]

# File lib/tmail/mail.rb, line 370
    def in_reply_to(default = nil)
      h = @header['in-reply-to'] or return default
      h.ids
    end

[Source]

# File lib/tmail/mail.rb, line 375
    def in_reply_to=(*idstrs)
      set_string_array_attr 'In-Reply-To', idstrs
    end
include?(key)

Alias for key?

indexes(*args)

Alias for values_at

indices(*args)

Alias for values_at

[Source]

# File lib/tmail/mail.rb, line 50
    def inspect
      "\#<#{self.class} port=#{@port.inspect} bodyport=#{@body_port.inspect}>"
    end

[Source]

# File lib/tmail/mail.rb, line 694
    def key?(key)
      @header.key?(key.downcase)
    end

[Source]

# File lib/tmail/mail.rb, line 690
    def keys
      @header.keys
    end

[Source]

# File lib/tmail/mail.rb, line 417
    def main_type(default = nil)
      h = @header['content-type'] or return default
      h.main_type || default
    end

identity & threading

[Source]

# File lib/tmail/mail.rb, line 361
    def message_id(default = nil)
      h = @header['message-id'] or return default
      h.id || default
    end

[Source]

# File lib/tmail/mail.rb, line 366
    def message_id=(str)
      set_string_attr 'Message-Id', str
    end

[Source]

# File lib/tmail/net.rb, line 70
    def mime_encode
      if parts.empty?
        mime_encode_singlepart
      else
        mime_encode_multipart true
      end
    end

[Source]

# File lib/tmail/net.rb, line 94
    def mime_encode_binary(body)
      self.body = [body].pack('m')
      self.set_content_type 'application', 'octet-stream'
      self.encoding = 'Base64'
    end

[Source]

# File lib/tmail/net.rb, line 100
    def mime_encode_multipart(top = true)
      self.mime_version = '1.0' if top
      self.set_content_type 'multipart', 'mixed'
      e = encoding(nil)
      if e and not /\A(?:7bit|8bit|binary)\z/i =~ e
        raise ArgumentError,
              'using C.T.Encoding with multipart mail is not permitted'
      end
    end

[Source]

# File lib/tmail/net.rb, line 78
    def mime_encode_singlepart
      self.mime_version = '1.0'
      b = body
      if NKF.guess(b) != NKF::BINARY
        mime_encode_text b
      else
        mime_encode_binary b
      end
    end

[Source]

# File lib/tmail/net.rb, line 88
    def mime_encode_text(body)
      self.body = NKF.nkf('-j -m0', body)
      self.set_content_type 'text', 'plain', {'charset' => 'iso-2022-jp'}
      self.encoding = '7bit'
    end

MIME headers

[Source]

# File lib/tmail/mail.rb, line 392
    def mime_version(default = nil)
      h = @header['mime-version'] or return default
      h.version || default
    end

[Source]

# File lib/tmail/mail.rb, line 397
    def mime_version=(m, opt = nil)
      if opt
        if h = @header['mime-version']
          h.major = m
          h.minor = opt
        else
          store 'Mime-Version', "#{m}.#{opt}"
        end
      else
        store 'Mime-Version', m
      end
      m
    end
msgid(default = nil)

Alias for message_id

msgid=(str)

Alias for message_id=

[Source]

# File lib/tmail/mail.rb, line 170
    def multipart?
      main_type('').downcase == 'multipart'
    end

[Source]

# File lib/tmail/mail.rb, line 659
    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

[Source]

# File lib/tmail/mail.rb, line 794
    def parts
      parse_body
      @parts
    end
preamble()

Alias for body

preamble=(str)

Alias for body=

[Source]

# File lib/tmail/net.rb, line 44
    def ready_to_send
      delete_no_send_fields
      add_message_id
      add_date
    end

[Source]

# File lib/tmail/mail.rb, line 379
    def references(default = nil)
      h = @header['references'] or return default
      h.refs
    end

[Source]

# File lib/tmail/mail.rb, line 384
    def references=(*strs)
      set_string_array_attr 'References', strs
    end

[Source]

# File lib/tmail/mail.rb, line 146
    def reply_addresses(default = nil)
      reply_to_addrs(nil) or from_addrs(nil) or default
    end

[Source]

# File lib/tmail/mail.rb, line 309
    def reply_to(default = nil)
      addrs2specs(reply_to_addrs(nil)) || default
    end

[Source]

# File lib/tmail/mail.rb, line 313
    def reply_to=(*strs)
      set_string_array_attr 'Reply-To', strs
    end

[Source]

# File lib/tmail/mail.rb, line 300
    def reply_to_addrs(default = nil)
      h = @header['reply-to'] or return default
      h.addrs
    end

[Source]

# File lib/tmail/mail.rb, line 305
    def reply_to_addrs=(arg)
      set_addrfield 'reply-to', arg
    end

[Source]

# File lib/tmail/net.rb, line 23
    def send_text_to(smtp)
      do_send_to(smtp) do
        ready_to_send
        mime_encode
      end
    end

[Source]

# File lib/tmail/net.rb, line 17
    def send_to(smtp)
      do_send_to(smtp) do
        ready_to_send
      end
    end

[Source]

# File lib/tmail/net.rb, line 38
    def send_to_0(smtp, from, to)
      smtp.ready(from, to) do |f|
        encoded "\r\n", 'j', f, ''
      end
    end

[Source]

# File lib/tmail/mail.rb, line 334
    def sender(default)
      f = @header['sender'] or return default
      a = f.addr            or return default
      a.spec
    end

[Source]

# File lib/tmail/mail.rb, line 340
    def sender=(str)
      set_string_attr 'Sender', str
    end

[Source]

# File lib/tmail/mail.rb, line 318
    def sender_addr(default = nil)
      f = @header['sender'] or return default
      f.addr || default
    end

[Source]

# File lib/tmail/mail.rb, line 323
    def sender_addr=(addr)
      if addr
        h = HeaderField.internal_new('sender', @config)
        h.addr = addr
        @header['sender'] = h
      else
        @header.delete 'sender'
      end
      addr
    end
set_content_disposition(pos, params = nil)

Alias for set_disposition

[Source]

# File lib/tmail/mail.rb, line 427
    def set_content_type(str, sub = nil, param = nil)
      if sub
        main, sub = str, sub
      else
        main, sub = str.split(%r</>, 2)
        raise ArgumentError, "sub type missing: #{str.inspect}" unless sub
      end
      if h = @header['content-type']
        h.main_type = main
        h.sub_type  = sub
        h.params.clear
      else
        store 'Content-Type', "#{main}/#{sub}"
      end
      @header['content-type'].params.replace param if param

      str
    end

[Source]

# File lib/tmail/mail.rb, line 498
    def set_disposition(pos, params = nil)
      @header.delete 'content-disposition'
      return pos unless pos
      store('Content-Disposition', pos)
      @header['content-disposition'].params.replace params if params
      pos
    end

[Source]

# File lib/tmail/net.rb, line 137
    def setup_forward(mail)
      m = Mail.new(StringPort.new(''))
      m.body = decoded
      m.set_content_type 'message', 'rfc822'
      m.encoding = encoding('7bit')
      mail.parts.push m
    end

[Source]

# File lib/tmail/net.rb, line 118
    def setup_reply(m)
      if tmp = reply_addresses(nil)
        m.to_addrs = tmp
      end

      mid = message_id(nil)
      tmp = references(nil) || []
      tmp.push mid if mid
      m.in_reply_to = [mid] if mid
      m.references = tmp unless tmp.empty?
      m.subject = 'Re: ' + subject('').sub(/\A(?:\s*re:)+/i, '')

      m
    end
store(key, val)

Alias for #[]=

[Source]

# File lib/tmail/mail.rb, line 215
    def strftime(fmt, default = nil)
      t = date or return default
      t.strftime(fmt)
    end

[Source]

# File lib/tmail/mail.rb, line 422
    def sub_type(default = nil)
      h = @header['content-type'] or return default
      h.sub_type || default
    end

subject

[Source]

# File lib/tmail/mail.rb, line 348
    def subject(default = nil)
      h = @header['subject'] or return default
      h.body
    end

[Source]

# File lib/tmail/mail.rb, line 353
    def subject=(str)
      set_string_attr 'Subject', str
    end

[Source]

# File lib/tmail/mail.rb, line 251
    def to(default = nil)
      addrs2specs(to_addrs(nil)) || default
    end

[Source]

# File lib/tmail/mail.rb, line 263
    def to=(*strs)
      set_string_array_attr 'To', strs
    end

destination

[Source]

# File lib/tmail/mail.rb, line 224
    def to_addrs(default = nil)
      h = @header['to'] or return default
      h.addrs
    end

[Source]

# File lib/tmail/mail.rb, line 239
    def to_addrs=(arg)
      set_addrfield 'to', arg
    end

[Source]

# File lib/tmail/mail.rb, line 470
    def transfer_encoding(default = nil)
      if h = @header['content-transfer-encoding']
        h.encoding || default
      else
        default
      end
    end

[Source]

# File lib/tmail/mail.rb, line 478
    def transfer_encoding=(str)
      set_string_attr 'Content-Transfer-Encoding', str
    end

[Source]

# File lib/tmail/mail.rb, line 448
    def type_param(name, default = nil)
      h = @header['content-type'] or return default
      h[name] || default
    end

[Source]

# File lib/tmail/obsolete.rb, line 35
    def value?(val)
      return false unless val.is_a?(HeaderField)
      [@header[val.name.downcase]].flatten.include?(val)
    end

[Source]

# File lib/tmail/obsolete.rb, line 27
    def values
      result = []
      each_field do |f|
        result.push f
      end
      result
    end

[Source]

# File lib/tmail/mail.rb, line 698
    def values_at(*args)
      args.map {|k| @header[k.downcase] }.flatten
    end

[Source]

# File lib/tmail/mail.rb, line 62
    def write_back(eol = "\n", charset = 'e')
      parse_body
      @port.wopen {|stream|
        encoded eol, charset, stream
      }
    end

[Validate]