shared-mime-info 0.1 → 0.2.5

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d7bc9f651e0b3ff517d8c2ec1dfad3912d246449
4
+ data.tar.gz: 84771f2ad03cb8a8c176297d3f5ddbc9055cddf5
5
+ SHA512:
6
+ metadata.gz: c91043438e9e4d8da897b2bc944ac0953817cea3d1e28e3fe1e4256f431fb7efe3cf01eeb8ce33fdb2b7477218b4683e745265ac8dde5b0abdbcd29f25701f55
7
+ data.tar.gz: bbcb438545358fd618c5425a4acf045b6d0ce6f7aeb6cecd29a44c4323481b0172882b4fca3ae3a3cc9eb4713b94afa2967586efcbb1ccc7c9264520039b3825
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2006 Mael Clerambault <mael@clerambault.fr>
2
+
3
+ Permission to use, copy, modify, and distribute this software for any
4
+ purpose with or without fee is hereby granted, provided that the above
5
+ copyright notice and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,25 @@
1
+ = shared-mime-info
2
+
3
+ shared-mime-info is a pure Ruby library for accessing the MIME info database provided by Freedesktop[http://freedesktop.org/] on {Standards/shared-mime-info-spec}[http://freedesktop.org/wiki/Specifications/shared-mime-info-spec].
4
+
5
+ = Project
6
+
7
+ The rubyforge project : http://rubyforge.org/projects/shared-mime
8
+
9
+ The github repository: http://github.com/hanklords/shared-mime-info/tree/master
10
+
11
+
12
+ = Usage
13
+
14
+ require 'shared-mime-info'
15
+
16
+ MIME.check 'sample.jpg' # => #<MIME::Type ..., @type="image/jpeg">
17
+
18
+ MIME['image/jpeg'].match_filename? 'sample.jpg' # => true
19
+
20
+ = Notes
21
+ * Ensure that shared-mime-info is installed on the system:
22
+ > brew install shared-mime-info
23
+ * You may need to update the mime database first:
24
+ > update-mime-database
25
+
@@ -0,0 +1,43 @@
1
+ require 'rdoc/task'
2
+ require 'rake/packagetask'
3
+ require 'rubygems/package_task'
4
+
5
+ require_relative 'lib/shared-mime-info/version'
6
+
7
+ PKG_FILES = FileList["lib/*.rb", "lib/shared-mime-info/*", "Rakefile", "LICENSE", "README.rdoc"]
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.summary = "Library to guess the MIME type of a file with both filename lookup and magic file detection"
11
+ s.name = "shared-mime-info"
12
+ s.description = 'shared-mime-info is a pure Ruby library for accessing the MIME info database provided by Freedesktop'
13
+ s.author = "Mael Clerambault"
14
+ s.email = "mael@clerambault.fr"
15
+ s.license = 'Public Domain'
16
+ s.homepage = 'http://shared-mime.rubyforge.org/'
17
+ s.version = SharedMimeInfo::VERSION
18
+ s.files = PKG_FILES.to_a
19
+ end
20
+
21
+ RDoc::Task.new do |rd|
22
+ rd.rdoc_files.include "README.rdoc", "lib/*.rb"
23
+ rd.options << "--inline-source"
24
+ end
25
+
26
+ Gem::PackageTask.new(spec).define
27
+
28
+ desc 'Generate the magics parser'
29
+ file "lib/magics.rb" => "magics.rl" do |t|
30
+ sh "ragel -R -o #{t.name} #{t.prerequisites.join(' ')}"
31
+ end
32
+
33
+ desc 'Generate the gemspec'
34
+ task :spec do
35
+ open("#{spec.name}.gemspec", "w") {|g| g.puts spec.to_ruby }
36
+ end
37
+
38
+ desc "Open an pry session preloaded with this library"
39
+ task :console do
40
+ require 'pry' rescue nil
41
+ console = defined?(Pry) ? :pry : :irb
42
+ sh "#{console} -rubygems -I lib -r shared-mime-info.rb"
43
+ end
@@ -0,0 +1,364 @@
1
+
2
+ # line 1 "magics.rl"
3
+ module MIME
4
+ module Magic
5
+
6
+ # line 7 "lib/magics.rb"
7
+ class << self
8
+ attr_accessor :_magic_actions
9
+ private :_magic_actions, :_magic_actions=
10
+ end
11
+ self._magic_actions = [
12
+ 0, 1, 0, 1, 1, 1, 3, 1,
13
+ 5, 1, 12, 1, 13, 2, 0, 1,
14
+ 2, 2, 6, 2, 2, 7, 2, 2,
15
+ 9, 2, 11, 12, 3, 2, 8, 4,
16
+ 3, 2, 9, 13, 3, 2, 10, 13,
17
+ 3, 12, 0, 1, 4, 11, 12, 0,
18
+ 1
19
+ ]
20
+
21
+ class << self
22
+ attr_accessor :_magic_key_offsets
23
+ private :_magic_key_offsets, :_magic_key_offsets=
24
+ end
25
+ self._magic_key_offsets = [
26
+ 0, 0, 1, 2, 3, 4, 5, 6,
27
+ 7, 8, 9, 10, 11, 12, 14, 17,
28
+ 27, 36, 46, 57, 58, 61, 64, 66,
29
+ 69, 73, 76, 78, 81, 83, 87, 88
30
+ ]
31
+
32
+ class << self
33
+ attr_accessor :_magic_trans_keys
34
+ private :_magic_trans_keys, :_magic_trans_keys=
35
+ end
36
+ self._magic_trans_keys = [
37
+ 77, 73, 77, 69, 45, 77, 97, 103,
38
+ 105, 99, 0, 10, 48, 57, 58, 48,
39
+ 57, 43, 95, 45, 46, 48, 57, 65,
40
+ 90, 97, 122, 43, 47, 95, 45, 57,
41
+ 65, 90, 97, 122, 43, 95, 45, 46,
42
+ 48, 57, 65, 90, 97, 122, 43, 93,
43
+ 95, 45, 46, 48, 57, 65, 90, 97,
44
+ 122, 10, 62, 48, 57, 62, 48, 57,
45
+ 48, 57, 61, 48, 57, 10, 38, 43,
46
+ 126, 10, 43, 126, 48, 57, 10, 48,
47
+ 57, 48, 57, 10, 43, 48, 57, 91,
48
+ 62, 91, 48, 57, 0
49
+ ]
50
+
51
+ class << self
52
+ attr_accessor :_magic_single_lengths
53
+ private :_magic_single_lengths, :_magic_single_lengths=
54
+ end
55
+ self._magic_single_lengths = [
56
+ 0, 1, 1, 1, 1, 1, 1, 1,
57
+ 1, 1, 1, 1, 1, 0, 1, 2,
58
+ 3, 2, 3, 1, 1, 1, 0, 1,
59
+ 4, 3, 0, 1, 0, 2, 1, 2
60
+ ]
61
+
62
+ class << self
63
+ attr_accessor :_magic_range_lengths
64
+ private :_magic_range_lengths, :_magic_range_lengths=
65
+ end
66
+ self._magic_range_lengths = [
67
+ 0, 0, 0, 0, 0, 0, 0, 0,
68
+ 0, 0, 0, 0, 0, 1, 1, 4,
69
+ 3, 4, 4, 0, 1, 1, 1, 1,
70
+ 0, 0, 1, 1, 1, 1, 0, 1
71
+ ]
72
+
73
+ class << self
74
+ attr_accessor :_magic_index_offsets
75
+ private :_magic_index_offsets, :_magic_index_offsets=
76
+ end
77
+ self._magic_index_offsets = [
78
+ 0, 0, 2, 4, 6, 8, 10, 12,
79
+ 14, 16, 18, 20, 22, 24, 26, 29,
80
+ 36, 43, 50, 58, 60, 63, 66, 68,
81
+ 71, 76, 80, 82, 85, 87, 91, 93
82
+ ]
83
+
84
+ class << self
85
+ attr_accessor :_magic_indicies
86
+ private :_magic_indicies, :_magic_indicies=
87
+ end
88
+ self._magic_indicies = [
89
+ 0, 1, 2, 1, 3, 1, 4, 1,
90
+ 5, 1, 6, 1, 7, 1, 8, 1,
91
+ 9, 1, 10, 1, 11, 1, 12, 1,
92
+ 13, 1, 15, 14, 1, 16, 16, 16,
93
+ 16, 16, 16, 1, 17, 18, 17, 17,
94
+ 17, 17, 1, 19, 19, 19, 19, 19,
95
+ 19, 1, 19, 20, 19, 19, 19, 19,
96
+ 19, 1, 21, 1, 23, 22, 1, 25,
97
+ 24, 1, 26, 1, 28, 27, 1, 29,
98
+ 30, 31, 32, 1, 29, 31, 32, 1,
99
+ 33, 1, 34, 35, 1, 36, 1, 37,
100
+ 38, 39, 1, 40, 1, 42, 40, 41,
101
+ 1, 0
102
+ ]
103
+
104
+ class << self
105
+ attr_accessor :_magic_trans_targs
106
+ private :_magic_trans_targs, :_magic_trans_targs=
107
+ end
108
+ self._magic_trans_targs = [
109
+ 2, 0, 3, 4, 5, 6, 7, 8,
110
+ 9, 10, 11, 12, 30, 14, 14, 15,
111
+ 16, 16, 17, 18, 19, 20, 21, 22,
112
+ 21, 22, 23, 23, 24, 31, 25, 26,
113
+ 28, 27, 31, 27, 29, 31, 26, 29,
114
+ 13, 21, 22
115
+ ]
116
+
117
+ class << self
118
+ attr_accessor :_magic_trans_actions
119
+ private :_magic_trans_actions, :_magic_trans_actions=
120
+ end
121
+ self._magic_trans_actions = [
122
+ 0, 0, 0, 0, 0, 0, 0, 0,
123
+ 0, 0, 0, 0, 0, 13, 3, 16,
124
+ 1, 0, 0, 3, 5, 0, 44, 25,
125
+ 3, 19, 13, 3, 28, 11, 7, 0,
126
+ 0, 13, 36, 3, 13, 32, 22, 3,
127
+ 0, 40, 9
128
+ ]
129
+
130
+ class << self
131
+ attr_accessor :magic_start
132
+ end
133
+ self.magic_start = 1;
134
+ class << self
135
+ attr_accessor :magic_first_final
136
+ end
137
+ self.magic_first_final = 30;
138
+ class << self
139
+ attr_accessor :magic_error
140
+ end
141
+ self.magic_error = 0;
142
+
143
+ class << self
144
+ attr_accessor :magic_en_main
145
+ end
146
+ self.magic_en_main = 1;
147
+
148
+
149
+ # line 53 "magics.rl"
150
+
151
+
152
+ def self.parse_magic( data )
153
+ magics = []
154
+ data = data.unpack("c*")
155
+
156
+
157
+ # line 158 "lib/magics.rb"
158
+ begin
159
+ p ||= 0
160
+ pe ||= data.length
161
+ cs = magic_start
162
+ end
163
+
164
+ # line 60 "magics.rl"
165
+ eof = pe
166
+
167
+ # line 168 "lib/magics.rb"
168
+ begin
169
+ _klen, _trans, _keys, _acts, _nacts = nil
170
+ _goto_level = 0
171
+ _resume = 10
172
+ _eof_trans = 15
173
+ _again = 20
174
+ _test_eof = 30
175
+ _out = 40
176
+ while true
177
+ _trigger_goto = false
178
+ if _goto_level <= 0
179
+ if p == pe
180
+ _goto_level = _test_eof
181
+ next
182
+ end
183
+ if cs == 0
184
+ _goto_level = _out
185
+ next
186
+ end
187
+ end
188
+ if _goto_level <= _resume
189
+ _keys = _magic_key_offsets[cs]
190
+ _trans = _magic_index_offsets[cs]
191
+ _klen = _magic_single_lengths[cs]
192
+ _break_match = false
193
+
194
+ begin
195
+ if _klen > 0
196
+ _lower = _keys
197
+ _upper = _keys + _klen - 1
198
+
199
+ loop do
200
+ break if _upper < _lower
201
+ _mid = _lower + ( (_upper - _lower) >> 1 )
202
+
203
+ if data[p] < _magic_trans_keys[_mid]
204
+ _upper = _mid - 1
205
+ elsif data[p] > _magic_trans_keys[_mid]
206
+ _lower = _mid + 1
207
+ else
208
+ _trans += (_mid - _keys)
209
+ _break_match = true
210
+ break
211
+ end
212
+ end # loop
213
+ break if _break_match
214
+ _keys += _klen
215
+ _trans += _klen
216
+ end
217
+ _klen = _magic_range_lengths[cs]
218
+ if _klen > 0
219
+ _lower = _keys
220
+ _upper = _keys + (_klen << 1) - 2
221
+ loop do
222
+ break if _upper < _lower
223
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1)
224
+ if data[p] < _magic_trans_keys[_mid]
225
+ _upper = _mid - 2
226
+ elsif data[p] > _magic_trans_keys[_mid+1]
227
+ _lower = _mid + 2
228
+ else
229
+ _trans += ((_mid - _keys) >> 1)
230
+ _break_match = true
231
+ break
232
+ end
233
+ end # loop
234
+ break if _break_match
235
+ _trans += _klen
236
+ end
237
+ end while false
238
+ _trans = _magic_indicies[_trans]
239
+ cs = _magic_trans_targs[_trans]
240
+ if _magic_trans_actions[_trans] != 0
241
+ _acts = _magic_trans_actions[_trans]
242
+ _nacts = _magic_actions[_acts]
243
+ _acts += 1
244
+ while _nacts > 0
245
+ _nacts -= 1
246
+ _acts += 1
247
+ case _magic_actions[_acts - 1]
248
+ when 0 then
249
+ # line 6 "magics.rl"
250
+ begin
251
+ b = p end
252
+ # line 6 "magics.rl"
253
+ when 1 then
254
+ # line 7 "magics.rl"
255
+ begin
256
+ e = data[ b .. p] end
257
+ # line 7 "magics.rl"
258
+ when 2 then
259
+ # line 8 "magics.rl"
260
+ begin
261
+ n = e.pack("c*").to_i end
262
+ # line 8 "magics.rl"
263
+ when 3 then
264
+ # line 12 "magics.rl"
265
+ begin
266
+ type = e.pack("c*") end
267
+ # line 12 "magics.rl"
268
+ when 4 then
269
+ # line 17 "magics.rl"
270
+ begin
271
+
272
+ value_length = data[p+1, 2].pack("c*").unpack('n').first
273
+ p +=2
274
+ value = data[p+1, value_length]
275
+ mask = [0xff] * value_length
276
+ p += value_length
277
+ end
278
+ # line 17 "magics.rl"
279
+ when 5 then
280
+ # line 24 "magics.rl"
281
+ begin
282
+
283
+ mask = data[p+1, value_length]
284
+ p += value_length
285
+ end
286
+ # line 24 "magics.rl"
287
+ when 6 then
288
+ # line 28 "magics.rl"
289
+ begin
290
+ priority = n end
291
+ # line 28 "magics.rl"
292
+ when 7 then
293
+ # line 29 "magics.rl"
294
+ begin
295
+ indent = n end
296
+ # line 29 "magics.rl"
297
+ when 8 then
298
+ # line 30 "magics.rl"
299
+ begin
300
+ start_offset = n end
301
+ # line 30 "magics.rl"
302
+ when 9 then
303
+ # line 31 "magics.rl"
304
+ begin
305
+ word_size = n end
306
+ # line 31 "magics.rl"
307
+ when 10 then
308
+ # line 32 "magics.rl"
309
+ begin
310
+ range_length = n end
311
+ # line 32 "magics.rl"
312
+ when 11 then
313
+ # line 33 "magics.rl"
314
+ begin
315
+ magics << RootEntry.new(type, priority) end
316
+ # line 33 "magics.rl"
317
+ when 12 then
318
+ # line 34 "magics.rl"
319
+ begin
320
+ indent = 0; word_size = 0; range_length = 1 end
321
+ # line 34 "magics.rl"
322
+ when 13 then
323
+ # line 35 "magics.rl"
324
+ begin
325
+
326
+ magics.last.add_subentry Entry.new(indent, start_offset, value_length, value, mask, word_size, range_length)
327
+ end
328
+ # line 35 "magics.rl"
329
+ # line 330 "lib/magics.rb"
330
+ end # action switch
331
+ end
332
+ end
333
+ if _trigger_goto
334
+ next
335
+ end
336
+ end
337
+ if _goto_level <= _again
338
+ if cs == 0
339
+ _goto_level = _out
340
+ next
341
+ end
342
+ p += 1
343
+ if p != pe
344
+ _goto_level = _resume
345
+ next
346
+ end
347
+ end
348
+ if _goto_level <= _test_eof
349
+ end
350
+ if _goto_level <= _out
351
+ break
352
+ end
353
+ end
354
+ end
355
+
356
+ # line 62 "magics.rl"
357
+ if cs < magic_first_final
358
+ raise BadMagic
359
+ end
360
+
361
+ magics
362
+ end
363
+ end
364
+ end
@@ -1,377 +1,145 @@
1
- # Copyright (c) 2006 Hank Lords <hanklords@gmail.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in all
12
- # copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
- # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
- # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
- # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
- # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
22
- require 'enumerator'
23
- require 'rexml/document'
24
-
25
- # shared-mime-info is a pure Ruby library for accessing the MIME info
26
- # database provided by Freedesktop[http://freedesktop.org/] on
27
- # {Standards/shared-mime-info-spec}[http://wiki.freedesktop.org/wiki/Standards_2fshared_2dmime_2dinfo_2dspec].
28
- #
29
- # This provides a way to guess the mime type of a file by doing both
30
- # filename lookups and _magic_ file checks. This implementation tries to
31
- # follow the version 0.13 of the
32
- # specification[http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.13.html].
33
- module MIME
34
- VERSION = '0.1'
35
-
36
- module Magic # :nodoc: all
37
- class BadMagic < StandardError; end
38
-
39
- class RootEntry
40
- def initialize
41
- @sub_entries = []
42
- @indent = -1
43
- end
44
-
45
- def add_subentry(entry)
46
- return unless entry.indent > @indent
47
- if entry.indent == @indent + 1
48
- @sub_entries << entry
49
- elsif entry.indent > @indent + 1
50
- if @sub_entries.last.respond_to? :add_subentry
51
- @sub_entries.last.add_subentry entry
52
- else
53
- raise BadMagic
54
- end
55
- else
56
- raise BadMagic
57
- end
58
- end
59
-
60
- def check_file(f)
61
- @sub_entries.empty? || @sub_entries.any? {|e| e.check_file f}
62
- end
63
- end
64
-
65
- class Entry < RootEntry
66
- attr_reader :indent
67
- def initialize(indent, start_offset, value_length, value, mask, word_size, range_length)
68
- super()
69
- @indent = indent
70
- @start_offset = start_offset
71
- @value_length = value_length
72
- @value = value.freeze
73
- @mask = mask.freeze
74
- @word_size = word_size
75
- @range_length = range_length
76
- end
77
-
78
- def check_file(f)
79
- check_entry(f) && super(f)
80
- end
81
-
82
- private
83
- def check_entry(f)
84
- f.pos = @start_offset
85
- f.read(@value_length) == @value
86
- end
87
- end
88
-
89
- def self.parse(magic)
90
- parsed = RootEntry.new
91
- entry = magic
92
-
93
- until entry.empty?
94
- entry = entry.sub /^(\d?)>(\d+)=/, ''
95
- indent = $1.to_i
96
- start_offset = $2.to_i
97
- value_length = entry.unpack('n').first
98
- value, entry = entry.unpack("x2a#{value_length}a*")
99
-
100
- if entry[/./m] == '&'
101
- mask, entry = entry.unpack("xa#{value_length}a*")
102
- end
103
-
104
- if entry[/./m] == '~'
105
- entry =~ /^~(\d+)(.*)/m
106
- word_size = $1
107
- entry = $2
108
- end
109
-
110
- if entry[/./m] == '+'
111
- entry =~ /^\+(\d+)(.*)/m
112
- range_length = $1
113
- entry = $2
114
- end
115
- entry = entry.sub /^[^\n]*\n/m, ''
116
-
117
- parsed.add_subentry Entry.new(indent, start_offset, value_length, value, mask, word_size, range_length)
118
- end
119
-
120
- parsed
121
- end
122
- end
123
-
124
- # Type represents a single mime type such as <b>text/html</b>.
125
- class Type
126
- attr_reader :magic_priority # :nodoc:
127
-
128
- # Returns the type of a mime type as a String, such as <b>text/html</b>.
129
- attr_reader :type
130
-
131
- # Returns the media part of the type of a mime type as a string,
132
- # such as <b>text</b> for a type of <b>text/html</b>.
133
- def media; @type.split('/', 2).first; end
134
-
135
- # Returns the subtype part of the type of a mime type as a string,
136
- # such as <b>html</b> for a type of <b>text/html</b>.
137
- def subtype; @type.split('/', 2).last; end
138
-
139
- # Synonym of type.
140
- def to_s; @type; end
141
-
142
- # Returns a Hash of the comments associated with a mime type in
143
- # different languages.
144
- #
145
- # MIME.types['text/html'].default
146
- # => "HTML page"
147
- #
148
- # MIME.types['text/html'].comment['fr']
149
- # => "page HTML"
150
- def comment
151
- file = ''
152
- MIME.mime_dirs.each { |dir|
153
- file = "#{dir}/#{@type}.xml"
154
- break if File.file? file
155
- }
156
-
157
- open(file) { |f|
158
- doc = REXML::Document.new f
159
- comments = {}
160
- REXML::XPath.match(doc, '*/comment').each { |c|
161
- if att = c.attributes['xml:lang']
162
- comments[att] = c.text
163
- else
164
- comments.default = c.text
165
- end
166
- }
167
- }
168
- comments
169
- end
170
-
171
- # Returns all the types this type is a subclass of.
172
- def parents
173
- file = ''
174
- MIME.mime_dirs.each { |dir|
175
- file = "#{dir}/#{@type}.xml"
176
- break if File.file? file
177
- }
178
-
179
- open(file) { |f|
180
- doc = REXML::Document.new f
181
- REXML::XPath.match(doc, '*/sub-class-of').collect { |c|
182
- MIME[c.attributes['type']]
183
- }
184
- }
185
- end
186
-
187
- # Equality test.
188
- #
189
- # MIME['text/html'] == 'text/html'
190
- # => true
191
- def ==(type)
192
- if type.is_a? Type
193
- @type == type.type
194
- elsif type.respond_to? :to_str
195
- @type == type
196
- else
197
- false
198
- end
199
- end
200
-
201
- # Check if _filename_ is of this particular type by comparing it to
202
- # some common extensions.
203
- #
204
- # MIME.types['text/html'].match_filename? 'index.html'
205
- # => true
206
- def match_filename?(filename)
207
- @glob_patterns.any? {|pattern| File.fnmatch pattern, filename}
208
- end
209
-
210
- # Check if _file_ is of this particular type by looking for precise
211
- # patterns (_magic_ numbers) in different locations of the file.
212
- #
213
- # _file_ must be an IO object opened with read permissions.
214
- def match_file?(file)
215
- if @magic.nil?
216
- false
217
- else
218
- @magic.check_file file
219
- end
220
- end
221
-
222
- def initialize(type) # :nodoc:
223
- @type = type.freeze
224
- @glob_patterns = []
225
- end
226
-
227
- def load_magic(magic, priority) # :nodoc:
228
- @magic_priority = priority
229
- @magic = Magic.parse magic
230
- end
231
-
232
- def add_glob(glob) # :nodoc:
233
- @glob_patterns << glob.freeze
234
- end
235
- end
236
-
237
- class << self
238
- attr_reader :mime_dirs # :nodoc:
239
-
240
- # Returns the MIME::Type object corresponding to _type_.
241
- def [](type)
242
- @types.fetch type, nil
243
- end
244
-
245
- # Look for the type of a file by doing successive checks on
246
- # the filename patterns.
247
- #
248
- # Returns a MIME::Type object or _nil_ if nothing matches.
249
- def check_globs(filename)
250
- enum = Enumerable::Enumerator.new(@globs, :each_key)
251
- found = enum.select { |pattern| File.fnmatch pattern, filename }
252
-
253
- if found.empty?
254
- downcase_filename = filename.downcase
255
- found = enum.select { |pattern|
256
- File.fnmatch pattern, downcase_filename
257
- }
258
- end
259
-
260
- @globs[found.max]
261
- end
262
-
263
- # Look for the type of a file by doing successive checks on
264
- # _magic_ numbers.
265
- #
266
- # Returns a MIME::Type object or _nil_ if nothing matches.
267
- def check_magics(file)
268
- if file.respond_to? :read
269
- check_magics_with_priority(file, 0)
270
- else
271
- open(file) {|f| check_magics_with_priority(f, 0) }
272
- end
273
- end
274
-
275
- # Look for the type of a file by doing successive checks with
276
- # the filename patterns or magic numbers. If none of the matches
277
- # are successful, returns a type of <b>application/octet-stream</b> if
278
- # the file contains control characters at its beginning, or <b>text/plain</b> otherwise.
279
- #
280
- # Returns a MIME::Type object.
281
- def check(filename)
282
- check_special(filename) ||
283
- open(filename) { |f|
284
- check_magics_with_priority(f, 80) ||
285
- check_globs(filename) ||
286
- check_magics_with_priority(f, 0) ||
287
- check_default(f)
288
- }
289
- end
290
-
291
- private
292
- def check_magics_with_priority(f, priority_threshold)
293
- @magics.find { |t|
294
- break if t.magic_priority < priority_threshold
295
- t.match_file? f
296
- }
297
- end
298
-
299
- def check_special(filename)
300
- case File.ftype(filename)
301
- when 'directory' then @types['inode/directory']
302
- when 'characterSpecial' then @types['inode/chardevice']
303
- when 'blockSpecial' then @types['inode/blockdevice']
304
- when 'fifo' then @types['inode/fifo']
305
- when 'socket' then @types['inode/socket']
306
- else
307
- nil
308
- end
309
- end
310
-
311
- def check_default(f)
312
- f.pos = 0
313
- firsts = f.read(32) || ''
314
- bytes = firsts.unpack('C*')
315
- if bytes.any? {|byte| byte < 32 && ![9, 10, 13].include?(byte) }
316
- @types['application/octet-stream']
317
- else
318
- @types['text/plain']
319
- end
320
- end
321
-
322
- def load_globs(file)
323
- open(file) { |f|
324
- f.each { |line|
325
- next if line =~ /^#/
326
- cline = line.chomp
327
- type, pattern = cline.split ':', 2
328
- @types[type].add_glob pattern
329
- @globs[pattern] = @types[type] unless @globs.has_key? pattern
330
- }
331
- }
332
- end
333
-
334
- def load_magic(file)
335
- open(file) { |f|
336
- raise 'Bad magic file' if f.readline != "MIME-Magic\0\n"
337
-
338
- f.gets =~ /^\[(\d\d):(.+)\]/
339
- priority = $1.to_i
340
- type = $2
341
- buf =''
342
-
343
- f.each { |line|
344
- if line =~ /^\[(\d\d):(.+)\]/
345
- @types[type].load_magic buf, priority
346
- @magics << @types[type]
347
-
348
- priority = $1.to_i
349
- type = $2
350
- buf = ''
351
- else
352
- buf << line
353
- end
354
- }
355
- }
356
- end
357
- end
358
-
359
- xdg_data_home = ENV['XDG_DATA_HOME'] || "#{ENV['HOME']}/.local/share"
360
- xdg_data_dirs = ENV['XDG_DATA_DIRS'] || "/usr/local/share/:/usr/share"
361
-
362
- @mime_dirs = (xdg_data_home + ':' + xdg_data_dirs).split(':').collect { |dir|
363
- "#{dir}/mime"
364
- }
365
-
366
- @types = Hash.new {|h,k| h[k] = Type.new(k)}
367
- @magics = []
368
- @globs = {}
369
-
370
- @mime_dirs.each {|dir|
371
- glob_file = "#{dir}/globs"
372
- load_globs glob_file if File.file? glob_file
373
-
374
- magic_file = "#{dir}/magic"
375
- load_magic magic_file if File.file? magic_file
376
- }
377
- end
1
+ # Copyright (c) 2006 Mael Clerambault <mael@clerambault.fr>
2
+ #
3
+ # Permission to use, copy, modify, and distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require 'shared-mime-info/magic'
16
+ require 'shared-mime-info/type'
17
+ require 'shared-mime-info/version'
18
+
19
+ # This provides a way to guess the mime type of a file by doing both
20
+ # filename lookups and _magic_ file checks. This implementation tries to
21
+ # follow the version 0.13 of the
22
+ # specification[http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.13.html].
23
+ module MIME
24
+ class << self
25
+ attr_reader :mime_dirs # :nodoc:
26
+
27
+ # Returns the MIME::Type object corresponding to _type_.
28
+ def [](type)
29
+ @types.fetch type, nil
30
+ end
31
+
32
+ # Look for the type of a file by doing successive checks on
33
+ # the filename patterns.
34
+ #
35
+ # Returns a MIME::Type object or _nil_ if nothing matches.
36
+ def check_globs(filename)
37
+ basename = File.basename(filename)
38
+ found = @globs.each_key.select { |pattern| File.fnmatch pattern, basename }
39
+
40
+ if found.empty?
41
+ downcase_basename = basename.downcase
42
+ found = @globs.each_key.select { |pattern|
43
+ File.fnmatch pattern, downcase_basename
44
+ }
45
+ end
46
+
47
+ @globs[found.max]
48
+ end
49
+
50
+ # Look for the type of a file by doing successive checks on
51
+ # _magic_ numbers.
52
+ #
53
+ # Returns a MIME::Type object or _nil_ if nothing matches.
54
+ def check_magics(file)
55
+ if file.respond_to? :read
56
+ check_magics_type(file, @magics)
57
+ else
58
+ open(file) {|f| check_magics_type(f, @magics) }
59
+ end
60
+ end
61
+
62
+ # Look for the type of a file by doing successive checks with
63
+ # the filename patterns or magic numbers. If none of the matches
64
+ # are successful, returns a type of <b>application/octet-stream</b> if
65
+ # the file contains control characters at its beginning, or <b>text/plain</b> otherwise.
66
+ #
67
+ # Returns a MIME::Type object.
68
+ def check(filename)
69
+ check_special(filename) ||
70
+ open(filename) { |f|
71
+ check_magics_gt80(f) ||
72
+ check_globs(filename) ||
73
+ check_magics_lt80(f) ||
74
+ check_default(f)
75
+ }
76
+ end
77
+
78
+ private
79
+ def check_magics_type(f, set); c = set.find {|m| m =~ f} and MIME[c.type] end
80
+ def check_magics_gt80(f); check_magics_type(f, @magics_gt80) end
81
+ def check_magics_lt80(f); check_magics_type(f, @magics_lt80) end
82
+
83
+ def check_special(filename)
84
+ case File.ftype(filename)
85
+ when 'directory' then @types['inode/directory']
86
+ when 'characterSpecial' then @types['inode/chardevice']
87
+ when 'blockSpecial' then @types['inode/blockdevice']
88
+ when 'fifo' then @types['inode/fifo']
89
+ when 'socket' then @types['inode/socket']
90
+ else
91
+ nil
92
+ end
93
+ end
94
+
95
+ def check_default(f)
96
+ f.pos = 0
97
+ firsts = f.read(32) || ''
98
+ bytes = firsts.unpack('C*')
99
+ if bytes.any? {|byte| byte < 32 && ![9, 10, 13].include?(byte) }
100
+ @types['application/octet-stream']
101
+ else
102
+ @types['text/plain']
103
+ end
104
+ end
105
+
106
+ def load_globs(file)
107
+ open(file) { |f|
108
+ f.each { |line|
109
+ next if line =~ /^#/
110
+ cline = line.chomp
111
+ type, pattern = cline.split ':', 2
112
+ @types[type].glob_patterns << pattern
113
+ @globs[pattern] = @types[type] unless @globs.has_key? pattern
114
+ }
115
+ }
116
+ end
117
+
118
+ def load_magic(file)
119
+ @magics.concat Magic.parse_magic(File.read(file))
120
+ end
121
+ end
122
+
123
+ xdg_data_home = ENV['XDG_DATA_HOME'] || "#{ENV['HOME']}/.local/share"
124
+ xdg_data_dirs = ENV['XDG_DATA_DIRS'] || "/usr/local/share:/usr/share"
125
+
126
+ @mime_dirs = (xdg_data_home + ':' + xdg_data_dirs).split(':').collect { |dir|
127
+ "#{dir}/mime"
128
+ }
129
+
130
+ @types = Hash.new {|h,k| h[k] = Type.new(k)}
131
+ @magics = []
132
+ @globs = {}
133
+
134
+ @mime_dirs.each {|dir|
135
+ glob_file = "#{dir}/globs"
136
+ load_globs glob_file if File.file? glob_file
137
+
138
+ magic_file = "#{dir}/magic"
139
+ load_magic magic_file if File.file? magic_file
140
+ }
141
+
142
+ @magics.sort! {|a,b| b.priority <=> a.priority}
143
+ @magics.each {|m| @types[m.type].magics << m}
144
+ @magics_gt80, @magics_lt80 = @magics.partition {|m| m.priority >= 80}
145
+ end
@@ -0,0 +1,79 @@
1
+ # Copyright (c) 2006 Mael Clerambault <mael@clerambault.fr>
2
+ #
3
+ # Permission to use, copy, modify, and distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require 'magics'
16
+
17
+ module MIME
18
+ module Magic # :nodoc: all
19
+ class BadMagic < StandardError; end
20
+
21
+ class Entry
22
+ attr_reader :indent
23
+ def initialize(indent, start_offset, value_length, value, mask, word_size, range_length)
24
+ @indent = indent
25
+ @start_offset = start_offset
26
+ @value_length = value_length
27
+ @value = value.freeze
28
+ @mask = mask.freeze
29
+ @word_size = word_size
30
+ @range_length = range_length
31
+ @sub_entries = []
32
+ end
33
+
34
+ def add_subentry(entry)
35
+ if entry.indent == @indent + 1
36
+ @sub_entries << entry
37
+ elsif entry.indent > @indent + 1
38
+ if not @sub_entries.empty?
39
+ @sub_entries.last.add_subentry entry
40
+ else
41
+ raise BadMagic
42
+ end
43
+ else
44
+ raise BadMagic
45
+ end
46
+ end
47
+
48
+ def =~(f)
49
+ check_file(f) and (@sub_entries.empty? || @sub_entries.any? {|e| e =~ f})
50
+ end
51
+
52
+ private
53
+ def check_file(f)
54
+ f.pos = @start_offset
55
+ r = (f.read(@value_length + @range_length -1)|| '').unpack("c*")
56
+ range_length = 0
57
+ found = false
58
+ while not found and range_length < r.size
59
+ found = @value.zip(@mask, r[range_length, @value_length]).all? {|vb, mb, rb| (rb & mb) == (vb & mb) }
60
+ range_length = range_length + 1
61
+ end
62
+ found
63
+ end
64
+ end
65
+
66
+ class RootEntry < Entry
67
+ attr_reader :priority, :type
68
+ def initialize(type, priority)
69
+ @indent = -1
70
+ @type = type
71
+ @priority = priority
72
+ @sub_entries = []
73
+ end
74
+
75
+ private
76
+ def check_file(*args) true end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,96 @@
1
+ # Copyright (c) 2006 Mael Clerambault <mael@clerambault.fr>
2
+ #
3
+ # Permission to use, copy, modify, and distribute this software for any
4
+ # purpose with or without fee is hereby granted, provided that the above
5
+ # copyright notice and this permission notice appear in all copies.
6
+ #
7
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+
15
+ require 'rexml/document'
16
+ require 'mime/types'
17
+
18
+ module MIME
19
+ # Override the existing MIME::Type class
20
+ OriginalType = Type
21
+ MIME.send(:remove_const, :Type)
22
+
23
+ # Type represents a single mime type such as <b>text/html</b>.
24
+ class Type < OriginalType
25
+ attr_reader :magics, :glob_patterns
26
+
27
+ def initialize(content_type) # :nodoc:
28
+ @glob_patterns = []
29
+ @magics = []
30
+ super
31
+ end
32
+
33
+ # Returns a Hash of the comments associated with a mime type in
34
+ # different languages.
35
+ #
36
+ # MIME['text/html'].comment.default
37
+ # => "HTML page"
38
+ #
39
+ # MIME['text/html'].comment['fr']
40
+ # => "page HTML"
41
+ def comment
42
+ file = ''
43
+ MIME.mime_dirs.each { |dir|
44
+ file = "#{dir}/#{content_type}.xml"
45
+ break if File.file? file
46
+ }
47
+
48
+ comments = {}
49
+ open(file) { |f|
50
+ doc = REXML::Document.new f
51
+ REXML::XPath.match(doc, '*/comment').each { |c|
52
+ if att = c.attributes['xml:lang']
53
+ comments[att] = c.text
54
+ else
55
+ comments.default = c.text
56
+ end
57
+ }
58
+ }
59
+ comments
60
+ end
61
+
62
+ # Returns all the types this type is a subclass of.
63
+ def parents
64
+ file = ''
65
+ MIME.mime_dirs.each { |dir|
66
+ file = "#{dir}/#{content_type}.xml"
67
+ break if File.file? file
68
+ }
69
+
70
+ open(file) { |f|
71
+ doc = REXML::Document.new f
72
+ REXML::XPath.match(doc, '*/sub-class-of').collect { |c|
73
+ MIME[c.attributes['type']]
74
+ }
75
+ }
76
+ end
77
+
78
+ # Check if _filename_ is of this particular type by comparing it to
79
+ # some common extensions.
80
+ #
81
+ # MIME['text/html'].match_filename? 'index.html'
82
+ # => true
83
+ def matches_filename?(filename)
84
+ basename = File.basename(filename)
85
+ @glob_patterns.any? {|pattern| File.fnmatch pattern, basename.downcase}
86
+ end
87
+
88
+ # Check if _file_ is of this particular type by looking for precise
89
+ # patterns (_magic_ numbers) in different locations of the file.
90
+ #
91
+ # _file_ must be an IO object opened with read permissions.
92
+ def matches_file?(f)
93
+ @magics.any? {|m| m =~ f }
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,3 @@
1
+ module SharedMimeInfo
2
+ VERSION = "0.2.5"
3
+ end
metadata CHANGED
@@ -1,47 +1,53 @@
1
- --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
3
- specification_version: 1
1
+ --- !ruby/object:Gem::Specification
4
2
  name: shared-mime-info
