mime-types 1.25.1 → 2.0

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 (61) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.autotest +5 -0
  5. data/.minitest.rb +2 -0
  6. data/.travis.yml +0 -4
  7. data/Contributing.rdoc +13 -14
  8. data/Gemfile +1 -0
  9. data/History.rdoc +100 -7
  10. data/Licence.rdoc +1 -1
  11. data/Manifest.txt +17 -24
  12. data/README.rdoc +26 -47
  13. data/Rakefile +42 -185
  14. data/data/mime-types.json +1 -0
  15. data/docs/COPYING.txt +339 -339
  16. data/docs/artistic.txt +127 -127
  17. data/lib/mime.rb +50 -0
  18. data/lib/mime/type.rb +634 -0
  19. data/lib/mime/types.rb +254 -912
  20. data/lib/mime/types/cache.rb +73 -0
  21. data/lib/mime/types/loader.rb +248 -0
  22. data/lib/mime/types/loader_path.rb +16 -0
  23. data/support/benchmarker.rb +55 -0
  24. data/support/convert.rb +130 -0
  25. data/support/iana_downloader.rb +201 -0
  26. data/test/fixture/json.json +1 -0
  27. data/test/fixture/old-data +9 -0
  28. data/test/fixture/yaml.yaml +75 -0
  29. data/test/minitest_helper.rb +22 -0
  30. data/test/test_mime_type.rb +337 -143
  31. data/test/test_mime_types.rb +75 -84
  32. data/test/test_mime_types_cache.rb +30 -29
  33. data/test/test_mime_types_class.rb +135 -0
  34. data/test/test_mime_types_lazy.rb +3 -2
  35. data/test/test_mime_types_loader.rb +42 -0
  36. metadata +61 -90
  37. metadata.gz.sig +0 -0
  38. data/lib/mime/types/application +0 -1010
  39. data/lib/mime/types/application.mac +0 -3
  40. data/lib/mime/types/application.nonstandard +0 -132
  41. data/lib/mime/types/application.obsolete +0 -41
  42. data/lib/mime/types/audio +0 -138
  43. data/lib/mime/types/audio.nonstandard +0 -11
  44. data/lib/mime/types/audio.obsolete +0 -1
  45. data/lib/mime/types/image +0 -46
  46. data/lib/mime/types/image.nonstandard +0 -20
  47. data/lib/mime/types/image.obsolete +0 -5
  48. data/lib/mime/types/message +0 -18
  49. data/lib/mime/types/message.obsolete +0 -2
  50. data/lib/mime/types/model +0 -15
  51. data/lib/mime/types/multipart +0 -14
  52. data/lib/mime/types/multipart.nonstandard +0 -1
  53. data/lib/mime/types/multipart.obsolete +0 -7
  54. data/lib/mime/types/other.nonstandard +0 -8
  55. data/lib/mime/types/text +0 -61
  56. data/lib/mime/types/text.nonstandard +0 -7
  57. data/lib/mime/types/text.obsolete +0 -8
  58. data/lib/mime/types/text.vms +0 -1
  59. data/lib/mime/types/video +0 -75
  60. data/lib/mime/types/video.nonstandard +0 -16
  61. data/lib/mime/types/video.obsolete +0 -3
@@ -1,968 +1,310 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
 
