mail 2.5.5 → 2.8.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.
Files changed (191) hide show
  1. checksums.yaml +5 -5
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +170 -108
  4. data/lib/mail/attachments_list.rb +13 -10
  5. data/lib/mail/body.rb +105 -91
  6. data/lib/mail/check_delivery_params.rb +30 -22
  7. data/lib/mail/configuration.rb +3 -0
  8. data/lib/mail/constants.rb +79 -0
  9. data/lib/mail/elements/address.rb +118 -174
  10. data/lib/mail/elements/address_list.rb +16 -56
  11. data/lib/mail/elements/content_disposition_element.rb +12 -22
  12. data/lib/mail/elements/content_location_element.rb +9 -17
  13. data/lib/mail/elements/content_transfer_encoding_element.rb +8 -19
  14. data/lib/mail/elements/content_type_element.rb +20 -30
  15. data/lib/mail/elements/date_time_element.rb +10 -21
  16. data/lib/mail/elements/envelope_from_element.rb +23 -31
  17. data/lib/mail/elements/message_ids_element.rb +22 -20
  18. data/lib/mail/elements/mime_version_element.rb +10 -21
  19. data/lib/mail/elements/phrase_list.rb +13 -15
  20. data/lib/mail/elements/received_element.rb +26 -21
  21. data/lib/mail/elements.rb +1 -0
  22. data/lib/mail/encodings/7bit.rb +10 -14
  23. data/lib/mail/encodings/8bit.rb +5 -18
  24. data/lib/mail/encodings/base64.rb +15 -10
  25. data/lib/mail/encodings/binary.rb +4 -22
  26. data/lib/mail/encodings/identity.rb +24 -0
  27. data/lib/mail/encodings/quoted_printable.rb +13 -7
  28. data/lib/mail/encodings/transfer_encoding.rb +47 -28
  29. data/lib/mail/encodings/unix_to_unix.rb +20 -0
  30. data/lib/mail/encodings.rb +102 -93
  31. data/lib/mail/envelope.rb +12 -19
  32. data/lib/mail/field.rb +143 -71
  33. data/lib/mail/field_list.rb +73 -19
  34. data/lib/mail/fields/bcc_field.rb +42 -48
  35. data/lib/mail/fields/cc_field.rb +29 -50
  36. data/lib/mail/fields/comments_field.rb +28 -37
  37. data/lib/mail/fields/common_address_field.rb +170 -0
  38. data/lib/mail/fields/common_date_field.rb +58 -0
  39. data/lib/mail/fields/common_field.rb +77 -0
  40. data/lib/mail/fields/common_message_id_field.rb +42 -0
  41. data/lib/mail/fields/content_description_field.rb +8 -14
  42. data/lib/mail/fields/content_disposition_field.rb +20 -44
  43. data/lib/mail/fields/content_id_field.rb +25 -51
  44. data/lib/mail/fields/content_location_field.rb +12 -25
  45. data/lib/mail/fields/content_transfer_encoding_field.rb +31 -36
  46. data/lib/mail/fields/content_type_field.rb +51 -80
  47. data/lib/mail/fields/date_field.rb +24 -52
  48. data/lib/mail/fields/from_field.rb +29 -50
  49. data/lib/mail/fields/in_reply_to_field.rb +39 -49
  50. data/lib/mail/fields/keywords_field.rb +19 -32
  51. data/lib/mail/fields/message_id_field.rb +26 -71
  52. data/lib/mail/fields/mime_version_field.rb +20 -30
  53. data/lib/mail/fields/named_structured_field.rb +11 -0
  54. data/lib/mail/fields/named_unstructured_field.rb +11 -0
  55. data/lib/mail/fields/optional_field.rb +10 -7
  56. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +16 -13
  57. data/lib/mail/fields/received_field.rb +44 -57
  58. data/lib/mail/fields/references_field.rb +36 -49
  59. data/lib/mail/fields/reply_to_field.rb +29 -50
  60. data/lib/mail/fields/resent_bcc_field.rb +29 -50
  61. data/lib/mail/fields/resent_cc_field.rb +29 -50
  62. data/lib/mail/fields/resent_date_field.rb +6 -30
  63. data/lib/mail/fields/resent_from_field.rb +29 -50
  64. data/lib/mail/fields/resent_message_id_field.rb +6 -29
  65. data/lib/mail/fields/resent_sender_field.rb +28 -57
  66. data/lib/mail/fields/resent_to_field.rb +29 -50
  67. data/lib/mail/fields/return_path_field.rb +51 -55
  68. data/lib/mail/fields/sender_field.rb +35 -56
  69. data/lib/mail/fields/structured_field.rb +4 -30
  70. data/lib/mail/fields/subject_field.rb +10 -11
  71. data/lib/mail/fields/to_field.rb +29 -50
  72. data/lib/mail/fields/unstructured_field.rb +43 -51
  73. data/lib/mail/fields.rb +1 -0
  74. data/lib/mail/header.rb +78 -129
  75. data/lib/mail/indifferent_hash.rb +1 -0
  76. data/lib/mail/mail.rb +18 -11
  77. data/lib/mail/matchers/attachment_matchers.rb +44 -0
  78. data/lib/mail/matchers/has_sent_mail.rb +81 -4
  79. data/lib/mail/message.rb +142 -139
  80. data/lib/mail/multibyte/chars.rb +24 -180
  81. data/lib/mail/multibyte/unicode.rb +32 -27
  82. data/lib/mail/multibyte/utils.rb +27 -43
  83. data/lib/mail/multibyte.rb +56 -16
  84. data/lib/mail/network/delivery_methods/exim.rb +6 -4
  85. data/lib/mail/network/delivery_methods/file_delivery.rb +12 -10
  86. data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  87. data/lib/mail/network/delivery_methods/sendmail.rb +63 -21
  88. data/lib/mail/network/delivery_methods/smtp.rb +76 -50
  89. data/lib/mail/network/delivery_methods/smtp_connection.rb +4 -4
  90. data/lib/mail/network/delivery_methods/test_mailer.rb +5 -2
  91. data/lib/mail/network/retriever_methods/base.rb +9 -8
  92. data/lib/mail/network/retriever_methods/imap.rb +37 -18
  93. data/lib/mail/network/retriever_methods/pop3.rb +6 -3
  94. data/lib/mail/network/retriever_methods/test_retriever.rb +4 -2
  95. data/lib/mail/network.rb +2 -0
  96. data/lib/mail/parser_tools.rb +15 -0
  97. data/lib/mail/parsers/address_lists_parser.rb +33242 -0
  98. data/lib/mail/parsers/address_lists_parser.rl +179 -0
  99. data/lib/mail/parsers/content_disposition_parser.rb +901 -0
  100. data/lib/mail/parsers/content_disposition_parser.rl +89 -0
  101. data/lib/mail/parsers/content_location_parser.rb +822 -0
  102. data/lib/mail/parsers/content_location_parser.rl +78 -0
  103. data/lib/mail/parsers/content_transfer_encoding_parser.rb +522 -0
  104. data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
  105. data/lib/mail/parsers/content_type_parser.rb +1048 -0
  106. data/lib/mail/parsers/content_type_parser.rl +90 -0
  107. data/lib/mail/parsers/date_time_parser.rb +891 -0
  108. data/lib/mail/parsers/date_time_parser.rl +69 -0
  109. data/lib/mail/parsers/envelope_from_parser.rb +3675 -0
  110. data/lib/mail/parsers/envelope_from_parser.rl +89 -0
  111. data/lib/mail/parsers/message_ids_parser.rb +5161 -0
  112. data/lib/mail/parsers/message_ids_parser.rl +93 -0
  113. data/lib/mail/parsers/mime_version_parser.rb +513 -0
  114. data/lib/mail/parsers/mime_version_parser.rl +68 -0
  115. data/lib/mail/parsers/phrase_lists_parser.rb +884 -0
  116. data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
  117. data/lib/mail/parsers/received_parser.rb +8782 -0
  118. data/lib/mail/parsers/received_parser.rl +91 -0
  119. data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  120. data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  121. data/lib/mail/parsers/rfc2045_mime.rl +16 -0
  122. data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  123. data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  124. data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  125. data/lib/mail/parsers/rfc5322.rl +74 -0
  126. data/lib/mail/parsers/rfc5322_address.rl +72 -0
  127. data/lib/mail/parsers/rfc5322_date_time.rl +37 -0
  128. data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  129. data/lib/mail/parsers.rb +13 -0
  130. data/lib/mail/part.rb +11 -12
  131. data/lib/mail/parts_list.rb +90 -14
  132. data/lib/mail/smtp_envelope.rb +57 -0
  133. data/lib/mail/utilities.rb +415 -76
  134. data/lib/mail/values/unicode_tables.dat +0 -0
  135. data/lib/mail/version.rb +8 -15
  136. data/lib/mail/yaml.rb +30 -0
  137. data/lib/mail.rb +9 -32
  138. metadata +127 -79
  139. data/CHANGELOG.rdoc +0 -742
  140. data/CONTRIBUTING.md +0 -45
  141. data/Dependencies.txt +0 -3
  142. data/Gemfile +0 -32
  143. data/Rakefile +0 -21
  144. data/TODO.rdoc +0 -9
  145. data/lib/VERSION +0 -4
  146. data/lib/load_parsers.rb +0 -35
  147. data/lib/mail/core_extensions/nil.rb +0 -19
  148. data/lib/mail/core_extensions/object.rb +0 -13
  149. data/lib/mail/core_extensions/smtp.rb +0 -24
  150. data/lib/mail/core_extensions/string/access.rb +0 -145
  151. data/lib/mail/core_extensions/string/multibyte.rb +0 -78
  152. data/lib/mail/core_extensions/string.rb +0 -33
  153. data/lib/mail/fields/common/address_container.rb +0 -16
  154. data/lib/mail/fields/common/common_address.rb +0 -140
  155. data/lib/mail/fields/common/common_date.rb +0 -42
  156. data/lib/mail/fields/common/common_field.rb +0 -57
  157. data/lib/mail/fields/common/common_message_id.rb +0 -48
  158. data/lib/mail/multibyte/exceptions.rb +0 -8
  159. data/lib/mail/parsers/address_lists.rb +0 -64
  160. data/lib/mail/parsers/address_lists.treetop +0 -19
  161. data/lib/mail/parsers/content_disposition.rb +0 -535
  162. data/lib/mail/parsers/content_disposition.treetop +0 -46
  163. data/lib/mail/parsers/content_location.rb +0 -139
  164. data/lib/mail/parsers/content_location.treetop +0 -20
  165. data/lib/mail/parsers/content_transfer_encoding.rb +0 -201
  166. data/lib/mail/parsers/content_transfer_encoding.treetop +0 -18
  167. data/lib/mail/parsers/content_type.rb +0 -971
  168. data/lib/mail/parsers/content_type.treetop +0 -68
  169. data/lib/mail/parsers/date_time.rb +0 -114
  170. data/lib/mail/parsers/date_time.treetop +0 -11
  171. data/lib/mail/parsers/envelope_from.rb +0 -194
  172. data/lib/mail/parsers/envelope_from.treetop +0 -32
  173. data/lib/mail/parsers/message_ids.rb +0 -45
  174. data/lib/mail/parsers/message_ids.treetop +0 -15
  175. data/lib/mail/parsers/mime_version.rb +0 -144
  176. data/lib/mail/parsers/mime_version.treetop +0 -19
  177. data/lib/mail/parsers/phrase_lists.rb +0 -45
  178. data/lib/mail/parsers/phrase_lists.treetop +0 -15
  179. data/lib/mail/parsers/received.rb +0 -71
  180. data/lib/mail/parsers/received.treetop +0 -11
  181. data/lib/mail/parsers/rfc2045.rb +0 -421
  182. data/lib/mail/parsers/rfc2045.treetop +0 -35
  183. data/lib/mail/parsers/rfc2822.rb +0 -5397
  184. data/lib/mail/parsers/rfc2822.treetop +0 -408
  185. data/lib/mail/parsers/rfc2822_obsolete.rb +0 -3768
  186. data/lib/mail/parsers/rfc2822_obsolete.treetop +0 -241
  187. data/lib/mail/patterns.rb +0 -35
  188. data/lib/mail/version_specific/ruby_1_8.rb +0 -119
  189. data/lib/mail/version_specific/ruby_1_9.rb +0 -147
  190. data/lib/tasks/corpus.rake +0 -125
  191. data/lib/tasks/treetop.rake +0 -10
