mime-types 2.99.3 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/{Code-of-Conduct.rdoc → Code-of-Conduct.md} +19 -20
  3. data/Contributing.md +143 -0
  4. data/History.md +240 -0
  5. data/{Licence.rdoc → Licence.md} +4 -18
  6. data/Manifest.txt +8 -25
  7. data/README.rdoc +62 -73
  8. data/Rakefile +175 -58
  9. data/lib/mime-types.rb +1 -1
  10. data/lib/mime/type.rb +213 -424
  11. data/lib/mime/type/columnar.rb +29 -62
  12. data/lib/mime/types.rb +46 -141
  13. data/lib/mime/types/_columnar.rb +136 -0
  14. data/lib/mime/types/cache.rb +51 -73
  15. data/lib/mime/types/columnar.rb +2 -147
  16. data/lib/mime/types/container.rb +96 -0
  17. data/lib/mime/types/deprecations.rb +4 -25
  18. data/lib/mime/types/full.rb +19 -0
  19. data/lib/mime/types/loader.rb +12 -141
  20. data/lib/mime/types/logger.rb +5 -1
  21. data/lib/mime/types/registry.rb +90 -0
  22. data/test/minitest_helper.rb +5 -13
  23. data/test/test_mime_type.rb +470 -456
  24. data/test/test_mime_types.rb +135 -87
  25. data/test/test_mime_types_cache.rb +82 -54
  26. data/test/test_mime_types_class.rb +118 -98
  27. data/test/test_mime_types_lazy.rb +26 -24
  28. data/test/test_mime_types_loader.rb +6 -33
  29. metadata +107 -64
  30. data/Contributing.rdoc +0 -170
  31. data/History-Types.rdoc +0 -454
  32. data/History.rdoc +0 -590
  33. data/data/mime-types.json +0 -1
  34. data/data/mime.content_type.column +0 -1980
  35. data/data/mime.docs.column +0 -1980
  36. data/data/mime.encoding.column +0 -1980
  37. data/data/mime.friendly.column +0 -1980
  38. data/data/mime.obsolete.column +0 -1980
  39. data/data/mime.registered.column +0 -1980
  40. data/data/mime.signature.column +0 -1980
  41. data/data/mime.use_instead.column +0 -1980
  42. data/data/mime.xrefs.column +0 -1980
  43. data/docs/COPYING.txt +0 -339
  44. data/docs/artistic.txt +0 -127
  45. data/lib/mime/types/loader_path.rb +0 -15
  46. data/support/apache_mime_types.rb +0 -108
  47. data/support/benchmarks/load.rb +0 -64
  48. data/support/benchmarks/load_allocations.rb +0 -83
  49. data/support/benchmarks/object_counts.rb +0 -41
  50. data/support/convert.rb +0 -158
  51. data/support/convert/columnar.rb +0 -88
  52. data/support/iana_registry.rb +0 -172
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mime/type'
2
4
 
3
5
  # A version of MIME::Type that works hand-in-hand with a MIME::Types::Columnar
@@ -11,80 +13,45 @@ require 'mime/type'
11
13
  # MIME::Type::Columnar is *not* intended to be created except by
12
14
  # MIME::Types::Columnar containers.
13
15
  class MIME::Type::Columnar < MIME::Type
14
- attr_writer :friendly # :nodoc:
15
-
16
16
  def initialize(container, content_type, extensions) # :nodoc:
17
17
  @container = container
18
18
  self.content_type = content_type
19
19
  self.extensions = extensions
20
20
  end
21
21
 
22
- def friendly(*) # :nodoc:
23
- @container.send(:load_friendly) unless defined?(@friendly)
24
- super if @friendly
25
- end
26
-
27
- def encoding # :nodoc:
28
- @container.send(:load_encoding) unless defined?(@encoding)
29
- @encoding
30
- end
31
-
32
- def docs # :nodoc:
33
- @container.send(:load_docs) unless defined?(@docs)
34
- @docs
35
- end
36
-
37
- def obsolete? # :nodoc:
38
- @container.send(:load_obsolete) unless defined?(@obsolete)
39
- super
40
- end
41
-
42
- def registered? # :nodoc:
43
- @container.send(:load_registered) unless defined?(@registered)
44
- super
45
- end
46
-
47
- def signature? # :nodoc:
48
- @container.send(:load_signature) unless defined?(@signature)
49
- super
50
- end
22
+ def self.column(*methods, file: nil) # :nodoc:
23
+ file ||= methods.first
51
24
 
