mime-types 2.99.3 → 3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.autotest +35 -0
  3. data/.gemtest +0 -0
  4. data/.gitignore +17 -0
  5. data/.hoerc +20 -0
  6. data/Code-of-Conduct.rdoc +27 -60
  7. data/Contributing.rdoc +0 -1
  8. data/History.rdoc +75 -36
  9. data/Licence.rdoc +2 -16
  10. data/Manifest.txt +10 -18
  11. data/README.rdoc +46 -46
  12. data/Rakefile +112 -58
  13. data/lib/mime-types.rb +0 -2
  14. data/lib/mime/type.rb +183 -415
  15. data/lib/mime/type/columnar.rb +27 -62
  16. data/lib/mime/types.rb +37 -135
  17. data/lib/mime/types/cache.rb +49 -73
  18. data/lib/mime/types/columnar.rb +42 -48
  19. data/lib/mime/types/container.rb +30 -0
  20. data/lib/mime/types/deprecations.rb +1 -22
  21. data/lib/mime/types/full.rb +17 -0
  22. data/lib/mime/types/loader.rb +10 -137
  23. data/lib/mime/types/logger.rb +2 -0
  24. data/lib/mime/types/registry.rb +81 -0
  25. data/support/benchmarks/load.rb +27 -26
  26. data/support/benchmarks/load_allocations.rb +14 -7
  27. data/support/benchmarks/object_counts.rb +6 -4
  28. data/support/profile/columnar.rb +5 -0
  29. data/support/profile/columnar_full.rb +5 -0
  30. data/support/profile/full.rb +5 -0
  31. data/test/minitest_helper.rb +3 -12
  32. data/test/test_mime_type.rb +461 -454
  33. data/test/test_mime_types.rb +126 -86
  34. data/test/test_mime_types_cache.rb +55 -45
  35. data/test/test_mime_types_class.rb +113 -97
  36. data/test/test_mime_types_lazy.rb +19 -23
  37. data/test/test_mime_types_loader.rb +5 -32
  38. metadata +67 -44
  39. data/History-Types.rdoc +0 -454
  40. data/data/mime-types.json +0 -1
  41. data/data/mime.content_type.column +0 -1980
  42. data/data/mime.docs.column +0 -1980
  43. data/data/mime.encoding.column +0 -1980
  44. data/data/mime.friendly.column +0 -1980
  45. data/data/mime.obsolete.column +0 -1980
  46. data/data/mime.registered.column +0 -1980
  47. data/data/mime.signature.column +0 -1980
  48. data/data/mime.use_instead.column +0 -1980
  49. data/data/mime.xrefs.column +0 -1980
  50. data/docs/COPYING.txt +0 -339
  51. data/docs/artistic.txt +0 -127
  52. data/lib/mime/types/loader_path.rb +0 -15
  53. data/support/apache_mime_types.rb +0 -108
  54. data/support/convert.rb +0 -158
  55. data/support/convert/columnar.rb +0 -88
  56. data/support/iana_registry.rb +0 -172
@@ -18,7 +18,7 @@ module MIME::Types::Columnar
18
18
  def self.extended(obj) # :nodoc:
19
19
  super
20
20
  obj.instance_variable_set(:@__mime_data__, [])
21
- obj.instance_variable_set(:@__attributes__, [])
21
+ obj.instance_variable_set(:@__files__, Set.new)
22
22
  end
23
23
 
24
24
  # Load the first column data file (type and extensions).
@@ -26,7 +26,10 @@ module MIME::Types::Columnar
26
26
  @__root__ = path
27
27
 
28
28
  each_file_line('content_type', false) do |line|
29
- content_type, *extensions = line.split
29
+ line = line.split
30
+ content_type = line.shift
31
+ extensions = line
32
+ # content_type, *extensions = line.split
30
33
 
31
34
  type = MIME::Type::Columnar.new(self, content_type, extensions)
32
35
  @__mime_data__ << type
