mimemagic-0.4.3/ 0000755 0000041 0000041 00000000000 14034263532 013500 5 ustar www-data www-data mimemagic-0.4.3/.travis.yml 0000644 0000041 0000041 00000001037 14034263532 015612 0 ustar www-data www-data language: 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.md 0000644 0000041 0000041 00000003715 14034263532 014765 0 ustar www-data www-data MimeMagic 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/).
[](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.md 0000644 0000041 0000041 00000005547 14034263532 015324 0 ustar www-data www-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/.gitignore 0000644 0000041 0000041 00000000164 14034263532 015471 0 ustar www-data www-data *.swp
*.gem
Gemfile.lock
.bundle
# doc
.yardoc
doc/
vendor
# don't include generated files
lib/mimemagic/path.rb
mimemagic-0.4.3/LICENSE 0000644 0000041 0000041 00000002062 14034263532 014505 0 ustar www-data www-data The 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/Rakefile 0000644 0000041 0000041 00000001025 14034263532 015143 0 ustar www-data www-data require '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/ 0000755 0000041 0000041 00000000000 14034263532 014246 5 ustar www-data www-data mimemagic-0.4.3/lib/mimemagic/ 0000755 0000041 0000041 00000000000 14034263532 016176 5 ustar www-data www-data mimemagic-0.4.3/lib/mimemagic/version.rb 0000644 0000041 0000041 00000000125 14034263532 020206 0 ustar www-data www-data class MimeMagic
# MimeMagic version string
# @api public
VERSION = '0.4.3'
end
mimemagic-0.4.3/lib/mimemagic/tables.rb 0000644 0000041 0000041 00000014473 14034263532 020006 0 ustar www-data www-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.rb 0000644 0000041 0000041 00000007402 14034263532 016526 0 ustar www-data www-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/.yardopts 0000644 0000041 0000041 00000000140 14034263532 015341 0 ustar www-data www-data --markup-provider=redcarpet
--markup=markdown
--no-private
- README.md
- LICENSE
- CHANGELOG.md
mimemagic-0.4.3/Gemfile 0000644 0000041 0000041 00000000127 14034263532 014773 0 ustar www-data www-data source 'https://rubygems.org/'
gemspec
gem 'yard'
gem 'redcarpet'
gem 'github-markup'
mimemagic-0.4.3/ext/ 0000755 0000041 0000041 00000000000 14034263532 014300 5 ustar www-data www-data mimemagic-0.4.3/ext/mimemagic/ 0000755 0000041 0000041 00000000000 14034263532 016230 5 ustar www-data www-data mimemagic-0.4.3/ext/mimemagic/Rakefile 0000644 0000041 0000041 00000002301 14034263532 017671 0 ustar www-data www-data require "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.gemspec 0000644 0000041 0000041 00000002220 14034263532 016771 0 ustar www-data www-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