module MIME

line 1 “magics.rl”

This provides a way to guess the mime type of a file by doing both filename lookups and magic file checks. This implementation tries to follow the version 0.13 of the specification.

Constants

OriginalType

Override the existing MIME::Type class

Public Class Methods

[](type) click to toggle source

Returns the MIME::Type object corresponding to type.

# File lib/shared-mime-info.rb, line 28
def [](type)
  @types.fetch type, nil
end
check(filename) click to toggle source

Look for the type of a file by doing successive checks with the filename patterns or magic numbers. If none of the matches are successful, returns a type of application/octet-stream if the file contains control characters at its beginning, or text/plain otherwise.

Returns a MIME::Type object.

# File lib/shared-mime-info.rb, line 68
def check(filename)
  check_special(filename) ||
  open(filename) { |f|
    check_magics_gt80(f) ||
    check_globs(filename) ||
    check_magics_lt80(f) ||
    check_default(f)
  }
end
check_globs(filename) click to toggle source

Look for the type of a file by doing successive checks on the filename patterns.

Returns a MIME::Type object or nil if nothing matches.

# File lib/shared-mime-info.rb, line 36
def check_globs(filename)
  basename = File.basename(filename)
  found = @globs.each_key.select { |pattern| File.fnmatch pattern, basename }

  if found.empty?
    downcase_basename = basename.downcase
    found = @globs.each_key.select { |pattern|
      File.fnmatch pattern, downcase_basename
    }
  end

  @globs[found.max]
end
check_magics(file) click to toggle source

Look for the type of a file by doing successive checks on magic numbers.

Returns a MIME::Type object or nil if nothing matches.

# File lib/shared-mime-info.rb, line 54
def check_magics(file)
  if file.respond_to? :read
    check_magics_type(file, @magics)
  else
    open(file) {|f| check_magics_type(f, @magics) }
  end
end

Private Class Methods

check_default(f) click to toggle source
# File lib/shared-mime-info.rb, line 95
def check_default(f)
  f.pos = 0
  firsts = f.read(32) || ''
  bytes = firsts.unpack('C*')
  if bytes.any? {|byte| byte < 32 && ![9, 10, 13].include?(byte) }
    @types['application/octet-stream']
  else
    @types['text/plain']
  end
end
check_magics_gt80(f) click to toggle source
# File lib/shared-mime-info.rb, line 80
def check_magics_gt80(f); check_magics_type(f, @magics_gt80) end
check_magics_lt80(f) click to toggle source
# File lib/shared-mime-info.rb, line 81
def check_magics_lt80(f); check_magics_type(f, @magics_lt80) end
check_magics_type(f, set) click to toggle source
# File lib/shared-mime-info.rb, line 79
def check_magics_type(f, set); c = set.find {|m| m =~ f} and MIME[c.type] end
check_special(filename) click to toggle source
# File lib/shared-mime-info.rb, line 83
def check_special(filename)
  case File.ftype(filename)
  when 'directory' then @types['inode/directory']
  when 'characterSpecial' then @types['inode/chardevice']
  when 'blockSpecial' then @types['inode/blockdevice']
  when 'fifo' then @types['inode/fifo']
  when 'socket' then @types['inode/socket']
  else
    nil
  end
end
load_globs(file) click to toggle source
# File lib/shared-mime-info.rb, line 106
def load_globs(file)
  open(file) { |f|
    f.each { |line|
      next if line =~ /^#/
      cline = line.chomp
      type, pattern = cline.split ':', 2
      @types[type].glob_patterns << pattern
      @globs[pattern] = @types[type] unless @globs.has_key? pattern
    }
  }
end
load_magic(file) click to toggle source
# File lib/shared-mime-info.rb, line 118
def load_magic(file)
  @magics.concat Magic.parse_magic(File.read(file))
end