mime-types 2.5 → 2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Contributing.rdoc +72 -20
  4. data/History-Types.rdoc +11 -0
  5. data/History.rdoc +31 -1
  6. data/Manifest.txt +18 -1
  7. data/README.rdoc +142 -61
  8. data/Rakefile +59 -91
  9. data/data/mime-types.json +1 -1
  10. data/data/mime.content_type.column +1907 -0
  11. data/data/mime.docs.column +1907 -0
  12. data/data/mime.encoding.column +1907 -0
  13. data/data/mime.friendly.column +1907 -0
  14. data/data/mime.obsolete.column +1907 -0
  15. data/data/mime.references.column +1907 -0
  16. data/data/mime.registered.column +1907 -0
  17. data/data/mime.signature.column +1907 -0
  18. data/data/mime.system.column +1907 -0
  19. data/data/mime.use_instead.column +1907 -0
  20. data/data/mime.xrefs.column +1907 -0
  21. data/lib/mime/type.rb +192 -119
  22. data/lib/mime/type/columnar.rb +112 -0
  23. data/lib/mime/types.rb +39 -25
  24. data/lib/mime/types/cache.rb +41 -35
  25. data/lib/mime/types/columnar.rb +160 -0
  26. data/lib/mime/types/deprecations.rb +53 -0
  27. data/lib/mime/types/loader.rb +60 -20
  28. data/lib/mime/types/loader_path.rb +2 -3
  29. data/lib/mime/types/logger.rb +35 -0
  30. data/support/apache_mime_types.rb +8 -1
  31. data/support/benchmarks/load.rb +17 -8
  32. data/support/benchmarks/load_allocations.rb +83 -0
  33. data/support/benchmarks/object_counts.rb +41 -0
  34. data/support/convert.rb +44 -24
  35. data/support/convert/columnar.rb +90 -0
  36. data/support/iana_registry.rb +18 -8
  37. data/test/fixture/json.json +1 -1
  38. data/test/fixture/yaml.yaml +3 -6
  39. data/test/minitest_helper.rb +9 -10
  40. data/test/test_mime_type.rb +126 -62
  41. data/test/test_mime_types.rb +15 -11
  42. data/test/test_mime_types_class.rb +16 -14
  43. data/test/test_mime_types_lazy.rb +7 -1
  44. data/test/test_mime_types_loader.rb +17 -8
  45. metadata +54 -12
  46. data/lib/mime.rb +0 -51