52
- def xrefs # :nodoc:
53
- @container.send(:load_xrefs) unless defined?(@xrefs)
54
- @xrefs
25
+ file_method = :"load_#{file}"
26
+ methods.each do |m|
27
+ define_method m do |*args|
28
+ @container.send(file_method)
29
+ super(*args)
30
+ end
31
+ end
55
32
  end
56
33
 
57
- def use_instead # :nodoc:
58
- @container.send(:load_use_instead) unless defined?(@use_instead)
59
- @use_instead
60
- end
61
-
62
- def binary? # :nodoc:
63
- @container.send(:load_encoding) unless defined?(@encoding)
64
- super
65
- end
34
+ column :friendly
35
+ column :encoding, :encoding=
36
+ column :docs, :docs=
37
+ column :preferred_extension, :preferred_extension=
38
+ column :obsolete, :obsolete=, :obsolete?, :registered, :registered=,
39
+ :registered?, :signature, :signature=, :signature?, file: 'flags'
40
+ column :xrefs, :xrefs=, :xref_urls
41
+ column :use_instead, :use_instead=
66
42
 
67
- def to_a # :nodoc:
68
- @container.send(:load_encoding) unless defined?(@encoding)
69
- @container.send(:load_docs) unless defined?(@docs)
70
- super
71
- end
72
-
73
- def to_hash # :nodoc:
74
- @container.send(:load_encoding) unless defined?(@encoding)
75
- @container.send(:load_docs) unless defined?(@docs)
43
+ def encode_with(coder) # :nodoc:
44
+ @container.send(:load_friendly)
45
+ @container.send(:load_encoding)
46
+ @container.send(:load_docs)
47
+ @container.send(:load_flags)
48
+ @container.send(:load_use_instead)
49
+ @container.send(:load_xrefs)
50
+ @container.send(:load_preferred_extension)
76
51
  super
77
52
  end
78
53
 
79
- def encode_with(coder) # :nodoc:
80
- @container.send(:load_friendly) unless defined?(@friendly)
81
- @container.send(:load_encoding) unless defined?(@encoding)
82
- @container.send(:load_docs) unless defined?(@docs)
83
- @container.send(:load_obsolete) unless defined?(@obsolete)
84
- @container.send(:load_use_instead) unless defined?(@use_instead)
85
- @container.send(:load_xrefs) unless defined?(@xrefs)
86
- @container.send(:load_registered) unless defined?(@registered)
87
- @container.send(:load_signature) unless defined?(@signature)
88
- super
54
+ class << self
55
+ undef column
89
56
  end
90
57
  end
@@ -1,9 +1,13 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ module MIME
5
+ ##
6
+ class Types
7
+ end
8
+ end
2
9
 
3
- require 'mime/types/deprecations'
4
10
  require 'mime/type'
5
- require 'mime/types/cache'
6
- require 'mime/types/loader'
7
11
 
8
12
  # MIME::Types is a registry of MIME types. It is both a class (created with
9
13
  # MIME::Types.new) and a default registry (loaded automatically or through
@@ -66,37 +70,19 @@ class MIME::Types
66
70
 
67
71
  include Enumerable
68
72
 
69
- # The data version.
70
- attr_reader :data_version
71
-
72
73
  # Creates a new MIME::Types registry.
73
74
  def initialize
74
75
  @type_variants = Container.new
75
76
  @extension_index = Container.new
76
- @data_version = VERSION.dup.freeze
77
- end
78
-
79
- # This method is deprecated and will be removed in mime-types 3.0.
80
- def add_type_variant(mime_type) # :nodoc:
81
- MIME::Types.deprecated(self, __method__, :private)
82
- add_type_variant!(mime_type)
83
- end
84
-
85
- # This method is deprecated and will be removed in mime-types 3.0.
86
- def index_extensions(mime_type) # :nodoc:
87
- MIME::Types.deprecated(self, __method__, :private)
88
- index_extensions!(mime_type)
89
- end
90
-
91
- # This method is deprecated and will be removed in mime-types 3.0.
92
- def defined_types # :nodoc:
93
- MIME::Types.deprecated(self, __method__)
94
- @type_variants.values.flatten
95
77
  end
