mime-types 3.3.1 → 3.4.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.
- checksums.yaml +4 -4
- data/Code-of-Conduct.md +10 -10
- data/Contributing.md +82 -93
- data/History.md +158 -138
- data/Licence.md +3 -3
- data/README.rdoc +1 -0
- data/Rakefile +131 -145
- data/lib/mime/type/columnar.rb +3 -3
- data/lib/mime/type.rb +141 -94
- data/lib/mime/types/_columnar.rb +20 -19
- data/lib/mime/types/cache.rb +8 -8
- data/lib/mime/types/columnar.rb +1 -1
- data/lib/mime/types/container.rb +14 -14
- data/lib/mime/types/deprecations.rb +15 -11
- data/lib/mime/types/full.rb +2 -2
- data/lib/mime/types/loader.rb +28 -15
- data/lib/mime/types/logger.rb +3 -5
- data/lib/mime/types/registry.rb +7 -7
- data/lib/mime/types.rb +18 -16
- data/lib/mime-types.rb +1 -1
- data/test/minitest_helper.rb +7 -9
- data/test/test_mime_type.rb +272 -261
- data/test/test_mime_types.rb +72 -72
- data/test/test_mime_types_cache.rb +38 -38
- data/test/test_mime_types_class.rb +59 -59
- data/test/test_mime_types_lazy.rb +16 -16
- data/test/test_mime_types_loader.rb +14 -14
- metadata +15 -43
data/lib/mime/type.rb
CHANGED
@@ -9,25 +9,61 @@ end
|
|
9
9
|
# == Usage
|
10
10
|
# require 'mime/types'
|
11
11
|
#
|
12
|
-
# plaintext = MIME::Types['text/plain']
|
13
|
-
# # returns [text/plain, text/plain]
|
12
|
+
# plaintext = MIME::Types['text/plain'] # => [ text/plain ]
|
14
13
|
# text = plaintext.first
|
15
|
-
#
|
16
|
-
#
|
14
|
+
# puts text.media_type # => 'text'
|
15
|
+
# puts text.sub_type # => 'plain'
|
17
16
|
#
|
18
|
-
# puts text.extensions.join(
|
17
|
+
# puts text.extensions.join(' ') # => 'txt asc c cc h hh cpp hpp dat hlp'
|
18
|
+
# puts text.preferred_extension # => 'txt'
|
19
|
+
# puts text.friendly # => 'Text Document'
|
20
|
+
# puts text.i18n_key # => 'text.plain'
|
19
21
|
#
|
20
|
-
# puts text.encoding # =>
|
22
|
+
# puts text.encoding # => quoted-printable
|
23
|
+
# puts text.default_encoding # => quoted-printable
|
21
24
|
# puts text.binary? # => false
|
22
25
|
# puts text.ascii? # => true
|
26
|
+
# puts text.obsolete? # => false
|
27
|
+
# puts text.registered? # => true
|
28
|
+
# puts text.provisional? # => false
|
29
|
+
# puts text.complete? # => true
|
30
|
+
#
|
31
|
+
# puts text # => 'text/plain'
|
32
|
+
#
|
23
33
|
# puts text == 'text/plain' # => true
|
24
|
-
# puts
|
34
|
+
# puts 'text/plain' == text # => true
|
35
|
+
# puts text == 'text/x-plain' # => false
|
36
|
+
# puts 'text/x-plain' == text # => false
|
37
|
+
#
|
38
|
+
# puts MIME::Type.simplified('x-appl/x-zip') # => 'x-appl/x-zip'
|
39
|
+
# puts MIME::Type.i18n_key('x-appl/x-zip') # => 'x-appl.x-zip'
|
40
|
+
#
|
41
|
+
# puts text.like?('text/x-plain') # => true
|
42
|
+
# puts text.like?(MIME::Type.new('x-text/x-plain')) # => true
|
43
|
+
#
|
44
|
+
# puts text.xrefs.inspect # => { "rfc" => [ "rfc2046", "rfc3676", "rfc5147" ] }
|
45
|
+
# puts text.xref_urls # => [ "http://www.iana.org/go/rfc2046",
|
46
|
+
# # "http://www.iana.org/go/rfc3676",
|
47
|
+
# # "http://www.iana.org/go/rfc5147" ]
|
48
|
+
#
|
49
|
+
# xtext = MIME::Type.new('x-text/x-plain')
|
50
|
+
# puts xtext.media_type # => 'text'
|
51
|
+
# puts xtext.raw_media_type # => 'x-text'
|
52
|
+
# puts xtext.sub_type # => 'plain'
|
53
|
+
# puts xtext.raw_sub_type # => 'x-plain'
|
54
|
+
# puts xtext.complete? # => false
|
55
|
+
#
|
56
|
+
# puts MIME::Types.any? { |type| type.content_type == 'text/plain' } # => true
|
57
|
+
# puts MIME::Types.all?(&:registered?) # => false
|
25
58
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# puts
|
30
|
-
#
|
59
|
+
# # Various string representations of MIME types
|
60
|
+
# qcelp = MIME::Types['audio/QCELP'].first # => audio/QCELP
|
61
|
+
# puts qcelp.content_type # => 'audio/QCELP'
|
62
|
+
# puts qcelp.simplified # => 'audio/qcelp'
|
63
|
+
#
|
64
|
+
# xwingz = MIME::Types['application/x-Wingz'].first # => application/x-Wingz
|
65
|
+
# puts xwingz.content_type # => 'application/x-Wingz'
|
66
|
+
# puts xwingz.simplified # => 'application/x-wingz'
|
31
67
|
class MIME::Type
|
32
68
|
# Reflects a MIME content-type specification that is not correctly
|
33
69
|
# formatted (it isn't +type+/+subtype+).
|
@@ -57,24 +93,24 @@ class MIME::Type
|
|
57
93
|
end
|
58
94
|
|
59
95
|
# The released version of the mime-types library.
|
60
|
-
VERSION =
|
96
|
+
VERSION = "3.4.0"
|
61
97
|
|
62
98
|
include Comparable
|
63
99
|
|
64
100
|
# :stopdoc:
|
65
101
|
# TODO verify mime-type character restrictions; I am pretty sure that this is
|
66
102
|
# too wide open.
|
67
|
-
MEDIA_TYPE_RE
|
68
|
-
I18N_RE
|
69
|
-
BINARY_ENCODINGS = %w
|
70
|
-
ASCII_ENCODINGS
|
103
|
+
MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}.freeze
|
104
|
+
I18N_RE = /[^[:alnum:]]/.freeze
|
105
|
+
BINARY_ENCODINGS = %w[base64 8bit].freeze
|
106
|
+
ASCII_ENCODINGS = %w[7bit quoted-printable].freeze
|
71
107
|
# :startdoc:
|
72
108
|
|
73
109
|
private_constant :MEDIA_TYPE_RE, :I18N_RE, :BINARY_ENCODINGS,
|
74
|
-
|
110
|
+
:ASCII_ENCODINGS
|
75
111
|
|
76
112
|
# Builds a MIME::Type object from the +content_type+, a MIME Content Type
|
77
|
-
# value (e.g., 'text/plain' or '
|
113
|
+
# value (e.g., 'text/plain' or 'application/x-eruby'). The constructed object
|
78
114
|
# is yielded to an optional block for additional configuration, such as
|
79
115
|
# associating extensions and encoding information.
|
80
116
|
#
|
@@ -86,9 +122,9 @@ class MIME::Type
|
|
86
122
|
# * Otherwise, the content_type will be used as a string.
|
87
123
|
#
|
88
124
|
# Yields the newly constructed +self+ object.
|
89
|
-
def initialize(content_type) # :yields self
|
125
|
+
def initialize(content_type) # :yields: self
|
90
126
|
@friendly = {}
|
91
|
-
@obsolete = @registered = false
|
127
|
+
@obsolete = @registered = @provisional = false
|
92
128
|
@preferred_extension = @docs = @use_instead = nil
|
93
129
|
self.extensions = []
|
94
130
|
|
@@ -113,11 +149,12 @@ class MIME::Type
|
|
113
149
|
# Indicates that a MIME type is like another type. This differs from
|
114
150
|
# <tt>==</tt> because <tt>x-</tt> prefixes are removed for this comparison.
|
115
151
|
def like?(other)
|
116
|
-
other =
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
152
|
+
other =
|
153
|
+
if other.respond_to?(:simplified)
|
154
|
+
MIME::Type.simplified(other.simplified, remove_x_prefix: true)
|
155
|
+
else
|
156
|
+
MIME::Type.simplified(other.to_s, remove_x_prefix: true)
|
157
|
+
end
|
121
158
|
MIME::Type.simplified(simplified, remove_x_prefix: true) == other
|
122
159
|
end
|
123
160
|
|
@@ -131,8 +168,8 @@ class MIME::Type
|
|
131
168
|
elsif other.respond_to?(:simplified)
|
132
169
|
simplified <=> other.simplified
|
133
170
|
else
|
134
|
-
filtered =
|
135
|
-
filtered ||=
|
171
|
+
filtered = "silent" if other == :silent
|
172
|
+
filtered ||= "true" if other == true
|
136
173
|
filtered ||= other.to_s
|
137
174
|
|
138
175
|
simplified <=> MIME::Type.simplified(filtered)
|
@@ -158,23 +195,24 @@ class MIME::Type
|
|
158
195
|
def priority_compare(other)
|
159
196
|
pc = simplified <=> other.simplified
|
160
197
|
if pc.zero? || !(extensions & other.extensions).empty?
|
161
|
-
pc =
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
198
|
+
pc =
|
199
|
+
if (reg = registered?) != other.registered?
|
200
|
+
reg ? -1 : 1 # registered < unregistered
|
201
|
+
elsif (comp = complete?) != other.complete?
|
202
|
+
comp ? -1 : 1 # complete < incomplete
|
203
|
+
elsif (obs = obsolete?) != other.obsolete?
|
204
|
+
obs ? 1 : -1 # current < obsolete
|
205
|
+
elsif obs && ((ui = use_instead) != (oui = other.use_instead))
|
206
|
+
if ui.nil?
|
207
|
+
1
|
208
|
+
elsif oui.nil?
|
209
|
+
-1
|
210
|
+
else
|
211
|
+
ui <=> oui
|
212
|
+
end
|
213
|
+
else
|
214
|
+
0
|
215
|
+
end
|
178
216
|
end
|
179
217
|
|
180
218
|
pc
|
@@ -183,7 +221,7 @@ class MIME::Type
|
|
183
221
|
# Returns +true+ if the +other+ object is a MIME::Type and the content types
|
184
222
|
# match.
|
185
223
|
def eql?(other)
|
186
|
-
other.
|
224
|
+
other.is_a?(MIME::Type) && (self == other)
|
187
225
|
end
|
188
226
|
|
189
227
|
# Returns the whole MIME content-type string.
|
@@ -197,8 +235,7 @@ class MIME::Type
|
|
197
235
|
# audio/QCELP => audio/QCELP
|
198
236
|
attr_reader :content_type
|
199
237
|
# A simplified form of the MIME content-type string, suitable for
|
200
|
-
# case-insensitive comparison, with
|
201
|
-
# removed and converted to lowercase.
|
238
|
+
# case-insensitive comparison, with the content_type converted to lowercase.
|
202
239
|
#
|
203
240
|
# text/plain => text/plain
|
204
241
|
# x-chemical/x-pdb => x-chemical/x-pdb
|
@@ -290,9 +327,9 @@ class MIME::Type
|
|
290
327
|
|
291
328
|
##
|
292
329
|
def encoding=(enc) # :nodoc:
|
293
|
-
if enc.nil?
|
330
|
+
if enc.nil? || (enc == :default)
|
294
331
|
@encoding = default_encoding
|
295
|
-
elsif BINARY_ENCODINGS.include?(enc)
|
332
|
+
elsif BINARY_ENCODINGS.include?(enc) || ASCII_ENCODINGS.include?(enc)
|
296
333
|
@encoding = enc
|
297
334
|
else
|
298
335
|
fail InvalidEncoding, enc
|
@@ -301,7 +338,7 @@ class MIME::Type
|
|
301
338
|
|
302
339
|
# Returns the default encoding for the MIME::Type based on the media type.
|
303
340
|
def default_encoding
|
304
|
-
@media_type ==
|
341
|
+
@media_type == "text" ? "quoted-printable" : "base64"
|
305
342
|
end
|
306
343
|
|
307
344
|
##
|
@@ -321,7 +358,7 @@ class MIME::Type
|
|
321
358
|
|
322
359
|
# Returns +true+ if the media type is obsolete.
|
323
360
|
attr_accessor :obsolete
|
324
|
-
|
361
|
+
alias_method :obsolete?, :obsolete
|
325
362
|
|
326
363
|
# The documentation for this MIME::Type.
|
327
364
|
attr_accessor :docs
|
@@ -331,7 +368,7 @@ class MIME::Type
|
|
331
368
|
# call-seq:
|
332
369
|
# text_plain.friendly # => "Text File"
|
333
370
|
# text_plain.friendly('en') # => "Text File"
|
334
|
-
def friendly(lang =
|
371
|
+
def friendly(lang = "en")
|
335
372
|
@friendly ||= {}
|
336
373
|
|
337
374
|
case lang
|
@@ -343,7 +380,7 @@ class MIME::Type
|
|
343
380
|
@friendly.update(lang)
|
344
381
|
else
|
345
382
|
fail ArgumentError,
|
346
|
-
|
383
|
+
"Expected a language or translation set, not #{lang.inspect}"
|
347
384
|
end
|
348
385
|
end
|
349
386
|
|
@@ -374,14 +411,22 @@ class MIME::Type
|
|
374
411
|
# The decoded cross-reference URL list for this MIME::Type.
|
375
412
|
def xref_urls
|
376
413
|
xrefs.flat_map { |type, values|
|
377
|
-
name = :"xref_url_for_#{type.tr(
|
378
|
-
respond_to?(name, true)
|
414
|
+
name = :"xref_url_for_#{type.tr("-", "_")}"
|
415
|
+
respond_to?(name, true) && xref_map(values, name) || values.to_a
|
379
416
|
}
|
380
417
|
end
|
381
418
|
|
382
419
|
# Indicates whether the MIME type has been registered with IANA.
|
383
420
|
attr_accessor :registered
|
384
|
-
|
421
|
+
alias_method :registered?, :registered
|
422
|
+
|
423
|
+
# Indicates whether the MIME type's registration with IANA is provisional.
|
424
|
+
attr_accessor :provisional
|
425
|
+
|
426
|
+
# Indicates whether the MIME type's registration with IANA is provisional.
|
427
|
+
def provisional?
|
428
|
+
registered? && @provisional
|
429
|
+
end
|
385
430
|
|
386
431
|
# MIME types can be specified to be sent across a network in particular
|
387
432
|
# formats. This method returns +true+ when the MIME::Type encoding is set
|
@@ -399,7 +444,7 @@ class MIME::Type
|
|
399
444
|
|
400
445
|
# Indicateswhether the MIME type is declared as a signature type.
|
401
446
|
attr_accessor :signature
|
402
|
-
|
447
|
+
alias_method :signature?, :signature
|
403
448
|
|
404
449
|
# Returns +true+ if the MIME::Type specifies an extension list,
|
405
450
|
# indicating that it is a complete MIME::Type.
|
@@ -422,7 +467,7 @@ class MIME::Type
|
|
422
467
|
|
423
468
|
# Converts the MIME::Type to a JSON string.
|
424
469
|
def to_json(*args)
|
425
|
-
require
|
470
|
+
require "json"
|
426
471
|
to_h.to_json(*args)
|
427
472
|
end
|
428
473
|
|
@@ -438,26 +483,27 @@ class MIME::Type
|
|
438
483
|
#
|
439
484
|
# This method should be considered a private implementation detail.
|
440
485
|
def encode_with(coder)
|
441
|
-
coder[
|
442
|
-
coder[
|
443
|
-
coder[
|
444
|
-
coder[
|
445
|
-
coder[
|
446
|
-
coder[
|
486
|
+
coder["content-type"] = @content_type
|
487
|
+
coder["docs"] = @docs unless @docs.nil? || @docs.empty?
|
488
|
+
coder["friendly"] = @friendly unless @friendly.nil? || @friendly.empty?
|
489
|
+
coder["encoding"] = @encoding
|
490
|
+
coder["extensions"] = @extensions.to_a unless @extensions.empty?
|
491
|
+
coder["preferred-extension"] = @preferred_extension if @preferred_extension
|
447
492
|
if obsolete?
|
448
|
-
coder[
|
449
|
-
coder[
|
493
|
+
coder["obsolete"] = obsolete?
|
494
|
+
coder["use-instead"] = use_instead if use_instead
|
450
495
|
end
|
451
496
|
unless xrefs.empty?
|
452
497
|
{}.tap do |hash|
|
453
498
|
xrefs.each do |k, v|
|
454
499
|
hash[k] = v.to_a.sort
|
455
500
|
end
|
456
|
-
coder[
|
501
|
+
coder["xrefs"] = hash
|
457
502
|
end
|
458
503
|
end
|
459
|
-
coder[
|
460
|
-
coder[
|
504
|
+
coder["registered"] = registered?
|
505
|
+
coder["provisional"] = provisional? if provisional?
|
506
|
+
coder["signature"] = signature? if signature?
|
461
507
|
coder
|
462
508
|
end
|
463
509
|
|
@@ -466,18 +512,19 @@ class MIME::Type
|
|
466
512
|
#
|
467
513
|
# This method should be considered a private implementation detail.
|
468
514
|
def init_with(coder)
|
469
|
-
self.content_type
|
470
|
-
self.docs
|
471
|
-
self.encoding
|
472
|
-
self.extensions
|
473
|
-
self.preferred_extension = coder[
|
474
|
-
self.obsolete
|
475
|
-
self.registered
|
476
|
-
self.
|
477
|
-
self.
|
478
|
-
self.
|
515
|
+
self.content_type = coder["content-type"]
|
516
|
+
self.docs = coder["docs"] || ""
|
517
|
+
self.encoding = coder["encoding"]
|
518
|
+
self.extensions = coder["extensions"] || []
|
519
|
+
self.preferred_extension = coder["preferred-extension"]
|
520
|
+
self.obsolete = coder["obsolete"] || false
|
521
|
+
self.registered = coder["registered"] || false
|
522
|
+
self.provisional = coder["provisional"] || false
|
523
|
+
self.signature = coder["signature"]
|
524
|
+
self.xrefs = coder["xrefs"] || {}
|
525
|
+
self.use_instead = coder["use-instead"]
|
479
526
|
|
480
|
-
friendly(coder[
|
527
|
+
friendly(coder["friendly"] || {})
|
481
528
|
end
|
482
529
|
|
483
530
|
def inspect # :nodoc:
|
@@ -501,8 +548,8 @@ class MIME::Type
|
|
501
548
|
# Converts a provided +content_type+ into a translation key suitable for
|
502
549
|
# use with the I18n library.
|
503
550
|
def i18n_key(content_type)
|
504
|
-
simplify_matchdata(match(content_type), joiner:
|
505
|
-
e.gsub!(I18N_RE,
|
551
|
+
simplify_matchdata(match(content_type), joiner: ".") { |e|
|
552
|
+
e.gsub!(I18N_RE, "-")
|
506
553
|
}
|
507
554
|
end
|
508
555
|
|
@@ -519,12 +566,12 @@ class MIME::Type
|
|
519
566
|
|
520
567
|
private
|
521
568
|
|
522
|
-
def simplify_matchdata(matchdata, remove_x = false, joiner:
|
569
|
+
def simplify_matchdata(matchdata, remove_x = false, joiner: "/")
|
523
570
|
return nil unless matchdata
|
524
571
|
|
525
572
|
matchdata.captures.map { |e|
|
526
573
|
e.downcase!
|
527
|
-
e.sub!(/^x-/,
|
574
|
+
e.sub!(/^x-/, "") if remove_x
|
528
575
|
yield e if block_given?
|
529
576
|
e
|
530
577
|
}.join(joiner)
|
@@ -537,11 +584,11 @@ class MIME::Type
|
|
537
584
|
match = MEDIA_TYPE_RE.match(type_string)
|
538
585
|
fail InvalidContentType, type_string if match.nil?
|
539
586
|
|
540
|
-
@content_type
|
587
|
+
@content_type = intern_string(type_string)
|
541
588
|
@raw_media_type, @raw_sub_type = match.captures
|
542
|
-
@simplified
|
543
|
-
@i18n_key
|
544
|
-
@media_type, @sub_type
|
589
|
+
@simplified = intern_string(MIME::Type.simplified(match))
|
590
|
+
@i18n_key = intern_string(MIME::Type.i18n_key(match))
|
591
|
+
@media_type, @sub_type = MEDIA_TYPE_RE.match(@simplified).captures
|
545
592
|
|
546
593
|
@raw_media_type = intern_string(@raw_media_type)
|
547
594
|
@raw_sub_type = intern_string(@raw_sub_type)
|
@@ -566,22 +613,22 @@ class MIME::Type
|
|
566
613
|
end
|
567
614
|
|
568
615
|
def xref_url_for_rfc(value)
|
569
|
-
|
616
|
+
"http://www.iana.org/go/%s" % value
|
570
617
|
end
|
571
618
|
|
572
619
|
def xref_url_for_draft(value)
|
573
|
-
|
620
|
+
"http://www.iana.org/go/%s" % value.sub(/\ARFC/, "draft")
|
574
621
|
end
|
575
622
|
|
576
623
|
def xref_url_for_rfc_errata(value)
|
577
|
-
|
624
|
+
"http://www.rfc-editor.org/errata_search.php?eid=%s" % value
|
578
625
|
end
|
579
626
|
|
580
627
|
def xref_url_for_person(value)
|
581
|
-
|
628
|
+
"http://www.iana.org/assignments/media-types/media-types.xhtml#%s" % value
|
582
629
|
end
|
583
630
|
|
584
631
|
def xref_url_for_template(value)
|
585
|
-
|
632
|
+
"http://www.iana.org/assignments/media-types/%s" % value
|
586
633
|
end
|
587
634
|
end
|
data/lib/mime/types/_columnar.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "mime/type/columnar"
|
4
4
|
|
5
5
|
# MIME::Types::Columnar is used to extend a MIME::Types container to load data
|
6
6
|
# by columns instead of from JSON or YAML. Column loads of MIME types loaded
|
@@ -19,10 +19,10 @@ module MIME::Types::Columnar
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# Load the first column data file (type and extensions).
|
22
|
-
def load_base_data(path)
|
22
|
+
def load_base_data(path) # :nodoc:
|
23
23
|
@__root__ = path
|
24
24
|
|
25
|
-
each_file_line(
|
25
|
+
each_file_line("content_type", false) do |line|
|
26
26
|
line = line.split
|
27
27
|
content_type = line.shift
|
28
28
|
extensions = line
|
@@ -45,11 +45,11 @@ module MIME::Types::Columnar
|
|
45
45
|
i = -1
|
46
46
|
column = File.join(@__root__, "mime.#{name}.column")
|
47
47
|
|
48
|
-
IO.readlines(column, encoding:
|
48
|
+
IO.readlines(column, encoding: "UTF-8").each do |line|
|
49
49
|
line.chomp!
|
50
50
|
|
51
51
|
if lookup
|
52
|
-
type = @__mime_data__[i += 1]
|
52
|
+
(type = @__mime_data__[i += 1]) || next
|
53
53
|
yield type, line
|
54
54
|
else
|
55
55
|
yield line
|
@@ -61,57 +61,58 @@ module MIME::Types::Columnar
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def load_encoding
|
64
|
-
each_file_line(
|
64
|
+
each_file_line("encoding") do |type, line|
|
65
65
|
pool ||= {}
|
66
66
|
type.instance_variable_set(:@encoding, (pool[line] ||= line))
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def load_docs
|
71
|
-
each_file_line(
|
71
|
+
each_file_line("docs") do |type, line|
|
72
72
|
type.instance_variable_set(:@docs, opt(line))
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
76
|
def load_preferred_extension
|
77
|
-
each_file_line(
|
77
|
+
each_file_line("pext") do |type, line|
|
78
78
|
type.instance_variable_set(:@preferred_extension, opt(line))
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
82
|
def load_flags
|
83
|
-
each_file_line(
|
83
|
+
each_file_line("flags") do |type, line|
|
84
84
|
line = line.split
|
85
85
|
type.instance_variable_set(:@obsolete, flag(line.shift))
|
86
86
|
type.instance_variable_set(:@registered, flag(line.shift))
|
87
87
|
type.instance_variable_set(:@signature, flag(line.shift))
|
88
|
+
type.instance_variable_set(:@provisional, flag(line.shift))
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
91
92
|
def load_xrefs
|
92
|
-
each_file_line(
|
93
|
+
each_file_line("xrefs") { |type, line|
|
93
94
|
type.instance_variable_set(:@xrefs, dict(line, array: true))
|
94
95
|
}
|
95
96
|
end
|
96
97
|
|
97
98
|
def load_friendly
|
98
|
-
each_file_line(
|
99
|
+
each_file_line("friendly") { |type, line|
|
99
100
|
type.instance_variable_set(:@friendly, dict(line))
|
100
101
|
}
|
101
102
|
end
|
102
103
|
|
103
104
|
def load_use_instead
|
104
|
-
each_file_line(
|
105
|
+
each_file_line("use_instead") do |type, line|
|
105
106
|
type.instance_variable_set(:@use_instead, opt(line))
|
106
107
|
end
|
107
108
|
end
|
108
109
|
|
109
110
|
def dict(line, array: false)
|
110
|
-
if line ==
|
111
|
+
if line == "-"
|
111
112
|
{}
|
112
113
|
else
|
113
|
-
line.split(
|
114
|
-
k, v = l.split(
|
114
|
+
line.split("|").each_with_object({}) { |l, h|
|
115
|
+
k, v = l.split("^")
|
115
116
|
v = nil if v.empty?
|
116
117
|
h[k] = array ? Array(v) : v
|
117
118
|
}
|
@@ -119,18 +120,18 @@ module MIME::Types::Columnar
|
|
119
120
|
end
|
120
121
|
|
121
122
|
def arr(line)
|
122
|
-
if line ==
|
123
|
+
if line == "-"
|
123
124
|
[]
|
124
125
|
else
|
125
|
-
line.split(
|
126
|
+
line.split("|").flatten.compact.uniq
|
126
127
|
end
|
127
128
|
end
|
128
129
|
|
129
130
|
def opt(line)
|
130
|
-
line unless line ==
|
131
|
+
line unless line == "-"
|
131
132
|
end
|
132
133
|
|
133
134
|
def flag(line)
|
134
|
-
line ==
|
135
|
+
line == "1"
|
135
136
|
end
|
136
137
|
end
|
data/lib/mime/types/cache.rb
CHANGED
@@ -15,21 +15,21 @@ class << MIME::Types::Cache
|
|
15
15
|
# file does not exist, if the file cannot be loaded, or if the data in
|
16
16
|
# the cache version is different than this version.
|
17
17
|
def load(cache_file = nil)
|
18
|
-
cache_file ||= ENV[
|
19
|
-
return nil unless cache_file
|
18
|
+
cache_file ||= ENV["RUBY_MIME_TYPES_CACHE"]
|
19
|
+
return nil unless cache_file && File.exist?(cache_file)
|
20
20
|
|
21
21
|
cache = Marshal.load(File.binread(cache_file))
|
22
22
|
if cache.version == MIME::Types::Data::VERSION
|
23
23
|
Marshal.load(cache.data)
|
24
24
|
else
|
25
|
-
MIME::Types.logger.warn
|
26
|
-
Could not load MIME::Types cache: invalid version
|
25
|
+
MIME::Types.logger.warn <<~WARNING.chomp
|
26
|
+
Could not load MIME::Types cache: invalid version
|
27
27
|
WARNING
|
28
28
|
nil
|
29
29
|
end
|
30
30
|
rescue => e
|
31
|
-
MIME::Types.logger.warn
|
32
|
-
Could not load MIME::Types cache: #{e}
|
31
|
+
MIME::Types.logger.warn <<~WARNING.chomp
|
32
|
+
Could not load MIME::Types cache: #{e}
|
33
33
|
WARNING
|
34
34
|
nil
|
35
35
|
end
|
@@ -44,12 +44,12 @@ Could not load MIME::Types cache: #{e}
|
|
44
44
|
# +RUBY_MIME_TYPES_CACHE+. If there is no cache file specified either
|
45
45
|
# directly or through the environment, this method will return +nil+
|
46
46
|
def save(types = nil, cache_file = nil)
|
47
|
-
cache_file ||= ENV[
|
47
|
+
cache_file ||= ENV["RUBY_MIME_TYPES_CACHE"]
|
48
48
|
return nil unless cache_file
|
49
49
|
|
50
50
|
types ||= MIME::Types.send(:__types__)
|
51
51
|
|
52
|
-
File.open(cache_file,
|
52
|
+
File.open(cache_file, "wb") do |f|
|
53
53
|
f.write(
|
54
54
|
Marshal.dump(new(MIME::Types::Data::VERSION, Marshal.dump(types)))
|
55
55
|
)
|
data/lib/mime/types/columnar.rb
CHANGED
data/lib/mime/types/container.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "set"
|
4
|
+
require "forwardable"
|
5
5
|
|
6
6
|
# MIME::Types requires a serializable keyed container that returns an empty Set
|
7
7
|
# on a key miss. Hash#default_value cannot be used because, while it traverses
|
@@ -9,7 +9,7 @@ require 'forwardable'
|
|
9
9
|
# format (plus, a default of a mutable object resuls in a shared mess).
|
10
10
|
# Hash#default_proc cannot be used without a wrapper because it prevents
|
11
11
|
# Marshal serialization (and doesn't survive the round-trip).
|
12
|
-
class MIME::Types::Container
|
12
|
+
class MIME::Types::Container # :nodoc:
|
13
13
|
extend Forwardable
|
14
14
|
|
15
15
|
def initialize(hash = {})
|
@@ -37,7 +37,7 @@ class MIME::Types::Container #:nodoc:
|
|
37
37
|
|
38
38
|
def merge!(other)
|
39
39
|
tap {
|
40
|
-
other = other.
|
40
|
+
other = other.is_a?(MIME::Types::Container) ? other.container : other
|
41
41
|
container.merge!(other)
|
42
42
|
normalize
|
43
43
|
}
|
@@ -48,15 +48,15 @@ class MIME::Types::Container #:nodoc:
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def_delegators :@container,
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
:==,
|
52
|
+
:count,
|
53
|
+
:each,
|
54
|
+
:each_value,
|
55
|
+
:empty?,
|
56
|
+
:flat_map,
|
57
|
+
:keys,
|
58
|
+
:select,
|
59
|
+
:values
|
60
60
|
|
61
61
|
def add(key, value)
|
62
62
|
(container[key] ||= Set.new).add(value)
|
@@ -85,7 +85,7 @@ class MIME::Types::Container #:nodoc:
|
|
85
85
|
|
86
86
|
def normalize
|
87
87
|
container.each do |k, v|
|
88
|
-
next if v.
|
88
|
+
next if v.is_a?(Set)
|
89
89
|
|
90
90
|
container[k] = Set[*v]
|
91
91
|
end
|