class Marcel::MimeType

Constants

BINARY

Public Class Methods

extend(type, extensions: [], parents: [], magic: nil) click to toggle source
# File lib/marcel/mime_type.rb, line 5
def extend(type, extensions: [], parents: [], magic: nil)
  existing = MimeMagic::TYPES[type] || [[], [], ""]

  extensions = (Array(extensions) + existing[0]).uniq
  parents = (Array(parents) + existing[1]).uniq
  comment = existing[2]

  MimeMagic.add(type, extensions: extensions, magic: magic, parents: parents, comment: comment)
end
for(pathname_or_io = nil, name: nil, extension: nil, declared_type: nil) click to toggle source
# File lib/marcel/mime_type.rb, line 15
def for(pathname_or_io = nil, name: nil, extension: nil, declared_type: nil)
  type_from_data = for_data(pathname_or_io)
  fallback_type = for_declared_type(declared_type) || for_name(name) || for_extension(extension) || BINARY

  if type_from_data
    most_specific_type type_from_data, fallback_type
  else
    fallback_type
  end
end

Private Class Methods

for_data(pathname_or_io) click to toggle source
# File lib/marcel/mime_type.rb, line 27
def for_data(pathname_or_io)
  if pathname_or_io
    with_io(pathname_or_io) do |io|
      if magic = MimeMagic.by_magic(io)
        magic.type.downcase
      end
    end
  end
end
for_declared_type(declared_type) click to toggle source
# File lib/marcel/mime_type.rb, line 53
def for_declared_type(declared_type)
  type = parse_media_type(declared_type)

  if type != BINARY && !type.nil?
    type.downcase
  end
end
for_extension(extension) click to toggle source
# File lib/marcel/mime_type.rb, line 45
def for_extension(extension)
  if extension
    if magic = MimeMagic.by_extension(extension)
      magic.type.downcase
    end
  end
end
for_name(name) click to toggle source
# File lib/marcel/mime_type.rb, line 37
def for_name(name)
  if name
    if magic = MimeMagic.by_path(name)
      magic.type.downcase
    end
  end
end
most_specific_type(from_magic_type, fallback_type) click to toggle source

For some document types (notably Microsoft Office) we recognise the main content type with magic, but not the specific subclass. In this situation, if we can get a more specific class using either the name or declared_type, we should use that in preference

# File lib/marcel/mime_type.rb, line 80
def most_specific_type(from_magic_type, fallback_type)
  if (root_types(from_magic_type) & root_types(fallback_type)).any?
    fallback_type
  else
    from_magic_type
  end
end
parse_media_type(content_type) click to toggle source
# File lib/marcel/mime_type.rb, line 70
def parse_media_type(content_type)
  if content_type
    result = content_type.downcase.split(/[;,\s]/, 2).first
    result if result && result.index("/")
  end
end
root_types(type) click to toggle source
# File lib/marcel/mime_type.rb, line 88
def root_types(type)
  if MimeMagic::TYPES[type].nil? || MimeMagic::TYPES[type][1].empty?
    [ type ]
  else
    MimeMagic::TYPES[type][1].map {|t| root_types t }.flatten
  end
end
with_io(pathname_or_io) { |pathname_or_io| ... } click to toggle source
# File lib/marcel/mime_type.rb, line 61
def with_io(pathname_or_io, &block)
  case pathname_or_io
  when Pathname
    pathname_or_io.open(&block)
  else
    yield pathname_or_io
  end
end