3
- # The namespace for MIME applications, tools, and libraries.
4
- module MIME
5
- # Reflects a MIME Content-Type which is in invalid format (e.g., it isn't
6
- # in the form of type/subtype).
7
- class InvalidContentType < RuntimeError; end
8
-
9
- # The definition of one MIME content-type.
10
- #
11
- # == Usage
12
- # require 'mime/types'
13
- #
14
- # plaintext = MIME::Types['text/plain'].first
15
- # # returns [text/plain, text/plain]
16
- # text = plaintext.first
17
- # print text.media_type # => 'text'
18
- # print text.sub_type # => 'plain'
19
- #
20
- # puts text.extensions.join(" ") # => 'asc txt c cc h hh cpp'
21
- #
22
- # puts text.encoding # => 8bit
23
- # puts text.binary? # => false
24
- # puts text.ascii? # => true
25
- # puts text == 'text/plain' # => true
26
- # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
27
- #
28
- # puts MIME::Types.any? { |type|
29
- # type.content_type == 'text/plain'
30
- # } # => true
31
- # puts MIME::Types.all?(&:registered?)
32
- # # => false
33
- #
34
- class Type
35
- # The released version of Ruby MIME::Types
36
- VERSION = '1.25.1'
37
-
38
- include Comparable
39
-
40
- MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}o
41
- UNREG_RE = %r{[Xx]-}o
42
- ENCODING_RE = %r{(?:base64|7bit|8bit|quoted\-printable)}o
43
- PLATFORM_RE = %r|#{RUBY_PLATFORM}|o
44
-
45
- SIGNATURES = %w(application/pgp-keys application/pgp
46
- application/pgp-signature application/pkcs10
47
- application/pkcs7-mime application/pkcs7-signature
48
- text/vcard)
49
-
50
- IANA_URL = "http://www.iana.org/assignments/media-types/%s/%s"
51
- RFC_URL = "http://rfc-editor.org/rfc/rfc%s.txt"
52
- DRAFT_URL = "http://datatracker.ietf.org/public/idindex.cgi?command=id_details&filename=%s"
53
- LTSW_URL = "http://www.ltsw.se/knbase/internet/%s.htp"
54
- CONTACT_URL = "http://www.iana.org/assignments/contact-people.htm#%s"
55
-
56
- # Returns +true+ if the simplified type matches the current
57
- def like?(other)
58
- if other.respond_to?(:simplified)
59
- @simplified == other.simplified
60
- else
61
- @simplified == Type.simplified(other)
62
- end
63
- end
64
-
65
- # Compares the MIME::Type against the exact content type or the
66
- # simplified type (the simplified type will be used if comparing against
67
- # something that can be treated as a String with #to_s). In comparisons,
68
- # this is done against the lowercase version of the MIME::Type.
69
- def <=>(other)
70
- if other.respond_to?(:content_type)
71
- @content_type.downcase <=> other.content_type.downcase
72
- elsif other.respond_to?(:to_s)
73
- @simplified <=> Type.simplified(other.to_s)
74
- else
75
- @content_type.downcase <=> other.downcase
76
- end
77
- end
78
-
79
- # Compares the MIME::Type based on how reliable it is before doing a
80
- # normal <=> comparison. Used by MIME::Types#[] to sort types. The
81
- # comparisons involved are:
82
- #
83
- # 1. self.simplified <=> other.simplified (ensures that we
84
- # don't try to compare different types)
85
- # 2. IANA-registered definitions < other definitions.
86
- # 3. Generic definitions < platform definitions.
87
- # 3. Complete definitions < incomplete definitions.
88
- # 4. Current definitions < obsolete definitions.
89
- # 5. Obselete with use-instead references < obsolete without.
90
- # 6. Obsolete use-instead definitions are compared.
91
- def priority_compare(other)
92
- pc = simplified <=> other.simplified
93
-
94
- if pc.zero?
95
- pc = if registered? != other.registered?
96
- registered? ? -1 : 1 # registered < unregistered
97
- elsif platform? != other.platform?
98
- platform? ? 1 : -1 # generic < platform
99
- elsif complete? != other.complete?
100
- complete? ? -1 : 1 # complete < incomplete
101
- elsif obsolete? != other.obsolete?
102
- obsolete? ? 1 : -1 # current < obsolete
103
- else
104
- 0
105
- end
106
-
107
- if pc.zero? and obsolete? and (use_instead != other.use_instead)
108
- pc = if use_instead.nil?
109
- -1
110
- elsif other.use_instead.nil?
111
- 1
112
- else
113
- use_instead <=> other.use_instead
114
- end
115
- end
116
- end
117
-
118
- pc
119
- end
120
-
121
- # Returns +true+ if the other object is a MIME::Type and the content
122
- # types match.
123
- def eql?(other)
124
- other.kind_of?(MIME::Type) and self == other
125
- end
126
-
127
- # Returns the whole MIME content-type string.
128
- #
129
- # text/plain => text/plain
130
- # x-chemical/x-pdb => x-chemical/x-pdb
131
- attr_reader :content_type
132
- # Returns the media type of the simplified MIME type.
133
- #
134
- # text/plain => text
135
- # x-chemical/x-pdb => chemical
136
- attr_reader :media_type
137
- # Returns the media type of the unmodified MIME type.
138
- #
139
- # text/plain => text
140
- # x-chemical/x-pdb => x-chemical
141
- attr_reader :raw_media_type
142
- # Returns the sub-type of the simplified MIME type.
143
- #
144
- # text/plain => plain
145
- # x-chemical/x-pdb => pdb
146
- attr_reader :sub_type
147
- # Returns the media type of the unmodified MIME type.
148
- #
149
- # text/plain => plain
150
- # x-chemical/x-pdb => x-pdb
151
- attr_reader :raw_sub_type
152
- # The MIME types main- and sub-label can both start with <tt>x-</tt>,
153
- # which indicates that it is a non-registered name. Of course, after
154
- # registration this flag can disappear, adds to the confusing
155
- # proliferation of MIME types. The simplified string has the <tt>x-</tt>
156
- # removed and are translated to lowercase.
157
- #
158
- # text/plain => text/plain
159
- # x-chemical/x-pdb => chemical/pdb
160
- attr_reader :simplified
161
- # The list of extensions which are known to be used for this MIME::Type.
162
- # Non-array values will be coerced into an array with #to_a. Array
163
- # values will be flattened and +nil+ values removed.
164
- attr_accessor :extensions
165
- remove_method :extensions= ;
166
- def extensions=(ext) #:nodoc:
167
- @extensions = [ext].flatten.compact
168
- end
169
-
170
- # The encoding (7bit, 8bit, quoted-printable, or base64) required to
171
- # transport the data of this content type safely across a network, which
172
- # roughly corresponds to Content-Transfer-Encoding. A value of +nil+ or
173
- # <tt>:default</tt> will reset the #encoding to the #default_encoding
174
- # for the MIME::Type. Raises ArgumentError if the encoding provided is
175
- # invalid.
176
- #
177
- # If the encoding is not provided on construction, this will be either
178
- # 'quoted-printable' (for text/* media types) and 'base64' for eveything
179
- # else.
180
- attr_accessor :encoding
181
- remove_method :encoding= ;
182
- def encoding=(enc) #:nodoc:
183
- if enc.nil? or enc == :default
184
- @encoding = self.default_encoding
185
- elsif enc =~ ENCODING_RE
186
- @encoding = enc
187
- else
188
- raise ArgumentError, "The encoding must be nil, :default, base64, 7bit, 8bit, or quoted-printable."
189
- end
190
- end
191
-
192
- # The regexp for the operating system that this MIME::Type is specific
193
- # to.
194
- attr_accessor :system
195
- remove_method :system= ;
196
- def system=(os) #:nodoc:
197
- if os.nil? or os.kind_of?(Regexp)
198
- @system = os
199
- else
200
- @system = %r|#{os}|
201
- end
202
- end
203
- # Returns the default encoding for the MIME::Type based on the media
204
- # type.
205
- attr_reader :default_encoding
206
- remove_method :default_encoding
207
- def default_encoding
208
- (@media_type == 'text') ? 'quoted-printable' : 'base64'
209
- end
210
-
211
- # Returns the media type or types that should be used instead of this
212
- # media type, if it is obsolete. If there is no replacement media type,
213
- # or it is not obsolete, +nil+ will be returned.
214
- attr_reader :use_instead
215
- remove_method :use_instead
216
- def use_instead
217
- return nil unless @obsolete
218
- @use_instead
219
- end
220
-
221
- # Returns +true+ if the media type is obsolete.
222
- def obsolete?
223
- @obsolete ? true : false
224
- end
225
- # Sets the obsolescence indicator for this media type.
226
- attr_writer :obsolete
227
-
228
- # The documentation for this MIME::Type. Documentation about media
229
- # types will be found on a media type definition as a comment.
230
- # Documentation will be found through #docs.
231
- attr_accessor :docs
232
- remove_method :docs= ;
233
- def docs=(d)
234
- if d
235
- a = d.scan(%r{use-instead:#{MEDIA_TYPE_RE}})
236
-
237
- if a.empty?
238
- @use_instead = nil
239
- else
240
- @use_instead = a.map { |el| "#{el[0]}/#{el[1]}" }
241
- end
242
- end
243
- @docs = d
244
- end
245
-
246
- # The encoded URL list for this MIME::Type. See #urls for more
247
- # information.
248
- attr_accessor :url
249
- # The decoded URL list for this MIME::Type.
250
- # The special URL value IANA will be translated into:
251
- # http://www.iana.org/assignments/media-types/<mediatype>/<subtype>
252
- #
253
- # The special URL value RFC### will be translated into:
254
- # http://www.rfc-editor.org/rfc/rfc###.txt
255
- #
256
- # The special URL value DRAFT:name will be translated into:
257
- # https://datatracker.ietf.org/public/idindex.cgi?
258
- # command=id_detail&filename=<name>
259
- #
260
- # The special URL value LTSW will be translated into:
261
- # http://www.ltsw.se/knbase/internet/<mediatype>.htp
262
- #
263
- # The special URL value [token] will be translated into:
264
- # http://www.iana.org/assignments/contact-people.htm#<token>
265
- #
266
- # These values will be accessible through #urls, which always returns an
267
- # array.
268
- def urls
269
- @url.map do |el|
270
- case el
271
- when %r{^IANA$}
272
- IANA_URL % [ @media_type, @sub_type ]
273
- when %r{^RFC(\d+)$}
274
- RFC_URL % $1
275
- when %r{^DRAFT:(.+)$}
276
- DRAFT_URL % $1
277
- when %r{^LTSW$}
278
- LTSW_URL % @media_type
279
- when %r{^\{([^=]+)=([^\}]+)\}}
280
- [$1, $2]
281
- when %r{^\[([^=]+)=([^\]]+)\]}
282
- [$1, CONTACT_URL % $2]
283
- when %r{^\[([^\]]+)\]}
284
- CONTACT_URL % $1
285
- else
286
- el
287
- end
288
- end
289
- end
290
-
291
- class << self
292
- # The MIME types main- and sub-label can both start with <tt>x-</tt>,
293
- # which indicates that it is a non-registered name. Of course, after
294
- # registration this flag can disappear, adds to the confusing
295
- # proliferation of MIME types. The simplified string has the
296
- # <tt>x-</tt> removed and are translated to lowercase.
297
- def simplified(content_type)
298
- matchdata = MEDIA_TYPE_RE.match(content_type)
299
-
300
- if matchdata.nil?
301
- simplified = nil
302
- else
303
- media_type = matchdata.captures[0].downcase.gsub(UNREG_RE, '')
304
- subtype = matchdata.captures[1].downcase.gsub(UNREG_RE, '')
305
- simplified = "#{media_type}/#{subtype}"
306
- end
307
- simplified
308
- end
309
-
310
- # Creates a MIME::Type from an array in the form of:
311
- # [type-name, [extensions], encoding, system]
312
- #
313
- # +extensions+, +encoding+, and +system+ are optional.
314
- #
315
- # MIME::Type.from_array("application/x-ruby", ['rb'], '8bit')
316
- # MIME::Type.from_array(["application/x-ruby", ['rb'], '8bit'])
317
- #
318
- # These are equivalent to:
319
- #
320
- # MIME::Type.new('application/x-ruby') do |t|
321
- # t.extensions = %w(rb)
322
- # t.encoding = '8bit'
323
- # end
324
- def from_array(*args) #:yields MIME::Type.new:
325
- # Dereferences the array one level, if necessary.
326
- args = args.first if args.first.kind_of? Array
327
-
328
- unless args.size.between?(1, 8)
329
- raise ArgumentError, "Array provided must contain between one and eight elements."
330
- end
331
-
332
- MIME::Type.new(args.shift) do |t|
333
- t.extensions, t.encoding, t.system, t.obsolete, t.docs, t.url,
334
- t.registered = *args
335
- yield t if block_given?
336
- end
337
- end
338
-
339
- # Creates a MIME::Type from a hash. Keys are case-insensitive,
340
- # dashes may be replaced with underscores, and the internal Symbol
341
- # of the lowercase-underscore version can be used as well. That is,
342
- # Content-Type can be provided as content-type, Content_Type,
343
- # content_type, or :content_type.
344
- #
345
- # Known keys are <tt>Content-Type</tt>,
346
- # <tt>Content-Transfer-Encoding</tt>, <tt>Extensions</tt>, and
347
- # <tt>System</tt>.
348
- #
349
- # MIME::Type.from_hash('Content-Type' => 'text/x-yaml',
350
- # 'Content-Transfer-Encoding' => '8bit',
351
- # 'System' => 'linux',
352
- # 'Extensions' => ['yaml', 'yml'])
353
- #
354
- # This is equivalent to:
355
- #
356
- # MIME::Type.new('text/x-yaml') do |t|
357
- # t.encoding = '8bit'
358
- # t.system = 'linux'
359
- # t.extensions = ['yaml', 'yml']
360
- # end
361
- def from_hash(hash) #:yields MIME::Type.new:
362
- type = {}
363
- hash.each_pair do |k, v|
364
- type[k.to_s.tr('A-Z', 'a-z').gsub(/-/, '_').to_sym] = v
365
- end
366
-
367
- MIME::Type.new(type[:content_type]) do |t|
368
- t.extensions = type[:extensions]
369
- t.encoding = type[:content_transfer_encoding]
370
- t.system = type[:system]
371
- t.obsolete = type[:obsolete]
372
- t.docs = type[:docs]
373
- t.url = type[:url]
374
- t.registered = type[:registered]
375
-
376
- yield t if block_given?
377
- end
378
- end
379
-
380
- # Essentially a copy constructor.
381
- #
382
- # MIME::Type.from_mime_type(plaintext)
383
- #
384
- # is equivalent to:
385
- #
386
- # MIME::Type.new(plaintext.content_type.dup) do |t|
387
- # t.extensions = plaintext.extensions.dup
388
- # t.system = plaintext.system.dup
389
- # t.encoding = plaintext.encoding.dup
390
- # end
391
- def from_mime_type(mime_type) #:yields the new MIME::Type:
392
- MIME::Type.new(mime_type.content_type.dup) do |t|
393
- t.extensions = mime_type.extensions.map { |e| e.dup }
394
- t.url = mime_type.url && mime_type.url.map { |e| e.dup }
395
-
396
- mime_type.system && t.system = mime_type.system.dup
397
- mime_type.encoding && t.encoding = mime_type.encoding.dup
398
-
399
- t.obsolete = mime_type.obsolete?
400
- t.registered = mime_type.registered?
401
-
402
- mime_type.docs && t.docs = mime_type.docs.dup
403
-
404
- yield t if block_given?
405
- end
406
- end
407
- end
408
-
409
- # Builds a MIME::Type object from the provided MIME Content Type value
410
- # (e.g., 'text/plain' or 'applicaton/x-eruby'). The constructed object
411
- # is yielded to an optional block for additional configuration, such as
412
- # associating extensions and encoding information.
413
- def initialize(content_type) #:yields self:
414
- matchdata = MEDIA_TYPE_RE.match(content_type)
415
-
416
- if matchdata.nil?
417
- raise InvalidContentType, "Invalid Content-Type provided ('#{content_type}')"
418
- end
419
-
420
- @content_type = content_type
421
- @raw_media_type = matchdata.captures[0]
422
- @raw_sub_type = matchdata.captures[1]
423
-
424
- @simplified = MIME::Type.simplified(@content_type)
425
- matchdata = MEDIA_TYPE_RE.match(@simplified)
426
- @media_type = matchdata.captures[0]
427
- @sub_type = matchdata.captures[1]
428
-
429
- self.extensions = nil
430
- self.encoding = :default
431
- self.system = nil
432
- self.registered = true
433
- self.url = nil
434
- self.obsolete = nil
435
- self.docs = nil
436
-
437
- yield self if block_given?
438
- end
439
-
440
- # MIME content-types which are not regestered by IANA nor defined in
441
- # RFCs are required to start with <tt>x-</tt>. This counts as well for
442
- # a new media type as well as a new sub-type of an existing media
443
- # type. If either the media-type or the content-type begins with
444
- # <tt>x-</tt>, this method will return +false+.
445
- def registered?
446
- if (@raw_media_type =~ UNREG_RE) || (@raw_sub_type =~ UNREG_RE)
447
- false
448
- else
449
- @registered
450
- end
451
- end
452
- attr_writer :registered #:nodoc:
453
-
454
- # MIME types can be specified to be sent across a network in particular
455
- # formats. This method returns +true+ when the MIME type encoding is set
456
- # to <tt>base64</tt>.
457
- def binary?
458
- @encoding == 'base64'
459
- end
460
-
461
- # MIME types can be specified to be sent across a network in particular
462
- # formats. This method returns +false+ when the MIME type encoding is
463
- # set to <tt>base64</tt>.
464
- def ascii?
465
- not binary?
466
- end
467
-
468
- # Returns +true+ when the simplified MIME type is in the list of known
469
- # digital signatures.
470
- def signature?
471
- SIGNATURES.include?(@simplified.downcase)
472
- end
473
-
474
- # Returns +true+ if the MIME::Type is specific to an operating system.
475
- def system?
476
- not @system.nil?
477
- end
478
-
479
- # Returns +true+ if the MIME::Type is specific to the current operating
480
- # system as represented by RUBY_PLATFORM.
481
- def platform?
482
- system? and (RUBY_PLATFORM =~ @system)
483
- end
3
+ require 'mime/type'
4
+ require 'mime/types/cache'
5
+ require 'mime/types/loader'
6
+
7
+ # MIME::Types is a registry of MIME types. It is both a class (created with
8
+ # MIME::Types.new) and a default registry (loaded automatically or through
9
+ # interactions with MIME::Types.[] and MIME::Types.type_for).
10
+ #
11
+ # == The Default mime-types Registry
12
+ #
13
+ # The default mime-types registry is loaded automatically when the library
14
+ # is required (<tt>require 'mime/types'</tt>), but it may be lazily loaded
15
+ # (loaded on first use) with the use of the environment variable
16
+ # +RUBY_MIME_TYPES_LAZY_LOAD+ having any value other than +false+. The
17
+ # initial startup is about 14× faster (~10 ms vs ~140 ms), but the
18
+ # registry will be loaded at some point in the future.
19
+ #
20
+ # The default mime-types registry can also be loaded from a Marshal cache
21
+ # file specific to the version of MIME::Types being loaded. This will be
22
+ # handled automatically with the use of a file referred to in the
23
+ # environment variable +RUBY_MIME_TYPES_CACHE+. MIME::Types will attempt to
24
+ # load the registry from this cache file (MIME::Type::Cache.load); if it
25
+ # cannot be loaded (because the file does not exist, there is an error, or
26
+ # the data is for a different version of mime-types), the default registry
27
+ # will be loaded from the normal JSON version and then the cache file will
28
+ # be *written* to the location indicated by +RUBY_MIME_TYPES_CACHE+. Cache
29
+ # file loads just over 4½× faster (~30 ms vs ~140 ms).
30
+ # loads.
31
+ #
32
+ # Notes:
33
+ # * The loading of the default registry is *not* atomic; when using a
34
+ # multi-threaded environment, it is recommended that lazy loading is not
35
+ # used and mime-types is loaded as early as possible.
36
+ # * Cache files should be specified per application in a multiprocess
37
+ # environment and should be initialized during deployment or before
38
+ # forking to minimize the chance that the multiple processes will be
39
+ # trying to write to the same cache file at the same time, or that two
40
+ # applications that are on different versions of mime-types would be
41
+ # thrashing the cache.
42
+ # * Unless cache files are preinitialized, the application using the
43
+ # mime-types cache file must have read/write permission to the cache file.
44
+ #
45
+ # == Usage
46
+ # require 'mime/types'
47
+ #
48
+ # plaintext = MIME::Types['text/plain']
49
+ # print plaintext.media_type # => 'text'
50
+ # print plaintext.sub_type # => 'plain'
51
+ #
52
+ # puts plaintext.extensions.join(" ") # => 'asc txt c cc h hh cpp'
53
+ #
54
+ # puts plaintext.encoding # => 8bit
55
+ # puts plaintext.binary? # => false
56
+ # puts plaintext.ascii? # => true
57
+ # puts plaintext.obsolete? # => false
58
+ # puts plaintext.registered? # => true
59
+ # puts plaintext == 'text/plain' # => true
60
+ # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
61
+ #
62
+ class MIME::Types
63
+ # The release version of Ruby MIME::Types
64
+ VERSION = MIME::Type::VERSION
65
+
66
+ include Enumerable
67
+
68
+ # The data version.
69
+ attr_reader :data_version
70
+
71
+ # Creates a new MIME::Types registry.
72
+ def initialize
73
+ @type_variants = Container.new
74
+ @extension_index = Container.new
75
+ @data_version = VERSION.dup.freeze
76
+ end
484
77
 
