Merge in latest tmail trunk r241

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9144 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jeremy Kemper
2008-03-30 05:05:19 +00:00
parent f66bbf5ed0
commit 316906cbbb
24 changed files with 533 additions and 192 deletions

View File

@@ -2,3 +2,4 @@ require 'tmail/version'
require 'tmail/mail'
require 'tmail/mailbox'
require 'tmail/core_extensions'
require 'tmail/net'

View File

@@ -3,7 +3,6 @@
= Address handling class
=end
#
#--
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
#
@@ -36,31 +35,72 @@ require 'tmail/parser'
module TMail
# = Class Address
#
# Provides a complete handling library for email addresses. Can parse a string of an
# address directly or take in preformatted addresses themseleves. Allows you to add
# and remove phrases from the front of the address and provides a compare function for
# email addresses.
#
# == Parsing and Handling a Valid Address:
#
# Just pass the email address in as a string to Address.parse:
#
# email = TMail::Address.parse('Mikel Lindsaar <mikel@lindsaar.net>)
# #=> #<TMail::Address mikel@lindsaar.net>
# email.address
# #=> "mikel@lindsaar.net"
# email.local
# #=> "mikel"
# email.domain
# #=> "lindsaar.net"
# email.name # Aliased as phrase as well
# #=> "Mikel Lindsaar"
#
# == Detecting an Invalid Address
#
# If you want to check the syntactical validity of an email address, just pass it to
# Address.parse and catch any SyntaxError:
#
# begin
# TMail::Mail.parse("mikel 2@@@@@ me .com")
# rescue TMail::SyntaxError
# puts("Invalid Email Address Detected")
# else
# puts("Address is valid")
# end
# #=> "Invalid Email Address Detected"
class Address
include TextUtils
include TextUtils #:nodoc:
# Sometimes you need to parse an address, TMail can do it for you and provide you with
# a fairly robust method of detecting a valid address.
#
# Takes in a string, returns a TMail::Address object.
#
# Raises a TMail::SyntaxError on invalid email format
def Address.parse( str )
Parser.parse :ADDRESS, special_quote_address(str)
end
# Takes a string which is an address and adds quotation marks to special
# edge case methods that the parser just barfs on.
#
# Right now just handles two edge cases:
#
# Full stop as the last character of the display name:
# Mikel A. <mikel@me.com>
# Returns:
# "Mikel A." <mikel@me.com>
#
# Unquoted @ symbol in the display name:
# mikel@me.com <mikel@me.com>
# Returns:
# "mikel@me.com" <mikel@me.com>
#
# Any other address not matching these patterns just gets returned as is.
def Address.special_quote_address(str)
def Address.special_quote_address(str) #:nodoc:
# Takes a string which is an address and adds quotation marks to special
# edge case methods that the RACC parser can not handle.
#
# Right now just handles two edge cases:
#
# Full stop as the last character of the display name:
# Mikel L. <mikel@me.com>
# Returns:
# "Mikel L." <mikel@me.com>
#
# Unquoted @ symbol in the display name:
# mikel@me.com <mikel@me.com>
# Returns:
# "mikel@me.com" <mikel@me.com>
#
# Any other address not matching these patterns just gets returned as is.
case
# This handles the missing "" in an older version of Apple Mail.app
# around the display name when the display name contains a '@'
@@ -78,10 +118,22 @@ module TMail
end
end
def address_group?
def address_group? #:nodoc:
false
end
# Address.new(local, domain)
#
# Accepts:
#
# * local - Left of the at symbol
#
# * domain - Array of the domain split at the periods.
#
# For example:
#
# Address.new("mikel", ["lindsaar", "net"])
# #=> "#<TMail::Address mikel@lindsaar.net>"
def initialize( local, domain )
if domain
domain.each do |s|
@@ -103,22 +155,67 @@ module TMail
@routes = []
end
attr_reader :name
# Provides the name or 'phrase' of the email address.
#
# For Example:
#
# email = TMail::Address.parse("Mikel Lindsaar <mikel@lindsaar.net>")
# email.name
# #=> "Mikel Lindsaar"
def name
@name
end
# Setter method for the name or phrase of the email
#
# For Example:
#
# email = TMail::Address.parse("mikel@lindsaar.net")
# email.name
# #=> nil
# email.name = "Mikel Lindsaar"
# email.to_s
# #=> "Mikel Lindsaar <mikel@me.com>"
def name=( str )
@name = str
@name = nil if str and str.empty?
end
#:stopdoc:
alias phrase name
alias phrase= name=
attr_reader :routes
def inspect
#:startdoc:
# This is still here from RFC 822, and is now obsolete per RFC2822 Section 4.
#
# "When interpreting addresses, the route portion SHOULD be ignored."
#
# It is still here, so you can access it.
#
# Routes return the route portion at the front of the email address, if any.
#
# For Example:
# email = TMail::Address.parse( "<@sa,@another:Mikel@me.com>")
# => #<TMail::Address Mikel@me.com>
# email.to_s
# => "<@sa,@another:Mikel@me.com>"
# email.routes
# => ["sa", "another"]
def routes
@routes
end
def inspect #:nodoc:
"#<#{self.class} #{address()}>"
end
# Returns the local part of the email address
#
# For Example:
#
# email = TMail::Address.parse("mikel@lindsaar.net")
# email.local
# #=> "mikel"
def local
return nil unless @local
return '""' if @local.size == 1 and @local[0].empty?
@@ -130,11 +227,25 @@ module TMail
end
end
# Returns the domain part of the email address
#
# For Example:
#
# email = TMail::Address.parse("mikel@lindsaar.net")
# email.local
# #=> "lindsaar.net"
def domain
return nil unless @domain
join_domain(@domain)
end
# Returns the full specific address itself
#
# For Example:
#
# email = TMail::Address.parse("mikel@lindsaar.net")
# email.address
# #=> "mikel@lindsaar.net"
def spec
s = self.local
d = self.domain
@@ -145,18 +256,41 @@ module TMail
end
end
alias address spec
alias address spec
# Provides == function to the email. Only checks the actual address
# and ignores the name/phrase component
#
# For Example
#
# addr1 = TMail::Address.parse("My Address <mikel@lindsaar.net>")
# #=> "#<TMail::Address mikel@lindsaar.net>"
# addr2 = TMail::Address.parse("Another <mikel@lindsaar.net>")
# #=> "#<TMail::Address mikel@lindsaar.net>"
# addr1 == addr2
# #=> true
def ==( other )
other.respond_to? :spec and self.spec == other.spec
end
alias eql? ==
# Provides a unique hash value for this record against the local and domain
# parts, ignores the name/phrase value
#
# email = TMail::Address.parse("mikel@lindsaar.net")
# email.hash
# #=> 18767598
def hash
@local.hash ^ @domain.hash
end
# Duplicates a TMail::Address object returning the duplicate
#
# addr1 = TMail::Address.parse("mikel@lindsaar.net")
# addr2 = addr1.dup
# addr1.id == addr2.id
# #=> false
def dup
obj = self.class.new(@local.dup, @domain.dup)
obj.name = @name.dup if @name
@@ -164,9 +298,9 @@ module TMail
obj
end
include StrategyInterface
include StrategyInterface #:nodoc:
def accept( strategy, dummy1 = nil, dummy2 = nil )
def accept( strategy, dummy1 = nil, dummy2 = nil ) #:nodoc:
unless @local
strategy.meta '<>' # empty return-path
return

