magic 0.0.2 → 0.1.0
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.
- 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
|