mimemagic 0.3.1
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.
Potentially problematic release.
This version of mimemagic might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +11 -0
- data/.yardopts +2 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +46 -0
- data/Rakefile +13 -0
- data/lib/mimemagic.rb +141 -0
- data/lib/mimemagic/overlay.rb +7 -0
- data/lib/mimemagic/tables.rb +1825 -0
- data/lib/mimemagic/version.rb +5 -0
- data/mimemagic.gemspec +24 -0
- data/script/freedesktop.org.xml +35475 -0
- data/script/generate-mime.rb +120 -0
- data/test/files/application.gzip +0 -0
- data/test/files/application.vnd.openxmlformats-officedocument.spreadsheetml.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 +125 -0
- metadata +96 -0
@@ -0,0 +1,120 @@
|
|
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' % $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
|
+
s.to_i(10)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_matches(parent)
|
23
|
+
parent.elements.map {|match|
|
24
|
+
if match['mask']
|
25
|
+
nil
|
26
|
+
else
|
27
|
+
type = match['type']
|
28
|
+
value = match['value']
|
29
|
+
offset = match['offset'].split(':').map {|x| x.to_i }
|
30
|
+
offset = offset.size == 2 ? offset[0]..offset[1] : offset[0]
|
31
|
+
case type
|
32
|
+
when 'string'
|
33
|
+
value.gsub!(/\\(x[\dA-Fa-f]{1,2}|0\d{1,3}|\d{1,3}|.)/) { eval("\"\\#{$1}\"") }
|
34
|
+
when 'big16'
|
35
|
+
value = str2int(value)
|
36
|
+
value = ((value >> 8).chr + (value & 0xFF).chr)
|
37
|
+
when 'big32'
|
38
|
+
value = str2int(value)
|
39
|
+
value = (((value >> 24) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 8) & 0xFF).chr + (value & 0xFF).chr)
|
40
|
+
when 'little16'
|
41
|
+
value = str2int(value)
|
42
|
+
value = ((value & 0xFF).chr + (value >> 8).chr)
|
43
|
+
when 'little32'
|
44
|
+
value = str2int(value)
|
45
|
+
value = ((value & 0xFF).chr + ((value >> 8) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 24) & 0xFF).chr)
|
46
|
+
when 'host16' # use little endian
|
47
|
+
value = str2int(value)
|
48
|
+
value = ((value & 0xFF).chr + (value >> 8).chr)
|
49
|
+
when 'host32' # use little endian
|
50
|
+
value = str2int(value)
|
51
|
+
value = ((value & 0xFF).chr + ((value >> 8) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 24) & 0xFF).chr)
|
52
|
+
when 'byte'
|
53
|
+
value = str2int(value)
|
54
|
+
value = value.chr
|
55
|
+
end
|
56
|
+
children = get_matches(match)
|
57
|
+
children.empty? ? [offset, value] : [offset, value, children]
|
58
|
+
end
|
59
|
+
}.compact
|
60
|
+
end
|
61
|
+
|
62
|
+
if ARGV.size != 1
|
63
|
+
puts "Usage: #{$0} <freedesktop.org.xml>"
|
64
|
+
exit 1
|
65
|
+
end
|
66
|
+
|
67
|
+
FILE = ARGV[0]
|
68
|
+
file = File.new(FILE)
|
69
|
+
doc = Nokogiri::XML(file)
|
70
|
+
extensions = {}
|
71
|
+
types = {}
|
72
|
+
magics = []
|
73
|
+
(doc/'mime-info/mime-type').each do |mime|
|
74
|
+
comments = Hash[*(mime/'comment').map {|comment| [comment['xml:lang'], comment.inner_text] }.flatten]
|
75
|
+
type = mime['type']
|
76
|
+
subclass = (mime/'sub-class-of').map{|x| x['type']}
|
77
|
+
exts = (mime/'glob').map{|x| x['pattern'] =~ /^\*\.([^\[\]]+)$/ ? $1.downcase : nil }.compact
|
78
|
+
(mime/'magic').each do |magic|
|
79
|
+
priority = magic['priority'].to_i
|
80
|
+
matches = get_matches(magic)
|
81
|
+
magics << [priority, type, matches]
|
82
|
+
end
|
83
|
+
if !exts.empty?
|
84
|
+
exts.each{|x|
|
85
|
+
extensions[x] = type if !extensions.include?(x)
|
86
|
+
}
|
87
|
+
types[type] = [exts,subclass,comments[nil]]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
magics = magics.sort {|a,b| [-a[0],a[1]] <=> [-b[0],b[1]] }
|
92
|
+
|
93
|
+
puts "# -*- coding: binary -*-"
|
94
|
+
puts "# Generated from #{FILE}"
|
95
|
+
puts "class MimeMagic"
|
96
|
+
puts " # @private"
|
97
|
+
puts " # :nodoc:"
|
98
|
+
puts " EXTENSIONS = {"
|
99
|
+
extensions.keys.sort.each do |key|
|
100
|
+
puts " '#{key}' => '#{extensions[key]}',"
|
101
|
+
end
|
102
|
+
puts " }"
|
103
|
+
puts " # @private"
|
104
|
+
puts " # :nodoc:"
|
105
|
+
puts " TYPES = {"
|
106
|
+
types.keys.sort.each do |key|
|
107
|
+
exts = types[key][0].sort.join(' ')
|
108
|
+
parents = types[key][1].sort.join(' ')
|
109
|
+
comment = types[key][2].inspect
|
110
|
+
puts " '#{key}' => [%w(#{exts}), %w(#{parents}), #{comment}],"
|
111
|
+
end
|
112
|
+
puts " }"
|
113
|
+
puts " # @private"
|
114
|
+
puts " # :nodoc:"
|
115
|
+
puts " MAGIC = ["
|
116
|
+
magics.each do |priority, type, matches|
|
117
|
+
puts " ['#{type}', #{matches.inspect}],"
|
118
|
+
end
|
119
|
+
puts " ]"
|
120
|
+
puts "end"
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'bacon'
|
2
|
+
require 'mimemagic'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
describe 'MimeMagic' do
|
6
|
+
it 'should have type, mediatype and subtype' do
|
7
|
+
MimeMagic.new('text/html').type.should.equal 'text/html'
|
8
|
+
MimeMagic.new('text/html').mediatype.should.equal 'text'
|
9
|
+
MimeMagic.new('text/html').subtype.should.equal 'html'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should have mediatype helpers' do
|
13
|
+
MimeMagic.new('text/plain').should.be.text
|
14
|
+
MimeMagic.new('text/html').should.be.text
|
15
|
+
MimeMagic.new('application/xhtml+xml').should.be.text
|
16
|
+
MimeMagic.new('application/octet-stream').should.not.be.text
|
17
|
+
MimeMagic.new('image/png').should.not.be.text
|
18
|
+
MimeMagic.new('image/png').should.be.image
|
19
|
+
MimeMagic.new('video/ogg').should.be.video
|
20
|
+
MimeMagic.new('audio/mpeg').should.be.audio
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should have hierarchy' do
|
24
|
+
MimeMagic.new('text/html').should.be.child_of 'text/plain'
|
25
|
+
MimeMagic.new('text/x-java').should.be.child_of 'text/plain'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should have extensions' do
|
29
|
+
MimeMagic.new('text/html').extensions.should.equal %w(htm html)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have comment' do
|
33
|
+
MimeMagic.new('text/html').comment.should.equal 'HTML document'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should recognize extensions' do
|
37
|
+
MimeMagic.by_extension('.html').should.equal 'text/html'
|
38
|
+
MimeMagic.by_extension('html').should.equal 'text/html'
|
39
|
+
MimeMagic.by_extension(:html).should.equal 'text/html'
|
40
|
+
MimeMagic.by_extension('rb').should.equal 'application/x-ruby'
|
41
|
+
MimeMagic.by_extension('crazy').should.equal nil
|
42
|
+
MimeMagic.by_extension('').should.equal nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should recognize by a path' do
|
46
|
+
MimeMagic.by_path('/adsjkfa/kajsdfkadsf/kajsdfjasdf.html').should.equal 'text/html'
|
47
|
+
MimeMagic.by_path('something.html').should.equal 'text/html'
|
48
|
+
MimeMagic.by_path('wtf.rb').should.equal 'application/x-ruby'
|
49
|
+
MimeMagic.by_path('where/am.html/crazy').should.equal nil
|
50
|
+
MimeMagic.by_path('').should.equal nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should recognize xlsx as zip without magic' do
|
54
|
+
file = "test/files/application.vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
55
|
+
MimeMagic.by_magic(File.read(file)).should.equal "application/zip"
|
56
|
+
MimeMagic.by_magic(File.open(file, 'rb')).should.equal "application/zip"
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should recognize by magic' do
|
60
|
+
require "mimemagic/overlay"
|
61
|
+
Dir['test/files/*'].each do |file|
|
62
|
+
mime = file[11..-1].sub('.', '/')
|
63
|
+
MimeMagic.by_magic(File.read(file)).should.equal mime
|
64
|
+
MimeMagic.by_magic(File.open(file, 'rb')).should.equal mime
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should have add' do
|
69
|
+
MimeMagic.add('application/mimemagic-test',
|
70
|
+
extensions: %w(ext1 ext2),
|
71
|
+
parents: 'application/xml',
|
72
|
+
comment: 'Comment')
|
73
|
+
MimeMagic.by_extension('ext1').should.equal 'application/mimemagic-test'
|
74
|
+
MimeMagic.by_extension('ext2').should.equal 'application/mimemagic-test'
|
75
|
+
MimeMagic.by_extension('ext2').comment.should.equal 'Comment'
|
76
|
+
MimeMagic.new('application/mimemagic-test').extensions.should.equal %w(ext1 ext2)
|
77
|
+
MimeMagic.new('application/mimemagic-test').should.be.child_of 'text/plain'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should process magic' do
|
81
|
+
MimeMagic.add('application/mimemagic-test',
|
82
|
+
magic: [[0, 'MAGICTEST'], # MAGICTEST at position 0
|
83
|
+
[1, 'MAGICTEST'], # MAGICTEST at position 1
|
84
|
+
[9..12, 'MAGICTEST'], # MAGICTEST starting at position 9 to 12
|
85
|
+
[2, 'MAGICTEST', [[0, 'X'], [0, 'Y']]]]) # MAGICTEST at position 2 and (X at 0 or Y at 0)
|
86
|
+
|
87
|
+
MimeMagic.by_magic('MAGICTEST').should.equal 'application/mimemagic-test'
|
88
|
+
MimeMagic.by_magic('XMAGICTEST').should.equal 'application/mimemagic-test'
|
89
|
+
MimeMagic.by_magic(' MAGICTEST').should.equal 'application/mimemagic-test'
|
90
|
+
MimeMagic.by_magic('123456789MAGICTEST').should.equal 'application/mimemagic-test'
|
91
|
+
MimeMagic.by_magic('123456789ABMAGICTEST').should.equal 'application/mimemagic-test'
|
92
|
+
MimeMagic.by_magic('123456789ABCMAGICTEST').should.equal 'application/mimemagic-test'
|
93
|
+
MimeMagic.by_magic('123456789ABCDMAGICTEST').should.equal nil
|
94
|
+
MimeMagic.by_magic('X MAGICTEST').should.equal 'application/mimemagic-test'
|
95
|
+
MimeMagic.by_magic('Y MAGICTEST').should.equal 'application/mimemagic-test'
|
96
|
+
MimeMagic.by_magic('Z MAGICTEST').should.equal nil
|
97
|
+
|
98
|
+
MimeMagic.by_magic(StringIO.new 'MAGICTEST').should.equal 'application/mimemagic-test'
|
99
|
+
MimeMagic.by_magic(StringIO.new 'XMAGICTEST').should.equal 'application/mimemagic-test'
|
100
|
+
MimeMagic.by_magic(StringIO.new ' MAGICTEST').should.equal 'application/mimemagic-test'
|
101
|
+
MimeMagic.by_magic(StringIO.new '123456789MAGICTEST').should.equal 'application/mimemagic-test'
|
102
|
+
MimeMagic.by_magic(StringIO.new '123456789ABMAGICTEST').should.equal 'application/mimemagic-test'
|
103
|
+
MimeMagic.by_magic(StringIO.new '123456789ABCMAGICTEST').should.equal 'application/mimemagic-test'
|
104
|
+
MimeMagic.by_magic(StringIO.new '123456789ABCDMAGICTEST').should.equal nil
|
105
|
+
MimeMagic.by_magic(StringIO.new 'X MAGICTEST').should.equal 'application/mimemagic-test'
|
106
|
+
MimeMagic.by_magic(StringIO.new 'Y MAGICTEST').should.equal 'application/mimemagic-test'
|
107
|
+
MimeMagic.by_magic(StringIO.new 'Z MAGICTEST').should.equal nil
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should handle different file objects' do
|
111
|
+
MimeMagic.add('application/mimemagic-test', magic: [[0, 'MAGICTEST']])
|
112
|
+
class ReadableObj
|
113
|
+
def read
|
114
|
+
'MAGICTEST'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
MimeMagic.by_magic(ReadableObj.new).should.equal 'application/mimemagic-test'
|
118
|
+
class StringableObject
|
119
|
+
def to_s
|
120
|
+
'MAGICTEST'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
MimeMagic.by_magic(StringableObject.new).should.equal 'application/mimemagic-test'
|
124
|
+
end
|
125
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mimemagic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Mendler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bacon
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
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
|
+
- Gemfile
|
53
|
+
- LICENSE
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- lib/mimemagic.rb
|
57
|
+
- lib/mimemagic/overlay.rb
|
58
|
+
- lib/mimemagic/tables.rb
|
59
|
+
- lib/mimemagic/version.rb
|
60
|
+
- mimemagic.gemspec
|
61
|
+
- script/freedesktop.org.xml
|
62
|
+
- script/generate-mime.rb
|
63
|
+
- test/files/application.gzip
|
64
|
+
- test/files/application.vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
65
|
+
- test/files/application.x-bzip
|
66
|
+
- test/files/application.x-ruby
|
67
|
+
- test/files/application.x-tar
|
68
|
+
- test/files/application.zip
|
69
|
+
- test/files/image.jpeg
|
70
|
+
- test/files/image.png
|
71
|
+
- test/mimemagic_test.rb
|
72
|
+
homepage: https://github.com/minad/mimemagic
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project: mimemagic
|
92
|
+
rubygems_version: 2.2.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Fast mime detection by extension or content
|
96
|
+
test_files: []
|