5
- version: !ruby/object:Gem::Version
6
- version: "0.1"
7
- date: 2006-09-24 00:00:00 +02:00
8
- summary: Library to guess the MIME type of a file with both filename lookup and magic file detection
9
- require_paths:
10
- - lib
11
- email: hanklords@gmail.com
12
- homepage:
13
- rubyforge_project:
14
- description:
15
- autorequire: rake
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.5
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- authors:
29
- - Hank Lords
30
- files:
31
- - lib/shared-mime-info.rb
32
- - rakefile
33
- - copying.txt
34
- test_files: []
35
-
36
- rdoc_options: []
37
-
38
- extra_rdoc_files: []
39
-
6
+ authors:
7
+ - Mael Clerambault
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-02 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: shared-mime-info is a pure Ruby library for accessing the MIME info database
14
+ provided by Freedesktop
15
+ email: mael@clerambault.fr
40
16
  executables: []
41
-
42
17
  extensions: []
43
-
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/magics.rb
21
+ - lib/shared-mime-info.rb
22
+ - lib/shared-mime-info/magic.rb
23
+ - lib/shared-mime-info/type.rb
24
+ - lib/shared-mime-info/version.rb
25
+ - Rakefile
26
+ - LICENSE
27
+ - README.rdoc
28
+ homepage: http://shared-mime.rubyforge.org/
29
+ licenses:
30
+ - Public Domain
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
44
46
  requirements: []