96
78
 
97
79
  # Returns the number of known type variants.
98
80
  def count
99
- @type_variants.values.reduce(0) { |m, o| m + o.size }
81
+ @type_variants.values.inject(0) { |a, e| a + e.size }
82
+ end
83
+
84
+ def inspect # :nodoc:
85
+ "#<#{self.class}: #{count} variants, #{@extension_index.count} extensions>"
100
86
  end
101
87
 
102
88
  # Iterates through the type variants.
@@ -108,7 +94,7 @@ class MIME::Types
108
94
  end
109
95
  end
110
96
 
111
- @__types__ = nil
97
+ @__types__ = nil
112
98
 
113
99
  # Returns a list of MIME::Type objects, which may be empty. The optional
114
100
  # flag parameters are <tt>:complete</tt> (finds only complete MIME::Type
@@ -135,13 +121,7 @@ class MIME::Types
135
121
  # without;
136
122
  # 5. Obsolete definitions use-instead clauses are compared.
137
123
  # 6. Sort on name.
138
- #
139
- # The previously supported (but deprecated) <tt>:platform</tt> flag is now ignored.
140
- def [](type_id, flags = {})
141
- if flags.key?(:platform)
142
- MIME::Types.deprecated(self, __method__, 'using the :platform flag')
143
- end
144
-
124
+ def [](type_id, complete: false, registered: false)
145
125
  matches = case type_id
146
126
  when MIME::Type
147
127
  @type_variants[type_id.simplified]
@@ -151,7 +131,9 @@ class MIME::Types
151
131
  @type_variants[MIME::Type.simplified(type_id)]
152
132
  end
153
133
 
154
- prune_matches(matches, flags).sort { |a, b| a.priority_compare(b) }
134
+ prune_matches(matches, complete, registered).sort { |a, b|
135
+ a.priority_compare(b)
136
+ }
155
137
  end
156
138
 
157
139
  # Return the list of MIME::Types which belongs to the file based on its
@@ -166,19 +148,14 @@ class MIME::Types
166
148
  # => [image/gif]
167
149
  # puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
168
150
  # => [application/xml, image/gif, text/xml]
169
- #
170
- # The deprecated +platform+ flag is ignored.
171
- def type_for(filename, platform = :deprecated)
172
- types = Array(filename).flat_map { |fn|
151
+ def type_for(filename)
152
+ Array(filename).flat_map { |fn|
173
153
  @extension_index[fn.chomp.downcase[/\.?([^.]*?)$/, 1]]
174
- }.compact.sort { |a, b| a.priority_compare(b) }.uniq
175
-
176
- unless platform == :deprecated
177
- MIME::Types.deprecated(self, __method__, 'using the platform parameter')
178
- end
179
- types
154
+ }.compact.inject(Set.new, :+).sort { |a, b|
155
+ a.priority_compare(b)
156
+ }
180
157
  end
181
- alias_method :of, :type_for
158
+ alias of type_for
182
159
 
183
160
  # Add one or more MIME::Type objects to the set of known types. If the
184
161
  # type is already known, a warning will be displayed.
@@ -194,7 +171,7 @@ class MIME::Types
194
171
  nil
195
172
  when MIME::Types
196
173
  variants = mime_type.instance_variable_get(:@type_variants)
197
- add(*variants.values.flatten, quiet)
174
+ add(*variants.values.inject(Set.new, :+).to_a, quiet)
198
175
  when Array
199
176
  add(*mime_type, quiet)
200
177
  else
@@ -208,119 +185,47 @@ class MIME::Types
208
185
  # truthy value to suppress that warning.
209
186
  def add_type(type, quiet = false)
210
187
  if !quiet and @type_variants[type.simplified].include?(type)
211
- MIME::Types.logger.warn <<-warning
188
+ MIME::Types.logger.warn <<-WARNING
212
189
  Type #{type} is already registered as a variant of #{type.simplified}.
213
- warning
190
+ WARNING
214
191
  end
215
192
 
216
193
  add_type_variant!(type)
217
194
  index_extensions!(type)
218
195
  end
219
196
 