485
- # Returns +true+ if the MIME::Type specifies an extension list,
486
- # indicating that it is a complete MIME::Type.
487
- def complete?
488
- not @extensions.empty?
489
- end
78
+ def add_type_variant(mime_type) # :nodoc:
79
+ MIME.deprecated(self, __method__, :private)
80
+ add_type_variant!(mime_type)
81
+ end
490
82
 
491
- # Returns the MIME type as a string.
492
- def to_s
493
- @content_type
494
- end
83
+ def index_extensions(mime_type) # :nodoc:
84
+ MIME.deprecated(self, __method__, :private)
85
+ index_extensions!(mime_type)
86
+ end
495
87
 
496
- # Returns the MIME type as a string for implicit conversions.
497
- def to_str
498
- @content_type
499
- end
88
+ def defined_types # :nodoc:
89
+ MIME.deprecated(self, __method__)
90
+ @type_variants.values.flatten
91
+ end
500
92
 
501
- # Returns the MIME type as an array suitable for use with
502
- # MIME::Type.from_array.
503
- def to_a
504
- [ @content_type, @extensions, @encoding, @system, @obsolete, @docs,
505
- @url, registered? ]
506
- end
93
+ # Returns the number of known type variants.
94
+ def count
95
+ @type_variants.values.reduce(0) { |m, o| m + o.size }
96
+ end
507
97
 
