afp_mimemagic 0.3.6
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 +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +20 -0
- data/.yardopts +2 -0
- data/CHANGELOG.md +96 -0
- data/Gemfile +2 -0
- data/LICENSE +339 -0
- data/README.md +51 -0
- data/Rakefile +15 -0
- data/lib/mimemagic/overlay.rb +11 -0
- data/lib/mimemagic/tables.rb +2208 -0
- data/lib/mimemagic/version.rb +5 -0
- data/lib/mimemagic.rb +148 -0
- data/mimemagic.gemspec +28 -0
- data/script/freedesktop.org.xml +41233 -0
- data/script/generate-mime.rb +164 -0
- data/test/files/application.gzip +0 -0
- data/test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{gdocs}.sheet +0 -0
- data/test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{msoffice}.sheet +0 -0
- data/test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{rubyxl}.sheet +0 -0
- data/test/files/application.x-bzip +0 -0
- data/test/files/application.x-ruby +2 -0
- data/test/files/application.x-tar +0 -0
- data/test/files/application.zip +0 -0
- data/test/files/image.jpeg +0 -0
- data/test/files/image.png +0 -0
- data/test/mimemagic_test.rb +160 -0
- metadata +101 -0
@@ -0,0 +1,164 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
class String
|
6
|
+
alias inspect_old inspect
|
7
|
+
|
8
|
+
def inspect
|
9
|
+
x = b.inspect_old.gsub(/\\x([0-9a-f]{2})/i) do
|
10
|
+
'\\%03o' % Regexp.last_match(1).to_i(16)
|
11
|
+
end
|
12
|
+
x =~ /[\\']/ ? x : x.gsub('"', '\'')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def str2int(s)
|
17
|
+
return s.to_i(16) if s[0..1].downcase == '0x'
|
18
|
+
return s.to_i(8) if s[0..0].downcase == '0'
|
19
|
+
|
20
|
+
s.to_i(10)
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_matches(parent)
|
24
|
+
parent.elements.map do |match|
|
25
|
+
if match['mask']
|
26
|
+
nil
|
27
|
+
else
|
28
|
+
type = match['type']
|
29
|
+
value = match['value']
|
30
|
+
offset = match['offset'].split(':').map { |x| x.to_i }
|
31
|
+
offset = offset.size == 2 ? offset[0]..offset[1] : offset[0]
|
32
|
+
case type
|
33
|
+
when 'string'
|
34
|
+
value.gsub!(/\\(x[\dA-Fa-f]{1,2}|0\d{1,3}|\d{1,3}|.)/) { eval("\"\\#{Regexp.last_match(1)}\"") }
|
35
|
+
when 'big16'
|
36
|
+
value = str2int(value)
|
37
|
+
value = ((value >> 8).chr + (value & 0xFF).chr)
|
38
|
+
when 'big32'
|
39
|
+
value = str2int(value)
|
40
|
+
value = (((value >> 24) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 8) & 0xFF).chr + (value & 0xFF).chr)
|
41
|
+
when 'little16'
|
42
|
+
value = str2int(value)
|
43
|
+
value = ((value & 0xFF).chr + (value >> 8).chr)
|
44
|
+
when 'little32'
|
45
|
+
value = str2int(value)
|
46
|
+
value = ((value & 0xFF).chr + ((value >> 8) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 24) & 0xFF).chr)
|
47
|
+
when 'host16' # use little endian
|
48
|
+
value = str2int(value)
|
49
|
+
value = ((value & 0xFF).chr + (value >> 8).chr)
|
50
|
+
when 'host32' # use little endian
|
51
|
+
value = str2int(value)
|
52
|
+
value = ((value & 0xFF).chr + ((value >> 8) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 24) & 0xFF).chr)
|
53
|
+
when 'byte'
|
54
|
+
value = str2int(value)
|
55
|
+
value = value.chr
|
56
|
+
end
|
57
|
+
children = get_matches(match)
|
58
|
+
children.empty? ? [offset, value] : [offset, value, children]
|
59
|
+
end
|
60
|
+
end.compact
|
61
|
+
end
|
62
|
+
|
63
|
+
if ARGV.size != 1
|
64
|
+
puts "Usage: #{$0} <freedesktop.org.xml>"
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
|
68
|
+
FILE = ARGV[0]
|
69
|
+
file = File.new(FILE)
|
70
|
+
doc = Nokogiri::XML(file)
|
71
|
+
extensions = {}
|
72
|
+
types = {}
|
73
|
+
magics = []
|
74
|
+
(doc / 'mime-info/mime-type').each do |mime|
|
75
|
+
comments = Hash[*(mime / 'comment').map { |comment| [comment['xml:lang'], comment.inner_text] }.flatten]
|
76
|
+
type = mime['type']
|
77
|
+
subclass = (mime / 'sub-class-of').map { |x| x['type'] }
|
78
|
+
exts = (mime / 'glob').map { |x| x['pattern'] =~ /^\*\.([^\[\]]+)$/ ? Regexp.last_match(1).downcase : nil }.compact
|
79
|
+
(mime / 'magic').each do |magic|
|
80
|
+
priority = magic['priority'].to_i
|
81
|
+
matches = get_matches(magic)
|
82
|
+
magics << [priority, type, matches]
|
83
|
+
end
|
84
|
+
next if exts.empty?
|
85
|
+
|
86
|
+
exts.each do |x|
|
87
|
+
extensions[x] = type unless extensions.include?(x)
|
88
|
+
end
|
89
|
+
types[type] = [exts, subclass, comments[nil]]
|
90
|
+
end
|
91
|
+
|
92
|
+
magics = magics.sort { |a, b| [-a[0], a[1]] <=> [-b[0], b[1]] }
|
93
|
+
|
94
|
+
common_types = [
|
95
|
+
'image/jpeg', # .jpg
|
96
|
+
'image/png', # .png
|
97
|
+
'image/gif', # .gif
|
98
|
+
'image/tiff', # .tiff
|
99
|
+
'image/bmp', # .bmp
|
100
|
+
'image/vnd.adobe.photoshop', # .psd
|
101
|
+
'image/webp', # .webp
|
102
|
+
'image/svg+xml', # .svg
|
103
|
+
|
104
|
+
'video/x-msvideo', # .avi
|
105
|
+
'video/x-ms-wmv', # .wmv
|
106
|
+
'video/mp4', # .mp4, .m4v
|
107
|
+
'video/quicktime', # .mov
|
108
|
+
'video/mpeg', # .mpeg
|
109
|
+
'video/ogg', # .ogv
|
110
|
+
'video/webm', # .webm
|
111
|
+
'video/x-matroska', # .mkv
|
112
|
+
'video/x-flv', # .flv
|
113
|
+
|
114
|
+
'audio/mpeg', # .mp3
|
115
|
+
'audio/x-wav', # .wav
|
116
|
+
'audio/aac', # .aac
|
117
|
+
'audio/flac', # .flac
|
118
|
+
'audio/mp4', # .m4a
|
119
|
+
'audio/ogg', # .ogg
|
120
|
+
|
121
|
+
'application/pdf', # .pdf
|
122
|
+
'application/msword', # .doc
|
123
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', # .docx
|
124
|
+
'application/vnd.ms-powerpoint', # .pps
|
125
|
+
'application/vnd.openxmlformats-officedocument.presentationml.slideshow', # .ppsx
|
126
|
+
'application/vnd.ms-excel', # .pps
|
127
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' # .ppsx
|
128
|
+
]
|
129
|
+
|
130
|
+
common_magics = common_types.map do |common_type|
|
131
|
+
magics.find { |_, type, _| type == common_type }
|
132
|
+
end
|
133
|
+
|
134
|
+
magics = (common_magics.compact + magics).uniq
|
135
|
+
|
136
|
+
puts '# -*- coding: binary -*-'
|
137
|
+
puts '# frozen_string_literal: true'
|
138
|
+
puts "# Generated from #{FILE}"
|
139
|
+
puts 'class MimeMagic'
|
140
|
+
puts ' # @private'
|
141
|
+
puts ' # :nodoc:'
|
142
|
+
puts ' EXTENSIONS = {'
|
143
|
+
extensions.keys.sort.each do |key|
|
144
|
+
puts " '#{key}' => '#{extensions[key]}',"
|
145
|
+
end
|
146
|
+
puts ' }'
|
147
|
+
puts ' # @private'
|
148
|
+
puts ' # :nodoc:'
|
149
|
+
puts ' TYPES = {'
|
150
|
+
types.keys.sort.each do |key|
|
151
|
+
exts = types[key][0].join(' ')
|
152
|
+
parents = types[key][1].sort.join(' ')
|
153
|
+
comment = types[key][2].inspect
|
154
|
+
puts " '#{key}' => [%w(#{exts}), %w(#{parents}), #{comment}],"
|
155
|
+
end
|
156
|
+
puts ' }'
|
157
|
+
puts ' # @private'
|
158
|
+
puts ' # :nodoc:'
|
159
|
+
puts ' MAGIC = ['
|
160
|
+
magics.each do |_priority, type, matches|
|
161
|
+
puts " ['#{type}', #{matches.inspect}],"
|
162
|
+
end
|
163
|
+
puts ' ]'
|
164
|
+
puts 'end'
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'mimemagic'
|
3
|
+
require 'stringio'
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
class TestMimeMagic < Minitest::Test
|
7
|
+
# Do deep copy for constants of initial state.
|
8
|
+
INIT_EXTENSIONS = Marshal.load(Marshal.dump(MimeMagic::EXTENSIONS))
|
9
|
+
INIT_TYPES = Marshal.load(Marshal.dump(MimeMagic::TYPES))
|
10
|
+
INIT_MAGIC = Marshal.load(Marshal.dump(MimeMagic::MAGIC))
|
11
|
+
|
12
|
+
def setup
|
13
|
+
extentions = Marshal.load(Marshal.dump(INIT_EXTENSIONS))
|
14
|
+
types = Marshal.load(Marshal.dump(INIT_TYPES))
|
15
|
+
magic = Marshal.load(Marshal.dump(INIT_MAGIC))
|
16
|
+
MimeMagic.send(:remove_const, :EXTENSIONS) if MimeMagic.const_defined?(:EXTENSIONS)
|
17
|
+
MimeMagic.send(:remove_const, :TYPES) if MimeMagic.const_defined?(:TYPES)
|
18
|
+
MimeMagic.send(:remove_const, :MAGIC) if MimeMagic.const_defined?(:MAGIC)
|
19
|
+
MimeMagic.const_set('EXTENSIONS', extentions)
|
20
|
+
MimeMagic.const_set('TYPES', types)
|
21
|
+
MimeMagic.const_set('MAGIC', magic)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_have_type_mediatype_and_subtype
|
25
|
+
assert_equal 'text/html', MimeMagic.new('text/html').type
|
26
|
+
assert_equal 'text', MimeMagic.new('text/html').mediatype
|
27
|
+
assert_equal 'html', MimeMagic.new('text/html').subtype
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_have_mediatype_helpers
|
31
|
+
assert MimeMagic.new('text/plain').text?
|
32
|
+
assert MimeMagic.new('text/html').text?
|
33
|
+
assert MimeMagic.new('application/xhtml+xml').text?
|
34
|
+
refute MimeMagic.new('application/octet-stream').text?
|
35
|
+
refute MimeMagic.new('image/png').text?
|
36
|
+
assert MimeMagic.new('image/png').image?
|
37
|
+
assert MimeMagic.new('video/ogg').video?
|
38
|
+
assert MimeMagic.new('audio/mpeg').audio?
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_have_hierarchy
|
42
|
+
assert MimeMagic.new('text/html').child_of?('text/plain')
|
43
|
+
assert MimeMagic.new('text/x-java').child_of?('text/plain')
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_have_extensions
|
47
|
+
assert_equal %w[htm html], MimeMagic.new('text/html').extensions
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_have_comment
|
51
|
+
assert_equal 'HTML document', MimeMagic.new('text/html').comment
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_recognize_extensions
|
55
|
+
assert_equal 'text/html', MimeMagic.by_extension('.html').to_s
|
56
|
+
assert_equal 'text/html', MimeMagic.by_extension('html').to_s
|
57
|
+
assert_equal 'text/html', MimeMagic.by_extension(:html).to_s
|
58
|
+
assert_equal 'application/x-ruby', MimeMagic.by_extension('rb').to_s
|
59
|
+
assert_nil MimeMagic.by_extension('crazy')
|
60
|
+
assert_nil MimeMagic.by_extension('')
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_recognize_by_a_path
|
64
|
+
assert_equal 'text/html', MimeMagic.by_path('/adsjkfa/kajsdfkadsf/kajsdfjasdf.html').to_s
|
65
|
+
assert_equal 'text/html', MimeMagic.by_path('something.html').to_s
|
66
|
+
assert_equal 'application/x-ruby', MimeMagic.by_path('wtf.rb').to_s
|
67
|
+
assert_nil MimeMagic.by_path('where/am.html/crazy')
|
68
|
+
assert_nil MimeMagic.by_path('')
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_recognize_xlsx_as_zip_without_magic
|
72
|
+
file = 'test/files/application.vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
73
|
+
%w[msoffice rubyxl gdocs].each do |variant|
|
74
|
+
file = "test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{#{variant}}.sheet"
|
75
|
+
assert_equal 'application/zip', MimeMagic.by_magic(File.read(file)).to_s
|
76
|
+
assert_equal 'application/zip', MimeMagic.by_magic(File.open(file, 'rb')).to_s
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_recognize_by_magic
|
81
|
+
load 'mimemagic/overlay.rb'
|
82
|
+
Dir['test/files/*'].each do |file|
|
83
|
+
mime = file[11..-1].sub('.', '/').sub(/\{\w+\}/, '')
|
84
|
+
assert_equal mime, MimeMagic.by_magic(File.read(file)).to_s
|
85
|
+
assert_equal mime, MimeMagic.by_magic(File.open(file, 'rb')).to_s
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_recognize_all_by_magic
|
90
|
+
load 'mimemagic/overlay.rb'
|
91
|
+
%w[msoffice rubyxl gdocs].each do |variant|
|
92
|
+
file = "test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{#{variant}}.sheet"
|
93
|
+
mimes = %w[application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/zip]
|
94
|
+
assert_equal mimes, MimeMagic.all_by_magic(File.read(file)).map(&:type)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_have_add
|
99
|
+
MimeMagic.add('application/mimemagic-test',
|
100
|
+
extensions: %w[ext1 ext2],
|
101
|
+
parents: 'application/xml',
|
102
|
+
comment: 'Comment')
|
103
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_extension('ext1').to_s
|
104
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_extension('ext2').to_s
|
105
|
+
assert_equal 'Comment', MimeMagic.by_extension('ext2').comment
|
106
|
+
assert_equal %w[ext1 ext2], MimeMagic.new('application/mimemagic-test').extensions
|
107
|
+
assert MimeMagic.new('application/mimemagic-test').child_of?('text/plain')
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_process_magic
|
111
|
+
MimeMagic.add('application/mimemagic-test',
|
112
|
+
magic: [[0, 'MAGICTEST'], # MAGICTEST at position 0
|
113
|
+
[1, 'MAGICTEST'], # MAGICTEST at position 1
|
114
|
+
[9..12, 'MAGICTEST'], # MAGICTEST starting at position 9 to 12
|
115
|
+
[2, 'MAGICTEST', [[0, 'X'], [0, 'Y']]]]) # MAGICTEST at position 2 and (X at 0 or Y at 0)
|
116
|
+
|
117
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic('MAGICTEST').to_s
|
118
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic('XMAGICTEST').to_s
|
119
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(' MAGICTEST').to_s
|
120
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic('123456789MAGICTEST').to_s
|
121
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic('123456789ABMAGICTEST').to_s
|
122
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic('123456789ABCMAGICTEST').to_s
|
123
|
+
assert_nil MimeMagic.by_magic('123456789ABCDMAGICTEST')
|
124
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic('X MAGICTEST').to_s
|
125
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic('Y MAGICTEST').to_s
|
126
|
+
assert_nil MimeMagic.by_magic('Z MAGICTEST')
|
127
|
+
|
128
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new('MAGICTEST')).to_s
|
129
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new('XMAGICTEST')).to_s
|
130
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new(' MAGICTEST')).to_s
|
131
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new('123456789MAGICTEST')).to_s
|
132
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new('123456789ABMAGICTEST')).to_s
|
133
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new('123456789ABCMAGICTEST')).to_s
|
134
|
+
assert_nil MimeMagic.by_magic(StringIO.new('123456789ABCDMAGICTEST'))
|
135
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new('X MAGICTEST')).to_s
|
136
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringIO.new('Y MAGICTEST')).to_s
|
137
|
+
assert_nil MimeMagic.by_magic(StringIO.new('Z MAGICTEST'))
|
138
|
+
end
|
139
|
+
|
140
|
+
class IOObject
|
141
|
+
def initialize
|
142
|
+
@io = StringIO.new('MAGICTEST')
|
143
|
+
end
|
144
|
+
|
145
|
+
extend Forwardable
|
146
|
+
delegate %i[read size rewind eof? close] => :@io
|
147
|
+
end
|
148
|
+
|
149
|
+
class StringableObject
|
150
|
+
def to_s
|
151
|
+
'MAGICTEST'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_handle_different_file_objects
|
156
|
+
MimeMagic.add('application/mimemagic-test', magic: [[0, 'MAGICTEST']])
|
157
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(IOObject.new).to_s
|
158
|
+
assert_equal 'application/mimemagic-test', MimeMagic.by_magic(StringableObject.new).to_s
|
159
|
+
end
|
160
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: afp_mimemagic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Mendler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-12-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Fast mime detection by extension or content in pure ruby (Uses freedesktop.org.xml
|
42
|
+
shared-mime-info database)
|
43
|
+
email:
|
44
|
+
- mail@daniel-mendler.de
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- ".travis.yml"
|
51
|
+
- ".yardopts"
|
52
|
+
- CHANGELOG.md
|
53
|
+
- Gemfile
|
54
|
+
- LICENSE
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- lib/mimemagic.rb
|
58
|
+
- lib/mimemagic/overlay.rb
|
59
|
+
- lib/mimemagic/tables.rb
|
60
|
+
- lib/mimemagic/version.rb
|
61
|
+
- mimemagic.gemspec
|
62
|
+
- script/freedesktop.org.xml
|
63
|
+
- script/generate-mime.rb
|
64
|
+
- test/files/application.gzip
|
65
|
+
- test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{gdocs}.sheet
|
66
|
+
- test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{msoffice}.sheet
|
67
|
+
- test/files/application.vnd.openxmlformats-officedocument.spreadsheetml{rubyxl}.sheet
|
68
|
+
- test/files/application.x-bzip
|
69
|
+
- test/files/application.x-ruby
|
70
|
+
- test/files/application.x-tar
|
71
|
+
- test/files/application.zip
|
72
|
+
- test/files/image.jpeg
|
73
|
+
- test/files/image.png
|
74
|
+
- test/mimemagic_test.rb
|
75
|
+
homepage: https://github.com/minad/mimemagic
|
76
|
+
licenses:
|
77
|
+
- GPL-2.0
|
78
|
+
metadata:
|
79
|
+
changelog_uri: https://github.com/minad/mimemagic/blob/master/CHANGELOG.md
|
80
|
+
source_code_uri: https://github.com/minad/mimemagic
|
81
|
+
bug_tracker_uri: https://github.com/minad/mimemagic/issues
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubygems_version: 3.0.8
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: Fast mime detection by extension or content
|
101
|
+
test_files: []
|