@@ -0,0 +1,112 @@
1
+ require 'mime/type'
2
+
3
+ # A version of MIME::Type that works hand-in-hand with a MIME::Types::Columnar
4
+ # container to load data by columns.
5
+ #
6
+ # When a field is has not yet been loaded, that data will be loaded for all
7
+ # types in the container before forwarding the message to MIME::Type.
8
+ #
9
+ # More information can be found in MIME::Types::Columnar.
10
+ #
11
+ # MIME::Type::Columnar is *not* intended to be created except by
12
+ # MIME::Types::Columnar containers.
13
+ class MIME::Type::Columnar < MIME::Type
14
+ attr_writer :friendly # :nodoc:
15
+
16
+ def initialize(container, content_type, extensions) # :nodoc:
17
+ @container = container
18
+ self.content_type = content_type
19
+ self.extensions = extensions
20
+ end
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 references(*) # :nodoc:
43
+ @container.send(:load_references) unless defined?(@references)
44
+ super if @references
45
+ end
46
+
47
+ def registered? # :nodoc:
48
+ @container.send(:load_registered) unless defined?(@registered)
49
+ super
50
+ end
51
+
52
+ def signature? # :nodoc:
53
+ @container.send(:load_signature) unless defined?(@signature)
54
+ super
55
+ end
56
+
57
+ def system?(*) # :nodoc:
58
+ @container.send(:load_system) unless defined?(@system)
59
+ super
60
+ end
61
+
62
+ def system # :nodoc:
63
+ @container.send(:load_system) unless defined?(@system)
64
+ @system
65
+ end
66
+
67
+ def xrefs # :nodoc:
68
+ @container.send(:load_xrefs) unless defined?(@xrefs)
69
+ @xrefs
70
+ end
71
+
72
+ def use_instead # :nodoc:
73
+ @container.send(:load_use_instead) unless defined?(@use_instead)
74
+ @use_instead
75
+ end
76
+
77
+ def binary? # :nodoc:
78
+ @container.send(:load_encoding) unless defined?(@encoding)
79
+ super
80
+ end
81
+
82
+ def to_a # :nodoc:
83
+ @container.send(:load_encoding) unless defined?(@encoding)
84
+ @container.send(:load_system) unless defined?(@system)
85
+ @container.send(:load_docs) unless defined?(@docs)
86
+ @container.send(:load_references) unless defined?(@references)
87
+ super
88
+ end
89
+
90
+ def to_hash # :nodoc:
91
+ @container.send(:load_encoding) unless defined?(@encoding)
92
+ @container.send(:load_system) unless defined?(@system)
93
+ @container.send(:load_docs) unless defined?(@docs)
94
+ @container.send(:load_references) unless defined?(@references)
95
+ super
96
+ end
97
+
98
+ def encode_with(coder) # :nodoc:
99
+ @container.send(:load_friendly) unless defined?(@friendly)
100
+ @container.send(:load_encoding) unless defined?(@encoding)
101
+ @container.send(:load_system) unless defined?(@system)
102
+ @container.send(:load_docs) unless defined?(@docs)
103
+ @container.send(:load_references) unless defined?(@references)
104
+ @container.send(:load_obsolete) unless defined?(@obsolete)
105
+ @container.send(:load_use_instead) unless defined?(@use_instead)
106
+ @container.send(:load_xrefs) unless defined?(@xrefs)
107
+ @container.send(:load_system) unless defined?(@system)
108
+ @container.send(:load_registered) unless defined?(@registered)
109
+ @container.send(:load_signature) unless defined?(@signature)
110
+ super
111
+ end
112
+ end
@@ -1,5 +1,6 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
 
3
+ require 'mime/types/deprecations'
3
4
  require 'mime/type'
4
5
  require 'mime/types/cache'
5
6
  require 'mime/types/loader'
@@ -75,18 +76,21 @@ class MIME::Types
75
76
  @data_version = VERSION.dup.freeze
76
77
  end
77
78
 
79
+ # This method is deprecated and will be removed in mime-types 3.0.
78
80
  def add_type_variant(mime_type) # :nodoc:
79
- MIME.deprecated(self, __method__, :private)
81
+ MIME::Types.deprecated(self, __method__, :private)
80
82
  add_type_variant!(mime_type)
81
83
  end
82
84
 
85
+ # This method is deprecated and will be removed in mime-types 3.0.
83
86
  def index_extensions(mime_type) # :nodoc:
84
- MIME.deprecated(self, __method__, :private)
87
+ MIME::Types.deprecated(self, __method__, :private)
85
88
  index_extensions!(mime_type)
86
89
  end
87
90
 
91
+ # This method is deprecated and will be removed in mime-types 3.0.
88
92
  def defined_types # :nodoc:
89
- MIME.deprecated(self, __method__)
93
+ MIME::Types.deprecated(self, __method__)
90
94
  @type_variants.values.flatten
91
95
  end
92
96
 
@@ -137,7 +141,7 @@ class MIME::Types
137
141
  # platform) is currently supported but deprecated.
138
142
  def [](type_id, flags = {})
139
143
  if flags[:platform]
140
- MIME.deprecated(self, __method__, "using the :platform flag")
144
+ MIME::Types.deprecated(self, __method__, 'using the :platform flag')
141
145
  end
142
146
 
143
147
  matches = case type_id
@@ -173,8 +177,7 @@ class MIME::Types
173
177
  }.compact.sort { |a, b| a.priority_compare(b) }.uniq
174
178
 
175
179
  if platform
176
- MIME.deprecated(self, __method__,
177
- "using the platform parameter")
180
+ MIME::Types.deprecated(self, __method__, 'using the platform parameter')
178
181
  types.select(&:platform?)
179
182
  else
180
183
  types
@@ -205,17 +208,18 @@ class MIME::Types
205
208
  end
206
209
  end
207
210
 