508
- # Returns the MIME type as an array suitable for use with
509
- # MIME::Type.from_hash.
510
- def to_hash
511
- { 'Content-Type' => @content_type,
512
- 'Content-Transfer-Encoding' => @encoding,
513
- 'Extensions' => @extensions,
514
- 'System' => @system,
515
- 'Obsolete' => @obsolete,
516
- 'Docs' => @docs,
517
- 'URL' => @url,
518
- 'Registered' => registered?,
519
- }
520
- end
98
+ # Iterates through the type variants.
99
+ def each
100
+ @type_variants.values.each { |tv| tv.each { |t| yield t } }
521
101
  end
522
102
 
523
- # = MIME::Types
524
- # MIME types are used in MIME-compliant communications, as in e-mail or
525
- # HTTP traffic, to indicate the type of content which is transmitted.
526
- # MIME::Types provides the ability for detailed information about MIME
527
- # entities (provided as a set of MIME::Type objects) to be determined and
528
- # used programmatically. There are many types defined by RFCs and vendors,
529
- # so the list is long but not complete; don't hesitate to ask to add
530
- # additional information. This library follows the IANA collection of MIME
531
- # types (see below for reference).
103
+ @__types__ = nil
104
+
105
+ # Returns a list of MIME::Type objects, which may be empty. The optional
106
+ # flag parameters are <tt>:complete</tt> (finds only complete MIME::Type
107
+ # objects) and <tt>:registered</tt> (finds only MIME::Types that are
108
+ # registered). It is possible for multiple matches to be returned for
109
+ # either type (in the example below, 'text/plain' returns two values --
110
+ # one for the general case, and one for VMS systems).
532
111
  #
