class MIME::Types

MIME::Types

MIME types are used in MIME-compliant communications, as in e-mail or HTTP traffic, to indicate the type of content which is transmitted. MIME::Types provides the ability for detailed information about MIME entities (provided as a set of MIME::Type objects) to be determined and used programmatically. There are many types defined by RFCs and vendors, so the list is long but not complete; don't hesitate to ask to add additional information. This library follows the IANA collection of MIME types (see below for reference).

Description

MIME types are used in MIME entities, as in email or HTTP traffic. It is useful at times to have information available about MIME types (or, inversely, about files). A MIME::Type stores the known information about one MIME type.

Usage

require 'mime/types'

plaintext = MIME::Types['text/plain']
print plaintext.media_type           # => 'text'
print plaintext.sub_type             # => 'plain'

puts plaintext.extensions.join(" ")  # => 'asc txt c cc h hh cpp'

puts plaintext.encoding              # => 8bit
puts plaintext.binary?               # => false
puts plaintext.ascii?                # => true
puts plaintext.obsolete?             # => false
puts plaintext.registered?           # => true
puts plaintext == 'text/plain'       # => true
puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'

This module is built to conform to the MIME types of RFCs 2045 and 2231. It follows the official IANA registry at www.iana.org/assignments/media-types/ and ftp.iana.org/assignments/media-types with some unofficial types added from the the collection at www.ltsw.se/knbase/internet/mime.htp

Constants

DATA_VERSION
TEXT_FORMAT_RE

The regular expression used to match a file-based MIME type definition.

VERSION

The released version of Ruby MIME::Types

Attributes

data_version[R]

The data version.

Public Class Methods

new(data_version = DATA_VERSION) click to toggle source
# File lib/mime/types.rb, line 590
def initialize(data_version = DATA_VERSION)
  @type_variants    = HashWithArrayDefault.new
  @extension_index  = HashWithArrayDefault.new
  @data_version     = data_version
end

Private Class Methods

[](type_id, flags = {}) click to toggle source

Returns a list of MIME::Type objects, which may be empty. The optional flag parameters are :complete (finds only complete MIME::Type objects) and :platform (finds only MIME::Types for the current platform). It is possible for multiple matches to be returned for either type (in the example below, 'text/plain' returns two values – one for the general case, and one for VMS systems.

puts "\nMIME::Types['text/plain']"
MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }

puts "\nMIME::Types[/^image/, :complete => true]"
MIME::Types[/^image/, :complete => true].each do |t|
  puts t.to_a.join(", ")
end
# File lib/mime/types.rb, line 848
def [](type_id, flags = {})
  __types__[type_id, flags]
end
__types__() click to toggle source
# File lib/mime/types.rb, line 949
def __types__
  load_mime_types unless @__types__
  @__types__
end
add(*types) click to toggle source

Add one or more MIME::Type objects to the set of known types. Each type should be experimental (e.g., 'application/x-ruby'). If the type is already known, a warning will be displayed.

<strong>Please inform the maintainer of this module when registered types are missing.</strong>

# File lib/mime/types.rb, line 887
def add(*types)
  __types__.add(*types)
end
cache_file() click to toggle source

Returns the currently defined cache file, if any.

# File lib/mime/types.rb, line 892
def cache_file
  ENV['RUBY_MIME_TYPES_CACHE']
end
count() click to toggle source
# File lib/mime/types.rb, line 854
def count
  __types__.count
end
each() { |t| ... } click to toggle source
# File lib/mime/types.rb, line 858
def each
  __types__.each {|t| yield t }