@@ -0,0 +1,170 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+
5
+ module Mail
6
+ class AddressContainer < Array #:nodoc:
7
+ def initialize(field, list = nil)
8
+ @field = field
9
+ super list if list
10
+ end
11
+
12
+ def <<(address)
13
+ @field << address
14
+ end
15
+ end
16
+
17
+ class CommonAddressField < NamedStructuredField #:nodoc:
18
+ def self.singular?
19
+ true
20
+ end
21
+
22
+ def initialize(value = nil, charset = nil)
23
+ super encode_if_needed(value, charset), charset
24
+ end
25
+
26
+ def element # :nodoc:
27
+ @element ||= AddressList.new(value)
28
+ end
29
+
30
+ # Allows you to iterate through each address object in the address_list
31
+ def each
32
+ element.addresses.each do |address|
33
+ yield(address)
34
+ end
35
+ end
36
+
37
+ def default
38
+ addresses
39
+ end
40
+
41
+ def address
42
+ addresses.first
43
+ end
44
+
45
+ # Returns the address string of all the addresses in the address list
46
+ def addresses
47
+ list = element.addresses.map { |a| a.address }
48
+ Mail::AddressContainer.new(self, list)
49
+ end
50
+
51
+ # Returns the formatted string of all the addresses in the address list
52
+ def formatted
53
+ list = element.addresses.map { |a| a.format }
54
+ Mail::AddressContainer.new(self, list)
55
+ end
56
+
57
+ # Returns the display name of all the addresses in the address list
58
+ def display_names
59
+ list = element.addresses.map { |a| a.display_name }
60
+ Mail::AddressContainer.new(self, list)
61
+ end
62
+
63
+ # Returns the actual address objects in the address list
64
+ def addrs
65
+ list = element.addresses
66
+ Mail::AddressContainer.new(self, list)
67
+ end
68
+
69
+ # Returns a hash of group name => address strings for the address list
70
+ def groups
71
+ element.addresses_grouped_by_group
72
+ end
73
+
74
+ # Returns the addresses that are part of groups
75
+ def group_addresses
76
+ decoded_group_addresses
77
+ end
78
+
79
+ # Returns a list of decoded group addresses
80
+ def decoded_group_addresses
81
+ groups.map { |k,v| v.map { |a| a.decoded } }.flatten
82
+ end
83
+
84
+ # Returns a list of encoded group addresses
85
+ def encoded_group_addresses
86
+ groups.map { |k,v| v.map { |a| a.encoded } }.flatten
87
+ end
88
+
89
+ # Returns the name of all the groups in a string
90
+ def group_names # :nodoc:
91
+ element.group_names
92
+ end
93
+
94
+ def <<(val)
95
+ case
96
+ when val.nil?
97
+ raise ArgumentError, "Need to pass an address to <<"
98
+ when Utilities.blank?(val)
99
+ self
100
+ else
101
+ self.value = [self.value, encode_if_needed(val)].reject { |a| Utilities.blank?(a) }.join(", ")
102
+ end
103
+ end
104
+
105
+ def encode_if_needed(val, val_charset = charset) #:nodoc:
106
+ case val
107
+ when nil
108
+ val
109
+
110
+ # Need to join arrays of addresses into a single value
111
+ when Array
112
+ val.compact.map { |a| encode_if_needed a, val_charset }.join(', ')
113
+
114
+ # Pass through UTF-8; encode non-UTF-8.
115
+ else
116
+ utf8_if_needed(val, val_charset) || Encodings.encode_non_usascii(val, val_charset)
117
+ end
118
+ end
119
+
120
+ private
121
+ if 'string'.respond_to?(:encoding)
122
+ # Pass through UTF-8 addresses
123
+ def utf8_if_needed(val, val_charset)
124
+ if val_charset =~ /\AUTF-?8\z/i
125
+ val
126
+ elsif val.encoding == Encoding::UTF_8
127
+ val
128
+ elsif (utf8 = val.dup.force_encoding(Encoding::UTF_8)).valid_encoding?
129
+ utf8
130
+ end
131
+ end
132
+ else
133
+ def utf8_if_needed(val, val_charset)
134
+ if val_charset =~ /\AUTF-?8\z/i
135
+ val
136
+ end
137
+ end
138
+ end
139
+
140
+ def do_encode
141
+ return '' if Utilities.blank?(value)
142
+ address_array = element.addresses.reject { |a| encoded_group_addresses.include?(a.encoded) }.compact.map { |a| a.encoded }
143
+ address_text = address_array.join(", \r\n\s")
144
+ group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.encoded }.join(", \r\n\s")};" }
145
+ group_text = group_array.join(" \r\n\s")
146
+ return_array = [address_text, group_text].reject { |a| Utilities.blank?(a) }
147
+ "#{name}: #{return_array.join(", \r\n\s")}\r\n"
148
+ end
149
+
150
+ def do_decode
151
+ return nil if Utilities.blank?(value)
152
+ address_array = element.addresses.reject { |a| decoded_group_addresses.include?(a.decoded) }.map { |a| a.decoded }
153
+ address_text = address_array.join(", ")
154
+ group_array = groups.map { |k,v| "#{k}: #{v.map { |a| a.decoded }.join(", ")};" }
155
+ group_text = group_array.join(" ")
156
+ return_array = [address_text, group_text].reject { |a| Utilities.blank?(a) }
157
+ return_array.join(", ")
158
+ end
159
+
160
+ def get_group_addresses(group_list)
161
+ if group_list.respond_to?(:addresses)
162
+ group_list.addresses.map do |address|
163
+ Mail::Address.new(address)
164
+ end
165
+ else
166
+ []
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,58 @@
1
+ require 'mail/fields/named_structured_field'
2
+ require 'mail/elements/date_time_element'
3
+ require 'mail/utilities'
4
+
5
+ module Mail
6
+ class CommonDateField < NamedStructuredField #:nodoc:
7
+ def self.singular?
8
+ true
9
+ end
10
+
11
+ def self.normalize_datetime(string)
12
+ if Utilities.blank?(string)
13
+ datetime = ::DateTime.now
14
+ else
15
+ stripped = string.to_s.gsub(/\(.*?\)/, '').squeeze(' ')
16
+ begin
17
+ datetime = ::DateTime.parse(stripped)
18
+ rescue ArgumentError => e
19
+ raise unless 'invalid date' == e.message
20
+ end
21
+ end
22
+
23
+ if datetime
24
+ datetime.strftime('%a, %d %b %Y %H:%M:%S %z')
25
+ else
26
+ string
27
+ end
28
+ end
29
+
30
+ def initialize(value = nil, charset = nil)
31
+ super self.class.normalize_datetime(value), charset
32
+ end
33
+
34
+ # Returns a date time object of the parsed date
35
+ def date_time
36
+ ::DateTime.parse("#{element.date_string} #{element.time_string}")
37
+ rescue ArgumentError => e
38
+ raise e unless e.message == 'invalid date'
39
+ end
40
+
41
+ def default
42
+ date_time
43
+ end
44
+
45
+ def element
46
+ @element ||= Mail::DateTimeElement.new(value)
47
+ end
48
+
49
+ private
50
+ def do_encode
51
+ "#{name}: #{value}\r\n"
52
+ end
53
+
54
+ def do_decode
55
+ value.to_s
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/constants'
4
+
5
+ module Mail
6
+ class CommonField #:nodoc:
7
+ def self.singular?
8
+ false
9
+ end
10
+
11
+ def self.parse(*args)
12
+ new(*args).tap(&:parse)
13
+ end
14
+
15
+ attr_accessor :name
16
+ attr_reader :value
17
+ attr_accessor :charset
18
+ attr_reader :errors
19
+
20
+ def initialize(name = nil, value = nil, charset = nil)
21
+ @errors = []
22
+
23
+ self.name = name
24
+ self.value = value
25
+ self.charset = charset || 'utf-8'
26
+ end
27
+
28
+ def singular?
29
+ self.class.singular?
30
+ end
31
+
32
+ def value=(value)
33
+ @element = nil
34
+ @value = value.is_a?(Array) ? value : value.to_s
35
+ parse
36
+ end
37
+
38
+ def parse
39
+ tap(&:element)
40
+ end
41
+
42
+ def element
43
+ nil
44
+ end
45
+
46
+ def to_s
47
+ decoded.to_s
48
+ end
49
+
50
+ def default
51
+ decoded
52
+ end
53
+
54
+ def decoded
55
+ do_decode
56
+ end
57
+
58
+ def encoded
59
+ do_encode
60
+ end
61
+
62
+ def responsible_for?(field_name)
63
+ name.to_s.casecmp(field_name.to_s) == 0
64
+ end
65
+
66
+ private
67
+
68
+ FILENAME_RE = /\b(filename|name)=([^;"\r\n]+\s[^;"\r\n]+)/
69
+ def ensure_filename_quoted(value)
70
+ if value.is_a?(String)
71
+ value.sub FILENAME_RE, '\1="\2"'
72
+ else
73
+ value
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/utilities'
5
+
6
+ module Mail
7
+ class CommonMessageIdField < NamedStructuredField #:nodoc:
8
+ def element
9
+ @element ||= Mail::MessageIdsElement.new(value)
10
+ end
11
+
12
+ def message_id
13
+ element.message_id
14
+ end
15
+
16
+ def message_ids
17
+ element.message_ids
18
+ end
19
+
20
+ def default
21
+ ids = message_ids
22
+ ids.one? ? ids.first : ids
23
+ end
24
+
25
+ def to_s
26
+ decoded.to_s
27
+ end
28
+
29
+ private
30
+ def do_encode
31
+ %Q{#{name}: #{formatted_message_ids("\r\n ")}\r\n}
32
+ end
33
+
34
+ def do_decode
35
+ formatted_message_ids
36
+ end
37
+
38
+ def formatted_message_ids(join = ' ')
39
+ message_ids.map { |m| "<#{m}>" }.join(join) if message_ids.any?
40
+ end
41
+ end
42
+ end
@@ -1,19 +1,13 @@
1
1
  # encoding: utf-8
2
- #
3
- #
4
- #
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_unstructured_field'
4
+
5
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
6
+ class ContentDescriptionField < NamedUnstructuredField #:nodoc:
7
+ NAME = 'Content-Description'
8
+
9
+ def self.singular?
10
+ true
16
11
  end
17
-
18
12
  end
19
13
  end
@@ -1,26 +1,20 @@
1
1
  # encoding: utf-8
2
- require 'mail/fields/common/parameter_hash'
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/fields/parameter_hash'
3
5
 
4
6
  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
- ensure_filename_quoted(value)
13
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
14
- self.parse
15
- self
7
+ class ContentDispositionField < NamedStructuredField #:nodoc:
8
+ NAME = 'Content-Disposition'
9
+
10
+ def self.singular?
11
+ true
16
12
  end
17
-
18
- def parse(val = value)
19
- unless val.blank?
20
- @element = Mail::ContentDispositionElement.new(val)
21
- end
13
+
14
+ def initialize(value = nil, charset = nil)
15
+ super ensure_filename_quoted(value), charset
22
16
  end
23
-
17
+
24
18
  def element
25
19
  @element ||= Mail::ContentDispositionElement.new(value)
26
20
  end
@@ -28,43 +22,25 @@ module Mail
28
22
  def disposition_type
29
23
  element.disposition_type
30
24
  end
31
-
25
+
32
26
  def parameters
33
27
  @parameters = ParameterHash.new
34
- element.parameters.each { |p| @parameters.merge!(p) }
28
+ element.parameters.each { |p| @parameters.merge!(p) } unless element.parameters.nil?
35
29
  @parameters
36
30
  end
37
31
 
38
32
  def filename
39
- case
40
- when !parameters['filename'].blank?
41
- @filename = parameters['filename']
42
- when !parameters['name'].blank?
43
- @filename = parameters['name']
44
- else
45
- @filename = nil
46
- end
47
- @filename
33
+ @filename ||= parameters['filename'] || parameters['name']
48
34
  end
49
35
 
50
- # TODO: Fix this up
51
36
  def encoded
52
- if parameters.length > 0
53
- p = ";\r\n\s#{parameters.encoded}\r\n"
54
- else
55
- p = "\r\n"
56
- end
57
- "#{CAPITALIZED_FIELD}: #{disposition_type}" + p
37
+ p = ";\r\n\s#{parameters.encoded}" if parameters.length > 0
38
+ "#{name}: #{disposition_type}#{p}\r\n"
58
39
  end
59
-
40
+
60
41
  def decoded
61
- if parameters.length > 0
62
- p = "; #{parameters.decoded}"
63
- else
64
- p = ""
65
- end
66
- "#{disposition_type}" + p
42
+ p = "; #{parameters.decoded}" if parameters.length > 0
43
+ "#{disposition_type}#{p}"
67
44
  end
68
-
69
45
  end
70
46
  end
@@ -1,62 +1,36 @@
1
1
  # encoding: utf-8
2
- #
3
- #
4
- #
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+ require 'mail/utilities'
5
+
5
6
  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
-
7
+ class ContentIdField < NamedStructuredField #:nodoc:
8
+ NAME = 'Content-ID'
9
+
10
+ def self.singular?
11
+ true
12
+ end
13
+
14
+ def initialize(value = nil, charset = nil)
15
+ value = Mail::Utilities.generate_message_id if Utilities.blank?(value)
16
+ super value, charset
17
+ end
18
+
30
19
  def element
31
20
  @element ||= Mail::MessageIdsElement.new(value)
32
21
  end
33
-
34
- def name
35
- 'Content-ID'
36
- end
37
-
22
+
38
23
  def content_id
39
24
  element.message_id
40
25
  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
-
26
+
55
27
  private
56
-
57
- def generate_content_id
58
- "<#{Mail.random_tag}@#{::Socket.gethostname}.mail>"
59
- end
60
-
28
+ def do_decode
29
+ "<#{content_id}>"
30
+ end
31
+
32
+ def do_encode
33
+ "#{name}: #{do_decode}\r\n"
34
+ end
61
35
  end
62
36
  end
@@ -1,26 +1,15 @@
1
1
  # encoding: utf-8
2
- #
3
- #
4
- #
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+
5
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
6
+ class ContentLocationField < NamedStructuredField #:nodoc:
7
+ NAME = 'Content-Location'
8
+
9
+ def self.singular?
10
+ true
22
11
  end
23
-
12
+
24
13
  def element
25
14
  @element ||= Mail::ContentLocationElement.new(value)
26
15
  end
@@ -29,14 +18,12 @@ module Mail
29
18
  element.location
30
19
  end
31
20
 
32
- # TODO: Fix this up
33
21
  def encoded
34
- "#{CAPITALIZED_FIELD}: #{location}\r\n"
22
+ "#{name}: #{location}\r\n"
35
23
  end
36
-
24
+
37
25
  def decoded
38
- location
26
+ location
39
27
  end
40
-
41
28
  end
42
29
  end
@@ -1,50 +1,45 @@
1
1
  # encoding: utf-8
2
- #
3
- #
4
- #
2
+ # frozen_string_literal: true
3
+ require 'mail/fields/named_structured_field'
4
+
5
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-?bits?/i
14
- value = '8bit' if value.to_s =~ /8-?bits?/i
15
- super(CAPITALIZED_FIELD, strip_field(FIELD_NAME, value), charset)
16
- self.parse
17
- self
6
+ class ContentTransferEncodingField < NamedStructuredField #:nodoc:
7
+ NAME = 'Content-Transfer-Encoding'
8
+
9
+ def self.singular?
10
+ true
18
11
  end
19
-
20
- def parse(val = value)
21
- unless val.blank?
22
- @element = Mail::ContentTransferEncodingElement.new(val)
12
+
13
+ def self.normalize_content_transfer_encoding(value)
14
+ case value
15
+ when /7-?bits?/i
16
+ '7bit'
17
+ when /8-?bits?/i
18
+ '8bit'
19
+ else
20
+ value
23
21
  end
24
22
  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
23
+
24
+ def initialize(value = nil, charset = nil)
25
+ super self.class.normalize_content_transfer_encoding(value), charset
30
26
  end
31
-
27
+
32
28
  def element
33
29
  @element ||= Mail::ContentTransferEncodingElement.new(value)
34
30
  end
35
-
31
+
36
32
  def encoding
37
33
  element.encoding
38
34
  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
-
35
+
36
+ private
37
+ def do_encode
38
+ "#{name}: #{encoding}\r\n"
39
+ end
40
+
41
+ def do_decode
42
+ encoding
43
+ end
49
44
  end
50
45
  end