533
- # == Description
534
- # MIME types are used in MIME entities, as in email or HTTP traffic. It is
535
- # useful at times to have information available about MIME types (or,
536
- # inversely, about files). A MIME::Type stores the known information about
537
- # one MIME type.
112
+ # puts "\nMIME::Types['text/plain']"
113
+ # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
538
114
  #
539
- # == Usage
540
- # require 'mime/types'
115
+ # puts "\nMIME::Types[/^image/, complete: true]"
116
+ # MIME::Types[/^image/, :complete => true].each do |t|
117
+ # puts t.to_a.join(", ")
118
+ # end
541
119
  #
542
- # plaintext = MIME::Types['text/plain']
543
- # print plaintext.media_type # => 'text'
544
- # print plaintext.sub_type # => 'plain'
120
+ # If multiple type definitions are returned, returns them sorted as
121
+ # follows:
122
+ # 1. Complete definitions sort before incomplete ones;
123
+ # 2. IANA-registered definitions sort before LTSW-recorded
124
+ # definitions.
125
+ # 3. Generic definitions sort before platform-specific ones;
126
+ # 4. Current definitions sort before obsolete ones;
127
+ # 5. Obsolete definitions with use-instead clauses sort before those
128
+ # without;
129
+ # 6. Obsolete definitions use-instead clauses are compared.
130
+ # 7. Sort on name.
545
131
  #
546
- # puts plaintext.extensions.join(" ") # => 'asc txt c cc h hh cpp'
132
+ # An additional flag of :platform (finds only MIME::Types for the current
133
+ # platform) is currently supported but deprecated.
134
+ def [](type_id, flags = {})
135
+ if flags[:platform]
136
+ MIME.deprecated(self, __method__, "using the :platform flag")
137
+ end
138
+
139
+ matches = case type_id
140
+ when MIME::Type
141
+ @type_variants[type_id.simplified]
142
+ when Regexp
143
+ match(type_id)
144
+ else
145
+ @type_variants[MIME::Type.simplified(type_id)]
146
+ end
147
+
148
+ prune_matches(matches, flags).sort { |a, b| a.priority_compare(b) }
149
+ end
150
+
151
+ # Return the list of MIME::Types which belongs to the file based on its
152
+ # filename extension. If there is no extension, the filename will be used
153
+ # as the matching criteria on its own.
547
154
  #
548
- # puts plaintext.encoding # => 8bit
549
- # puts plaintext.binary? # => false
550
- # puts plaintext.ascii? # => true
551
- # puts plaintext.obsolete? # => false
552
- # puts plaintext.registered? # => true
553
- # puts plaintext == 'text/plain' # => true
554
- # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
155
+ # This will always return a merged, flatten, priority sorted, unique array.
555
156
  #
