Class | TMail::Mail |
In: |
lib/tmail/mail.rb
lib/tmail/net.rb lib/tmail/obsolete.rb |
Parent: | Object |
facade.rb
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 ) |
load | -> | loadfrom |
load | -> | load_from |
port | [R] |
# 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
# 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
# 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
# File lib/tmail/net.rb, line 62 def add_message_id(fqdn = nil) self.message_id = ::TMail::new_msgid(fqdn) end
# 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
# File lib/tmail/mail.rb, line 158 def base64_encode store 'Content-Transfer-Encoding', 'Base64' self.body = Base64.folding_encode(self.body) end
# File lib/tmail/mail.rb, line 259 def bcc(default = nil) addrs2specs(bcc_addrs(nil)) || default end
# File lib/tmail/mail.rb, line 234 def bcc_addrs(default = nil) h = @header['bcc'] or return default h.addrs end
# File lib/tmail/mail.rb, line 774 def body=(str) parse_body @body_port.wopen {|f| f.write str } str end
# File lib/tmail/mail.rb, line 229 def cc_addrs(default = nil) h = @header['cc'] or return default h.addrs end
# File lib/tmail/mail.rb, line 453 def charset(default = nil) h = @header['content-type'] or return default h['charset'] || default end
# 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
# File lib/tmail/mail.rb, line 412 def content_type(default = nil) h = @header['content-type'] or return default h.content_type || default end
# File lib/tmail/net.rb, line 110 def create_empty_mail self.class.new(StringPort.new(''), @config) end
# 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
# File lib/tmail/mail.rb, line 201 def date(default = nil) h = @header['date'] or return default h.date end
# File lib/tmail/mail.rb, line 206 def date=(time) if time store 'Date', time2str(time) else @header.delete 'date' end time end
# 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
# 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
# File lib/tmail/mail.rb, line 134 def destinations(default = nil) result = to([]) + cc([]) + bcc([]) return default if result.empty? result end
# File lib/tmail/mail.rb, line 488 def disposition(default = nil) if h = @header['content-disposition'] h.disposition || default else default end end
# 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
# File lib/tmail/mail.rb, line 628 def each_header @header.each do |key, val| [val].flatten.each {|v| yield key, v } end end
# File lib/tmail/mail.rb, line 150 def error_reply_addresses(default = nil) if s = sender(nil) [s] else from_addrs(default) end end
High level utilities
# 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
# File lib/tmail/mail.rb, line 291 def from(default = nil) addrs2specs(from_addrs(nil)) || default end
# File lib/tmail/obsolete.rb, line 46 def from_addr(default = nil) addr, = from_addrs(nil) addr || default end
originator
# File lib/tmail/mail.rb, line 279 def from_addrs(default = nil) if h = @header['from'] h.addrs else default end end
# File lib/tmail/obsolete.rb, line 53 def from_phrase(default = nil) if a = from_addr(nil) a.phrase else default end end
# File lib/tmail/mail.rb, line 192 def header_string(name, default = nil) h = @header[name.downcase] or return default h.to_s end
# File lib/tmail/mail.rb, line 370 def in_reply_to(default = nil) h = @header['in-reply-to'] or return default h.ids end
# File lib/tmail/mail.rb, line 375 def in_reply_to=(*idstrs) set_string_array_attr 'In-Reply-To', idstrs end
# File lib/tmail/mail.rb, line 50 def inspect "\#<#{self.class} port=#{@port.inspect} bodyport=#{@body_port.inspect}>" end
# 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
# File lib/tmail/mail.rb, line 361 def message_id(default = nil) h = @header['message-id'] or return default h.id || default end
# File lib/tmail/net.rb, line 70 def mime_encode if parts.empty? mime_encode_singlepart else mime_encode_multipart true end end
# 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
# 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
# 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
# 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
# File lib/tmail/mail.rb, line 392 def mime_version(default = nil) h = @header['mime-version'] or return default h.version || default end
# 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
# 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
# File lib/tmail/net.rb, line 44 def ready_to_send delete_no_send_fields add_message_id add_date end
# File lib/tmail/mail.rb, line 379 def references(default = nil) h = @header['references'] or return default h.refs end
# File lib/tmail/mail.rb, line 384 def references=(*strs) set_string_array_attr 'References', strs end
# File lib/tmail/mail.rb, line 146 def reply_addresses(default = nil) reply_to_addrs(nil) or from_addrs(nil) or default end
# File lib/tmail/mail.rb, line 309 def reply_to(default = nil) addrs2specs(reply_to_addrs(nil)) || default end
# File lib/tmail/mail.rb, line 300 def reply_to_addrs(default = nil) h = @header['reply-to'] or return default h.addrs end
# File lib/tmail/net.rb, line 23 def send_text_to(smtp) do_send_to(smtp) do ready_to_send mime_encode end end
# 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
# 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
# File lib/tmail/mail.rb, line 318 def sender_addr(default = nil) f = @header['sender'] or return default f.addr || default end
# 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
# 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
# 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
# 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
# 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
# File lib/tmail/mail.rb, line 215 def strftime(fmt, default = nil) t = date or return default t.strftime(fmt) end
# 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
# File lib/tmail/mail.rb, line 348 def subject(default = nil) h = @header['subject'] or return default h.body end
destination
# File lib/tmail/mail.rb, line 224 def to_addrs(default = nil) h = @header['to'] or return default h.addrs end
# 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
# File lib/tmail/mail.rb, line 478 def transfer_encoding=(str) set_string_attr 'Content-Transfer-Encoding', str end
# File lib/tmail/mail.rb, line 448 def type_param(name, default = nil) h = @header['content-type'] or return default h[name] || default end
# 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
# File lib/tmail/obsolete.rb, line 27 def values result = [] each_field do |f| result.push f end result end
# File lib/tmail/mail.rb, line 698 def values_at(*args) args.map {|k| @header[k.downcase] }.flatten end