mimemagic-0.4.3/0000755000004100000410000000000014034263532013500 5ustar www-datawww-datamimemagic-0.4.3/.travis.yml0000644000004100000410000000103714034263532015612 0ustar www-datawww-datalanguage: ruby jobs: include: - rvm: 1.9.3 - rvm: 2.0.0 - rvm: 2.1 - rvm: 2.2 - rvm: 2.3 - rvm: 2.4 env: RUBYOPT="--enable-frozen-string-literal" - rvm: 2.5 env: RUBYOPT="--enable-frozen-string-literal" - rvm: ruby-head env: RUBYOPT="--enable-frozen-string-literal" before_install: # 1. The pre-installed Bundler version on Travis is very old; causes 1.9.3 build issues # 2. Bundler 2.0 is not supported by the whole matrix - gem install bundler -v'< 2' script: - bundle exec rake mimemagic-0.4.3/README.md0000644000004100000410000000371514034263532014765 0ustar www-datawww-dataMimeMagic is a library to detect the mime type of a file by extension or by content. It uses the mime database provided by freedesktop.org (see http://freedesktop.org/wiki/Software/shared-mime-info/). [![Gem Version](https://img.shields.io/gem/v/mimemagic.svg)](http://rubygems.org/gems/mimemagic) Dependencies ============ You will require a copy of the Freedesktop.org shared-mime-info database to be available. If you're on Linux, it's probably available via your package manager, and will probably be in the location it's being looked for when the gem is installed. macOS users can install the database via Homebrew with `brew install shared-mime-info`. Should you be unable to use a package manager you can obtain a copy of the needed file by extracting it from the Debian package. This process will also work on a Windows machine. 1. Download the package from https://packages.debian.org/sid/amd64/shared-mime-info/download 2. Ensure the command line version of 7-Zip is installed 3. `7z x -so shared-mime-info_2.0-1_amd64.deb data.tar | 7z e -sidata.tar "./usr/share/mime/packages/freedesktop.org.xml"` Place the file `freedesktop.org.xml` in an appropriate location, and then set the environment variable `FREEDESKTOP_MIME_TYPES_PATH` to that path. Once that has been done the gem should install successfully. Please note that the gem will depend upon the file remaining in that location at run time. Usage ===== ```ruby require 'mimemagic' MimeMagic.by_extension('html').text? MimeMagic.by_extension('.html').child_of? 'text/plain' MimeMagic.by_path('filename.txt') MimeMagic.by_magic(File.open('test.html')) # etc... ``` You can add your own magic with `MimeMagic.add`. API === http://www.rubydoc.info/github/mimemagicrb/mimemagic Tests ===== ```console $ bundle install $ bundle exec rake test ``` Authors ======= * Daniel Mendler * Jon Wood * [MimeMagic Contributors](https://github.com/mimemagicrb/mimemagic/graphs/contributors) LICENSE ======= {file:LICENSE MIT} mimemagic-0.4.3/CHANGELOG.md0000644000004100000410000000554714034263532015324 0ustar www-datawww-data# Changelog ## Unreleased ### Breaking Changes ## 0.4.1 Remove `mimemagic/overlay` as it contains outdated, little used, data. ## 0.3.7 (2021-03-25) You will now need to ensure you have a copy of the fd.o shared MIME types information available before installing this gem. More details can be found in the readme. ### Added None ### Fixed None ## 0.4.2 * Resolve issues parsing the version of freedesktop.org.xml shipped with Ubuntu Trusty. * Make Rake a runtime dependency. * Fix the test suite. * Relax the dependency on Nokogiri to something less specific in order to avoid conflicting with other dependencies in people's applications. ## 0.4.1 ## 0.4.0 Yanked release. ## 0.3.9 (2021-03-25) * Resolve issues parsing the version of freedesktop.org.xml shipped with Ubuntu Trusty. * Reintroduce overlays, since it seems at least some people were using them. * Make Rake a runtime dependency. * Fix the test suite. ## 0.3.8 (2021-03-25) Relax the dependency on Nokogiri to something less specific in order to avoid conflicting with other dependencies in people's applications. ## 0.3.7 (2021-03-25) Add a dependency on having a preinstalled version of the fd.o shared MIME types info to resolve licensing concerns, and allow this gem to remain MIT licensed. See the readme for details on ensuring you have a copy of the database available at install time. ## 0.3.6 (2021-03-23) Yanked release, relicensing to GPL due to licensing concerns. ## 0.3.5 (2020-05-04) Mimetype extensions are now ordered by freedesktop.org's priority ## 0.3.4 (2020-01-28) Added frozen string literal comments ## 0.3.3 (2018-12-20) Upgrade to shared-mime-info-1.10 ## 0.3.2 (2016-08-02) ### Breaking Changes None ### Added - [#37](https://github.com/minad/mimemagic/pull/37) A convenient way to get all possible mime types by magic ### Fixed - [#40](https://github.com/minad/mimemagic/pull/40), [#41](https://github.com/minad/mimemagic/pull/41) Performance improvements - [#38](https://github.com/minad/mimemagic/pull/38) Updated to shared-mime-info 1.6 ## 0.3.1 (2016-01-04) No release notes yet. Contributions welcome. ## 0.3.0 (2015-03-25) No release notes yet. Contributions welcome. ## 0.2.1 (2013-07-29) No release notes yet. Contributions welcome. ## 0.2.0 (2012-10-19) No release notes yet. Contributions welcome. ## 0.1.9 (2012-09-20) No release notes yet. Contributions welcome. ## 0.1.8 (2009-05-08) No release notes yet. Contributions welcome. ## 0.1.7 (2009-05-08) No release notes yet. Contributions welcome. ## 0.1.5 (2009-05-08) No release notes yet. Contributions welcome. ## 0.1.4 (2009-05-08) No release notes yet. Contributions welcome. ## 0.1.3 (2009-05-08) No release notes yet. Contributions welcome. ## 0.1.2 (2009-05-08) No release notes yet. Contributions welcome. ## 0.1.1 (2009-05-08) No release notes yet. Contributions welcome. mimemagic-0.4.3/.gitignore0000644000004100000410000000016414034263532015471 0ustar www-datawww-data*.swp *.gem Gemfile.lock .bundle # doc .yardoc doc/ vendor # don't include generated files lib/mimemagic/path.rb mimemagic-0.4.3/LICENSE0000644000004100000410000000206214034263532014505 0ustar www-datawww-dataThe MIT License Copyright (c) 2011 Daniel Mendler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.mimemagic-0.4.3/Rakefile0000644000004100000410000000102514034263532015143 0ustar www-datawww-datarequire 'rake/testtask' require 'rake/clean' namespace :ext do load 'ext/mimemagic/Rakefile' end CLOBBER.include("lib/mimemagic/path.rb") task :default => %w(test) desc 'Run tests with minitest' Rake::TestTask.new("test" => "ext:default") do |t| t.libs << 'test' t.pattern = 'test/*_test.rb' end desc 'Generate mime tables' task :tables => 'lib/mimemagic/tables.rb' file 'lib/mimemagic/tables.rb' => FileList['script/freedesktop.org.xml'] do |f| sh "script/generate-mime.rb #{f.prerequisites.join(' ')} > #{f.name}" end mimemagic-0.4.3/lib/0000755000004100000410000000000014034263532014246 5ustar www-datawww-datamimemagic-0.4.3/lib/mimemagic/0000755000004100000410000000000014034263532016176 5ustar www-datawww-datamimemagic-0.4.3/lib/mimemagic/version.rb0000644000004100000410000000012514034263532020206 0ustar www-datawww-dataclass MimeMagic # MimeMagic version string # @api public VERSION = '0.4.3' end mimemagic-0.4.3/lib/mimemagic/tables.rb0000644000004100000410000001447314034263532020006 0ustar www-datawww-data# -*- coding: binary -*- # frozen_string_literal: true # Generated from script/freedesktop.org.xml require 'nokogiri' require 'mimemagic/path' class MimeMagic EXTENSIONS = {} TYPES = {} MAGIC = [] def self.str2int(s) return s.to_i(16) if s[0..1].downcase == '0x' return s.to_i(8) if s[0..0].downcase == '0' s.to_i(10) end def self.get_matches(parent) parent.elements.map {|match| if match['mask'] nil else type = match['type'] value = match['value'] offset = match['offset'].split(':').map {|x| x.to_i } offset = offset.size == 2 ? offset[0]..offset[1] : offset[0] case type when 'string' # This *one* pattern match, in the entirety of fd.o's mime types blows up the parser # because of the escape character \c, so right here we have a hideous hack to # accommodate that. if value == '\chapter' '\chapter' else value.gsub!(/\\(x[\dA-Fa-f]{1,2}|0\d{1,3}|\d{1,3}|.)/) { eval("\"\\#{$1}\"") } end when 'big16' value = str2int(value) value = ((value >> 8).chr + (value & 0xFF).chr) when 'big32' value = str2int(value) value = (((value >> 24) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 8) & 0xFF).chr + (value & 0xFF).chr) when 'little16' value = str2int(value) value = ((value & 0xFF).chr + (value >> 8).chr) when 'little32' value = str2int(value) value = ((value & 0xFF).chr + ((value >> 8) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 24) & 0xFF).chr) when 'host16' # use little endian value = str2int(value) value = ((value & 0xFF).chr + (value >> 8).chr) when 'host32' # use little endian value = str2int(value) value = ((value & 0xFF).chr + ((value >> 8) & 0xFF).chr + ((value >> 16) & 0xFF).chr + ((value >> 24) & 0xFF).chr) when 'byte' value = str2int(value) value = value.chr end children = get_matches(match) children.empty? ? [offset, value] : [offset, value, children] end }.compact end def self.open_mime_database path = MimeMagic::DATABASE_PATH File.open(path) end def self.parse_database file = open_mime_database doc = Nokogiri::XML(file) extensions = {} types = {} magics = [] (doc/'mime-info/mime-type').each do |mime| comments = Hash[*(mime/'comment').map {|comment| [comment['xml:lang'], comment.inner_text] }.flatten] type = mime['type'] subclass = (mime/'sub-class-of').map{|x| x['type']} exts = (mime/'glob').map{|x| x['pattern'] =~ /^\*\.([^\[\]]+)$/ ? $1.downcase : nil }.compact (mime/'magic').each do |magic| priority = magic['priority'].to_i matches = get_matches(magic) magics << [priority, type, matches] end if !exts.empty? exts.each{|x| extensions[x] = type if !extensions.include?(x) } types[type] = [exts,subclass,comments[nil]] end end magics = magics.sort {|a,b| [-a[0],a[1]] <=> [-b[0],b[1]] } common_types = [ "image/jpeg", # .jpg "image/png", # .png "image/gif", # .gif "image/tiff", # .tiff "image/bmp", # .bmp "image/vnd.adobe.photoshop", # .psd "image/webp", # .webp "image/svg+xml", # .svg "video/x-msvideo", # .avi "video/x-ms-wmv", # .wmv "video/mp4", # .mp4, .m4v "video/quicktime", # .mov "video/mpeg", # .mpeg "video/ogg", # .ogv "video/webm", # .webm "video/x-matroska", # .mkv "video/x-flv", # .flv "audio/mpeg", # .mp3 "audio/x-wav", # .wav "audio/aac", # .aac "audio/flac", # .flac "audio/mp4", # .m4a "audio/ogg", # .ogg "application/pdf", # .pdf "application/msword", # .doc "application/vnd.openxmlformats-officedocument.wordprocessingml.document", # .docx "application/vnd.ms-powerpoint", # .pps "application/vnd.openxmlformats-officedocument.presentationml.slideshow", # .ppsx "application/vnd.ms-excel", # .pps "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", # .ppsx ] common_magics = common_types.map do |common_type| magics.find { |_, type, _| type == common_type } end magics = (common_magics.compact + magics).uniq extensions.keys.sort.each do |key| EXTENSIONS[key] = extensions[key] end types.keys.sort.each do |key| exts = types[key][0] parents = types[key][1].sort comment = types[key][2] TYPES[key] = [exts, parents, comment] end magics.each do |priority, type, matches| MAGIC << [type, matches] end end end mimemagic-0.4.3/lib/mimemagic.rb0000644000004100000410000000740214034263532016526 0ustar www-datawww-data# frozen_string_literal: true require 'mimemagic/tables' require 'mimemagic/version' require 'stringio' MimeMagic.parse_database # Mime type detection class MimeMagic attr_reader :type, :mediatype, :subtype # Mime type by type string def initialize(type) @type = type @mediatype, @subtype = type.split('/', 2) end # Add custom mime type. Arguments: # * type: Mime type # * options: Options hash # # Option keys: # * :extensions: String list or single string of file extensions # * :parents: String list or single string of parent mime types # * :magic: Mime magic specification # * :comment: Comment string def self.add(type, options) extensions = [options[:extensions]].flatten.compact TYPES[type] = [extensions, [options[:parents]].flatten.compact, options[:comment]] extensions.each {|ext| EXTENSIONS[ext] = type } MAGIC.unshift [type, options[:magic]] if options[:magic] end # Removes a mime type from the dictionary. You might want to do this if # you're seeing impossible conflicts (for instance, application/x-gmc-link). # * type: The mime type to remove. All associated extensions and magic are removed too. def self.remove(type) EXTENSIONS.delete_if {|ext, t| t == type } MAGIC.delete_if {|t, m| t == type } TYPES.delete(type) end # Returns true if type is a text format def text?; mediatype == 'text' || child_of?('text/plain'); end # Mediatype shortcuts def image?; mediatype == 'image'; end def audio?; mediatype == 'audio'; end def video?; mediatype == 'video'; end # Returns true if type is child of parent type def child_of?(parent) MimeMagic.child?(type, parent) end # Get string list of file extensions def extensions TYPES.key?(type) ? TYPES[type][0] : [] end # Get mime comment def comment (TYPES.key?(type) ? TYPES[type][2] : nil).to_s end # Lookup mime type by file extension def self.by_extension(ext) ext = ext.to_s.downcase mime = ext[0..0] == '.' ? EXTENSIONS[ext[1..-1]] : EXTENSIONS[ext] mime && new(mime) end # Lookup mime type by filename def self.by_path(path) by_extension(File.extname(path)) end # Lookup mime type by magic content analysis. # This is a slow operation. def self.by_magic(io) 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 end # Allow comparison with string def eql?(other) type == other.to_s end def hash type.hash end alias == eql? 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) return magic_match(StringIO.new(io.to_s), method) unless io.respond_to?(:read) io.binmode if io.respond_to?(:binmode) io.set_encoding(Encoding::BINARY) if io.respond_to?(:set_encoding) buffer = "".encode(Encoding::BINARY) MAGIC.send(method) { |type, matches| magic_match_io(io, matches, buffer) } end def self.magic_match_io(io, matches, buffer) matches.any? do |offset, value, children| match = if Range === offset io.read(offset.begin, buffer) x = io.read(offset.end - offset.begin + value.bytesize, buffer) x && x.include?(value) else io.read(offset, buffer) io.read(value.bytesize, buffer) == value end io.rewind match && (!children || magic_match_io(io, children, buffer)) end end private_class_method :magic_match, :magic_match_io end mimemagic-0.4.3/.yardopts0000644000004100000410000000014014034263532015341 0ustar www-datawww-data--markup-provider=redcarpet --markup=markdown --no-private - README.md - LICENSE - CHANGELOG.md mimemagic-0.4.3/Gemfile0000644000004100000410000000012714034263532014773 0ustar www-datawww-datasource 'https://rubygems.org/' gemspec gem 'yard' gem 'redcarpet' gem 'github-markup' mimemagic-0.4.3/ext/0000755000004100000410000000000014034263532014300 5ustar www-datawww-datamimemagic-0.4.3/ext/mimemagic/0000755000004100000410000000000014034263532016230 5ustar www-datawww-datamimemagic-0.4.3/ext/mimemagic/Rakefile0000644000004100000410000000230114034263532017671 0ustar www-datawww-datarequire "rubygems" require "rake/clean" def locate_mime_database possible_paths = [ (File.expand_path(ENV["FREEDESKTOP_MIME_TYPES_PATH"]) if ENV["FREEDESKTOP_MIME_TYPES_PATH"]), "/usr/local/share/mime/packages/freedesktop.org.xml", "/opt/homebrew/share/mime/packages/freedesktop.org.xml", "/opt/local/share/mime/packages/freedesktop.org.xml", "/usr/share/mime/packages/freedesktop.org.xml" ].compact path = possible_paths.find { |candidate| File.exist?(candidate) } return path unless path.nil? raise(<<-ERROR.gsub(/^ {3}/, "")) Could not find MIME type database in the following locations: #{possible_paths} Ensure you have either installed the shared-mime-info package for your distribution, or obtain a version of freedesktop.org.xml and set FREEDESKTOP_MIME_TYPES_PATH to the location of that file. ERROR end desc "Build a file pointing at the database" task :default do mime_database_path = locate_mime_database target_dir = "#{ENV.fetch("RUBYARCHDIR")}/mimemagic" mkdir_p target_dir open("#{target_dir}/path.rb", "w") do |f| f.print(<<~SOURCE class MimeMagic DATABASE_PATH="#{mime_database_path}" end SOURCE ) end end mimemagic-0.4.3/mimemagic.gemspec0000644000004100000410000000222014034263532016771 0ustar www-datawww-data# -*- encoding: utf-8 -*- require File.dirname(__FILE__) + '/lib/mimemagic/version' require 'date' Gem::Specification.new do |s| s.name = 'mimemagic' s.version = MimeMagic::VERSION s.authors = ['Daniel Mendler', 'Jon Wood'] s.date = Date.today.to_s s.email = ['mail@daniel-mendler.de', 'jon@blankpad.net'] s.files = `git ls-files`.split("\n").reject { |f| f.match(%r{^(test|script)/}) } s.require_paths = %w(lib) s.extensions = %w(ext/mimemagic/Rakefile) s.summary = 'Fast mime detection by extension or content' s.description = 'Fast mime detection by extension or content (Uses freedesktop.org.xml shared-mime-info database)' s.homepage = 'https://github.com/mimemagicrb/mimemagic' s.license = 'MIT' s.add_dependency('nokogiri', '~> 1') s.add_dependency('rake') s.add_development_dependency('minitest', '~> 5.14') if s.respond_to?(:metadata) s.metadata['changelog_uri'] = "https://github.com/mimemagicrb/mimemagic/blob/master/CHANGELOG.md" s.metadata['source_code_uri'] = "https://github.com/mimemagicrb/mimemagic" s.metadata['bug_tracker_uri'] = "https://github.com/mimemagicrb/mimemagic/issues" end end