556
- # This module is built to conform to the MIME types of RFCs 2045 and 2231.
557
- # It follows the official IANA registry at
558
- # http://www.iana.org/assignments/media-types/ and
559
- # ftp://ftp.iana.org/assignments/media-types with some unofficial types
560
- # added from the the collection at
561
- # http://www.ltsw.se/knbase/internet/mime.htp
562
- class Types
563
- # The released version of Ruby MIME::Types
564
- VERSION = MIME::Type::VERSION
565
- DATA_VERSION = (VERSION.to_f * 100).to_i
566
-
567
- # The data version.
568
- attr_reader :data_version
569
-
570
- class HashWithArrayDefault < Hash # :nodoc:
571
- def initialize
572
- super { |h, k| h[k] = [] }
573
- end
574
-
575
- def marshal_dump
576
- {}.merge(self)
577
- end
578
-
579
- def marshal_load(hash)
580
- self.merge!(hash)
581
- end
157
+ # puts MIME::Types.type_for('citydesk.xml')
158
+ # => [application/xml, text/xml]
159
+ # puts MIME::Types.type_for('citydesk.gif')
160
+ # => [image/gif]
161
+ # puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
162
+ # => [application/xml, image/gif, text/xml]
163
+ #
164
+ # If +platform+ is +true+, then only file types that are specific to the
165
+ # current platform will be returned. This parameter has been deprecated.
166
+ def type_for(filename, platform = false)
167
+ types = [ filename ].flatten.map { |fn|
168
+ @extension_index[File.basename(fn.chomp.downcase).gsub(/.*\./o, '')]
169
+ }.flatten.sort { |a, b| a.priority_compare(b) }.uniq
170
+
171
+ if platform
172
+ MIME.deprecated(self, __method__,
173
+ "using the platform parameter")
174
+ types.select(&:platform?)
175
+ else
176
+ types
582
177
  end
178
+ end
179
+ alias_method :of, :type_for
583
180
 
584
- class CacheContainer # :nodoc:
585
- attr_reader :version, :data
586
- def initialize(version, data)
587
- @version, @data = version, data
181
+ # Add one or more MIME::Type objects to the set of known types. If the
182
+ # type is already known, a warning will be displayed.
183
+ #
184
+ # The last parameter may be the value <tt>:silent</tt> or +true+ which
185
+ # will suppress duplicate MIME type warnings.
186
+ def add(*types)
187
+ quiet = ((types.last == :silent) or (types.last == true))
188
+
189
+ types.each do |mime_type|
190
+ case mime_type
191
+ when true, false, nil, Symbol
192
+ nil
193
+ when MIME::Types
194
+ variants = mime_type.instance_variable_get(:@type_variants)
195
+ add(*variants.values.flatten, quiet)
196
+ when Array
197
+ add(*mime_type, quiet)
198
+ else
199
+ add_type(mime_type, quiet)
588
200
  end
589
201
  end
202
+ end
590
203
 
591
- def initialize(data_version = DATA_VERSION)
592
- @type_variants = HashWithArrayDefault.new
593
- @extension_index = HashWithArrayDefault.new
594
- @data_version = data_version
204
+ # Add a single MIME::Type object to the set of known types. If the type is
205
+ # already known, a warning will be displayed. The +quiet+ parameter may be
206
+ # a truthy value to suppress that warning.
207
+ def add_type(mime_type, quiet = false)
208
+ if !quiet and @type_variants[mime_type.simplified].include?(mime_type)
209
+ warn("Type %s is already registered as a variant of %s." % [
210
+ mime_type, mime_type.simplified ])
595
211
  end
596
212
 
597
- def add_type_variant(mime_type) #:nodoc:
598
- @type_variants[mime_type.simplified] << mime_type
599
- end
213
+ add_type_variant!(mime_type)
214
+ index_extensions!(mime_type)
215
+ end
216
+
217
+ class << self
218
+ include Enumerable
600
219
 
601
- def index_extensions(mime_type) #:nodoc:
602
- mime_type.extensions.each { |ext| @extension_index[ext] << mime_type }
220
+ # Load MIME::Types from a v1 file registry.
221
+ #
222
+ # This method has been deprecated.
223
+ def load_from_file(filename)
224
+ MIME.deprecated(self, __method__)
225
+ MIME::Types::Loader.load_from_v1(filename)
603
226
  end
604
227
 
605
- def defined_types #:nodoc:
606
- @type_variants.values.flatten
228
+ # MIME::Types#[] against the default MIME::Types registry.
229
+ def [](type_id, flags = {})
230
+ __types__[type_id, flags]
607
231
  end
608
232
 
609
- # Returns the number of known types. A shortcut of MIME::Types[//].size.
610
- # (Keep in mind that this is memory intensive, cache the result to spare
611
- # resources)
233
+ # MIME::Types#count against the default MIME::Types registry.
612
234
  def count
613
- defined_types.size
235
+ __types__.count
614
236
  end
615
237
 
238
+ # MIME::Types#each against the default MIME::Types registry.
616
239
  def each
617
- defined_types.each { |t| yield t }
240
+ __types__.each {|t| yield t }
618
241
  end
619
242
 
620
- @__types__ = nil
243
+ # MIME::Types#type_for against the default MIME::Types registry.
244
+ def type_for(filename, platform = false)
245
+ __types__.type_for(filename, platform)
246
+ end
247
+ alias_method :of, :type_for
621
248
 
622
- # Returns a list of MIME::Type objects, which may be empty. The optional
623
- # flag parameters are :complete (finds only complete MIME::Type objects)
624
- # and :platform (finds only MIME::Types for the current platform). It is
625
- # possible for multiple matches to be returned for either type (in the
626
- # example below, 'text/plain' returns two values -- one for the general
627
- # case, and one for VMS systems.
628
- #
629
- # puts "\nMIME::Types['text/plain']"
630
- # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
631
- #
632
- # puts "\nMIME::Types[/^image/, :complete => true]"
633
- # MIME::Types[/^image/, :complete => true].each do |t|
634
- # puts t.to_a.join(", ")
635
- # end
636
- #
637
- # If multiple type definitions are returned, returns them sorted as
638
- # follows:
639
- # 1. Complete definitions sort before incomplete ones;
640
- # 2. IANA-registered definitions sort before LTSW-recorded
641
- # definitions.
642
- # 3. Generic definitions sort before platform-specific ones;
643
- # 4. Current definitions sort before obsolete ones;
644
- # 5. Obsolete definitions with use-instead clauses sort before those
645
- # without;
646
- # 6. Obsolete definitions use-instead clauses are compared.
647
- # 7. Sort on name.
648
- def [](type_id, flags = {})
649
- matches = case type_id
650
- when MIME::Type
651
- @type_variants[type_id.simplified]
652
- when Regexp
653
- match(type_id)
654
- else
655
- @type_variants[MIME::Type.simplified(type_id)]
656
- end
657
-
658
- prune_matches(matches, flags).sort { |a, b| a.priority_compare(b) }
249
+ # MIME::Types#add against the default MIME::Types registry.
250
+ def add(*types)
251
+ __types__.add(*types)
659
252
  end
