# frozen_string_literal: true ## module MIME; end ## class MIME::Types; end require "mime/types/data" # This class is responsible for initializing the MIME::Types registry from # the data files supplied with the mime-types library. # # The Loader will use one of the following paths: # 1. The +path+ provided in its constructor argument; # 2. The value of ENV['RUBY_MIME_TYPES_DATA']; or # 3. The value of MIME::Types::Data::PATH. # # When #load is called, the +path+ will be searched recursively for all YAML # (.yml or .yaml) files. By convention, there is one file for each media # type (application.yml, audio.yml, etc.), but this is not required. class MIME::Types::Loader # The path that will be read for the MIME::Types files. attr_reader :path # The MIME::Types container instance that will be loaded. If not provided # at initialization, a new MIME::Types instance will be constructed. attr_reader :container # Creates a Loader object that can be used to load MIME::Types registries # into memory, using YAML, JSON, or Columnar registry format loaders. def initialize(path = nil, container = nil) path = path || ENV["RUBY_MIME_TYPES_DATA"] || MIME::Types::Data::PATH @container = container || MIME::Types.new @path = File.expand_path(path) end # Loads a MIME::Types registry from YAML files (*.yml or # *.yaml) recursively found in +path+. # # It is expected that the YAML objects contained within the registry array # will be tagged as !ruby/object:MIME::Type. # # Note that the YAML format is about 2½ times *slower* than the JSON format. # # NOTE: The purpose of this format is purely for maintenance reasons. def load_yaml Dir[yaml_path].sort.each do |f| container.add(*self.class.load_from_yaml(f), :silent) end container end # Loads a MIME::Types registry from JSON files (*.json) # recursively found in +path+. # # It is expected that the JSON objects will be an array of hash objects. # The JSON format is the registry format for the MIME types registry # shipped with the mime-types library. def load_json Dir[json_path].sort.each do |f| types = self.class.load_from_json(f) container.add(*types, :silent) end container end # Loads a MIME::Types registry from columnar files recursively found in # +path+. def load_columnar require "mime/types/columnar" unless defined?(MIME::Types::Columnar) container.extend(MIME::Types::Columnar) container.load_base_data(path) container end # Loads a MIME::Types registry. Loads from JSON files by default # (#load_json). # # This will load from columnar files (#load_columnar) if columnar: # true is provided in +options+ and there are columnar files in +path+. def load(options = {columnar: false}) if options[:columnar] && !Dir[columnar_path].empty? load_columnar else load_json end end class << self # Loads the default MIME::Type registry. def load(options = {columnar: false}) new.load(options) end # Loads MIME::Types from a single YAML file. # # It is expected that the YAML objects contained within the registry # array will be tagged as !ruby/object:MIME::Type. # # Note that the YAML format is about 2½ times *slower* than the JSON # format. # # NOTE: The purpose of this format is purely for maintenance reasons. def load_from_yaml(filename) begin require "psych" rescue LoadError nil end require "yaml" if old_yaml? YAML.safe_load(read_file(filename), [MIME::Type]) else YAML.safe_load(read_file(filename), permitted_classes: [MIME::Type]) end end # Loads MIME::Types from a single JSON file. # # It is expected that the JSON objects will be an array of hash objects. # The JSON format is the registry format for the MIME types registry # shipped with the mime-types library. def load_from_json(filename) require "json" JSON.parse(read_file(filename)).map { |type| MIME::Type.new(type) } end private def read_file(filename) File.open(filename, "r:UTF-8:-", &:read) end def old_yaml? @old_yaml ||= begin require "rubygems/version" Gem::Version.new(YAML::VERSION) < Gem::Version.new("3.1") end end end private def yaml_path File.join(path, "*.y{,a}ml") end def json_path File.join(path, "*.json") end def columnar_path File.join(path, "*.column") end end