220
- class << self
221
- include Enumerable
222
-
223
- # Load MIME::Types from a v1 file registry.
224
- #
225
- # This method has been deprecated and will be removed in mime-types 3.0.
226
- def load_from_file(filename)
227
- MIME::Types.deprecated(self, __method__)
228
- MIME::Types::Loader.load_from_v1(filename)
229
- end
230
-
231
- # MIME::Types#[] against the default MIME::Types registry.
232
- def [](type_id, flags = {})
233
- __types__[type_id, flags]
234
- end
235
-
236
- # MIME::Types#count against the default MIME::Types registry.
237
- def count
238
- __types__.count
239
- end
240
-
241
- # MIME::Types#each against the default MIME::Types registry.
242
- def each
243
- if block_given?
244
- __types__.each { |t| yield t }
245
- else
246
- enum_for(:each)
247
- end
248
- end
249
-
250
- # MIME::Types#type_for against the default MIME::Types registry.
251
- def type_for(filename, platform = :deprecated)
252
- __types__.type_for(filename, platform)
253
- end
254
- alias_method :of, :type_for
255
-
256
- # MIME::Types#add against the default MIME::Types registry.
257
- def add(*types)
258
- __types__.add(*types)
259
- end
260
-
261
- # Returns the currently defined cache file, if any.
262
- #
263
- # This method has been deprecated and will be removed in mime-types 3.0.
264
- def cache_file
265
- MIME::Types.deprecated(self, __method__)
266
- ENV['RUBY_MIME_TYPES_CACHE']
267
- end
268
-
269
- def add_type_variant(mime_type) # :nodoc:
270
- __types__.add_type_variant(mime_type)
271
- end
272
-
273
- def index_extensions(mime_type) # :nodoc:
274
- __types__.index_extensions(mime_type)
275
- end
276
-
277
- private
278
-
279
- def lazy_load?
280
- (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
281
- end
282
-
283
- def __types__
284
- (defined?(@__types__) and @__types__) or load_default_mime_types
285
- end
286
-
287
- unless private_method_defined?(:load_mode)
288
- def load_mode
289
- {}
290
- end
291
- end
197
+ private
292
198
 
293
- def load_default_mime_types(mode = load_mode())
294
- @__types__ = MIME::Types::Cache.load
295
- unless @__types__
296
- @__types__ = MIME::Types::Loader.load(mode)
297
- MIME::Types::Cache.save(@__types__)
298
- end
299
- @__types__
300
- end
199
+ def add_type_variant!(mime_type)
200
+ @type_variants.add(mime_type.simplified, mime_type)
301
201
  end
302
202
 
303
- private
203
+ def reindex_extensions!(mime_type)
204
+ return unless @type_variants[mime_type.simplified].include?(mime_type)
304
205
 
305
- def add_type_variant!(mime_type)
306
- @type_variants[mime_type.simplified] << mime_type
206
+ index_extensions!(mime_type)
307
207
  end
308
208
 
309
209
  def index_extensions!(mime_type)
310
- mime_type.extensions.each { |ext| @extension_index[ext] << mime_type }
210
+ mime_type.extensions.each { |ext| @extension_index.add(ext, mime_type) }
311
211
  end
312
212
 
313
- def prune_matches(matches, flags)
314
- matches.delete_if { |e| !e.complete? } if flags[:complete]
315
- matches.delete_if { |e| !e.registered? } if flags[:registered]
213
+ def prune_matches(matches, complete, registered)
214
+ matches.delete_if { |e| !e.complete? } if complete
215
+ matches.delete_if { |e| !e.registered? } if registered
316
216
  matches
317
217
  end
318
218
 
319
219
  def match(pattern)
320
- @type_variants.select { |k, _| k =~ pattern }.values.flatten
220
+ @type_variants.select { |k, _|
221
+ k =~ pattern
222
+ }.values.inject(Set.new, :+)
321
223
  end
322
-
323
- load_default_mime_types(load_mode) unless lazy_load?
324
224
  end
325
225
 
326
- # vim: ft=ruby
226
+ require 'mime/types/cache'
227
+ require 'mime/types/container'
228
+ require 'mime/types/loader'
229
+ require 'mime/types/logger'
230
+ require 'mime/types/_columnar'
231
+ require 'mime/types/registry'
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mime/type/columnar'
4
+
5
+ # MIME::Types::Columnar is used to extend a MIME::Types container to load data
6
+ # by columns instead of from JSON or YAML. Column loads of MIME types loaded
7
+ # through the columnar store are synchronized with a Mutex.
8
+ #
9
+ # MIME::Types::Columnar is not intended to be used directly, but will be added
10
+ # to an instance of MIME::Types when it is loaded with
11
+ # MIME::Types::Loader#load_columnar.
12
+ module MIME::Types::Columnar
13
+ LOAD_MUTEX = Mutex.new # :nodoc:
14
+
15
+ def self.extended(obj) # :nodoc:
16
+ super
17
+ obj.instance_variable_set(:@__mime_data__, [])
18
+ obj.instance_variable_set(:@__files__, Set.new)
19
+ end
20
+
21
+ # Load the first column data file (type and extensions).
22
+ def load_base_data(path) #:nodoc:
23
+ @__root__ = path
24
+
25
+ each_file_line('content_type', false) do |line|
26
+ line = line.split
27
+ content_type = line.shift
28
+ extensions = line
29
+ # content_type, *extensions = line.split
30
+
31
+ type = MIME::Type::Columnar.new(self, content_type, extensions)
32
+ @__mime_data__ << type
33
+ add(type)
34
+ end
35
+
36
+ self
37
+ end
38
+
39
+ private
40
+
41
+ def each_file_line(name, lookup = true)
42
+ LOAD_MUTEX.synchronize do
43
+ next if @__files__.include?(name)
44
+
45
+ i = -1
46
+ column = File.join(@__root__, "mime.#{name}.column")
47
+
48
+ IO.readlines(column, encoding: 'UTF-8').each do |line|
49
+ line.chomp!
50
+
51
+ if lookup
52
+ type = @__mime_data__[i += 1] or next
53
+ yield type, line
54
+ else
55
+ yield line
56
+ end
57
+ end
58
+
59
+ @__files__ << name
60
+ end
61
+ end
62
+
63
+ def load_encoding
64
+ each_file_line('encoding') do |type, line|
65
+ pool ||= {}
66
+ type.instance_variable_set(:@encoding, (pool[line] ||= line))
67
+ end
68
+ end
69
+
70
+ def load_docs
71
+ each_file_line('docs') do |type, line|
72
+ type.instance_variable_set(:@docs, opt(line))
73
+ end
74
+ end
75
+
76
+ def load_preferred_extension
77
+ each_file_line('pext') do |type, line|
78
+ type.instance_variable_set(:@preferred_extension, opt(line))
79
+ end
80
+ end
81
+
82
+ def load_flags
83
+ each_file_line('flags') do |type, line|
84
+ line = line.split
85
+ type.instance_variable_set(:@obsolete, flag(line.shift))
86
+ type.instance_variable_set(:@registered, flag(line.shift))
87
+ type.instance_variable_set(:@signature, flag(line.shift))
88
+ end
89
+ end
90
+
91
+ def load_xrefs
92
+ each_file_line('xrefs') { |type, line|
93
+ type.instance_variable_set(:@xrefs, dict(line, array: true))
94
+ }
95
+ end
96
+
97
+ def load_friendly
98
+ each_file_line('friendly') { |type, line|
99
+ type.instance_variable_set(:@friendly, dict(line))
100
+ }
101
+ end
102
+
103
+ def load_use_instead
104
+ each_file_line('use_instead') do |type, line|
105
+ type.instance_variable_set(:@use_instead, opt(line))
106
+ end
107
+ end
108
+
109
+ def dict(line, array: false)
110
+ if line == '-'
111
+ {}
112
+ else
113
+ line.split('|').each_with_object({}) { |l, h|
114
+ k, v = l.split('^')
115
+ v = nil if v.empty?
116
+ h[k] = array ? Array(v) : v
117
+ }
118
+ end
119
+ end
120
+
121
+ def arr(line)
122
+ if line == '-'
123
+ []
124
+ else
125
+ line.split('|').flatten.compact.uniq
126
+ end
127
+ end
128
+
129
+ def opt(line)
130
+ line unless line == '-'
131
+ end
132
+
133
+ def flag(line)
134
+ line == '1'
135
+ end
136
+ end