@@ -40,84 +43,81 @@ module MIME::Types::Columnar
40
43
 
41
44
  def each_file_line(name, lookup = true)
42
45
  LOAD_MUTEX.synchronize do
43
- next if @__attributes__.include?(name)
46
+ next if @__files__.include?(name)
44
47
 
45
- File.open(File.join(@__root__, "mime.#{name}.column"), 'r:UTF-8') do |f|
46
- i = -1
48
+ i = -1
49
+ column = File.join(@__root__, "mime.#{name}.column")
47
50
 
48
- f.each_line do |line|
49
- line.chomp!
51
+ IO.readlines(column, encoding: 'UTF-8'.freeze).each do |line|
52
+ line.chomp!
50
53
 
51
- if lookup
52
- type = @__mime_data__[i += 1] or next
53
- yield type, line
54
- else
55
- yield line
56
- end
54
+ if lookup
55
+ type = @__mime_data__[i += 1] or next
56
+ yield type, line
57
+ else
58
+ yield line
57
59
  end
58
60
  end
59
61
 
60
- @__attributes__ << name
62
+ @__files__ << name
61
63
  end
62
64
  end
63
65
 
64
66
  def load_encoding
65
- pool = {}
66
67
  each_file_line('encoding') do |type, line|
68
+ pool ||= {}
67
69
  line.freeze
68
- type.encoding = (pool[line] ||= line)
70
+ type.instance_variable_set(:@encoding, (pool[line] ||= line))
69
71
  end
70
72
  end
71
73
 
72
74
  def load_docs
73
75
  each_file_line('docs') do |type, line|
74
- type.docs = arr(line)
76
+ type.instance_variable_set(:@docs, opt(line))
75
77
  end
76
78
  end
77
79
 
78
- def load_obsolete
79
- each_file_line('obsolete') do |type, line|
80
- type.obsolete = bool(line)
80
+ def load_preferred_extension
81
+ each_file_line('pext') do |type, line|
82
+ type.instance_variable_set(:@preferred_extension, opt(line))
81
83
  end
82
84
  end
83
85
 
84
- def load_registered
85
- each_file_line('registered') do |type, line|
86
- type.registered = bool(line)
87
- end
88
- end
89
-
90
- def load_signature
91
- each_file_line('signature') do |type, line|
92
- type.signature = bool(line)
86
+ def load_flags
87
+ each_file_line('flags') do |type, line|
88
+ line = line.split
89
+ type.instance_variable_set(:@obsolete, flag(line.shift))
90
+ type.instance_variable_set(:@registered, flag(line.shift))
91
+ type.instance_variable_set(:@signature, flag(line.shift))
93
92
  end
94
93
  end
95
94
 
96
95
  def load_xrefs
97
- each_file_line('xrefs') { |type, line| type.xrefs = dict(line) }
96
+ each_file_line('xrefs') { |type, line|
97
+ type.instance_variable_set(:@xrefs, dict(line, array: true))
98
+ }
98
99
  end
99
100
 
100
101
  def load_friendly
101
102
  each_file_line('friendly') { |type, line|
102
- v = dict(line)
103
- type.friendly = v.empty? ? nil : v
103
+ type.instance_variable_set(:@friendly, dict(line))
104
104
  }
105
105
  end
106
106
 
107
107
  def load_use_instead
108
108
  each_file_line('use_instead') do |type, line|
109
- type.use_instead = (line unless line == '-'.freeze)
109
+ type.instance_variable_set(:@use_instead, opt(line))
110
110
  end
111
111
  end
112
112
 
113
- def dict(line)
113
+ def dict(line, array: false)
114
114
  if line == '-'.freeze
115
115
  {}
116
116
  else
117
117
  line.split('|'.freeze).each_with_object({}) { |l, h|
118
118
  k, v = l.split('^'.freeze)
119
- v = [ nil ] if v.empty?
120
- h[k] = v
119
+ v = nil if v.empty?
120
+ h[k] = array ? Array(v) : v
121
121
  }
122
122
  end
