kbaum-mail 2.1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +289 -0
- data/README.rdoc +575 -0
- data/Rakefile +72 -0
- data/TODO.rdoc +19 -0
- data/lib/mail.rb +113 -0
- data/lib/mail/attachments_list.rb +76 -0
- data/lib/mail/body.rb +243 -0
- data/lib/mail/configuration.rb +69 -0
- data/lib/mail/core_extensions/nil.rb +11 -0
- data/lib/mail/core_extensions/string.rb +19 -0
- data/lib/mail/elements/address.rb +306 -0
- data/lib/mail/elements/address_list.rb +74 -0
- data/lib/mail/elements/content_disposition_element.rb +30 -0
- data/lib/mail/elements/content_location_element.rb +25 -0
- data/lib/mail/elements/content_transfer_encoding_element.rb +21 -0
- data/lib/mail/elements/content_type_element.rb +35 -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 +18 -0
- data/lib/mail/encodings/encodings.rb +201 -0
- data/lib/mail/encodings/quoted_printable.rb +26 -0
- data/lib/mail/envelope.rb +35 -0
- data/lib/mail/field.rb +219 -0
- data/lib/mail/field_list.rb +33 -0
- data/lib/mail/fields/bcc_field.rb +53 -0
- data/lib/mail/fields/cc_field.rb +52 -0
- data/lib/mail/fields/comments_field.rb +41 -0
- data/lib/mail/fields/common/address_container.rb +16 -0
- data/lib/mail/fields/common/common_address.rb +128 -0
- data/lib/mail/fields/common/common_date.rb +51 -0
- data/lib/mail/fields/common/common_field.rb +64 -0
- data/lib/mail/fields/common/common_message_id.rb +57 -0
- data/lib/mail/fields/common/parameter_hash.rb +39 -0
- data/lib/mail/fields/content_description_field.rb +19 -0
- data/lib/mail/fields/content_disposition_field.rb +60 -0
- data/lib/mail/fields/content_id_field.rb +63 -0
- data/lib/mail/fields/content_location_field.rb +42 -0
- data/lib/mail/fields/content_transfer_encoding_field.rb +45 -0
- data/lib/mail/fields/content_type_field.rb +175 -0
- data/lib/mail/fields/date_field.rb +53 -0
- data/lib/mail/fields/from_field.rb +53 -0
- data/lib/mail/fields/in_reply_to_field.rb +52 -0
- data/lib/mail/fields/keywords_field.rb +43 -0
- data/lib/mail/fields/message_id_field.rb +80 -0
- data/lib/mail/fields/mime_version_field.rb +54 -0
- data/lib/mail/fields/optional_field.rb +11 -0
- data/lib/mail/fields/received_field.rb +62 -0
- data/lib/mail/fields/references_field.rb +53 -0
- data/lib/mail/fields/reply_to_field.rb +53 -0
- data/lib/mail/fields/resent_bcc_field.rb +53 -0
- data/lib/mail/fields/resent_cc_field.rb +53 -0
- data/lib/mail/fields/resent_date_field.rb +33 -0
- data/lib/mail/fields/resent_from_field.rb +53 -0
- data/lib/mail/fields/resent_message_id_field.rb +32 -0
- data/lib/mail/fields/resent_sender_field.rb +60 -0
- data/lib/mail/fields/resent_to_field.rb +53 -0
- data/lib/mail/fields/return_path_field.rb +62 -0
- data/lib/mail/fields/sender_field.rb +65 -0
- data/lib/mail/fields/structured_field.rb +36 -0
- data/lib/mail/fields/subject_field.rb +15 -0
- data/lib/mail/fields/to_field.rb +53 -0
- data/lib/mail/fields/unstructured_field.rb +117 -0
- data/lib/mail/header.rb +235 -0
- data/lib/mail/mail.rb +194 -0
- data/lib/mail/message.rb +1780 -0
- data/lib/mail/network/delivery_methods/file_delivery.rb +40 -0
- data/lib/mail/network/delivery_methods/sendmail.rb +62 -0
- data/lib/mail/network/delivery_methods/smtp.rb +110 -0
- data/lib/mail/network/delivery_methods/test_mailer.rb +40 -0
- data/lib/mail/network/retriever_methods/imap.rb +31 -0
- data/lib/mail/network/retriever_methods/pop3.rb +149 -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 +369 -0
- data/lib/mail/parsers/content_disposition.treetop +46 -0
- data/lib/mail/parsers/content_location.rb +133 -0
- data/lib/mail/parsers/content_location.treetop +20 -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 +512 -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 +5081 -0
- data/lib/mail/parsers/rfc2822.treetop +410 -0
- data/lib/mail/parsers/rfc2822_obsolete.rb +3607 -0
- data/lib/mail/parsers/rfc2822_obsolete.treetop +241 -0
- data/lib/mail/part.rb +82 -0
- data/lib/mail/parts_list.rb +34 -0
- data/lib/mail/patterns.rb +43 -0
- data/lib/mail/utilities.rb +163 -0
- data/lib/mail/vendor/treetop.rb +4 -0
- data/lib/mail/version.rb +10 -0
- data/lib/mail/version_specific/ruby_1_8.rb +84 -0
- data/lib/mail/version_specific/ruby_1_9.rb +77 -0
- data/lib/tasks/corpus.rake +125 -0
- data/lib/tasks/treetop.rake +10 -0
- metadata +188 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
module Mail
|
|
6
|
+
class ContentLocationField < StructuredField
|
|
7
|
+
|
|
8
|
+
FIELD_NAME = 'content-location'
|
|
9
|
+
CAPITALIZED_FIELD = 'Content-Location'
|
|
10
|
+
|
|
11
|
+
def initialize(*args)
|
|
12
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
13
|
+
self.parse
|
|
14
|
+
self
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def parse(val = value)
|
|
19
|
+
unless val.blank?
|
|
20
|
+
@element = Mail::ContentLocationElement.new(val)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def element
|
|
25
|
+
@element ||= Mail::ContentLocationElement.new(value)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def location
|
|
29
|
+
element.location
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# TODO: Fix this up
|
|
33
|
+
def encoded
|
|
34
|
+
"#{CAPITALIZED_FIELD}: #{value}\r\n"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def decoded
|
|
38
|
+
value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
module Mail
|
|
6
|
+
class ContentTransferEncodingField < StructuredField
|
|
7
|
+
|
|
8
|
+
FIELD_NAME = 'content-transfer-encoding'
|
|
9
|
+
CAPITALIZED_FIELD = 'Content-Transfer-Encoding'
|
|
10
|
+
|
|
11
|
+
def initialize(*args)
|
|
12
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last.to_s.downcase))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def parse(val = value)
|
|
16
|
+
unless val.blank?
|
|
17
|
+
@element = Mail::ContentTransferEncodingElement.new(val)
|
|
18
|
+
@tree = @element.tree
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def tree
|
|
23
|
+
@element ||= Mail::ContentTransferEncodingElement.new(value)
|
|
24
|
+
@tree ||= @element.tree
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def element
|
|
28
|
+
@element ||= Mail::ContentTransferEncodingElement.new(value)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def encoding
|
|
32
|
+
element.encoding
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# TODO: Fix this up
|
|
36
|
+
def encoded
|
|
37
|
+
"#{CAPITALIZED_FIELD}: #{value}\r\n"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def decoded
|
|
41
|
+
value
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
module Mail
|
|
6
|
+
class ContentTypeField < StructuredField
|
|
7
|
+
|
|
8
|
+
FIELD_NAME = 'content-type'
|
|
9
|
+
CAPITALIZED_FIELD = 'Content-Type'
|
|
10
|
+
|
|
11
|
+
def initialize(*args)
|
|
12
|
+
if args.last.class == Array
|
|
13
|
+
@main_type = args.last[0]
|
|
14
|
+
@sub_type = args.last[1]
|
|
15
|
+
@parameters = ParameterHash.new.merge!(args.last.last)
|
|
16
|
+
super(CAPITALIZED_FIELD, args.last)
|
|
17
|
+
else
|
|
18
|
+
@main_type = nil
|
|
19
|
+
@sub_type = nil
|
|
20
|
+
@parameters = nil
|
|
21
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
22
|
+
end
|
|
23
|
+
self.parse
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def parse(val = value)
|
|
28
|
+
unless val.blank?
|
|
29
|
+
self.value = val
|
|
30
|
+
@element = nil
|
|
31
|
+
element
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def element
|
|
36
|
+
begin
|
|
37
|
+
@element ||= Mail::ContentTypeElement.new(value)
|
|
38
|
+
rescue
|
|
39
|
+
attempt_to_clean
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def attempt_to_clean
|
|
44
|
+
# Sanitize the value, handle special cases
|
|
45
|
+
@element ||= Mail::ContentTypeElement.new(sanatize(value))
|
|
46
|
+
rescue
|
|
47
|
+
# All else fails, just get the mime type
|
|
48
|
+
@element ||= Mail::ContentTypeElement.new(get_mime_type(value))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def main_type
|
|
52
|
+
@main_type ||= element.main_type
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def sub_type
|
|
56
|
+
@sub_type ||= element.sub_type
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def string
|
|
60
|
+
"#{main_type}/#{sub_type}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def default
|
|
64
|
+
decoded
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
alias :content_type :string
|
|
68
|
+
|
|
69
|
+
def parameters
|
|
70
|
+
unless @parameters
|
|
71
|
+
@parameters = ParameterHash.new
|
|
72
|
+
element.parameters.each { |p| @parameters.merge!(p) }
|
|
73
|
+
end
|
|
74
|
+
@parameters
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def ContentTypeField.with_boundary(type)
|
|
78
|
+
new("#{type}; boundary=#{generate_boundary}")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def ContentTypeField.generate_boundary
|
|
82
|
+
"--==_mimepart_#{Mail.random_tag}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def value
|
|
86
|
+
if @value.class == Array
|
|
87
|
+
"#{@main_type}/#{@sub_type}; #{stringify(parameters)}"
|
|
88
|
+
else
|
|
89
|
+
@value
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def stringify(params)
|
|
94
|
+
params.map { |k,v| "#{k}=#{Encodings.param_encode(v)}" }.join("; ")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def filename
|
|
98
|
+
case
|
|
99
|
+
when parameters['filename']
|
|
100
|
+
@filename = parameters['filename']
|
|
101
|
+
when parameters['name']
|
|
102
|
+
@filename = parameters['name']
|
|
103
|
+
else
|
|
104
|
+
@filename = nil
|
|
105
|
+
end
|
|
106
|
+
@filename
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# TODO: Fix this up
|
|
110
|
+
def encoded
|
|
111
|
+
"#{CAPITALIZED_FIELD}: #{content_type};\r\n\t#{parameters.encoded};\r\n"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def decoded
|
|
115
|
+
value
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
|
|
120
|
+
def method_missing(name, *args, &block)
|
|
121
|
+
if name.to_s =~ /([\w_]+)=/
|
|
122
|
+
self.parameters[$1] = args.first
|
|
123
|
+
@value = "#{content_type}; #{stringify(parameters)}"
|
|
124
|
+
else
|
|
125
|
+
super
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Various special cases from random emails found that I am not going to change
|
|
130
|
+
# the parser for
|
|
131
|
+
def sanatize( val )
|
|
132
|
+
case
|
|
133
|
+
when val.chomp =~ /^\s*([\w\d\-_]+)\/([\w\d\-_]+)\s*;;+(.*)$/i
|
|
134
|
+
# Handles 'text/plain;; format="flowed"' (double semi colon)
|
|
135
|
+
"#{$1}/#{$2}; #{$3}"
|
|
136
|
+
when val.chomp =~ /^\s*([\w\d\-_]+)\/([\w\d\-_]+)\s*;(ISO[\w\d\-_]+)$/i
|
|
137
|
+
# Microsoft helper:
|
|
138
|
+
# Handles 'mime/type;ISO-8559-1'
|
|
139
|
+
"#{$1}/#{$2}; charset=#{quote_atom($3)}"
|
|
140
|
+
when val.chomp =~ /^text;?$/i
|
|
141
|
+
# Handles 'text;' and 'text'
|
|
142
|
+
"text/plain;"
|
|
143
|
+
when val.chomp =~ /^(\w+);\s(.*)$/i
|
|
144
|
+
# Handles 'text; <parameters>'
|
|
145
|
+
"text/plain; #{$2}"
|
|
146
|
+
when val =~ /([\w\d\-_]+\/[\w\d\-_]+);\scharset="charset="(\w+)""/i
|
|
147
|
+
# Handles text/html; charset="charset="GB2312""
|
|
148
|
+
"#{$1}; charset=#{quote_atom($2)}"
|
|
149
|
+
when val =~ /([\w\d\-_]+\/[\w\d\-_]+);\s+(.*)/i
|
|
150
|
+
type = $1
|
|
151
|
+
# Handles misquoted param values
|
|
152
|
+
# e.g: application/octet-stream; name=archiveshelp1[1].htm
|
|
153
|
+
# and: audio/x-midi;\r\n\tname=Part .exe
|
|
154
|
+
params = $2.to_s.split(/\s+/)
|
|
155
|
+
params = params.map { |i| i.to_s.chomp.strip }
|
|
156
|
+
params = params.map { |i| i.split(/\s*\=\s*/) }
|
|
157
|
+
params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s)}" }.join('; ')
|
|
158
|
+
"#{type}; #{params}"
|
|
159
|
+
when val =~ /^\s*$/
|
|
160
|
+
'text/plain'
|
|
161
|
+
else
|
|
162
|
+
''
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def get_mime_type( val )
|
|
167
|
+
case
|
|
168
|
+
when val =~ /^([\w\d\-_]+)\/([\w\d\-_]+);.+$/i
|
|
169
|
+
"#{$1}/#{$2}"
|
|
170
|
+
else
|
|
171
|
+
'text/plain'
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = Date Field
|
|
4
|
+
#
|
|
5
|
+
# The Date field inherits from StructuredField and handles the Date: header
|
|
6
|
+
# field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending date to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a DateField as it's field type. This includes all Mail::CommonAddress
|
|
10
|
+
# module instance methods.
|
|
11
|
+
#
|
|
12
|
+
# There must be excatly one Date field in an RFC2822 email.
|
|
13
|
+
#
|
|
14
|
+
# == Examples:
|
|
15
|
+
#
|
|
16
|
+
# mail = Mail.new
|
|
17
|
+
# mail.date = 'Mon, 24 Nov 1997 14:22:01 -0800'
|
|
18
|
+
# mail.date #=> #<DateTime: 211747170121/86400,-1/3,2299161>
|
|
19
|
+
# mail.date.to_s #=> 'Mon, 24 Nov 1997 14:22:01 -0800'
|
|
20
|
+
# mail[:date] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
21
|
+
# mail['date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
22
|
+
# mail['Date'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::DateField:0x180e1c4
|
|
23
|
+
#
|
|
24
|
+
module Mail
|
|
25
|
+
class DateField < StructuredField
|
|
26
|
+
|
|
27
|
+
include Mail::CommonDate
|
|
28
|
+
|
|
29
|
+
FIELD_NAME = 'date'
|
|
30
|
+
CAPITALIZED_FIELD = "Date"
|
|
31
|
+
|
|
32
|
+
def initialize(*args)
|
|
33
|
+
if args.last.blank?
|
|
34
|
+
self.name = CAPITALIZED_FIELD
|
|
35
|
+
self.value = Time.now.strftime('%a, %d %b %Y %H:%M:%S %z')
|
|
36
|
+
self
|
|
37
|
+
else
|
|
38
|
+
value = strip_field(FIELD_NAME, args.last)
|
|
39
|
+
value = ::DateTime.parse(value.to_s).strftime('%a, %d %b %Y %H:%M:%S %z')
|
|
40
|
+
super(CAPITALIZED_FIELD, value)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def encoded
|
|
45
|
+
do_encode(CAPITALIZED_FIELD)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def decoded
|
|
49
|
+
do_decode
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = From Field
|
|
4
|
+
#
|
|
5
|
+
# The From field inherits from StructuredField and handles the From: header
|
|
6
|
+
# field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending from to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a FromField as it's field type. This includes all Mail::CommonAddress
|
|
10
|
+
# module instance metods.
|
|
11
|
+
#
|
|
12
|
+
# Only one From field can appear in a header, though it can have multiple
|
|
13
|
+
# addresses and groups of addresses.
|
|
14
|
+
#
|
|
15
|
+
# == Examples:
|
|
16
|
+
#
|
|
17
|
+
# mail = Mail.new
|
|
18
|
+
# mail.from = 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
19
|
+
# mail.from #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
20
|
+
# mail[:from] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
21
|
+
# mail['from'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
22
|
+
# mail['From'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::FromField:0x180e1c4
|
|
23
|
+
#
|
|
24
|
+
# mail[:from].encoded #=> 'from: Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net\r\n'
|
|
25
|
+
# mail[:from].decoded #=> 'Mikel Lindsaar <mikel@test.lindsaar.net>, ada@test.lindsaar.net'
|
|
26
|
+
# mail[:from].addresses #=> ['mikel@test.lindsaar.net', 'ada@test.lindsaar.net']
|
|
27
|
+
# mail[:from].formatted #=> ['Mikel Lindsaar <mikel@test.lindsaar.net>', 'ada@test.lindsaar.net']
|
|
28
|
+
#
|
|
29
|
+
module Mail
|
|
30
|
+
class FromField < StructuredField
|
|
31
|
+
|
|
32
|
+
include Mail::CommonAddress
|
|
33
|
+
|
|
34
|
+
FIELD_NAME = 'from'
|
|
35
|
+
CAPITALIZED_FIELD = 'From'
|
|
36
|
+
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
39
|
+
self.parse
|
|
40
|
+
self
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def encoded
|
|
45
|
+
do_encode(CAPITALIZED_FIELD)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def decoded
|
|
49
|
+
do_decode
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# = In-Reply-To Field
|
|
4
|
+
#
|
|
5
|
+
# The In-Reply-To field inherits from StructuredField and handles the
|
|
6
|
+
# In-Reply-To: header field in the email.
|
|
7
|
+
#
|
|
8
|
+
# Sending in_reply_to to a mail message will instantiate a Mail::Field object that
|
|
9
|
+
# has a InReplyToField as it's field type. This includes all Mail::CommonMessageId
|
|
10
|
+
# module instance metods.
|
|
11
|
+
#
|
|
12
|
+
# Note that, the #message_ids method will return an array of message IDs without the
|
|
13
|
+
# enclosing angle brackets which per RFC are not syntactically part of the message id.
|
|
14
|
+
#
|
|
15
|
+
# Only one InReplyTo field can appear in a header, though it can have multiple
|
|
16
|
+
# Message IDs.
|
|
17
|
+
#
|
|
18
|
+
# == Examples:
|
|
19
|
+
#
|
|
20
|
+
# mail = Mail.new
|
|
21
|
+
# mail.in_reply_to = '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
|
|
22
|
+
# mail.in_reply_to #=> '<F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom>'
|
|
23
|
+
# mail[:in_reply_to] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
24
|
+
# mail['in_reply_to'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
25
|
+
# mail['In-Reply-To'] #=> '#<Mail::Field:0x180e5e8 @field=#<Mail::InReplyToField:0x180e1c4
|
|
26
|
+
#
|
|
27
|
+
# mail[:in_reply_to].message_ids #=> ['F6E2D0B4-CC35-4A91-BA4C-C7C712B10C13@test.me.dom']
|
|
28
|
+
#
|
|
29
|
+
module Mail
|
|
30
|
+
class InReplyToField < StructuredField
|
|
31
|
+
|
|
32
|
+
include Mail::CommonMessageId
|
|
33
|
+
|
|
34
|
+
FIELD_NAME = 'in-reply-to'
|
|
35
|
+
CAPITALIZED_FIELD = 'In-Reply-To'
|
|
36
|
+
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
39
|
+
self.parse
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def encoded
|
|
44
|
+
do_encode(CAPITALIZED_FIELD)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def decoded
|
|
48
|
+
do_decode
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
# keywords = "Keywords:" phrase *("," phrase) CRLF
|
|
4
|
+
module Mail
|
|
5
|
+
class KeywordsField < StructuredField
|
|
6
|
+
|
|
7
|
+
FIELD_NAME = 'keywords'
|
|
8
|
+
CAPITALIZED_FIELD = 'Keywords'
|
|
9
|
+
|
|
10
|
+
def initialize(*args)
|
|
11
|
+
super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, args.last))
|
|
12
|
+
self.parse
|
|
13
|
+
self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def parse(val = value)
|
|
17
|
+
unless val.blank?
|
|
18
|
+
@phrase_list ||= PhraseList.new(value)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def phrase_list
|
|
23
|
+
@phrase_list ||= PhraseList.new(value)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def keywords
|
|
27
|
+
phrase_list.phrases
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def encoded
|
|
31
|
+
"#{CAPITALIZED_FIELD}: #{keywords.join(', ')}\r\n"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def decoded
|
|
35
|
+
keywords.join(', ')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def default
|
|
39
|
+
keywords
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|