660
253
 
661
- # Return the list of MIME::Types which belongs to the file based on its
662
- # filename extension. If +platform+ is +true+, then only file types that
663
- # are specific to the current platform will be returned.
664
- #
665
- # This will always return an array.
666
- #
667
- # puts "MIME::Types.type_for('citydesk.xml')
668
- # => [application/xml, text/xml]
669
- # puts "MIME::Types.type_for('citydesk.gif')
670
- # => [image/gif]
671
- def type_for(filename, platform = false)
672
- ext = filename.chomp.downcase.gsub(/.*\./o, '')
673
- list = @extension_index[ext]
674
- list.delete_if { |e| not e.platform? } if platform
675
- list
254
+ # Returns the currently defined cache file, if any.
255
+ def cache_file
256
+ MIME.deprecated(self, __method__)
257
+ ENV['RUBY_MIME_TYPES_CACHE']
676
258
  end
677
259
 
678
- # A synonym for MIME::Types.type_for
679
- def of(filename, platform = false)
680
- type_for(filename, platform)
260
+ def add_type_variant(mime_type) # :nodoc:
261
+ __types__.add_type_variant(mime_type)
681
262
  end
682
263
 
683
- # Add one or more MIME::Type objects to the set of known types. Each
684
- # type should be experimental (e.g., 'application/x-ruby'). If the type
685
- # is already known, a warning will be displayed.
686
- #
687
- # <strong>Please inform the maintainer of this module when registered
688
- # types are missing.</strong>
689
- def add(*types)
690
- types.each do |mime_type|
691
- if mime_type.kind_of? MIME::Types
692
- add(*mime_type.defined_types)
693
- else
694
- if @type_variants.include?(mime_type.simplified)
695
- if @type_variants[mime_type.simplified].include?(mime_type)
696
- warn "Type #{mime_type} already registered as a variant of #{mime_type.simplified}." unless defined? MIME::Types::LOAD
697
- end
698
- end
699
- add_type_variant(mime_type)
700
- index_extensions(mime_type)
701
- end
702
- end
264
+ def index_extensions(mime_type) # :nodoc:
265
+ __types__.index_extensions(mime_type)
703
266
  end
704
267
 
705
268
  private