View File

@@ -1,6 +1,6 @@
=begin rdoc
= Attachment handling class
= Attachment handling file
=end
@@ -17,8 +17,7 @@ module TMail
end
def attachment?(part)
(part['content-disposition'] && part['content-disposition'].disposition == "attachment") ||
part.header['content-type'].main_type != "text"
part.disposition_is_attachment? || part.content_type_is_text?
end
def attachments

View File

@@ -1,9 +1,4 @@
# = TITLE:
#
# Base64
#
# = COPYRIGHT:
#
#--
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -27,10 +22,9 @@
#
# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
# with permission of Minero Aoki.
#
#++
#:stopdoc:
module TMail
module Base64
module_function
@@ -48,5 +42,5 @@ module TMail
end
end
end
#:startdoc:

View File

@@ -1,17 +1,18 @@
unless Enumerable.method_defined?(:map)
module Enumerable
#:stopdoc:
unless Enumerable.method_defined?(:map)
module Enumerable #:nodoc:
alias map collect
end
end
unless Enumerable.method_defined?(:select)
module Enumerable
module Enumerable #:nodoc:
alias select find_all
end
end
unless Enumerable.method_defined?(:reject)
module Enumerable
module Enumerable #:nodoc:
def reject
result = []
each do |i|
@@ -23,7 +24,7 @@ unless Enumerable.method_defined?(:reject)
end
unless Enumerable.method_defined?(:sort_by)
module Enumerable
module Enumerable #:nodoc:
def sort_by
map {|i| [yield(i), i] }.sort.map {|val, i| i }
end
@@ -31,9 +32,10 @@ unless Enumerable.method_defined?(:sort_by)
end
unless File.respond_to?(:read)
def File.read(fname)
def File.read(fname) #:nodoc:
File.open(fname) {|f|
return f.read
}
end
end
#:startdoc:

View File

@@ -1,8 +1,3 @@
=begin rdoc
= Configuration Class
=end
#--
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
#
@@ -28,7 +23,7 @@
# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
# with permission of Minero Aoki.
#++
#:stopdoc:
module TMail
class Config
@@ -69,3 +64,4 @@ module TMail
end
end
#:startdoc:

View File

@@ -1,14 +1,9 @@
=begin rdoc
= Ruby on Rails Core Extensions
provides .blank?
=end
unless Object.respond_to?(:blank?) #:nodoc:
# Check first to see if we are in a Rails environment, no need to
# define these methods if we are
#:stopdoc:
unless Object.respond_to?(:blank?)
class Object
# Check first to see if we are in a Rails environment, no need to
# define these methods if we are
# An object is blank if it's nil, empty, or a whitespace string.
# For example, "", " ", nil, [], and {} are blank.
#
@@ -27,41 +22,42 @@ unless Object.respond_to?(:blank?) #:nodoc:
end
end
class NilClass #:nodoc:
class NilClass
def blank?
true
end
end
class FalseClass #:nodoc:
class FalseClass
def blank?
true
end
end
class TrueClass #:nodoc:
class TrueClass
def blank?
false
end
end
class Array #:nodoc:
class Array
alias_method :blank?, :empty?
end
class Hash #:nodoc:
class Hash
alias_method :blank?, :empty?
end
class String #:nodoc:
class String
def blank?
empty? || strip.empty?
end
end
class Numeric #:nodoc:
class Numeric
def blank?
false
end
end
end
end
#:startdoc:

View File