123
123
  end
@@ -130,19 +130,13 @@ module MIME::Types::Columnar
130
130
  end
131
131
  end
132
132
 
133
- def bool(line)
134
- line == '1'.freeze ? true : false
133
+ def opt(line)
134
+ line unless line == '-'.freeze
135
135
  end
136
- end
137
136
 
138
- unless MIME::Types.private_method_defined?(:load_mode)
139
- class << MIME::Types
140
- private
141
-
142
- def load_mode
143
- { columnar: true }
144
- end
137
+ def flag(line)
138
+ line == '1'.freeze ? true : false
145
139
  end
146
-
147
- require 'mime/types'
148
140
  end
141
+
142
+ require 'mime/types' unless defined?(MIME::Types::VERSION)
@@ -0,0 +1,30 @@
1
+ require 'set'
2
+
3
+ # MIME::Types requires a container Hash with a default values for keys
4
+ # resulting in an empty array (<tt>[]</tt>), but this cannot be dumped through
5
+ # Marshal because of the presence of that default Proc. This class exists
6
+ # solely to satisfy that need.
7
+ class MIME::Types::Container < Hash # :nodoc:
8
+ def initialize
9
+ super
10
+ self.default_proc = ->(h, k) { h[k] = Set.new }
11
+ end
12
+
13
+ def marshal_dump
14
+ {}.merge(self)
15
+ end
16
+
17
+ def marshal_load(hash)
18
+ self.default_proc = ->(h, k) { h[k] = Set.new }
19
+ merge!(hash)
20
+ end
21
+
22
+ def encode_with(coder)
23
+ each { |k, v| coder[k] = v.to_a }
24
+ end
25
+
26
+ def init_with(coder)
27
+ self.default_proc = ->(h, k) { h[k] = Set.new }
28
+ coder.map.each { |k, v| self[k] = Set[*v] }
29
+ end
30
+ end
@@ -4,6 +4,7 @@ require 'mime/types/logger'
4
4
 
5
5
  # The namespace for MIME applications, tools, and libraries.
6
6
  module MIME
7
+ ##
7
8
  class Types
8
9
  # Used to mark a method as deprecated in the mime-types interface.
9
10
  def self.deprecated(klass, sym, message = nil, &block) # :nodoc:
@@ -28,26 +29,4 @@ module MIME
28
29
  block.call if block
29
30
  end
30
31
  end
31
-
32
- class << self
33
- # MIME::InvalidContentType was moved to MIME::Type::InvalidContentType.
34
- # Provide a single warning about this fact in the interim.
35
- def const_missing(name) # :nodoc:
36
- case name.to_s
37
- when 'InvalidContentType'
38
- warn_about_moved_constants(name)
39
- MIME::Type.const_get(name.to_sym)
40
- else
41
- super
42
- end
43
- end
44
-
45
- private
46
-
47
- def warn_about_moved_constants(name)
48
- MIME::Types.logger.warn <<-warning.chomp
49
- #{caller[1]}: MIME::#{name} is deprecated. Use MIME::Type::#{name} instead.
50
- warning
51
- end
52
- end
53
32
  end
@@ -0,0 +1,17 @@
1
+ ##
2
+ module MIME
3
+ ##
4
+ class Types
5
+ unless private_method_defined?(:load_mode)
6
+ class << self
7
+ private
8
+
9
+ def load_mode
10
+ { columnar: false }
11
+ end
12
+ end
13
+
14
+ require 'mime/types'
15
+ end
16
+ end
17
+ end
@@ -1,9 +1,11 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
 
3
+ ##
3
4
  module MIME; end
5
+ ##
4
6
  class MIME::Types; end
5
7
 
6
- require 'mime/types/loader_path'
8
+ require 'mime/types/data'
7
9
 
8
10
  # This class is responsible for initializing the MIME::Types registry from
9
11
  # the data files supplied with the mime-types library.
@@ -11,7 +13,7 @@ require 'mime/types/loader_path'
11
13
  # The Loader will use one of the following paths:
12
14
  # 1. The +path+ provided in its constructor argument;
13
15
  # 2. The value of ENV['RUBY_MIME_TYPES_DATA']; or
14
- # 3. The value of MIME::Types::Loader::PATH.
16
+ # 3. The value of MIME::Types::Data::PATH.
15
17
  #
16
18
  # When #load is called, the +path+ will be searched recursively for all YAML
17
19
  # (.yml or .yaml) files. By convention, there is one file for each media
@@ -24,9 +26,9 @@ class MIME::Types::Loader
24
26
  attr_reader :container
25
27
 
26
28
  # Creates a Loader object that can be used to load MIME::Types registries
27
- # into memory, using YAML, JSON, or v1 registry format loaders.
29
+ # into memory, using YAML, JSON, or Columnar registry format loaders.
28
30
  def initialize(path = nil, container = nil)
29
- path = path || ENV['RUBY_MIME_TYPES_DATA'] || MIME::Types::Loader::PATH
31
+ path = path || ENV['RUBY_MIME_TYPES_DATA'] || MIME::Types::Data::PATH
30
32
  @container = container || MIME::Types.new
31
33
  @path = File.expand_path(path)
32
34
  # begin
@@ -41,8 +43,7 @@ class MIME::Types::Loader
41
43
  # It is expected that the YAML objects contained within the registry array
42
44
  # will be tagged as <tt>!ruby/object:MIME::Type</tt>.
43
45
  #
44
- # Note that the YAML format is about 2½ times *slower* than either the v1
45
- # format or the JSON format.
46
+ # Note that the YAML format is about 2½ times *slower* than the JSON format.
46
47
  #
47
48
  # NOTE: The purpose of this format is purely for maintenance reasons.
48
49
  def load_yaml
@@ -89,122 +90,19 @@ class MIME::Types::Loader
89
90
  end
90
91
  end
91
92
 
92
- # Loads a MIME::Types registry from files found in +path+ that are in the
93
- # v1 data format. The file search for this will exclude both JSON
94
- # (<tt>*.json</tt>) and YAML (<tt>*.yml</tt> or <tt>*.yaml</tt>) files.
95
- #
96
- # This method has been deprecated and will be removed from mime-types 3.0.
97
- def load_v1
98
- MIME::Types.deprecated(self.class, __method__)
99
- Dir[v1_path].sort.each do |f|
100
- next if f =~ /\.(?:ya?ml|json|column)$/
101
- container.add(self.class.load_from_v1(f, true), true)
102
- end
103
- container
104
- end
105
-
106
- # Raised when a V1 format file is discovered. This exception will be removed
107
- # for mime-types 3.0.
108
- BadV1Format = Class.new(Exception)
109
-
110
93
  class << self
111
94
  # Loads the default MIME::Type registry.
112
95
  def load(options = { columnar: false })
113
96
  new.load(options)
114
97
  end
115
98
 
