afp_mimemagic 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ class MimeMagic
2
+ # MimeMagic version string
3
+ # @api public
4
+ VERSION = '0.3.6'
5
+ end
data/lib/mimemagic.rb ADDED
@@ -0,0 +1,148 @@
1
+ require 'mimemagic/tables'
2
+ require 'mimemagic/version'
3
+
4
+ require 'stringio'
5
+
6
+ # Mime type detection
7
+ class MimeMagic
8
+ attr_reader :type, :mediatype, :subtype
9
+
10
+ # Mime type by type string
11
+ def initialize(type)
12
+ @type = type
13
+ @mediatype, @subtype = type.split('/', 2)
14
+ end
15
+
16
+ # Add custom mime type. Arguments:
17
+ # * <i>type</i>: Mime type
18
+ # * <i>options</i>: Options hash
19
+ #
20
+ # Option keys:
21
+ # * <i>:extensions</i>: String list or single string of file extensions
22
+ # * <i>:parents</i>: String list or single string of parent mime types
23
+ # * <i>:magic</i>: Mime magic specification
24
+ # * <i>:comment</i>: Comment string
25
+ def self.add(type, options)
26
+ extensions = [options[:extensions]].flatten.compact
27
+ TYPES[type] = [extensions,
28
+ [options[:parents]].flatten.compact,
29
+ options[:comment]]
30
+ extensions.each { |ext| EXTENSIONS[ext] = type }
31
+ MAGIC.unshift [type, options[:magic]] if options[:magic]
32
+ end
33
+
34
+ # Removes a mime type from the dictionary. You might want to do this if
35
+ # you're seeing impossible conflicts (for instance, application/x-gmc-link).
36
+ # * <i>type</i>: The mime type to remove. All associated extensions and magic are removed too.
37
+ def self.remove(type)
38
+ EXTENSIONS.delete_if { |_ext, t| t == type }
39
+ MAGIC.delete_if { |t, _m| t == type }
40
+ TYPES.delete(type)
41
+ end
42
+
43
+ # Returns true if type is a text format
44
+ def text?
45
+ mediatype == 'text' || child_of?('text/plain')
46
+ end
47
+
48
+ # Mediatype shortcuts
49
+ def image?
50
+ mediatype == 'image'
51
+ end
52
+
53
+ def audio?
54
+ mediatype == 'audio'
55
+ end
56
+
57
+ def video?
58
+ mediatype == 'video'
59
+ end
60
+
61
+ # Returns true if type is child of parent type
62
+ def child_of?(parent)
63
+ MimeMagic.child?(type, parent)
64
+ end
65
+
66
+ # Get string list of file extensions
67
+ def extensions
68
+ TYPES.key?(type) ? TYPES[type][0] : []
69
+ end
70
+
71
+ # Get mime comment
72
+ def comment
73
+ (TYPES.key?(type) ? TYPES[type][2] : nil).to_s
74
+ end
75
+
76
+ # Lookup mime type by file extension
77
+ def self.by_extension(ext)
78
+ ext = ext.to_s.downcase
79
+ mime = ext[0..0] == '.' ? EXTENSIONS[ext[1..-1]] : EXTENSIONS[ext]
80
+ mime && new(mime)
81
+ end
82
+
83
+ # Lookup mime type by filename
84
+ def self.by_path(path)
85
+ by_extension(File.extname(path))
86
+ end
87
+
88
+ # Lookup mime type by magic content analysis.
89
+ # This is a slow operation.
90
+ def self.by_magic(io)
91
+ mime = magic_match(io, :find)
92
+ mime && new(mime[0])
93
+ end
94
+
95
+ # Lookup all mime types by magic content analysis.
96
+ # This is a slower operation.
97
+ def self.all_by_magic(io)
98
+ magic_match(io, :select).map { |mime| new(mime[0]) }
99
+ end
100
+
101
+ # Return type as string
102
+ def to_s
103
+ type
104
+ end
105
+
106
+ # Allow comparison with string
107
+ def eql?(other)
108
+ type == other.to_s
109
+ end
110
+
111
+ def hash
112
+ type.hash
113
+ end
114
+
115
+ alias == eql?
116
+
117
+ def self.child?(child, parent)
118
+ child == parent || TYPES.key?(child) && TYPES[child][1].any? { |p| child?(p, parent) }
119
+ end
120
+
121
+ def self.magic_match(io, method)
122
+ return magic_match(StringIO.new(io.to_s), method) unless io.respond_to?(:read)
123
+
124
+ io.binmode if io.respond_to?(:binmode)
125
+ io.set_encoding(Encoding::BINARY) if io.respond_to?(:set_encoding)
126
+ buffer = ''.force_encoding(Encoding::BINARY)
127
+
128
+ MAGIC.send(method) { |_type, matches| magic_match_io(io, matches, buffer) }
129
+ end
130
+
131
+ def self.magic_match_io(io, matches, buffer)
132
+ matches.any? do |offset, value, children|
133
+ match =
134
+ if offset.is_a?(Range)
135
+ io.read(offset.begin, buffer)
136
+ x = io.read(offset.end - offset.begin + value.bytesize, buffer)
137
+ x && x.include?(value)
138
+ else
139
+ io.read(offset, buffer)
140
+ io.read(value.bytesize, buffer) == value
141
+ end
142
+ io.rewind
143
+ match && (!children || magic_match_io(io, children, buffer))
144
+ end
145
+ end
146
+
147
+ private_class_method :magic_match, :magic_match_io
148
+ end
data/mimemagic.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/lib/mimemagic/version'
2
+ require 'date'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'afp_mimemagic'
6
+ s.version = MimeMagic::VERSION
7
+
8
+ s.authors = ['Daniel Mendler']
9
+ s.date = Date.today.to_s
10
+ s.email = ['mail@daniel-mendler.de']
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.require_paths = %w[lib]
14
+
15
+ s.summary = 'Fast mime detection by extension or content'
16
+ s.description = 'Fast mime detection by extension or content in pure ruby (Uses freedesktop.org.xml shared-mime-info database)'
17
+ s.homepage = 'https://github.com/minad/mimemagic'
18
+ s.license = 'GPL-2.0'
19
+
20
+ s.add_development_dependency('minitest', '~> 5.11')
21
+ s.add_development_dependency('rake')
22
+
23
+ if s.respond_to?(:metadata)
24
+ s.metadata['changelog_uri'] = 'https://github.com/minad/mimemagic/blob/master/CHANGELOG.md'
25
+ s.metadata['source_code_uri'] = 'https://github.com/minad/mimemagic'
26
+ s.metadata['bug_tracker_uri'] = 'https://github.com/minad/mimemagic/issues'
27
+ end
28
+ end