208
- # Add a single MIME::Type object to the set of known types. If the type is
209
- # already known, a warning will be displayed. The +quiet+ parameter may be
210
- # a truthy value to suppress that warning.
211
- def add_type(mime_type, quiet = false)
212
- if !quiet and @type_variants[mime_type.simplified].include?(mime_type)
213
- warn('Type %s is already registered as a variant of %s.' %
214
- [ mime_type, mime_type.simplified ])
211
+ # Add a single MIME::Type object to the set of known types. If the +type+ is
212
+ # already known, a warning will be displayed. The +quiet+ parameter may be a
213
+ # truthy value to suppress that warning.
214
+ def add_type(type, quiet = false)
215
+ if !quiet and @type_variants[type.simplified].include?(type)
216
+ MIME::Types.logger.warn <<-warning
217
+ Type #{type} is already registered as a variant of #{type.simplified}.
218
+ warning
215
219
  end
216
220
 
217
- add_type_variant!(mime_type)
218
- index_extensions!(mime_type)
221
+ add_type_variant!(type)
222
+ index_extensions!(type)
219
223
  end
220
224
 
221
225
  class << self
@@ -223,9 +227,9 @@ class MIME::Types
223
227
 
224
228
  # Load MIME::Types from a v1 file registry.
225
229
  #
226
- # This method has been deprecated.
230
+ # This method has been deprecated and will be removed in mime-types 3.0.
227
231
  def load_from_file(filename)
228
- MIME.deprecated(self, __method__)
232
+ MIME::Types.deprecated(self, __method__)
229
233
  MIME::Types::Loader.load_from_v1(filename)
230
234
  end
231
235
 
@@ -260,8 +264,10 @@ class MIME::Types
260
264
  end
261
265
 
262
266
  # Returns the currently defined cache file, if any.
267
+ #
268
+ # This method has been deprecated and will be removed in mime-types 3.0.
263
269
  def cache_file
264
- MIME.deprecated(self, __method__)
270
+ MIME::Types.deprecated(self, __method__)
265
271
  ENV['RUBY_MIME_TYPES_CACHE']
266
272
  end
267
273
 
@@ -274,6 +280,7 @@ class MIME::Types
274
280
  end
275
281
 
276
282
  private
283
+
277
284
  def lazy_load?