116
- # Build the type list from a file in the format:
117
- #
118
- # [*][!][os:]mt/st[<ws>@ext][<ws>:enc][<ws>'url-list][<ws>=docs]
119
- #
120
- # == *
121
- # An unofficial MIME type. This should be used if and only if the MIME type
122
- # is not properly specified (that is, not under either x-type or
123
- # vnd.name.type).
124
- #
125
- # == !
126
- # An obsolete MIME type. May be used with an unofficial MIME type.
127
- #
128
- # == os:
129
- # Platform-specific MIME type definition.
130
- #
131
- # == mt
132
- # The media type.
133
- #
134
- # == st
135
- # The media subtype.
136
- #
137
- # == <ws>@ext
138
- # The list of comma-separated extensions.
139
- #
140
- # == <ws>:enc
141
- # The encoding.
142
- #
143
- # == <ws>'url-list
144
- # The list of comma-separated URLs.
145
- #
146
- # == <ws>=docs
147
- # The documentation string.
148
- #
149
- # That is, everything except the media type and the subtype is optional. The
150
- # more information that's available, though, the richer the values that can
151
- # be provided.
152
- #
153
- # This method has been deprecated and will be removed in mime-types 3.0.
154
- def load_from_v1(filename, __internal__ = false)
155
- MIME::Types.deprecated(self.class, __method__) unless __internal__
156
- data = read_file(filename).split($/)
157
- mime = MIME::Types.new
158
- data.each_with_index { |line, index|
159
- item = line.chomp.strip
160
- next if item.empty?
161
-
162
- m = V1_FORMAT.match(item)
163
-
164
- unless m
165
- MIME::Types.logger.warn <<-EOS
166
- #{filename}:#{index + 1}: Parsing error in v1 MIME type definition.
167
- => #{line}
168
- EOS
169
- fail BadV1Format, line
170
- end
171
-
172
- unregistered, obsolete, _, mediatype, subtype, extensions, encoding,
173
- urls, docs, _ = *m.captures
174
-
175
- next if mediatype.nil?
176
-
177
- extensions &&= extensions.split(/,/)
178
- urls &&= urls.split(/,/)
179
-
180
- if docs.nil?
181
- use_instead = nil
182
- else
183
- use_instead = docs.scan(%r{use-instead:(\S+)}).flatten.first
184
- docs = docs.gsub(%r{use-instead:\S+}, '').squeeze(' \t')
185
- end
186
-
187
- mime_type = MIME::Type.new("#{mediatype}/#{subtype}") do |t|
188
- t.extensions = extensions
189
- t.encoding = encoding
190
- t.obsolete = obsolete
191
- t.registered = false if unregistered
192
- t.use_instead = use_instead
193
- t.docs = docs
194
- end
195
-
196
- mime.add_type(mime_type, true)
197
- }
198
- mime
199
- end
200
-
201
99
  # Loads MIME::Types from a single YAML file.
202
100
  #
203
101
  # It is expected that the YAML objects contained within the registry
204
102
  # array will be tagged as <tt>!ruby/object:MIME::Type</tt>.
205
103
  #
206
- # Note that the YAML format is about 2½ times *slower* than either the v1
207
- # format or the JSON format.
104
+ # Note that the YAML format is about 2½ times *slower* than the JSON
105
+ # format.
208
106
  #
209
107
  # NOTE: The purpose of this format is purely for maintenance reasons.
210
108
  def load_from_yaml(filename)
@@ -230,7 +128,7 @@ class MIME::Types::Loader
230
128
  private
231
129
 
232
130
  def read_file(filename)
233
- File.open(filename, 'r:UTF-8:-') { |f| f.read }
131
+ File.open(filename, 'r:UTF-8:-', &:read)
234
132
  end
235
133
  end
236
134
 
@@ -247,29 +145,4 @@ class MIME::Types::Loader
247
145
  def columnar_path
248
146
  File.join(path, '*.column')
249
147
  end
250
-
251
- def v1_path
252
- File.join(path, '*')
253
- end
254
-
255
- # The regular expression used to match a v1-format file-based MIME type
256
- # definition.
257
- #
258
- # This constant has been deprecated and will be removed in mime-types 3.0.
259
- V1_FORMAT = # :nodoc:
260
- %r{\A\s*
261
- ([*])? # 0: Unregistered?
262
- (!)? # 1: Obsolete?
263
- (?:(\w+):)? # 2: Platform marker
264
- ([-\w.+]+)/([-\w.+]*) # 3, 4: Media Type
265
- (?:\s+@(\S+))? # 5: Extensions
266
- (?:\s+:(base64|7bit|8bit|quoted\-printable))? # 6: Encoding
267
- (?:\s+'(\S+))? # 7: URL list
268
- (?:\s+=(.+))? # 8: Documentation
269
- (?:\s*([#].*)?)? # Comments
270
- \s*
271
- \z
272
- }x
273
-
274
- private_constant :V1_FORMAT if respond_to? :private_constant
275
148
  end