Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for returning all possible mime types by magic. #37

Merged
merged 3 commits into from
May 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ rvm:
- 1.9.3
- 2.0.0
- 2.1.0
- 2.2.0
- 2.3.0
- ruby-head
- jruby-19mode
- rbx
before_install:
- gem install bundler # the default bundler version on travis is very old and causes 1.9.3 build issues
matrix:
allow_failures:
- rvm: ruby-head
31 changes: 20 additions & 11 deletions lib/mimemagic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,16 @@ def self.by_path(path)
# Lookup mime type by magic content analysis.
# This is a slow operation.
def self.by_magic(io)
mime =
unless io.respond_to?(:seek) && io.respond_to?(:read)
str = io.respond_to?(:read) ? io.read : io.to_s
str = str.force_encoding(Encoding::BINARY) if str.respond_to? :force_encoding
MAGIC.find {|type, matches| magic_match_str(str, matches) }
else
io.binmode
io.set_encoding(Encoding::BINARY) if io.respond_to?(:set_encoding)
MAGIC.find {|type, matches| magic_match_io(io, matches) }
end
mime = magic_match(io, :find)
mime && new(mime[0])
end

# Lookup all mime types by magic content analysis.
# This is a slower operation.
def self.all_by_magic(io)
magic_match(io, :select).map { |mime| new(mime[0]) }
end

# Return type as string
def to_s
type
Expand All @@ -109,6 +106,18 @@ def self.child?(child, parent)
child == parent || TYPES.key?(child) && TYPES[child][1].any? {|p| child?(p, parent) }
end

def self.magic_match(io, method)
if io.respond_to?(:seek) && io.respond_to?(:read)
io.binmode
io.set_encoding(Encoding::BINARY) if io.respond_to?(:set_encoding)
MAGIC.send(method) { |type, matches| magic_match_io(io, matches) }
else
str = io.respond_to?(:read) ? io.read : io.to_s
str = str.force_encoding(Encoding::BINARY) if str.respond_to?(:force_encoding)
MAGIC.send(method) { |type, matches| magic_match_str(str, matches) }
end
end

def self.magic_match_io(io, matches)
matches.any? do |offset, value, children|
match =
Expand Down Expand Up @@ -137,5 +146,5 @@ def self.magic_match_str(str, matches)
end
end

private_class_method :magic_match_io, :magic_match_str
private_class_method :magic_match, :magic_match_io, :magic_match_str
end
7 changes: 7 additions & 0 deletions test/mimemagic_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@
end
end

it 'should recognize all by magic' do
require 'mimemagic/overlay'
file = 'test/files/application.vnd.openxmlformats-officedocument.spreadsheetml.sheet'
mimes = %w[application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/zip]
MimeMagic.all_by_magic(File.read(file)).map(&:type).should.equal mimes
end

it 'should have add' do
MimeMagic.add('application/mimemagic-test',
extensions: %w(ext1 ext2),
Expand Down