magic 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +34 -6
- data/Rakefile +32 -2
- data/VERSION +1 -1
- data/lib/magic.rb +27 -3
- data/lib/magic/api.rb +2 -2
- data/lib/magic/constants.rb +46 -23
- data/lib/magic/database.rb +9 -2
- data/lib/magic/errors.rb +3 -1
- data/test/fixtures/filelogo.jpg +0 -0
- data/test/fixtures/magic.txt +1 -0
- data/test/helper.rb +5 -2
- data/test/test_magic.rb +40 -2
- metadata +35 -4
data/README.rdoc
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
= magic
|
2
2
|
|
3
|
-
|
3
|
+
Ruby FFI bindings to the "magic" library. Determines content type and
|
4
|
+
encoding of files and strings. There are three sets of tests,
|
5
|
+
performed in this order: filesystem tests, magic number tests, and
|
6
|
+
language tests. The first test that succeeds causes the file type to
|
7
|
+
be printed.
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
require "magic"
|
11
|
+
Magic.guess_file_mime("public/images/rails.png")
|
12
|
+
# => "image/png; charset=binary"
|
13
|
+
Magic.guess_file_mime_encoding("public/images/rails.png")
|
14
|
+
# => "binary"
|
15
|
+
Magic.guess_file_mime_type("public/images/rails.png")
|
16
|
+
# => "image/png"
|
17
|
+
Magic.guess_string_mime("Magic® File™")
|
18
|
+
# => "text/plain; charset=utf-8"
|
19
|
+
Magic.guess_string_mime_encoding("Magic® File™")
|
20
|
+
# => "utf-8"
|
21
|
+
Magic.guess_string_mime_type("Magic® File™")
|
22
|
+
# => "text/plain"
|
23
|
+
|
24
|
+
== Links
|
25
|
+
* gemcutter[http://gemcutter.org/gems/magic]
|
26
|
+
* repository[http://github.com/qoobaa/magic]
|
27
|
+
* {issue tracker}[http://github.com/qoobaa/magic/issues]
|
28
|
+
* rdoc[http://qoobaa.github.com/magic]
|
4
29
|
|
5
30
|
== Note on Patches/Pull Requests
|
6
|
-
|
7
31
|
* Fork the project.
|
8
32
|
* Make your feature addition or bug fix.
|
9
|
-
* Add tests for it. This is important so I don't break it in a future
|
10
|
-
|
33
|
+
* Add tests for it. This is important so I don't break it in a future
|
34
|
+
version unintentionally.
|
35
|
+
* Commit, do not mess with rakefile, version, or history. (if you want
|
36
|
+
to have your own version, that is fine but bump version in a commit
|
37
|
+
by itself I can ignore when I pull)
|
11
38
|
* Send me a pull request. Bonus points for topic branches.
|
12
39
|
|
13
40
|
== Copyright
|
14
|
-
|
15
|
-
|
41
|
+
Copyright (c) 2010 Jakub Kuźma. See
|
42
|
+
LICENSE[http://github.com/qoobaa/magic/raw/master/LICENSE] for
|
43
|
+
details.
|
data/Rakefile
CHANGED
@@ -7,14 +7,44 @@ begin
|
|
7
7
|
require 'jeweler'
|
8
8
|
Jeweler::Tasks.new do |gem|
|
9
9
|
gem.name = "magic"
|
10
|
-
gem.summary = %Q{
|
11
|
-
gem.description = %Q{Ruby bindings
|
10
|
+
gem.summary = %Q{Determine file type and encoding using "magic" numbers}
|
11
|
+
gem.description = %Q{Ruby FFI bindings to libmagic}
|
12
12
|
gem.email = "qoobaa@gmail.com"
|
13
13
|
gem.homepage = "http://github.com/qoobaa/magic"
|
14
14
|
gem.authors = ["Jakub Kuźma"]
|
15
15
|
gem.add_dependency "ffi", ">= 0.5.1"
|
16
16
|
gem.add_development_dependency "test-unit", ">= 2.0"
|
17
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
gem.post_install_message = <<-EOM
|
19
|
+
+-NOTE FOR LINUX USERS----------------------------------------------+
|
20
|
+
| |
|
21
|
+
| Install libmagic using your package manager, e.g. |
|
22
|
+
| |
|
23
|
+
| sudo apt-get install file |
|
24
|
+
| |
|
25
|
+
+-NOTE FOR WINDOWS USERS -------------------------------------------+
|
26
|
+
| |
|
27
|
+
| Install File for Windows from |
|
28
|
+
| |
|
29
|
+
| http://gnuwin32.sourceforge.net/packages/file.htm |
|
30
|
+
| |
|
31
|
+
+-NOTE FOR MAC OS USERS --------------------------------------------+
|
32
|
+
| |
|
33
|
+
| If you don't have libmagic.1.dylib file in your system |
|
34
|
+
| |
|
35
|
+
| find / -name libmagic.1.dylib |
|
36
|
+
| |
|
37
|
+
| You need to install it via port command |
|
38
|
+
| |
|
39
|
+
| sudo port install file |
|
40
|
+
| |
|
41
|
+
| Sometimes you'll also need to set your DYLD_FALLBACK_LIBRARY_PATH |
|
42
|
+
| environment variable to the directory of the libmagic.1.dylib |
|
43
|
+
| |
|
44
|
+
| export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib |
|
45
|
+
| |
|
46
|
+
+-------------------------------------------------------------------+
|
47
|
+
EOM
|
18
48
|
end
|
19
49
|
Jeweler::GemcutterTasks.new
|
20
50
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lib/magic.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
require "ffi"
|
4
4
|
|
5
5
|
require "magic/errors"
|
6
6
|
require "magic/api"
|
@@ -9,33 +9,57 @@ require "magic/database"
|
|
9
9
|
|
10
10
|
module Magic
|
11
11
|
class << self
|
12
|
+
# Guesses mime of given file
|
13
|
+
# ====== Example
|
14
|
+
# Magic.guess_file_mime("public/images/rails.png")
|
15
|
+
# # => "image/png; charset=binary"
|
12
16
|
def guess_file_mime(file)
|
13
17
|
guess(:file, :mime, file)
|
14
18
|
end
|
15
19
|
|
20
|
+
# Guesses mime encoding of given file
|
21
|
+
# ===== Example
|
22
|
+
# Magic.guess_file_mime_encoding("public/images/rails.png")
|
23
|
+
# # => "binary"
|
16
24
|
def guess_file_mime_encoding(file)
|
17
25
|
guess(:file, :mime_encoding, file)
|
18
26
|
end
|
19
27
|
|
28
|
+
# Guesses mime type of given file
|
29
|
+
# ===== Example
|
30
|
+
# Magic.guess_file_mime_type("public/images/rails.png")
|
31
|
+
# # => "image/png"
|
20
32
|
def guess_file_mime_type(file)
|
21
33
|
guess(:file, :mime_type, file)
|
22
34
|
end
|
23
35
|
|
36
|
+
# Guesses mime type of given string
|
37
|
+
# ===== Example
|
38
|
+
# Magic.guess_string_mime("Magic® File™")
|
39
|
+
# # => "text/plain; charset=utf-8"
|
24
40
|
def guess_string_mime(string)
|
25
41
|
guess(:buffer, :mime, string)
|
26
42
|
end
|
27
43
|
|
44
|
+
# Guesses mime type of given string
|
45
|
+
# ===== Example
|
46
|
+
# Magic.guess_string_mime_encoding("Magic® File™")
|
47
|
+
# # => "utf-8"
|
28
48
|
def guess_string_mime_encoding(string)
|
29
49
|
guess(:buffer, :mime_encoding, string)
|
30
50
|
end
|
31
51
|
|
52
|
+
# Guesses mime type of given string
|
53
|
+
# ===== Example
|
54
|
+
# Magic.guess_string_mime_type("Magic® File™")
|
55
|
+
# # => "text/plain"
|
32
56
|
def guess_string_mime_type(string)
|
33
57
|
guess(:buffer, :mime_type, string)
|
34
58
|
end
|
35
59
|
|
36
60
|
protected
|
37
61
|
|
38
|
-
def guess(type, what, where)
|
62
|
+
def guess(type, what, where) #:nodoc:
|
39
63
|
db = Database.new(what)
|
40
64
|
result = db.send(type, where)
|
41
65
|
db.close
|
data/lib/magic/api.rb
CHANGED
data/lib/magic/constants.rb
CHANGED
@@ -1,29 +1,52 @@
|
|
1
1
|
module Magic
|
2
|
-
module Constants
|
2
|
+
module Constants #:nodoc:
|
3
3
|
module Flag
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
4
|
+
# No flags
|
5
|
+
NONE = 0x000000
|
6
|
+
# Turn on debugging
|
7
|
+
DEBUG = 0x000001
|
8
|
+
# Follow symlinks
|
9
|
+
SYMLINK = 0x000002
|
10
|
+
# Check inside compressed files
|
11
|
+
COMPRESS = 0x000004
|
12
|
+
# Look at the contents of devices
|
13
|
+
DEVICES = 0x000008
|
14
|
+
# Return the MIME type
|
15
|
+
MIME_TYPE = 0x000010
|
16
|
+
# Return all matches
|
17
|
+
CONTINUE = 0x000020
|
18
|
+
# Print warnings to stderr
|
19
|
+
CHECK = 0x000040
|
20
|
+
# Restore access time on exit
|
21
|
+
PRESERVE_ATIME = 0x000080
|
22
|
+
# Don't translate unprintable chars
|
23
|
+
RAW = 0x000100
|
24
|
+
# Handle ENOENT etc as real errors
|
25
|
+
ERROR = 0x000200
|
26
|
+
# Return the MIME encoding
|
27
|
+
MIME_ENCODING = 0x000400
|
28
|
+
# Return the MIME "type; charset=encoding"
|
16
29
|
MIME = (MIME_TYPE | MIME_ENCODING)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
# Return the Apple creator and type
|
31
|
+
APPLE = 0x000800
|
32
|
+
# Don't check for compressed files
|
33
|
+
NO_CHECK_COMPRESS = 0x001000
|
34
|
+
# Don't check for tar files
|
35
|
+
NO_CHECK_TAR = 0x002000
|
36
|
+
# Don't check magic entries
|
37
|
+
NO_CHECK_SOFT = 0x004000
|
38
|
+
# Don't check application type
|
39
|
+
NO_CHECK_APPTYPE = 0x008000
|
40
|
+
# Don't check for elf details
|
41
|
+
NO_CHECK_ELF = 0x010000
|
42
|
+
# Don't check for text files
|
43
|
+
NO_CHECK_TEXT = 0x020000
|
44
|
+
# Don't check for cdf files
|
45
|
+
NO_CHECK_CDF = 0x040000
|
46
|
+
# Don't check tokens
|
47
|
+
NO_CHECK_TOKENS = 0x100000
|
48
|
+
# Don't check text encodings
|
49
|
+
NO_CHECK_ENCODING = 0x200000
|
27
50
|
end
|
28
51
|
end
|
29
52
|
end
|
data/lib/magic/database.rb
CHANGED
@@ -1,25 +1,30 @@
|
|
1
1
|
module Magic
|
2
2
|
class Database
|
3
|
+
# Creates an instance of +Magic::Database+ using given flags
|
3
4
|
def initialize(*flags)
|
4
5
|
open(*flags)
|
5
6
|
load
|
6
7
|
end
|
7
8
|
|
9
|
+
# Opens magic db using given flags
|
8
10
|
def open(*flags)
|
9
11
|
magic_flags = flags.inject(0) { |acc, flag| acc |= Constants::Flag.const_get(flag.to_s.upcase) }
|
10
12
|
@magic_set = Api.magic_open(magic_flags)
|
11
13
|
end
|
12
14
|
|
15
|
+
# Closes the database
|
13
16
|
def close
|
14
17
|
Api.magic_close(@magic_set)
|
15
18
|
end
|
16
19
|
|
20
|
+
# Loads given database file (or default if +nil+ given)
|
17
21
|
def load(database = nil)
|
18
22
|
Api.magic_load(@magic_set, database)
|
19
23
|
end
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
# Determine type of a file at given path
|
26
|
+
def file(filename)
|
27
|
+
result = Api.magic_file(@magic_set, filename.to_s)
|
23
28
|
if result.null?
|
24
29
|
raise Exception, error
|
25
30
|
else
|
@@ -27,6 +32,7 @@ module Magic
|
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
35
|
+
# Determine type of given string
|
30
36
|
def buffer(string)
|
31
37
|
result = Api.magic_buffer(@magic_set, string, string.bytesize)
|
32
38
|
if result.null?
|
@@ -36,6 +42,7 @@ module Magic
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
45
|
+
# Returns last error occured
|
39
46
|
def error
|
40
47
|
Api.magic_error(@magic_set)
|
41
48
|
end
|
data/lib/magic/errors.rb
CHANGED
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
Magic® File™
|
data/test/helper.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
|
3
|
-
require
|
2
|
+
gem "test-unit"
|
3
|
+
require "test/unit"
|
4
4
|
|
5
5
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
6
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
7
|
require 'magic'
|
8
8
|
|
9
9
|
class Test::Unit::TestCase
|
10
|
+
def fixture(filename)
|
11
|
+
File.join(File.dirname(__FILE__), "fixtures", filename)
|
12
|
+
end
|
10
13
|
end
|
data/test/test_magic.rb
CHANGED
@@ -1,7 +1,45 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
class TestMagic < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
4
|
+
def test_guess_magic_text_mime
|
5
|
+
assert_equal "text/plain; charset=utf-8", Magic.guess_file_mime(fixture("magic.txt"))
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_guess_magic_text_mime_type
|
9
|
+
assert_equal "text/plain", Magic.guess_file_mime_type(fixture("magic.txt"))
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_guess_magic_text_mime_encoding
|
13
|
+
assert_equal "utf-8", Magic.guess_file_mime_encoding(fixture("magic.txt"))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_guess_magic_logo_mime
|
17
|
+
assert_equal "image/jpeg; charset=binary", Magic.guess_file_mime(fixture("filelogo.jpg"))
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_guess_magic_logo_mime_type
|
21
|
+
assert_equal "image/jpeg", Magic.guess_file_mime_type(fixture("filelogo.jpg"))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_guess_magic_logo_mime_encoding
|
25
|
+
assert_equal "binary", Magic.guess_file_mime_encoding(fixture("filelogo.jpg"))
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_guess_non_existing_file_mime
|
29
|
+
assert_raises Magic::Exception do
|
30
|
+
Magic.guess_file_mime(fixture("non-existing.file"))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_guess_non_existing_file_mime_type
|
35
|
+
assert_raises Magic::Exception do
|
36
|
+
Magic.guess_file_mime_type(fixture("non-existing.file"))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_guess_non_existing_file_mime_encoding
|
41
|
+
assert_raises Magic::Exception do
|
42
|
+
Magic.guess_file_mime_encoding(fixture("non-existing.file"))
|
43
|
+
end
|
6
44
|
end
|
7
45
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Jakub Ku\xC5\xBAma"
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: "2.0"
|
34
34
|
version:
|
35
|
-
description: Ruby bindings
|
35
|
+
description: Ruby FFI bindings to libmagic
|
36
36
|
email: qoobaa@gmail.com
|
37
37
|
executables: []
|
38
38
|
|
@@ -53,13 +53,44 @@ files:
|
|
53
53
|
- lib/magic/constants.rb
|
54
54
|
- lib/magic/database.rb
|
55
55
|
- lib/magic/errors.rb
|
56
|
+
- test/fixtures/filelogo.jpg
|
57
|
+
- test/fixtures/magic.txt
|
56
58
|
- test/helper.rb
|
57
59
|
- test/test_magic.rb
|
58
60
|
has_rdoc: true
|
59
61
|
homepage: http://github.com/qoobaa/magic
|
60
62
|
licenses: []
|
61
63
|
|
62
|
-
post_install_message:
|
64
|
+
post_install_message: |
|
65
|
+
+-NOTE FOR LINUX USERS----------------------------------------------+
|
66
|
+
| |
|
67
|
+
| Install libmagic using your package manager, e.g. |
|
68
|
+
| |
|
69
|
+
| sudo apt-get install file |
|
70
|
+
| |
|
71
|
+
+-NOTE FOR WINDOWS USERS -------------------------------------------+
|
72
|
+
| |
|
73
|
+
| Install File for Windows from |
|
74
|
+
| |
|
75
|
+
| http://gnuwin32.sourceforge.net/packages/file.htm |
|
76
|
+
| |
|
77
|
+
+-NOTE FOR MAC OS USERS --------------------------------------------+
|
78
|
+
| |
|
79
|
+
| If you don't have libmagic.1.dylib file in your system |
|
80
|
+
| |
|
81
|
+
| find / -name libmagic.1.dylib |
|
82
|
+
| |
|
83
|
+
| You need to install it via port command |
|
84
|
+
| |
|
85
|
+
| sudo port install file |
|
86
|
+
| |
|
87
|
+
| Sometimes you'll also need to set your DYLD_FALLBACK_LIBRARY_PATH |
|
88
|
+
| environment variable to the directory of the libmagic.1.dylib |
|
89
|
+
| |
|
90
|
+
| export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib |
|
91
|
+
| |
|
92
|
+
+-------------------------------------------------------------------+
|
93
|
+
|
63
94
|
rdoc_options:
|
64
95
|
- --charset=UTF-8
|
65
96
|
require_paths:
|
@@ -82,7 +113,7 @@ rubyforge_project:
|
|
82
113
|
rubygems_version: 1.3.5
|
83
114
|
signing_key:
|
84
115
|
specification_version: 3
|
85
|
-
summary:
|
116
|
+
summary: Determine file type and encoding using "magic" numbers
|
86
117
|
test_files:
|
87
118
|
- test/test_magic.rb
|
88
119
|
- test/helper.rb
|