@@ -1,7 +1,4 @@
# = TITLE:
#
# Text Encoding class
#
#--
# = COPYRIGHT:
#
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
@@ -27,15 +24,18 @@
#
# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
# with permission of Minero Aoki.
#++
#:stopdoc:
require 'nkf'
require 'tmail/base64'
require 'tmail/stringio'
require 'tmail/utils'
#:startdoc:
module TMail
#:stopdoc:
class << self
attr_accessor :KCODE
end
@@ -57,10 +57,34 @@ module TMail
end
module_function :create_dest
#:startdoc:
# Returns the TMail object encoded and ready to be sent via SMTP etc.
# You should call this before you are packaging up your email to
# correctly escape all the values that need escaping in the email, line
# wrap the email etc.
#
# It is also a good idea to call this before you marshal or serialize
# a TMail object.
#
# For Example:
#
# email = TMail::Load(my_email_file)
# email_to_send = email.encoded
def encoded( eol = "\r\n", charset = 'j', dest = nil )
accept_strategy Encoder, eol, charset, dest
end
# Returns the TMail object decoded and ready to be used by you, your
# program etc.
#
# You should call this before you are packaging up your email to
# correctly escape all the values that need escaping in the email, line
# wrap the email etc.
#
# For Example:
#
# email = TMail::Load(my_email_file)
# email_to_send = email.encoded
def decoded( eol = "\n", charset = 'e', dest = nil )
# Turn the E-Mail into a string and return it with all
# encoded characters decoded. alias for to_s
@@ -69,7 +93,7 @@ module TMail
alias to_s decoded
def accept_strategy( klass, eol, charset, dest = nil )
def accept_strategy( klass, eol, charset, dest = nil ) #:nodoc:
dest ||= ''
accept klass.new( create_dest(dest), charset, eol )
dest
@@ -77,6 +101,7 @@ module TMail
end
#:stopdoc:
###
### MIME B encoding decoder
@@ -501,7 +526,7 @@ module TMail
# Check the text to see if there is whitespace, or if not
@wrapped_text = []
until @text == ''
until @text.blank?
fold_the_string
end
@text = @wrapped_text.join("#{@eol}#{SPACER}")
@@ -512,10 +537,12 @@ module TMail
# Is the location of the whitespace shorter than the RCF_2822_MAX_LENGTH?
# if there is no whitespace in the string, then this
unless mazsize(whitespace_location) <= 0
@text.strip!
@wrapped_text << @text.slice!(0...whitespace_location)
# If it is not less, we have to wrap it destructively
else
slice_point = RFC_2822_MAX_LENGTH - @curlen - @lwsp.length
@text.strip!
@wrapped_text << @text.slice!(0...slice_point)
end
end
@@ -530,5 +557,5 @@ module TMail
end
end
#:startdoc:
end # module TMail

View File

@@ -1,11 +1,3 @@
=begin rdoc
= Header handling class
=end
# RFC #822 ftp://ftp.isi.edu/in-notes/rfc822.txt
#
#
#--
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
#
@@ -38,9 +30,10 @@ require 'tmail/parser'
require 'tmail/config'
require 'tmail/utils'
#:startdoc:
module TMail
# Provides methods to handle and manipulate headers in the email
class HeaderField
include TextUtils

View File

@@ -1,3 +1,4 @@
#:stopdoc:
# This is here for Rolls.
# Rolls uses this instead of lib/tmail.rb.
@@ -5,4 +6,4 @@ require 'tmail/version'
require 'tmail/mail'
require 'tmail/mailbox'
require 'tmail/core_extensions'
#:startdoc:

View File

@@ -966,31 +966,33 @@ module TMail
end
end
# Destructively convert the Mail object's body into a Base64 encoded email
# Convert the Mail object's body into a Base64 encoded email
# returning the modified Mail object
def base64_encode!
store 'Content-Transfer-Encoding', 'Base64'
self.body = Base64.folding_encode(self.body)
self.body = base64_encode
end
# ==Depreciation warning
# base64_encode will return the body encoded, not modify the message body in
# future versions of TMail
alias :base64_encode :base64_encode!
# Return the result of encoding the TMail::Mail object body
# without altering the current body
def base64_encode
Base64.folding_encode(self.body)
end
# Destructively convert the Mail object's body into a Base64 decoded email
# Convert the Mail object's body into a Base64 decoded email
# returning the modified Mail object
def base64_decode!
if /base64/i === self.transfer_encoding('')
store 'Content-Transfer-Encoding', '8bit'
self.body = Base64.decode(self.body, @config.strict_base64decode?)
self.body = base64_decode
end
end
# ==Depreciation warning
# base64_decode will return the body decoded, not modify the message body in
# future versions of TMail
alias :base64_decode :base64_decode!
# Returns the result of decoding the TMail::Mail object body
# without altering the current body
def base64_decode
Base64.decode(self.body, @config.strict_base64decode?)
end
# Returns an array of each destination in the email message including to: cc: or bcc:
#

View File

@@ -1 +1,3 @@
#:stopdoc:
require 'tmail/mailbox'
#:startdoc:

View File

@@ -28,22 +28,7 @@
# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
# with permission of Minero Aoki.
#++
# == TMail::Mail
# === Class Methods
#
#
#
#
#
#
#
#
#
#
#
#
#
#
require 'tmail/interface'
@@ -58,23 +43,89 @@ 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 )
def initialize( port = nil, conf = DEFAULT_CONFIG ) #:nodoc:
@port = port || StringPort.new
@config = Config.to_config(conf)
@@ -90,6 +141,12 @@ module TMail
}
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
@@ -395,10 +452,12 @@ module TMail
end
def quoted_body
parse_body
@body_port.ropen {|f|
return f.read
}
body_port.ropen {|f| return f.read }
end
def quoted_body= str
body_port.wopen { |f| f.write str }
str
end
def body=( str )
@@ -420,8 +479,8 @@ module TMail
str
end
alias preamble body
alias preamble= body=
alias preamble quoted_body
alias preamble= quoted_body=
def epilogue
parse_body
@@ -442,6 +501,18 @@ module TMail
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

View File

@@ -150,9 +150,78 @@ module TMail
class UNIXMbox
class << self
alias newobj new
end
# Creates a new mailbox object that you can iterate through to collect the
# emails from with "each_port".
#
# You need to pass it a filename of a unix mailbox format file, the format of this
# file can be researched at this page at {wikipedia}[link:http://en.wikipedia.org/wiki/Mbox]
#
# ==== Parameters
#
# +filename+: The filename of the mailbox you want to open
#
# +tmpdir+: Can be set to override TMail using the system environment's temp dir. TMail will first
# use the temp dir specified by you (if any) or then the temp dir specified in the Environment's TEMP
# value then the value in the Environment's TMP value or failing all of the above, '/tmp'
#
# +readonly+: If set to false, each email you take from the mail box will be removed from the mailbox.
# default is *false* - ie, it *WILL* truncate your mailbox file to ZERO once it has read the emails out.
#
# ==== Options:
#
# None
#
# ==== Examples:
#
# # First show using readonly true:
#
# require 'ftools'
# File.size("../test/fixtures/mailbox")
# #=> 20426
#
# mailbox = TMail::UNIXMbox.new("../test/fixtures/mailbox", nil, true)
# #=> #<TMail::UNIXMbox:0x14a2aa8 @readonly=true.....>
#
# mailbox.each_port do |port|
# mail = TMail::Mail.new(port)
# puts mail.subject
# end
# #Testing mailbox 1
# #Testing mailbox 2
# #Testing mailbox 3
# #Testing mailbox 4
# require 'ftools'
# File.size?("../test/fixtures/mailbox")
# #=> 20426
#
# # Now show with readonly set to the default false
#
# mailbox = TMail::UNIXMbox.new("../test/fixtures/mailbox")
# #=> #<TMail::UNIXMbox:0x14a2aa8 @readonly=false.....>
#
# mailbox.each_port do |port|
# mail = TMail::Mail.new(port)
# puts mail.subject
# end
# #Testing mailbox 1
# #Testing mailbox 2
# #Testing mailbox 3
# #Testing mailbox 4
#
# File.size?("../test/fixtures/mailbox")
# #=> nil
def UNIXMbox.new( filename, tmpdir = nil, readonly = false )
tmpdir = ENV['TEMP'] || ENV['TMP'] || '/tmp'
newobj(filename, "#{tmpdir}/ruby_tmail_#{$$}_#{rand()}", readonly, false)
end
def UNIXMbox.lock( fname )
begin
f = File.open(fname)
f = File.open(fname, 'r+')
f.flock File::LOCK_EX
yield f
ensure
@@ -161,15 +230,6 @@ module TMail
end
end
class << self
alias newobj new
end
def UNIXMbox.new( fname, tmpdir = nil, readonly = false )
tmpdir = ENV['TEMP'] || ENV['TMP'] || '/tmp'
newobj(fname, "#{tmpdir}/ruby_tmail_#{$$}_#{rand()}", readonly, false)
end
def UNIXMbox.static_new( fname, dir, readonly = false )
newobj(fname, dir, readonly, true)
end