45
-
46
- dependencies: []
47
-
47
+ rubyforge_project:
48
+ rubygems_version: 2.0.3
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: Library to guess the MIME type of a file with both filename lookup and magic
52
+ file detection
53
+ test_files: []
@@ -1,20 +0,0 @@
1
- Copyright (c) 2006 Hank Lords <hanklords@gmail.com>
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in all
12
- copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/rakefile DELETED
@@ -1,30 +0,0 @@
1
- require 'rake/rdoctask'
2
- require 'rake/packagetask'
3
- require 'rake/gempackagetask'
4
-
5
- require 'lib/shared-mime-info'
6
-
7
- PKG_FILES = FileList["lib/*.rb", "rakefile", "copying.txt"].to_a
8
-
9
- spec = Gem::Specification.new do |s|
10
- s.summary = "Library to guess the MIME type of a file with both filename lookup and magic file detection"
11
- s.name = "shared-mime-info"
12
- s.author = "Hank Lords"
13
- s.email = "hanklords@gmail.com"
14
- s.version = MIME::VERSION
15
- s.has_rdoc = true
16
- s.require_path = 'lib'
17
- s.autorequire = 'rake'
18
- s.files = PKG_FILES
19
- # s.description = ""
20
- end
21
-
22
- Rake::RDocTask.new do |rd|
23
- rd.rdoc_files.include "lib/*.rb"
24
- rd.options << "--inline-source"
25
- rd.main = "MIME"
26
- end
27
-
28
- Rake::GemPackageTask.new spec do |p|
29
- p.need_tar_gz = true
30
- end