706
- def prune_matches(matches, flags)
707
- matches.delete_if { |e| not e.complete? } if flags[:complete]
708
- matches.delete_if { |e| not e.platform? } if flags[:platform]
709
- matches
269
+ def lazy_load?
270
+ (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
710
271
  end
711
272
 
712
- def match(pattern)
713
- matches = @type_variants.select { |k, v| k =~ pattern }
714
- if matches.respond_to? :values
715
- matches.values.flatten
716
- else
717
- matches.map { |m| m.last }.flatten
718
- end
273
+ def __types__
274
+ (defined?(@__types__) and @__types__) or load_default_mime_types
719
275
  end
720
276
 
721
- class << self
722
- def add_type_variant(mime_type) #:nodoc:
723
- __types__.add_type_variant(mime_type)
724
- end
725
-
726
- def index_extensions(mime_type) #:nodoc:
727
- __types__.index_extensions(mime_type)
728
- end
729
-
730
- # The regular expression used to match a file-based MIME type
731
- # definition.
732
- TEXT_FORMAT_RE = %r{
733
- \A
734
- \s*
735
- ([*])? # 0: Unregistered?
736
- (!)? # 1: Obsolete?
737
- (?:(\w+):)? # 2: Platform marker
738
- #{MIME::Type::MEDIA_TYPE_RE}? # 3,4: Media type
739
- (?:\s+@([^\s]+))? # 5: Extensions
740
- (?:\s+:(#{MIME::Type::ENCODING_RE}))? # 6: Encoding
741
- (?:\s+'(.+))? # 7: URL list
742
- (?:\s+=(.+))? # 8: Documentation
743
- (?:\s*([#].*)?)?
744
- \s*
745
- \z
746
- }x
747
-
748
- # Build the type list from a file in the format:
749
- #
750
- # [*][!][os:]mt/st[<ws>@ext][<ws>:enc][<ws>'url-list][<ws>=docs]
751
- #
752
- # == *
753
- # An unofficial MIME type. This should be used if and only if the MIME type
754
- # is not properly specified (that is, not under either x-type or
755
- # vnd.name.type).
756
- #
757
- # == !
758
- # An obsolete MIME type. May be used with an unofficial MIME type.
759
- #
760
- # == os:
761
- # Platform-specific MIME type definition.
762
- #
763
- # == mt
764
- # The media type.
765
- #
766
- # == st
767
- # The media subtype.
768
- #
769
- # == <ws>@ext
770
- # The list of comma-separated extensions.
771
- #
772
- # == <ws>:enc
773
- # The encoding.
774
- #
775
- # == <ws>'url-list
776
- # The list of comma-separated URLs.
777
- #
778
- # == <ws>=docs
779
- # The documentation string.
780
- #
781
- # That is, everything except the media type and the subtype is optional. The
782
- # more information that's available, though, the richer the values that can
783
- # be provided.
784
- def load_from_file(filename) #:nodoc:
785
- if defined? ::Encoding
786
- data = File.open(filename, 'r:UTF-8:-') { |f| f.read }
787
- else
788
- data = File.open(filename) { |f| f.read }
789
- end
790
- data = data.split($/)
791
- mime = MIME::Types.new
792
- data.each_with_index { |line, index|
793
- item = line.chomp.strip
794
- next if item.empty?
795
-
796
- begin
797
- m = TEXT_FORMAT_RE.match(item).captures
798
- rescue Exception
799
- puts "#{filename}:#{index}: Parsing error in MIME type definitions."
800
- puts "=> #{line}"
801
- raise
802
- end
803
-
804
- unregistered, obsolete, platform, mediatype, subtype, extensions,
805
- encoding, urls, docs, comment = *m
806
-
807
- if mediatype.nil?
808
- if comment.nil?
809
- puts "#{filename}:#{index}: Parsing error in MIME type definitions."
810
- puts "=> #{line}"
811
- raise RuntimeError
812
- end
813
-
814
- next
815
- end
816
-
817
- extensions &&= extensions.split(/,/)
818
- urls &&= urls.split(/,/)
819
-
820
- mime_type = MIME::Type.new("#{mediatype}/#{subtype}") do |t|
821
- t.extensions = extensions
822
- t.encoding = encoding
823
- t.system = platform
824
- t.obsolete = obsolete
825
- t.registered = false if unregistered
826
- t.docs = docs
827
- t.url = urls
828
- end
829
-
830
- mime.add(mime_type)
831
- }
832
- mime
833
- end
834
-
835
- # Returns a list of MIME::Type objects, which may be empty. The
836
- # optional flag parameters are :complete (finds only complete
837
- # MIME::Type objects) and :platform (finds only MIME::Types for the
838
- # current platform). It is possible for multiple matches to be
839
- # returned for either type (in the example below, 'text/plain' returns
840
- # two values -- one for the general case, and one for VMS systems.
841
- #
842
- # puts "\nMIME::Types['text/plain']"
843
- # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
844
- #
845
- # puts "\nMIME::Types[/^image/, :complete => true]"
846
- # MIME::Types[/^image/, :complete => true].each do |t|
847
- # puts t.to_a.join(", ")
848
- # end
849
- def [](type_id, flags = {})
850
- __types__[type_id, flags]
851
- end
852
-
853
- include Enumerable
854
-
855
- def count
856
- __types__.count
857
- end
858
-
859
- def each
860
- __types__.each {|t| yield t }
861
- end
862
-
863
- # Return the list of MIME::Types which belongs to the file based on
864
- # its filename extension. If +platform+ is +true+, then only file
865
- # types that are specific to the current platform will be returned.
866
- #
867
- # This will always return an array.
868
- #
869
- # puts "MIME::Types.type_for('citydesk.xml')
870
- # => [application/xml, text/xml]
871
- # puts "MIME::Types.type_for('citydesk.gif')
872
- # => [image/gif]
873
- def type_for(filename, platform = false)
874
- __types__.type_for(filename, platform)
875
- end
876
-
877
- # A synonym for MIME::Types.type_for
878
- def of(filename, platform = false)
879
- __types__.type_for(filename, platform)
880
- end
881
-
882
- # Add one or more MIME::Type objects to the set of known types. Each
883
- # type should be experimental (e.g., 'application/x-ruby'). If the
884
- # type is already known, a warning will be displayed.
885
- #
886
- # <strong>Please inform the maintainer of this module when registered
887
- # types are missing.</strong>
888
- def add(*types)
889
- __types__.add(*types)
890
- end
891
-
892
- # Returns the currently defined cache file, if any.
893
- def cache_file
894
- ENV['RUBY_MIME_TYPES_CACHE']
895
- end
896
-
897
- private
898
- def load_mime_types_from_cache
899
- load_mime_types_from_cache! if cache_file
900
- end
901
-
902
- def load_mime_types_from_cache!
903
- raise ArgumentError, "No RUBY_MIME_TYPES_CACHE set." unless cache_file
904
- return false unless File.exists? cache_file
905
-
906
- begin
907
- data = File.read(cache_file)
908
- container = Marshal.load(data)
909
-
910
- if container.version == VERSION
911
- @__types__ = Marshal.load(container.data)
912
- true
913
- else
914
- false
915
- end
916
- rescue => e
917
- warn "Could not load MIME::Types cache: #{e}"
918
- false
919
- end
920
- end
921
-
922
- def write_mime_types_to_cache
923
- write_mime_types_to_cache! if cache_file
924
- end
925
-
926
- def write_mime_types_to_cache!
927
- raise ArgumentError, "No RUBY_MIME_TYPES_CACHE set." unless cache_file
928
-
929
- File.open(cache_file, 'w') do |f|
930
- cache = MIME::Types::CacheContainer.new(VERSION,
931
- Marshal.dump(__types__))
932
- f.write Marshal.dump(cache)
933
- end
934
-
935
- true
936
- end
937
-
938
- def load_and_parse_mime_types
939
- const_set(:LOAD, true) unless $DEBUG
940
- Dir[File.join(File.dirname(__FILE__), 'types', '*')].sort.each { |f|
941
- add(load_from_file(f))
942
- }
943
- remove_const :LOAD if defined? LOAD
277
+ def load_default_mime_types
278
+ @__types__ = MIME::Types::Cache.load
279
+ unless @__types__
280
+ @__types__ = MIME::Types::Loader.load
281
+ MIME::Types::Cache.save(@__types__)
944
282
  end
283
+ @__types__
284
+ end
285
+ end
945
286
 
946
- def lazy_load?
947
- (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
948
- end
287
+ private
288
+ def add_type_variant!(mime_type)
289
+ @type_variants[mime_type.simplified] << mime_type
290
+ end
949
291
 
950
- def __types__
951
- load_mime_types unless @__types__
952
- @__types__
953
- end
292
+ def index_extensions!(mime_type)
293
+ mime_type.extensions.each { |ext| @extension_index[ext] << mime_type }
294
+ end
954
295
 
955
- def load_mime_types
956
- @__types__ = new(VERSION)
957
- unless load_mime_types_from_cache
958
- load_and_parse_mime_types
959
- write_mime_types_to_cache
960
- end
961
- end
962
- end
296
+ def prune_matches(matches, flags)
297
+ matches.delete_if { |e| not e.complete? } if flags[:complete]
298
+ matches.delete_if { |e| not e.platform? } if flags[:platform]
299
+ matches.delete_if { |e| not e.registered? } if flags[:registered]
300
+ matches
301
+ end
963
302
 
964
- load_mime_types unless lazy_load?
303
+ def match(pattern)
304
+ @type_variants.select { |k, v| k =~ pattern }.values.flatten
965
305
  end
306
+
307
+ load_default_mime_types unless lazy_load?
966
308
  end
967
309
 
968
310
  # vim: ft=ruby