278
285
  (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
279
286
  end
@@ -282,10 +289,16 @@ class MIME::Types
282
289
  (defined?(@__types__) and @__types__) or load_default_mime_types
283
290
  end
284
291
 
285
- def load_default_mime_types
292
+ unless private_method_defined?(:load_mode)
293
+ def load_mode
294
+ {}
295
+ end
296
+ end
297
+
298
+ def load_default_mime_types(mode = load_mode())
286
299
  @__types__ = MIME::Types::Cache.load
287
300
  unless @__types__
288
- @__types__ = MIME::Types::Loader.load
301
+ @__types__ = MIME::Types::Loader.load(mode)
289
302
  MIME::Types::Cache.save(@__types__)
290
303
  end
291
304
  @__types__
@@ -293,6 +306,7 @@ class MIME::Types
293
306
  end
294
307
 
295
308
  private
309
+
296
310
  def add_type_variant!(mime_type)
297
311
  @type_variants[mime_type.simplified] << mime_type
298
312
  end
@@ -302,17 +316,17 @@ class MIME::Types
302
316
  end
303
317
 
304
318
  def prune_matches(matches, flags)
305
- matches.delete_if { |e| not e.complete? } if flags[:complete]
306
- matches.delete_if { |e| not e.platform? } if flags[:platform]
307
- matches.delete_if { |e| not e.registered? } if flags[:registered]
319
+ matches.delete_if { |e| !e.complete? } if flags[:complete]
320
+ matches.delete_if { |e| !e.platform? } if flags[:platform]
321
+ matches.delete_if { |e| !e.registered? } if flags[:registered]
308
322
  matches
309
323
  end
310
324
 
311
325
  def match(pattern)
312
- @type_variants.select { |k, v| k =~ pattern }.values.flatten
326
+ @type_variants.select { |k, _| k =~ pattern }.values.flatten
313
327
  end
314
328
 
315
- load_default_mime_types unless lazy_load?
329
+ load_default_mime_types(load_mode) unless lazy_load?
316
330
  end
317
331
 
318
332
  # vim: ft=ruby
@@ -1,6 +1,8 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
 
3
3
  class MIME::Types
4
+ Cache = Struct.new(:version, :data) # :nodoc:
5
+
4
6
  # Caching of MIME::Types registries is advisable if you will be loading
5
7
  # the default registry relatively frequently. With the class methods on
6
8
  # MIME::Types::Cache, any MIME::Types registry can be marshaled quickly
@@ -8,46 +10,50 @@ class MIME::Types
8
10
  #
9
11
  # The cache is invalidated on a per-version basis; a cache file for
10
12
  # version 2.0 will not be reused with version 2.0.1.
11
- Cache = Struct.new(:version, :data)
12
-
13
- class << Cache
14
- # Attempts to load the cache from the file provided as a parameter or in
15
- # the environment variable +RUBY_MIME_TYPES_CACHE+. Returns +nil+ if the
16
- # file does not exist, if the file cannot be loaded, or if the data in
17
- # the cache version is different than this version.
18
- def load(cache_file = nil)
19
- cache_file = cache_file || ENV['RUBY_MIME_TYPES_CACHE']
20
- return nil unless cache_file and File.exist?(cache_file)
13
+ class Cache
14
+ class << self
15
+ # Attempts to load the cache from the file provided as a parameter or in
16
+ # the environment variable +RUBY_MIME_TYPES_CACHE+. Returns +nil+ if the
17
+ # file does not exist, if the file cannot be loaded, or if the data in
18
+ # the cache version is different than this version.
19
+ def load(cache_file = nil)
20
+ cache_file ||= ENV['RUBY_MIME_TYPES_CACHE']
21
+ return nil unless cache_file and File.exist?(cache_file)
21
22
 
22
- cache = Marshal.load(File.binread(cache_file))
23
- if cache.version == MIME::Types::VERSION
24
- Marshal.load(cache.data)
25
- else
26
- warn "Could not load MIME::Types cache: invalid version"
27
- nil
23
+ cache = Marshal.load(File.binread(cache_file))
24
+ if cache.version == MIME::Types::VERSION
25
+ Marshal.load(cache.data)
26
+ else
27
+ MIME::Types.logger.warn <<-warning.chomp
28
+ Could not load MIME::Types cache: invalid version
29
+ warning
30
+ nil
31
+ end
32
+ rescue => e
33
+ MIME::Types.logger.warn <<-warning.chomp
34
+ Could not load MIME::Types cache: #{e}
35
+ warning
36
+ return nil
28
37
  end
29
- rescue => e
30
- warn "Could not load MIME::Types cache: #{e}"
31
- return nil
32
- end
33
38
 
34
- # Attempts to save the types provided to the cache file provided.
35
- #
36
- # If +types+ is not provided or is +nil+, the cache will contain the
37
- # current MIME::Types default registry.
38
- #
39
- # If +cache_file+ is not provided or is +nil+, the cache will be written
40
- # to the file specified in the environment variable
41
- # +RUBY_MIME_TYPES_CACHE+. If there is no cache file specified either
42
- # directly or through the environment, this method will return +nil+
43
- def save(types = nil, cache_file = nil)
44
- cache_file = cache_file || ENV['RUBY_MIME_TYPES_CACHE']
45
- return nil unless cache_file
39
+ # Attempts to save the types provided to the cache file provided.
40
+ #
41
+ # If +types+ is not provided or is +nil+, the cache will contain the
42
+ # current MIME::Types default registry.
43
+ #
44
+ # If +cache_file+ is not provided or is +nil+, the cache will be written
45
+ # to the file specified in the environment variable
46
+ # +RUBY_MIME_TYPES_CACHE+. If there is no cache file specified either
47
+ # directly or through the environment, this method will return +nil+
48
+ def save(types = nil, cache_file = nil)
49
+ cache_file ||= ENV['RUBY_MIME_TYPES_CACHE']
50
+ return nil unless cache_file
46
51
 
47
- types = types || MIME::Types.send(:__types__)
52
+ types ||= MIME::Types.send(:__types__)
48
53
 
49
- File.open(cache_file, 'wb') do |f|
50
- f.write(Marshal.dump(new(types.data_version, Marshal.dump(types))))
54
+ File.open(cache_file, 'wb') do |f|
55
+ f.write(Marshal.dump(new(types.data_version, Marshal.dump(types))))
56
+ end
51
57
  end
52
58
  end
53
59
  end
@@ -0,0 +1,160 @@
1
+ module MIME
2
+ class Types
3
+ end
4
+ end
5
+
6
+ require 'mime/type/columnar'
7
+
8
+ # MIME::Types::Columnar is used to extend a MIME::Types container to load data
9
+ # by columns instead of from JSON or YAML. Column loads of MIME types loaded
10
+ # through the columnar store are synchronized with a Mutex.
11
+ #
12
+ # MIME::Types::Columnar is not intended to be used directly, but will be added
13
+ # to an instance of MIME::Types when it is loaded with
14
+ # MIME::Types::Loader#load_columnar.
15
+ module MIME::Types::Columnar
16
+ LOAD_MUTEX = Mutex.new # :nodoc:
17
+
18
+ def self.extended(obj) # :nodoc:
19
+ super
20
+ obj.instance_variable_set(:@__mime_data__, [])
21
+ obj.instance_variable_set(:@__attributes__, [])
22
+ end
23
+
24
+ # Load the first column data file (type and extensions).
25
+ def load_base_data(path) #:nodoc:
26
+ @__root__ = path
27
+
28
+ each_file_line('content_type', false) do |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 @__attributes__.include?(name)
44
+
45
+ File.open(File.join(@__root__, "mime.#{name}.column"), 'r:UTF-8') do |f|
46
+ i = -1
47
+
48
+ f.each_line 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
+ end
59
+
60
+ @__attributes__ << name
61
+ end
62
+ end
63
+
64
+ def load_encoding
65
+ pool = {}
66
+ each_file_line('encoding') do |type, line|
67
+ line.freeze
68
+ type.encoding = (pool[line] ||= line)
69
+ end
70
+ end
71
+
72
+ def load_docs
73
+ each_file_line('docs') do |type, line|
74
+ type.docs = arr(line)
75
+ end
76
+ end
77
+
78
+ def load_obsolete
79
+ each_file_line('obsolete') do |type, line|
80
+ type.obsolete = bool(line)
81
+ end
82
+ end
83
+
84
+ def load_references
85
+ each_file_line('references') do |type, line|
86
+ type.instance_variable_set(:@references, arr(line))
87
+ end
88
+ end
89
+
90
+ def load_registered
91
+ each_file_line('registered') do |type, line|
92
+ type.registered = bool(line)
93
+ end
94
+ end
95
+
96
+ def load_signature
97
+ each_file_line('signature') do |type, line|
98
+ type.signature = bool(line)
99
+ end
100
+ end
101
+
102
+ def load_system
103
+ each_file_line('system') do |type, line|
104
+ type.system = (line unless line == '-'.freeze)
105
+ end
106
+ end
107
+
108
+ def load_xrefs
109
+ each_file_line('xrefs') { |type, line| type.xrefs = dict(line) }
110
+ end
111
+
112
+ def load_friendly
113
+ each_file_line('friendly') { |type, line|
114
+ v = dict(line)
115
+ type.friendly = v.empty? ? nil : v
116
+ }
117
+ end
118
+
119
+ def load_use_instead
120
+ each_file_line('use_instead') do |type, line|
121
+ type.use_instad = (line unless line == '-'.freeze)
122
+ end
123
+ end
124
+
125
+ def dict(line)
126
+ if line == '-'.freeze
127
+ {}
128
+ else
129
+ line.split('|'.freeze).each_with_object({}) { |h, l|
130
+ k, v = l.split('^'.freeze)
131
+ v = [ nil ] if v.empty?
132
+ h[k] = v
133
+ }
134
+ end
135
+ end
136
+
137
+ def arr(line)
138
+ if line == '-'.freeze
139
+ []
140
+ else
141
+ line.split('|'.freeze).flatten.compact.uniq
142
+ end
143
+ end
144
+
145
+ def bool(line)
146
+ line == '1'.freeze ? true : false
147
+ end
148
+ end
149
+
150
+ unless MIME::Types.private_method_defined?(:load_mode)
151
+ class << MIME::Types
152
+ private
153
+
154
+ def load_mode
155
+ { columnar: true }
156
+ end
157
+ end
158
+
159
+ require 'mime/types'
160
+ end