View File

@@ -1,4 +1,6 @@
#:stopdoc:
require 'tmail/version'
require 'tmail/mail'
require 'tmail/mailbox'
require 'tmail/core_extensions'
#:startdoc:

View File

@@ -1 +1,3 @@
#:stopdoc:
require 'tmail/mailbox'
#:startdoc:

View File

@@ -1,8 +1,3 @@
=begin rdoc
= Net provides SMTP wrapping
=end
#--
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
#
@@ -29,13 +24,14 @@
# with permission of Minero Aoki.
#++
#:stopdoc:
require 'nkf'
#:startdoc:
module TMail
class Mail
def send_to( smtp )
do_send_to(smtp) do
ready_to_send
@@ -131,7 +127,7 @@ module TMail
end
#:stopdoc:
class DeleteFields
NOSEND_FIELDS = %w(
@@ -155,8 +151,9 @@ module TMail
end
end
#:startdoc:
#:stopdoc:
class AddMessageId
def initialize( fqdn = nil )
@@ -170,8 +167,9 @@ module TMail
end
end
#:startdoc:
#:stopdoc:
class AddDate
def exec( mail )
@@ -179,8 +177,9 @@ module TMail
end
end
#:startdoc:
#:stopdoc:
class MimeEncodeAuto
def initialize( s = nil, m = nil )
@@ -198,8 +197,9 @@ module TMail
end
end
#:startdoc:
#:stopdoc:
class MimeEncodeSingle
def exec( mail )
@@ -225,8 +225,9 @@ module TMail
end
end
#:startdoc:
#:stopdoc:
class MimeEncodeMulti
def exec( mail, top = true )
@@ -243,5 +244,5 @@ module TMail
end
end
#:startdoc:
end # module TMail

View File

@@ -2,6 +2,9 @@
= Obsolete methods that are depriciated
If you really want to see them, go to lib/tmail/obsolete.rb and view to your
heart's content.
=end
#--
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
@@ -28,10 +31,9 @@
# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
# with permission of Minero Aoki.
#++
#:stopdoc:
module TMail #:nodoc:
module TMail
# mail.rb
class Mail
alias include? key?
alias has_key? key?
@@ -51,8 +53,6 @@ module TMail
alias has_value? value?
end
# facade.rb
class Mail
def from_addr( default = nil )
addr, = from_addrs(nil)
@@ -83,13 +83,11 @@ module TMail
alias each_dest each_destination
end
# address.rb
class Address
alias route routes
alias addr spec
def spec=( str )
def spec=( str )
@local, @domain = str.split(/@/,2).map {|s| s.split(/\./) }
end
@@ -97,8 +95,6 @@ module TMail
alias address= spec=
end
# mbox.rb
class MhMailbox
alias new_mail new_port
alias each_mail each_port
@@ -115,8 +111,6 @@ module TMail
alias each_newmail each_new_port
end
# utils.rb
extend TextUtils
class << self
@@ -135,3 +129,4 @@ module TMail
end
end # module TMail
#:startdoc:

View File

@@ -1,3 +1,4 @@
#:stopdoc:
# DO NOT MODIFY!!!!
# This file is automatically generated by racc 1.4.5
# from racc grammer file "parser.y".

View File

@@ -1,3 +1,4 @@
#:stopdoc:
require 'rbconfig'
# Attempts to require anative extension.
@@ -54,3 +55,4 @@ end
# end
# end
# end
#:startdoc:

View File

@@ -28,7 +28,7 @@
# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
# with permission of Minero Aoki.
#++
#:stopdoc:
#require 'tmail/require_arch'
require 'tmail/utils'
require 'tmail/config'
@@ -46,3 +46,4 @@ module TMail
Scanner = TMailScanner
end
end
#:stopdoc:

View File

@@ -26,7 +26,7 @@
# Note: Originally licensed under LGPL v2+. Using MIT license for Rails
# with permission of Minero Aoki.
#++
#:stopdoc:
require 'tmail/config'
module TMail
@@ -259,3 +259,4 @@ module TMail
end
end # module TMail
#:startdoc:

View File

@@ -1,8 +1,3 @@
=begin rdoc
= General Purpose TMail Utilities
=end
#--
# Copyright (c) 1998-2003 Minero Aoki <aamine@loveruby.net>
#
@@ -29,21 +24,73 @@
# with permission of Minero Aoki.
#++
# = TMail - The EMail Swiss Army Knife for Ruby
#
# The TMail library provides you with a very complete way to handle and manipulate EMails
# from within your Ruby programs.
#
# Used as the backbone for email handling by the Ruby on Rails and Nitro web frameworks as
# well as a bunch of other Ruby apps including the Ruby-Talk mailing list to newsgroup email
# gateway, it is a proven and reliable email handler that won't let you down.
#
# Originally created by Minero Aoki, TMail has been recently picked up by Mikel Lindsaar and
# is being actively maintained. Numerous backlogged bug fixes have been applied as well as
# Ruby 1.9 compatibility and a swath of documentation to boot.
#
# TMail allows you to treat an email totally as an object and allow you to get on with your
# own programming without having to worry about crafting the perfect email address validation
# parser, or assembling an email from all it's component parts.
#
# TMail handles the most complex part of the email - the header. It generates and parses
# headers and provides you with instant access to their innards through simple and logically
# named accessor and setter methods.
#
# TMail also provides a wrapper to Net/SMTP as well as Unix Mailbox handling methods to
# directly read emails from your unix mailbox, parse them and use them.
#
# Following is the comprehensive list of methods to access TMail::Mail objects. You can also
# check out TMail::Mail, TMail::Address and TMail::Headers for other lists.
module TMail
# Provides an exception to throw on errors in Syntax within TMail's parsers
class SyntaxError < StandardError; end
# Provides a new email boundary to separate parts of the email. This is a random
# string based off the current time, so should be fairly unique.
#
# For Example:
#
# TMail.new_boundary
# #=> "mimepart_47bf656968207_25a8fbb80114"
# TMail.new_boundary
# #=> "mimepart_47bf66051de4_25a8fbb80240"
def TMail.new_boundary
'mimepart_' + random_tag
end
# Provides a new email message ID. You can use this to generate unique email message
# id's for your email so you can track them.
#
# Optionally takes a fully qualified domain name (default to the current hostname
# returned by Socket.gethostname) that will be appended to the message ID.
#
# For Example:
#
# email.message_id = TMail.new_message_id
# #=> "<47bf66845380e_25a8fbb80332@baci.local.tmail>"
# email.to_s
# #=> "Message-Id: <47bf668b633f1_25a8fbb80475@baci.local.tmail>\n\n"
# email.message_id = TMail.new_message_id("lindsaar.net")
# #=> "<47bf668b633f1_25a8fbb80475@lindsaar.net.tmail>"
# email.to_s
# #=> "Message-Id: <47bf668b633f1_25a8fbb80475@lindsaar.net.tmail>\n\n"
def TMail.new_message_id( fqdn = nil )
fqdn ||= ::Socket.gethostname
"<#{random_tag()}@#{fqdn}.tmail>"
end
def TMail.random_tag
#:stopdoc:
def TMail.random_tag #:nodoc:
@uniq += 1
t = Time.now
sprintf('%x%x_%x%x%d%x',
@@ -54,8 +101,13 @@ module TMail
@uniq = 0
#:startdoc:
# Text Utils provides a namespace to define TOKENs, ATOMs, PHRASEs and CONTROL characters that
# are OK per RFC 2822.
#
# It also provides methods you can call to determine if a string is safe
module TextUtils
# Defines characters per RFC that are OK for TOKENs, ATOMs, PHRASEs and CONTROL characters.
aspecial = '()<>[]:;.\\,"'
tspecial = '()<>[];:\\,"/?='
@@ -67,37 +119,37 @@ module TMail
TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{lwsp}]/n
CONTROL_CHAR = /[#{control}]/n
# Returns true if the string supplied is free from characters not allowed as an ATOM
def atom_safe?( str )
# Returns true if the string supplied is free from characters not allowed as an ATOM
not ATOM_UNSAFE === str
end
# If the string supplied has ATOM unsafe characters in it, will return the string quoted
# in double quotes, otherwise returns the string unmodified
def quote_atom( str )
# If the string supplied has ATOM unsafe characters in it, will return the string quoted
# in double quotes, otherwise returns the string unmodified
(ATOM_UNSAFE === str) ? dquote(str) : str
end
# If the string supplied has PHRASE unsafe characters in it, will return the string quoted
# in double quotes, otherwise returns the string unmodified
def quote_phrase( str )
# If the string supplied has PHRASE unsafe characters in it, will return the string quoted
# in double quotes, otherwise returns the string unmodified
(PHRASE_UNSAFE === str) ? dquote(str) : str
end
# Returns true if the string supplied is free from characters not allowed as a TOKEN
def token_safe?( str )
# Returns true if the string supplied is free from characters not allowed as a TOKEN
not TOKEN_UNSAFE === str
end
# If the string supplied has TOKEN unsafe characters in it, will return the string quoted
# in double quotes, otherwise returns the string unmodified
def quote_token( str )
# If the string supplied has TOKEN unsafe characters in it, will return the string quoted
# in double quotes, otherwise returns the string unmodified
(TOKEN_UNSAFE === str) ? dquote(str) : str
end
def dquote( str )
# Wraps supplied string in double quotes unless it is already wrapped
# Returns double quoted string
# Wraps supplied string in double quotes unless it is already wrapped
# Returns double quoted string
def dquote( str ) #:nodoc:
unless str =~ /^".*?"$/
'"' + str.gsub(/["\\]/n) {|s| '\\' + s } + '"'
else
@@ -106,12 +158,14 @@ module TMail
end
private :dquote
# Unwraps supplied string from inside double quotes
# Returns unquoted string
def unquote( str )
# Unwraps supplied string from inside double quotes
# Returns unquoted string
str =~ /^"(.*?)"$/ ? $1 : str
end
# Provides a method to join a domain name by it's parts and also makes it
# ATOM safe by quoting it as needed
def join_domain( arr )
arr.map {|i|
if /\A\[.*\]\z/ === i
@@ -122,7 +176,7 @@ module TMail
}.join('.')
end
#:stopdoc:
ZONESTR_TABLE = {
'jst' => 9 * 60,
'eet' => 2 * 60,
@@ -168,9 +222,10 @@ module TMail
'y' => 12 * 60,
'z' => 0 * 60
}
#:startdoc:
# Takes a time zone string from an EMail and converts it to Unix Time (seconds)
def timezone_string_to_unixtime( str )
# Takes a time zone string from an EMail and converts it to Unix Time (seconds)
if m = /([\+\-])(\d\d?)(\d\d)/.match(str)
sec = (m[2].to_i * 60 + m[3].to_i) * 60
m[1] == '-' ? -sec : sec
@@ -181,7 +236,7 @@ module TMail
end
end
#:stopdoc:
WDAY = %w( Sun Mon Tue Wed Thu Fri Sat TMailBUG )
MONTH = %w( TMailBUG Jan Feb Mar Apr May Jun
Jul Aug Sep Oct Nov Dec TMailBUG )
@@ -201,7 +256,7 @@ module TMail
MESSAGE_ID = /<[^\@>]+\@[^>\@]+>/
def message_id?( str )
MESSAGE_ID === str
end
@@ -274,6 +329,8 @@ module TMail
end
end
end
#:startdoc:
end

View File

@@ -27,8 +27,9 @@
# with permission of Minero Aoki.
#++
module TMail #:nodoc:
module VERSION #:nodoc:
#:stopdoc:
module TMail
module VERSION
MAJOR = 1
MINOR = 2
TINY = 2