end
lazy_load?() click to toggle source
# File lib/mime/types.rb, line 945
def lazy_load?
  (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
end
load_and_parse_mime_types() click to toggle source
# File lib/mime/types.rb, line 937
def load_and_parse_mime_types
  const_set(:LOAD, true) unless $DEBUG
  Dir[File.join(File.dirname(__FILE__), 'types', '*')].sort.each { |f|
    add(load_from_file(f))
  }
  remove_const :LOAD if defined? LOAD
end
load_mime_types() click to toggle source
# File lib/mime/types.rb, line 954
def load_mime_types
  @__types__ = new(VERSION)
  unless load_mime_types_from_cache
    load_and_parse_mime_types
    write_mime_types_to_cache
  end
end
load_mime_types_from_cache() click to toggle source
# File lib/mime/types.rb, line 897
def load_mime_types_from_cache
  load_mime_types_from_cache! if cache_file
end
load_mime_types_from_cache!() click to toggle source
# File lib/mime/types.rb, line 901
def load_mime_types_from_cache!
  raise ArgumentError, "No RUBY_MIME_TYPES_CACHE set." unless cache_file
  return false unless File.exists? cache_file

  begin
    data      = File.read(cache_file)
    container = Marshal.load(data)

    if container.version == VERSION
      @__types__ = Marshal.load(container.data)
      true
    else
      false
    end
  rescue => e
    warn "Could not load MIME::Types cache: #{e}"
    false
  end
end
of(filename, platform = false) click to toggle source

A synonym for #type_for

# File lib/mime/types.rb, line 877
def of(filename, platform = false)
  __types__.type_for(filename, platform)
end
type_for(filename, platform = false) click to toggle source

Return the list of MIME::Types which belongs to the file based on its filename extension. If platform is true, then only file types that are specific to the current platform will be returned.

This will always return an array.

puts "MIME::Types.type_for('citydesk.xml')
  => [application/xml, text/xml]
puts "MIME::Types.type_for('citydesk.gif')
  => [image/gif]
# File lib/mime/types.rb, line 872
def type_for(filename, platform = false)
  __types__.type_for(filename, platform)
end
write_mime_types_to_cache() click to toggle source
# File lib/mime/types.rb, line 921
def write_mime_types_to_cache
  write_mime_types_to_cache! if cache_file
end
write_mime_types_to_cache!() click to toggle source
# File lib/mime/types.rb, line 925
def write_mime_types_to_cache!
  raise ArgumentError, "No RUBY_MIME_TYPES_CACHE set." unless cache_file

  File.open(cache_file, 'w') do |f|
    cache = MIME::Types::CacheContainer.new(VERSION,
                                            Marshal.dump(__types__))
    f.write Marshal.dump(cache)
  end

  true
end

Public Instance Methods

[](type_id, flags = {}) click to toggle source

Returns a list of MIME::Type objects, which may be empty. The optional flag parameters are :complete (finds only complete MIME::Type objects) and :platform (finds only MIME::Types for the current platform). It is possible for multiple matches to be returned for either type (in the example below, 'text/plain' returns two values – one for the general case, and one for VMS systems.

puts "\nMIME::Types['text/plain']"
MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }

puts "\nMIME::Types[/^image/, :complete => true]"
MIME::Types[/^image/, :complete => true].each do |t|
  puts t.to_a.join(", ")
end

If multiple type definitions are returned, returns them sorted as follows:

1. Complete definitions sort before incomplete ones;
2. IANA-registered definitions sort before LTSW-recorded
   definitions.
3. Generic definitions sort before platform-specific ones;
4. Current definitions sort before obsolete ones;
5. Obsolete definitions with use-instead clauses sort before those
   without;
6. Obsolete definitions use-instead clauses are compared.
7. Sort on name.
# File lib/mime/types.rb, line 647
def [](type_id, flags = {})
  matches = case type_id
            when MIME::Type
              @type_variants[type_id.simplified]
            when Regexp
              match(type_id)
            else
              @type_variants[MIME::Type.simplified(type_id)]
            end

  prune_matches(matches, flags).sort { |a, b| a.priority_compare(b) }
end
add(*types) click to toggle source

Add one or more MIME::Type objects to the set of known types. Each type should be experimental (e.g., 'application/x-ruby'). If the type is already known, a warning will be displayed.

<strong>Please inform the maintainer of this module when registered types are missing.</strong>

# File lib/mime/types.rb, line 688
def add(*types)
  types.each do |mime_type|
    if mime_type.kind_of? MIME::Types
      add(*mime_type.defined_types)
    else
      if @type_variants.include?(mime_type.simplified)
        if @type_variants[mime_type.simplified].include?(mime_type)
          warn "Type #{mime_type} already registered as a variant of #{mime_type.simplified}." unless defined? MIME::Types::LOAD
        end
      end
      add_type_variant(mime_type)
      index_extensions(mime_type)
    end
  end
end
count() click to toggle source

Returns the number of known types. A shortcut of MIME::Types.size. (Keep in mind that this is memory intensive, cache the result to spare resources)

# File lib/mime/types.rb, line 611
def count
  defined_types.size
end
each() { |t| ... } click to toggle source
# File lib/mime/types.rb, line 615
def each
 defined_types.each { |t| yield t }
end
of(filename, platform = false) click to toggle source

A synonym for #type_for

# File lib/mime/types.rb, line 678
def of(filename, platform = false)
  type_for(filename, platform)
end
type_for(filename, platform = false) click to toggle source

Return the list of MIME::Types which belongs to the file based on its filename extension. If platform is true, then only file types that are specific to the current platform will be returned.

This will always return an array.

puts "MIME::Types.type_for('citydesk.xml')
  => [application/xml, text/xml]
puts "MIME::Types.type_for('citydesk.gif')
  => [image/gif]
# File lib/mime/types.rb, line 670
def type_for(filename, platform = false)
  ext = filename.chomp.downcase.gsub(/.*\./o, '')
  list = @extension_index[ext]
  list.delete_if { |e| not e.platform? } if platform
  list
end

Private Instance Methods

match(pattern) click to toggle source
# File lib/mime/types.rb, line 711
def match(pattern)
  matches = @type_variants.select { |k, v| k =~ pattern }
  if matches.respond_to? :values
    matches.values.flatten
  else
    matches.map { |m| m.last }.flatten
  end
end
prune_matches(matches, flags) click to toggle source
# File lib/mime/types.rb, line 705
def prune_matches(matches, flags)
  matches.delete_if { |e| not e.complete? } if flags[:complete]
  matches.delete_if { |e| not e.platform? } if flags[:platform]
  matches
end