dball-mail 2.2.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/CHANGELOG.rdoc +459 -0
  2. data/README.rdoc +582 -0
  3. data/Rakefile +66 -0
  4. data/TODO.rdoc +9 -0
  5. data/lib/VERSION +4 -0
  6. data/lib/mail/attachments_list.rb +105 -0
  7. data/lib/mail/body.rb +286 -0
  8. data/lib/mail/configuration.rb +71 -0
  9. data/lib/mail/core_extensions/nil.rb +11 -0
  10. data/lib/mail/core_extensions/string.rb +27 -0
  11. data/lib/mail/elements/address.rb +306 -0
  12. data/lib/mail/elements/address_list.rb +74 -0
  13. data/lib/mail/elements/content_disposition_element.rb +30 -0
  14. data/lib/mail/elements/content_location_element.rb +25 -0
  15. data/lib/mail/elements/content_transfer_encoding_element.rb +24 -0
  16. data/lib/mail/elements/content_type_element.rb +35 -0
  17. data/lib/mail/elements/date_time_element.rb +26 -0
  18. data/lib/mail/elements/envelope_from_element.rb +34 -0
  19. data/lib/mail/elements/message_ids_element.rb +29 -0
  20. data/lib/mail/elements/mime_version_element.rb +26 -0
  21. data/lib/mail/elements/phrase_list.rb +21 -0
  22. data/lib/mail/elements/received_element.rb +30 -0
  23. data/lib/mail/elements.rb +14 -0
  24. data/lib/mail/encodings/7bit.rb +31 -0
  25. data/lib/mail/encodings/8bit.rb +31 -0
  26. data/lib/mail/encodings/base64.rb +33 -0
  27. data/lib/mail/encodings/binary.rb +31 -0
  28. data/lib/mail/encodings/quoted_printable.rb +38 -0
  29. data/lib/mail/encodings/transfer_encoding.rb +58 -0
  30. data/lib/mail/encodings.rb +268 -0
  31. data/lib/mail/envelope.rb +35 -0
  32. data/lib/mail/field.rb +223 -0
  33. data/lib/mail/field_list.rb +33 -0
  34. data/lib/mail/fields/bcc_field.rb +56 -0
  35. data/lib/mail/fields/cc_field.rb +55 -0
  36. data/lib/mail/fields/comments_field.rb +41 -0
  37. data/lib/mail/fields/common/address_container.rb +16 -0
  38. data/lib/mail/fields/common/common_address.rb +125 -0
  39. data/lib/mail/fields/common/common_date.rb +42 -0
  40. data/lib/mail/fields/common/common_field.rb +50 -0
  41. data/lib/mail/fields/common/common_message_id.rb +44 -0
  42. data/lib/mail/fields/common/parameter_hash.rb +58 -0
  43. data/lib/mail/fields/content_description_field.rb +19 -0
  44. data/lib/mail/fields/content_disposition_field.rb +69 -0
  45. data/lib/mail/fields/content_id_field.rb +63 -0
  46. data/lib/mail/fields/content_location_field.rb +42 -0
  47. data/lib/mail/fields/content_transfer_encoding_field.rb +50 -0
  48. data/lib/mail/fields/content_type_field.rb +198 -0
  49. data/lib/mail/fields/date_field.rb +55 -0
  50. data/lib/mail/fields/from_field.rb +55 -0
  51. data/lib/mail/fields/in_reply_to_field.rb +55 -0
  52. data/lib/mail/fields/keywords_field.rb +44 -0
  53. data/lib/mail/fields/message_id_field.rb +83 -0
  54. data/lib/mail/fields/mime_version_field.rb +53 -0
  55. data/lib/mail/fields/optional_field.rb +13 -0
  56. data/lib/mail/fields/received_field.rb +67 -0
  57. data/lib/mail/fields/references_field.rb +55 -0
  58. data/lib/mail/fields/reply_to_field.rb +55 -0
  59. data/lib/mail/fields/resent_bcc_field.rb +55 -0
  60. data/lib/mail/fields/resent_cc_field.rb +55 -0
  61. data/lib/mail/fields/resent_date_field.rb +35 -0
  62. data/lib/mail/fields/resent_from_field.rb +55 -0
  63. data/lib/mail/fields/resent_message_id_field.rb +34 -0
  64. data/lib/mail/fields/resent_sender_field.rb +62 -0
  65. data/lib/mail/fields/resent_to_field.rb +55 -0
  66. data/lib/mail/fields/return_path_field.rb +64 -0
  67. data/lib/mail/fields/sender_field.rb +67 -0
  68. data/lib/mail/fields/structured_field.rb +51 -0
  69. data/lib/mail/fields/subject_field.rb +16 -0
  70. data/lib/mail/fields/to_field.rb +55 -0
  71. data/lib/mail/fields/unstructured_field.rb +179 -0
  72. data/lib/mail/fields.rb +35 -0
  73. data/lib/mail/header.rb +264 -0
  74. data/lib/mail/mail.rb +255 -0
  75. data/lib/mail/message.rb +1972 -0
  76. data/lib/mail/network/delivery_methods/file_delivery.rb +40 -0
  77. data/lib/mail/network/delivery_methods/sendmail.rb +62 -0
  78. data/lib/mail/network/delivery_methods/smtp.rb +136 -0
  79. data/lib/mail/network/delivery_methods/test_mailer.rb +40 -0
  80. data/lib/mail/network/retriever_methods/imap.rb +213 -0
  81. data/lib/mail/network/retriever_methods/pop3.rb +194 -0
  82. data/lib/mail/network/retriever_methods/test_retriever.rb +31 -0
  83. data/lib/mail/network.rb +10 -0
  84. data/lib/mail/parsers/address_lists.rb +64 -0
  85. data/lib/mail/parsers/address_lists.treetop +19 -0
  86. data/lib/mail/parsers/content_disposition.rb +535 -0
  87. data/lib/mail/parsers/content_disposition.treetop +46 -0
  88. data/lib/mail/parsers/content_location.rb +139 -0
  89. data/lib/mail/parsers/content_location.treetop +20 -0
  90. data/lib/mail/parsers/content_transfer_encoding.rb +162 -0
  91. data/lib/mail/parsers/content_transfer_encoding.treetop +20 -0
  92. data/lib/mail/parsers/content_type.rb +967 -0
  93. data/lib/mail/parsers/content_type.treetop +68 -0
  94. data/lib/mail/parsers/date_time.rb +114 -0
  95. data/lib/mail/parsers/date_time.treetop +11 -0
  96. data/lib/mail/parsers/envelope_from.rb +194 -0
  97. data/lib/mail/parsers/envelope_from.treetop +32 -0
  98. data/lib/mail/parsers/message_ids.rb +45 -0
  99. data/lib/mail/parsers/message_ids.treetop +15 -0
  100. data/lib/mail/parsers/mime_version.rb +144 -0
  101. data/lib/mail/parsers/mime_version.treetop +19 -0
  102. data/lib/mail/parsers/phrase_lists.rb +45 -0
  103. data/lib/mail/parsers/phrase_lists.treetop +15 -0
  104. data/lib/mail/parsers/received.rb +71 -0
  105. data/lib/mail/parsers/received.treetop +11 -0
  106. data/lib/mail/parsers/rfc2045.rb +464 -0
  107. data/lib/mail/parsers/rfc2045.treetop +36 -0
  108. data/lib/mail/parsers/rfc2822.rb +5318 -0
  109. data/lib/mail/parsers/rfc2822.treetop +410 -0
  110. data/lib/mail/parsers/rfc2822_obsolete.rb +3757 -0
  111. data/lib/mail/parsers/rfc2822_obsolete.treetop +241 -0
  112. data/lib/mail/part.rb +116 -0
  113. data/lib/mail/parts_list.rb +43 -0
  114. data/lib/mail/patterns.rb +34 -0
  115. data/lib/mail/utilities.rb +211 -0
  116. data/lib/mail/version.rb +24 -0
  117. data/lib/mail/version_specific/ruby_1_8.rb +97 -0
  118. data/lib/mail/version_specific/ruby_1_9.rb +87 -0
  119. data/lib/mail.rb +80 -0
  120. data/lib/tasks/corpus.rake +125 -0
  121. data/lib/tasks/treetop.rake +10 -0
  122. metadata +255 -0
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module Mail
3
+
4
+ # ParameterHash is an intelligent Hash that allows you to add
5
+ # parameter values including the MIME extension paramaters that
6
+ # have the name*0="blah", name*1="bleh" keys, and will just return
7
+ # a single key called name="blahbleh" and do any required un-encoding
8
+ # to make that happen
9
+ # Parameters are defined in RFC2045, split keys are in RFC2231
10
+
11
+ class ParameterHash < HashWithIndifferentAccess
12
+
13
+ include Mail::Utilities
14
+
15
+ def [](key_name)
16
+ key_pattern = Regexp.escape(key_name.to_s)
17
+ pairs = []
18
+ exact = nil
19
+ each do |k,v|
20
+ if k =~ /^#{key_pattern}(\*|$)/i
21
+ if $1 == '*'
22
+ pairs << [k, v]
23
+ else
24
+ exact = k
25
+ end
26
+ end
27
+ end
28
+ if pairs.empty? # Just dealing with a single value pair
29
+ super(exact || key_name)
30
+ else # Dealing with a multiple value pair or a single encoded value pair
31
+ string = pairs.sort { |a,b| a.first <=> b.first }.map { |v| v.last }.join('')
32
+ if mt = string.match(/([\w\d\-]+)'(\w\w)'(.*)/)
33
+ string = mt[3]
34
+ encoding = mt[1]
35
+ else
36
+ encoding = nil
37
+ end
38
+ Mail::Encodings.param_decode(string, encoding)
39
+ end
40
+ end
41
+
42
+ def encoded
43
+ map.sort { |a,b| a.first <=> b.first }.map do |key_name, value|
44
+ unless value.ascii_only?
45
+ value = Mail::Encodings.param_encode(value)
46
+ key_name = "#{key_name}*"
47
+ end
48
+ %Q{#{key_name}=#{quote_token(value)}}
49
+ end.join(";\r\n\s")
50
+ end
51
+
52
+ def decoded
53
+ map.sort { |a,b| a.first <=> b.first }.map do |key_name, value|
54
+ %Q{#{key_name}=#{quote_token(value)}}
55
+ end.join("; ")
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ #
3
+ #
4
+ #
5
+ module Mail
6
+ class ContentDescriptionField < UnstructuredField
7
+
8
+ FIELD_NAME = 'content-description'
9
+ CAPITALIZED_FIELD = 'Content-Description'
10
+
11
+ def initialize(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
14
+ self.parse
15
+ self
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ require 'mail/fields/common/parameter_hash'
3
+
4
+ module Mail
5
+ class ContentDispositionField < StructuredField
6
+
7
+ FIELD_NAME = 'content-disposition'
8
+ CAPITALIZED_FIELD = 'Content-Disposition'
9
+
10
+ def initialize(value = nil, charset = 'utf-8')
11
+ self.charset = charset
12
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
13
+ self.parse
14
+ self
15
+ end
16
+
17
+ def parse(val = value)
18
+ unless val.blank?
19
+ @element = Mail::ContentDispositionElement.new(val)
20
+ end
21
+ end
22
+
23
+ def element
24
+ @element ||= Mail::ContentDispositionElement.new(value)
25
+ end
26
+
27
+ def disposition_type
28
+ element.disposition_type
29
+ end
30
+
31
+ def parameters
32
+ @parameters = ParameterHash.new
33
+ element.parameters.each { |p| @parameters.merge!(p) }
34
+ @parameters
35
+ end
36
+
37
+ def filename
38
+ case
39
+ when !parameters['filename'].blank?
40
+ @filename = parameters['filename']
41
+ when !parameters['name'].blank?
42
+ @filename = parameters['name']
43
+ else
44
+ @filename = nil
45
+ end
46
+ @filename
47
+ end
48
+
49
+ # TODO: Fix this up
50
+ def encoded
51
+ if parameters.length > 0
52
+ p = ";\r\n\s#{parameters.encoded}\r\n"
53
+ else
54
+ p = "\r\n"
55
+ end
56
+ "#{CAPITALIZED_FIELD}: #{disposition_type}" + p
57
+ end
58
+
59
+ def decoded
60
+ if parameters.length > 0
61
+ p = "; #{parameters.decoded}"
62
+ else
63
+ p = ""
64
+ end
65
+ "#{disposition_type}" + p
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ #
3
+ #
4
+ #
5
+ module Mail
6
+ class ContentIdField < StructuredField
7
+
8
+ FIELD_NAME = 'content-id'
9
+ CAPITALIZED_FIELD = "Content-ID"
10
+
11
+ def initialize(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ @uniq = 1
14
+ if value.blank?
15
+ value = generate_content_id
16
+ else
17
+ value = strip_field(FIELD_NAME, value)
18
+ end
19
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
20
+ self.parse
21
+ self
22
+ end
23
+
24
+ def parse(val = value)
25
+ unless val.blank?
26
+ @element = Mail::MessageIdsElement.new(val)
27
+ end
28
+ end
29
+
30
+ def element
31
+ @element ||= Mail::MessageIdsElement.new(value)
32
+ end
33
+
34
+ def name
35
+ 'Content-ID'
36
+ end
37
+
38
+ def content_id
39
+ element.message_id
40
+ end
41
+
42
+ def to_s
43
+ "<#{content_id}>"
44
+ end
45
+
46
+ # TODO: Fix this up
47
+ def encoded
48
+ "#{CAPITALIZED_FIELD}: #{to_s}\r\n"
49
+ end
50
+
51
+ def decoded
52
+ "#{to_s}"
53
+ end
54
+
55
+ private
56
+
57
+ def generate_content_id
58
+ fqdn = ::Socket.gethostname
59
+ "<#{Mail.random_tag}@#{fqdn}.mail>"
60
+ end
61
+
62
+ end
63
+ end
@@ -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(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
14
+ self.parse
15
+ self
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}: #{location}\r\n"
35
+ end
36
+
37
+ def decoded
38
+ location
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,50 @@
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(value = nil, charset = 'utf-8')
12
+ self.charset = charset
13
+ value = '7bit' if value.to_s =~ /7-bit/i
14
+ value = '8bit' if value.to_s =~ /8-bit/i
15
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
16
+ self.parse
17
+ self
18
+ end
19
+
20
+ def parse(val = value)
21
+ unless val.blank?
22
+ @element = Mail::ContentTransferEncodingElement.new(val)
23
+ end
24
+ end
25
+
26
+ def tree
27
+ STDERR.puts("tree is deprecated. Please use encoding to get parse result\n#{caller}")
28
+ @element ||= Mail::ContentTransferEncodingElement.new(value)
29
+ @tree ||= @element.tree
30
+ end
31
+
32
+ def element
33
+ @element ||= Mail::ContentTransferEncodingElement.new(value)
34
+ end
35
+
36
+ def encoding
37
+ element.encoding
38
+ end
39
+
40
+ # TODO: Fix this up
41
+ def encoded
42
+ "#{CAPITALIZED_FIELD}: #{encoding}\r\n"
43
+ end
44
+
45
+ def decoded
46
+ encoding
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,198 @@
1
+ # encoding: utf-8
2
+ require 'mail/fields/common/parameter_hash'
3
+
4
+ module Mail
5
+ class ContentTypeField < StructuredField
6
+
7
+ FIELD_NAME = 'content-type'
8
+ CAPITALIZED_FIELD = 'Content-Type'
9
+
10
+ def initialize(value = nil, charset = 'utf-8')
11
+ self.charset = charset
12
+ if value.class == Array
13
+ @main_type = value[0]
14
+ @sub_type = value[1]
15
+ @parameters = ParameterHash.new.merge!(value.last)
16
+ else
17
+ @main_type = nil
18
+ @sub_type = nil
19
+ @parameters = nil
20
+ value = strip_field(FIELD_NAME, value)
21
+ end
22
+ super(CAPITALIZED_FIELD, value, charset)
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 media 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
+ if parameters.length > 0
112
+ p = ";\r\n\s#{parameters.encoded}"
113
+ else
114
+ p = ""
115
+ end
116
+ "#{CAPITALIZED_FIELD}: #{content_type}#{p}\r\n"
117
+ end
118
+
119
+ def decoded
120
+ if parameters.length > 0
121
+ p = "; #{parameters.decoded}"
122
+ else
123
+ p = ""
124
+ end
125
+ "#{content_type}" + p
126
+ end
127
+
128
+ private
129
+
130
+ def method_missing(name, *args, &block)
131
+ if name.to_s =~ /([\w_]+)=/
132
+ self.parameters[$1] = args.first
133
+ @value = "#{content_type}; #{stringify(parameters)}"
134
+ else
135
+ super
136
+ end
137
+ end
138
+
139
+ # Various special cases from random emails found that I am not going to change
140
+ # the parser for
141
+ def sanatize( val )
142
+
143
+ # TODO: check if there are cases where whitespace is not a separator
144
+ val = val.tr(' ',';').
145
+ squeeze(';').
146
+ gsub(';', '; '). #use '; ' as a separator (or EOL)
147
+ gsub(/;\s*$/,'') #remove trailing to keep examples below
148
+
149
+ if val =~ /(boundary=(\S*))/i
150
+ val = "#{$`.downcase}boundary=#{$2}#{$'.downcase}"
151
+ else
152
+ val.downcase!
153
+ end
154
+
155
+ case
156
+ when val.chomp =~ /^\s*([\w\d\-_]+)\/([\w\d\-_]+)\s*;;+(.*)$/i
157
+ # Handles 'text/plain;; format="flowed"' (double semi colon)
158
+ "#{$1}/#{$2}; #{$3}"
159
+ when val.chomp =~ /^\s*([\w\d\-_]+)\/([\w\d\-_]+)\s*;\s?(ISO[\w\d\-_]+)$/i
160
+ # Microsoft helper:
161
+ # Handles 'type/subtype;ISO-8559-1'
162
+ "#{$1}/#{$2}; charset=#{quote_atom($3)}"
163
+ when val.chomp =~ /^text;?$/i
164
+ # Handles 'text;' and 'text'
165
+ "text/plain;"
166
+ when val.chomp =~ /^(\w+);\s(.*)$/i
167
+ # Handles 'text; <parameters>'
168
+ "text/plain; #{$2}"
169
+ when val =~ /([\w\d\-_]+\/[\w\d\-_]+);\scharset="charset="(\w+)""/i
170
+ # Handles text/html; charset="charset="GB2312""
171
+ "#{$1}; charset=#{quote_atom($2)}"
172
+ when val =~ /([\w\d\-_]+\/[\w\d\-_]+);\s+(.*)/i
173
+ type = $1
174
+ # Handles misquoted param values
175
+ # e.g: application/octet-stream; name=archiveshelp1[1].htm
176
+ # and: audio/x-midi;\r\n\sname=Part .exe
177
+ params = $2.to_s.split(/\s+/)
178
+ params = params.map { |i| i.to_s.chomp.strip }
179
+ params = params.map { |i| i.split(/\s*\=\s*/) }
180
+ params = params.map { |i| "#{i[0]}=#{dquote(i[1].to_s)}" }.join('; ')
181
+ "#{type}; #{params}"
182
+ when val =~ /^\s*$/
183
+ 'text/plain'
184
+ else
185
+ ''
186
+ end
187
+ end
188
+
189
+ def get_mime_type( val )
190
+ case
191
+ when val =~ /^([\w\d\-_]+)\/([\w\d\-_]+);.+$/i
192
+ "#{$1}/#{$2}"
193
+ else
194
+ 'text/plain'
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,55 @@
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
+ require 'mail/fields/common/common_date'
25
+
26
+ module Mail
27
+ class DateField < StructuredField
28
+
29
+ include Mail::CommonDate
30
+
31
+ FIELD_NAME = 'date'
32
+ CAPITALIZED_FIELD = "Date"
33
+
34
+ def initialize(value = nil, charset = 'utf-8')
35
+ self.charset = charset
36
+ if value.blank?
37
+ value = Time.now.strftime('%a, %d %b %Y %H:%M:%S %z')
38
+ else
39
+ value = strip_field(FIELD_NAME, value)
40
+ value.to_s.gsub!(/\(.*?\)/, '')
41
+ value = ::DateTime.parse(value.to_s.squeeze(" ")).strftime('%a, %d %b %Y %H:%M:%S %z')
42
+ end
43
+ super(CAPITALIZED_FIELD, value, charset)
44
+ end
45
+
46
+ def encoded
47
+ do_encode(CAPITALIZED_FIELD)
48
+ end
49
+
50
+ def decoded
51
+ do_decode
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,55 @@
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
+ require 'mail/fields/common/common_address'
30
+
31
+ module Mail
32
+ class FromField < StructuredField
33
+
34
+ include Mail::CommonAddress
35
+
36
+ FIELD_NAME = 'from'
37
+ CAPITALIZED_FIELD = 'From'
38
+
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
42
+ self.parse
43
+ self
44
+ end
45
+
46
+ def encoded
47
+ do_encode(CAPITALIZED_FIELD)
48
+ end
49
+
50
+ def decoded
51
+ do_decode
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,55 @@
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
+ require 'mail/fields/common/common_message_id'
30
+
31
+ module Mail
32
+ class InReplyToField < StructuredField
33
+
34
+ include Mail::CommonMessageId
35
+
36
+ FIELD_NAME = 'in-reply-to'
37
+ CAPITALIZED_FIELD = 'In-Reply-To'
38
+
39
+ def initialize(value = nil, charset = 'utf-8')
40
+ self.charset = charset
41
+ super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
42
+ self.parse
43
+ self
44
+ end
45
+
46
+ def encoded
47
+ do_encode(CAPITALIZED_FIELD)
48
+ end
49
+
50
+ def decoded
51
+ do_decode
52
+ end
53
+
54
+ end
55
+ end