mail 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mail might be problematic. Click here for more details.
- data/.gitignore +4 -0
- data/Manifest.txt +106 -0
- data/README.rdoc +441 -0
- data/Rakefile +38 -0
- data/lib/mail.rb +86 -0
- data/lib/mail/attachment.rb +90 -0
- data/lib/mail/body.rb +149 -0
- data/lib/mail/configuration.rb +90 -0
- data/lib/mail/core_extensions.rb +6 -0
- data/lib/mail/core_extensions/blank.rb +41 -0
- data/lib/mail/core_extensions/nil.rb +15 -0
- data/lib/mail/core_extensions/string.rb +31 -0
- data/lib/mail/elements/address.rb +293 -0
- data/lib/mail/elements/address_list.rb +62 -0
- data/lib/mail/elements/content_disposition_element.rb +34 -0
- data/lib/mail/elements/content_transfer_encoding_element.rb +21 -0
- data/lib/mail/elements/content_type_element.rb +39 -0
- data/lib/mail/elements/date_time_element.rb +26 -0
- data/lib/mail/elements/envelope_from_element.rb +34 -0
- data/lib/mail/elements/message_ids_element.rb +29 -0
- data/lib/mail/elements/mime_version_element.rb +26 -0
- data/lib/mail/elements/phrase_list.rb +21 -0
- data/lib/mail/elements/received_element.rb +30 -0
- data/lib/mail/encodings/base64.rb +17 -0
- data/lib/mail/encodings/encodings.rb +24 -0
- data/lib/mail/encodings/quoted_printable.rb +26 -0
- data/lib/mail/envelope.rb +35 -0
- data/lib/mail/field.rb +202 -0
- data/lib/mail/field_list.rb +33 -0
- data/lib/mail/fields/bcc_field.rb +40 -0
- data/lib/mail/fields/cc_field.rb +40 -0
- data/lib/mail/fields/comments_field.rb +41 -0
- data/lib/mail/fields/common/common_address.rb +62 -0
- data/lib/mail/fields/common/common_date.rb +35 -0
- data/lib/mail/fields/common/common_field.rb +128 -0
- data/lib/mail/fields/common/common_message_id.rb +35 -0
- data/lib/mail/fields/content_description_field.rb +15 -0
- data/lib/mail/fields/content_disposition_field.rb +34 -0
- data/lib/mail/fields/content_id_field.rb +50 -0
- data/lib/mail/fields/content_transfer_encoding_field.rb +28 -0
- data/lib/mail/fields/content_type_field.rb +50 -0
- data/lib/mail/fields/date_field.rb +44 -0
- data/lib/mail/fields/from_field.rb +40 -0
- data/lib/mail/fields/in_reply_to_field.rb +42 -0
- data/lib/mail/fields/keywords_field.rb +22 -0
- data/lib/mail/fields/message_id_field.rb +70 -0
- data/lib/mail/fields/mime_version_field.rb +42 -0
- data/lib/mail/fields/optional_field.rb +11 -0
- data/lib/mail/fields/received_field.rb +49 -0
- data/lib/mail/fields/references_field.rb +42 -0
- data/lib/mail/fields/reply_to_field.rb +40 -0
- data/lib/mail/fields/resent_bcc_field.rb +40 -0
- data/lib/mail/fields/resent_cc_field.rb +40 -0
- data/lib/mail/fields/resent_date_field.rb +16 -0
- data/lib/mail/fields/resent_from_field.rb +40 -0
- data/lib/mail/fields/resent_message_id_field.rb +20 -0
- data/lib/mail/fields/resent_sender_field.rb +48 -0
- data/lib/mail/fields/resent_to_field.rb +40 -0
- data/lib/mail/fields/return_path_field.rb +34 -0
- data/lib/mail/fields/sender_field.rb +48 -0
- data/lib/mail/fields/structured_field.rb +32 -0
- data/lib/mail/fields/subject_field.rb +14 -0
- data/lib/mail/fields/to_field.rb +40 -0
- data/lib/mail/fields/unstructured_field.rb +27 -0
- data/lib/mail/header.rb +213 -0
- data/lib/mail/mail.rb +120 -0
- data/lib/mail/message.rb +648 -0
- data/lib/mail/network/deliverable.rb +42 -0
- data/lib/mail/network/retrievable.rb +63 -0
- data/lib/mail/parsers/address_lists.rb +61 -0
- data/lib/mail/parsers/address_lists.treetop +19 -0
- data/lib/mail/parsers/content_disposition.rb +358 -0
- data/lib/mail/parsers/content_disposition.treetop +45 -0
- data/lib/mail/parsers/content_transfer_encoding.rb +179 -0
- data/lib/mail/parsers/content_transfer_encoding.treetop +25 -0
- data/lib/mail/parsers/content_type.rb +507 -0
- data/lib/mail/parsers/content_type.treetop +58 -0
- data/lib/mail/parsers/date_time.rb +111 -0
- data/lib/mail/parsers/date_time.treetop +11 -0
- data/lib/mail/parsers/envelope_from.rb +188 -0
- data/lib/mail/parsers/envelope_from.treetop +32 -0
- data/lib/mail/parsers/message_ids.rb +42 -0
- data/lib/mail/parsers/message_ids.treetop +15 -0
- data/lib/mail/parsers/mime_version.rb +141 -0
- data/lib/mail/parsers/mime_version.treetop +19 -0
- data/lib/mail/parsers/phrase_lists.rb +42 -0
- data/lib/mail/parsers/phrase_lists.treetop +15 -0
- data/lib/mail/parsers/received.rb +68 -0
- data/lib/mail/parsers/received.treetop +11 -0
- data/lib/mail/parsers/rfc2045.rb +406 -0
- data/lib/mail/parsers/rfc2045.treetop +35 -0
- data/lib/mail/parsers/rfc2822.rb +5005 -0
- data/lib/mail/parsers/rfc2822.treetop +402 -0
- data/lib/mail/parsers/rfc2822_obsolete.rb +3607 -0
- data/lib/mail/parsers/rfc2822_obsolete.treetop +241 -0
- data/lib/mail/part.rb +120 -0
- data/lib/mail/patterns.rb +42 -0
- data/lib/mail/utilities.rb +142 -0
- data/lib/mail/version.rb +10 -0
- data/lib/mail/version_specific/multibyte.rb +62 -0
- data/lib/mail/version_specific/multibyte/chars.rb +701 -0
- data/lib/mail/version_specific/multibyte/exceptions.rb +8 -0
- data/lib/mail/version_specific/multibyte/unicode_database.rb +71 -0
- data/lib/mail/version_specific/ruby_1_8.rb +61 -0
- data/lib/mail/version_specific/ruby_1_8_string.rb +88 -0
- data/lib/mail/version_specific/ruby_1_9.rb +49 -0
- metadata +192 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class ContentDispositionElement # :nodoc:
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize( string )
|
8
|
+
parser = Mail::ContentDispositionParser.new
|
9
|
+
if tree = parser.parse(cleaned(string))
|
10
|
+
@disposition_type = tree.disposition_type.text_value
|
11
|
+
@parameters = tree.parameters
|
12
|
+
else
|
13
|
+
raise Mail::Field::ParseError, "ContentDispositionElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def disposition_type
|
18
|
+
@disposition_type
|
19
|
+
end
|
20
|
+
|
21
|
+
def parameters
|
22
|
+
@parameters
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s(*args)
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def cleaned(string)
|
30
|
+
string =~ /(.+);\s*$/ ? $1 : string
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class ContentTransferEncodingElement
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize( string )
|
8
|
+
parser = Mail::ContentTransferEncodingParser.new
|
9
|
+
if tree = parser.parse(string.downcase)
|
10
|
+
@encoding = tree.encoding.text_value
|
11
|
+
else
|
12
|
+
raise Mail::Field::ParseError, "ContentTransferEncodingElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def encoding
|
17
|
+
@encoding
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class ContentTypeElement # :nodoc:
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize( string )
|
8
|
+
parser = Mail::ContentTypeParser.new
|
9
|
+
if tree = parser.parse(cleaned(string))
|
10
|
+
@main_type = tree.main_type.text_value
|
11
|
+
@sub_type = tree.sub_type.text_value
|
12
|
+
@parameters = tree.parameters
|
13
|
+
else
|
14
|
+
raise Mail::Field::ParseError, "ContentTypeElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def main_type
|
19
|
+
@main_type
|
20
|
+
end
|
21
|
+
|
22
|
+
def sub_type
|
23
|
+
@sub_type
|
24
|
+
end
|
25
|
+
|
26
|
+
def parameters
|
27
|
+
@parameters
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s(*args)
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def cleaned(string)
|
35
|
+
string =~ /(.+);\s*$/ ? $1 : string
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class DateTimeElement # :nodoc:
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize( string )
|
8
|
+
parser = Mail::DateTimeParser.new
|
9
|
+
if tree = parser.parse(string)
|
10
|
+
@date_string = tree.date.text_value
|
11
|
+
@time_string = tree.time.text_value
|
12
|
+
else
|
13
|
+
raise Mail::Field::ParseError, "DateTimeElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def date_string
|
18
|
+
@date_string
|
19
|
+
end
|
20
|
+
|
21
|
+
def time_string
|
22
|
+
@time_string
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class EnvelopeFromElement
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize( string )
|
8
|
+
parser = Mail::EnvelopeFromParser.new
|
9
|
+
if @tree = parser.parse(string)
|
10
|
+
@address = tree.addr_spec.text_value.strip
|
11
|
+
@date_time = ::DateTime.parse("#{tree.ctime_date.text_value}")
|
12
|
+
else
|
13
|
+
raise Mail::Field::ParseError, "EnvelopeFromElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def tree
|
18
|
+
@tree
|
19
|
+
end
|
20
|
+
|
21
|
+
def date_time
|
22
|
+
@date_time
|
23
|
+
end
|
24
|
+
|
25
|
+
def address
|
26
|
+
@address
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s(*args)
|
30
|
+
"#{@info}; #{@date_time.to_s(*args)}"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class MessageIdsElement
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize(string)
|
8
|
+
parser = Mail::MessageIdsParser.new
|
9
|
+
if tree = parser.parse(string)
|
10
|
+
@message_ids = tree.message_ids.map { |msg_id| clean_msg_id(msg_id.text_value) }
|
11
|
+
else
|
12
|
+
raise Mail::Field::ParseError, "MessageIdsElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def message_ids
|
17
|
+
@message_ids
|
18
|
+
end
|
19
|
+
|
20
|
+
def message_id
|
21
|
+
@message_ids.first
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean_msg_id( val )
|
25
|
+
val =~ /.*<(.*)>.*/ ; $1
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class MimeVersionElement
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize( string )
|
8
|
+
parser = Mail::MimeVersionParser.new
|
9
|
+
if tree = parser.parse(string)
|
10
|
+
@major = tree.major.text_value
|
11
|
+
@minor = tree.minor.text_value
|
12
|
+
else
|
13
|
+
raise Mail::Field::ParseError, "MimeVersionElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def major
|
18
|
+
@major
|
19
|
+
end
|
20
|
+
|
21
|
+
def minor
|
22
|
+
@minor
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class PhraseList
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize(string)
|
8
|
+
parser = Mail::PhraseListsParser.new
|
9
|
+
if tree = parser.parse(string)
|
10
|
+
@phrases = tree.phrases
|
11
|
+
else
|
12
|
+
raise Mail::Field::ParseError, "PhraseList can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def phrases
|
17
|
+
@phrases.map { |p| unquote(p.text_value) }
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
class ReceivedElement
|
4
|
+
|
5
|
+
include Mail::Utilities
|
6
|
+
|
7
|
+
def initialize( string )
|
8
|
+
parser = Mail::ReceivedParser.new
|
9
|
+
if tree = parser.parse(string)
|
10
|
+
@date_time = ::DateTime.parse("#{tree.date_time.date.text_value} #{tree.date_time.time.text_value}")
|
11
|
+
@info = tree.name_val_list.text_value
|
12
|
+
else
|
13
|
+
raise Mail::Field::ParseError, "ReceivedElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def date_time
|
18
|
+
@date_time
|
19
|
+
end
|
20
|
+
|
21
|
+
def info
|
22
|
+
@info
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s(*args)
|
26
|
+
"#{@info}; #{@date_time.to_s(*args)}"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
module Encodings
|
4
|
+
class Base64
|
5
|
+
|
6
|
+
# Decode the string from Base64
|
7
|
+
def self.decode(str)
|
8
|
+
RubyVer.decode_base64( str )
|
9
|
+
end
|
10
|
+
|
11
|
+
# Encode the string to Base64
|
12
|
+
def self.encode(str)
|
13
|
+
RubyVer.encode_base64( str )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
module Encodings
|
4
|
+
|
5
|
+
def Encodings.defined?( str )
|
6
|
+
string = str.to_s.split(/[_-]/).map { |v| v.capitalize }.join('')
|
7
|
+
RubyVer.has_constant?(Mail::Encodings, string)
|
8
|
+
end
|
9
|
+
|
10
|
+
def Encodings.get_encoding( str )
|
11
|
+
string = str.to_s.split(/[_-]/).map { |v| v.capitalize }.join('')
|
12
|
+
RubyVer.get_constant(Mail::Encodings, string)
|
13
|
+
end
|
14
|
+
|
15
|
+
def Encodings.b_encode(str, encoding = nil)
|
16
|
+
RubyVer.b_encode(str, encoding)
|
17
|
+
end
|
18
|
+
|
19
|
+
def Encodings.q_encode(str, encoding = nil)
|
20
|
+
RubyVer.q_encode(str, encoding)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
module Encodings
|
4
|
+
class QuotedPrintable
|
5
|
+
|
6
|
+
# Decode the string from Quoted-Printable
|
7
|
+
def self.decode(str)
|
8
|
+
str.unpack("M*").first
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.encode(str)
|
12
|
+
str.gsub( /[^a-z ]/i ) { quoted_printable_encode($&) }.gsub( / /, "_" )
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Convert the given character to quoted printable format, taking into
|
18
|
+
# account multi-byte characters (if executing with $KCODE="u", for instance)
|
19
|
+
def self.quoted_printable_encode(character)
|
20
|
+
result = ""
|
21
|
+
character.each_byte { |b| result << "=%02X" % b }
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# = Mail Envelope
|
4
|
+
#
|
5
|
+
# The Envelope class provides a field for the first line in an
|
6
|
+
# mbox file, that looks like "From mikel@test.lindsaar.net DATETIME"
|
7
|
+
#
|
8
|
+
# This envelope class reads that line, and turns it into an
|
9
|
+
# Envelope.from and Envelope.date for your use.
|
10
|
+
module Mail
|
11
|
+
class Envelope < StructuredField
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
super(FIELD_NAME, strip_field(FIELD_NAME, args.last))
|
15
|
+
end
|
16
|
+
|
17
|
+
def tree
|
18
|
+
@element ||= Mail::EnvelopeFromElement.new(value)
|
19
|
+
@tree ||= @element.tree
|
20
|
+
end
|
21
|
+
|
22
|
+
def element
|
23
|
+
@element ||= Mail::EnvelopeFromElement.new(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def date
|
27
|
+
::DateTime.parse("#{element.date_time}")
|
28
|
+
end
|
29
|
+
|
30
|
+
def from
|
31
|
+
element.address
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/mail/field.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mail
|
3
|
+
# Provides a single class to call to create a new structured or unstructured
|
4
|
+
# field. Works out per RFC what field of field it is being given and returns
|
5
|
+
# the correct field of class back on new.
|
6
|
+
#
|
7
|
+
# ===Per RFC 2822
|
8
|
+
#
|
9
|
+
# 2.2. Header Fields
|
10
|
+
#
|
11
|
+
# Header fields are lines composed of a field name, followed by a colon
|
12
|
+
# (":"), followed by a field body, and terminated by CRLF. A field
|
13
|
+
# name MUST be composed of printable US-ASCII characters (i.e.,
|
14
|
+
# characters that have values between 33 and 126, inclusive), except
|
15
|
+
# colon. A field body may be composed of any US-ASCII characters,
|
16
|
+
# except for CR and LF. However, a field body may contain CRLF when
|
17
|
+
# used in header "folding" and "unfolding" as described in section
|
18
|
+
# 2.2.3. All field bodies MUST conform to the syntax described in
|
19
|
+
# sections 3 and 4 of this standard.
|
20
|
+
#
|
21
|
+
class Field
|
22
|
+
|
23
|
+
include Patterns
|
24
|
+
include Comparable
|
25
|
+
|
26
|
+
STRUCTURED_FIELDS = %w[ bcc cc content-description content-disposition
|
27
|
+
content-id content-transfer-encoding content-type
|
28
|
+
date from in-reply-to keywords message-id
|
29
|
+
mime-version received references reply-to
|
30
|
+
resent-bcc resent-cc resent-date resent-from
|
31
|
+
resent-message-id resent-sender resent-to
|
32
|
+
return-path sender to ]
|
33
|
+
|
34
|
+
KNOWN_FIELDS = STRUCTURED_FIELDS + ['comments', 'subject']
|
35
|
+
|
36
|
+
# Generic Field Exception
|
37
|
+
class FieldError < StandardError
|
38
|
+
end
|
39
|
+
|
40
|
+
# Raised when a parsing error has occurred (ie, a StructuredField has tried
|
41
|
+
# to parse a field that is invalid or improperly written)
|
42
|
+
class ParseError < FieldError #:nodoc:
|
43
|
+
end
|
44
|
+
|
45
|
+
# Raised when attempting to set a structured field's contents to an invalid syntax
|
46
|
+
class SyntaxError < FieldError #:nodoc:
|
47
|
+
end
|
48
|
+
|
49
|
+
# Accepts a text string in the format of:
|
50
|
+
#
|
51
|
+
# "field-name: field data"
|
52
|
+
#
|
53
|
+
# Note, does not want a terminating carriage return. Returns
|
54
|
+
# self appropriately parsed
|
55
|
+
def initialize(raw_field_text)
|
56
|
+
if raw_field_text !~ /:/
|
57
|
+
name = raw_field_text
|
58
|
+
create_field(name, nil)
|
59
|
+
else
|
60
|
+
name, value = split(raw_field_text)
|
61
|
+
create_field(name, value)
|
62
|
+
end
|
63
|
+
return self
|
64
|
+
end
|
65
|
+
|
66
|
+
def field=(value)
|
67
|
+
@field = value
|
68
|
+
end
|
69
|
+
|
70
|
+
def field
|
71
|
+
@field
|
72
|
+
end
|
73
|
+
|
74
|
+
def name
|
75
|
+
field.name
|
76
|
+
end
|
77
|
+
|
78
|
+
def value
|
79
|
+
field.value
|
80
|
+
end
|
81
|
+
|
82
|
+
def value=(str)
|
83
|
+
create_field(name, str)
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_s
|
87
|
+
field.to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def update(name, value)
|
91
|
+
create_field(name, value)
|
92
|
+
end
|
93
|
+
|
94
|
+
def same( other )
|
95
|
+
match_to_s(other.name, field.name)
|
96
|
+
end
|
97
|
+
|
98
|
+
def <=>( other )
|
99
|
+
self_order = FIELD_ORDER.rindex(self.name.downcase) || 100
|
100
|
+
other_order = FIELD_ORDER.rindex(other.name.downcase) || 100
|
101
|
+
self_order <=> other_order
|
102
|
+
end
|
103
|
+
|
104
|
+
def method_missing(name, *args, &block)
|
105
|
+
field.send(name, *args, &block)
|
106
|
+
end
|
107
|
+
|
108
|
+
FIELD_ORDER = %w[ return-path received
|
109
|
+
resent-date resent-from resent-sender resent-to
|
110
|
+
resent-cc resent-bcc resent-message-id
|
111
|
+
date from sender reply-to to cc bcc
|
112
|
+
message-id in-reply-to references
|
113
|
+
subject comments keywords
|
114
|
+
mime-version content-type content-transfer-encoding
|
115
|
+
content-disposition content-description ]
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def split(raw_field)
|
120
|
+
match_data = raw_field.match(/^(#{FIELD_NAME})\s*:\s*(#{FIELD_BODY})$/)
|
121
|
+
[match_data[1].to_s.strip, match_data[2].to_s.strip]
|
122
|
+
rescue
|
123
|
+
STDERR.puts "WARNING: Could not parse (and so ignorning) '#{raw_field}'"
|
124
|
+
end
|
125
|
+
|
126
|
+
def create_field(name, value)
|
127
|
+
begin
|
128
|
+
self.field = new_field(name, value)
|
129
|
+
rescue
|
130
|
+
self.field = Mail::UnstructuredField.new(name, value)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def new_field(name, value)
|
135
|
+
# Could do this with constantize and make it as DRY as, but a simple case is,
|
136
|
+
# well, simpler...
|
137
|
+
case name.downcase
|
138
|
+
when /^to$/
|
139
|
+
ToField.new(name,value)
|
140
|
+
when /^cc$/
|
141
|
+
CcField.new(name,value)
|
142
|
+
when /^bcc$/
|
143
|
+
BccField.new(name, value)
|
144
|
+
when /^message-id$/
|
145
|
+
MessageIdField.new(name, value)
|
146
|
+
when /^in-reply-to$/
|
147
|
+
InReplyToField.new(name, value)
|
148
|
+
when /^references$/
|
149
|
+
ReferencesField.new(name, value)
|
150
|
+
when /^subject$/
|
151
|
+
SubjectField.new(name, value)
|
152
|
+
when /^comments$/
|
153
|
+
CommentsField.new(name, value)
|
154
|
+
when /^keywords$/
|
155
|
+
KeywordsField.new(name, value)
|
156
|
+
when /^date$/
|
157
|
+
DateField.new(name, value)
|
158
|
+
when /^from$/
|
159
|
+
FromField.new(name, value)
|
160
|
+
when /^sender$/
|
161
|
+
SenderField.new(name, value)
|
162
|
+
when /^reply-to$/
|
163
|
+
ReplyToField.new(name, value)
|
164
|
+
when /^resent-date$/
|
165
|
+
ResentDateField.new(name, value)
|
166
|
+
when /^resent-from$/
|
167
|
+
ResentFromField.new(name, value)
|
168
|
+
when /^resent-sender$/
|
169
|
+
ResentSenderField.new(name, value)
|
170
|
+
when /^resent-to$/
|
171
|
+
ResentToField.new(name, value)
|
172
|
+
when /^resent-cc$/
|
173
|
+
ResentCcField.new(name, value)
|
174
|
+
when /^resent-bcc$/
|
175
|
+
ResentBccField.new(name, value)
|
176
|
+
when /^resent-message-id$/
|
177
|
+
ResentMessageIdField.new(name, value)
|
178
|
+
when /^return-path$/
|
179
|
+
ReturnPathField.new(name, value)
|
180
|
+
when /^received$/
|
181
|
+
ReceivedField.new(name, value)
|
182
|
+
when /^mime-version$/
|
183
|
+
MimeVersionField.new(name, value)
|
184
|
+
when /^content-transfer-encoding$/
|
185
|
+
ContentTransferEncodingField.new(name, value)
|
186
|
+
when /^content-description$/
|
187
|
+
ContentDescriptionField.new(name, value)
|
188
|
+
when /^content-disposition$/
|
189
|
+
ContentDispositionField.new(name, value)
|
190
|
+
when /^content-type$/
|
191
|
+
ContentTypeField.new(name, value)
|
192
|
+
when /^content-id$/
|
193
|
+
ContentIdField.new(name, value)
|
194
|
+
else
|
195
|
+
OptionalField.new(name, value)
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|