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.
@@ -1,15 +1,43 @@
1
1
  = magic
2
2
 
3
- Description goes here.
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 version unintentionally.
10
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
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
- Copyright (c) 2010 Jakub Kuźma. See LICENSE for details.
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{Ruby bindings for Magic}
11
- gem.description = %Q{Ruby bindings for Magic}
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.2
1
+ 0.1.0
@@ -1,6 +1,6 @@
1
- require "ffi"
1
+ # encoding: utf-8
2
2
 
3
- ENV["DYLD_FALLBACK_LIBRARY_PATH"] ||= "/opt/local/lib" if FFI::Platform.mac?
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
@@ -1,8 +1,8 @@
1
1
  module Magic
2
- module Api
2
+ module Api #:nodoc:
3
3
  extend FFI::Library
4
4
 
5
- ffi_lib "magic.1"
5
+ ffi_lib "libmagic.so.1", "libmagic.1.dylib", "magic1.dll"
6
6
 
7
7
  attach_function :magic_open, [:int], :pointer
8
8
  attach_function :magic_close, [:pointer], :void
@@ -1,29 +1,52 @@
1
1
  module Magic
2
- module Constants
2
+ module Constants #:nodoc:
3
3
  module Flag
4
- NONE = 0x000000 # No flags
5
- DEBUG = 0x000001 # Turn on debugging
6
- SYMLINK = 0x000002 # Follow symlinks
7
- COMPRESS = 0x000004 # Check inside compressed files
8
- DEVICES = 0x000008 # Look at the contents of devices
9
- MIME_TYPE = 0x000010 # Return the MIME type
10
- CONTINUE = 0x000020 # Return all matches
11
- CHECK = 0x000040 # Print warnings to stderr
12
- PRESERVE_ATIME = 0x000080 # Restore access time on exit
13
- RAW = 0x000100 # Don't translate unprintable chars
14
- ERROR = 0x000200 # Handle ENOENT etc as real errors
15
- MIME_ENCODING = 0x000400 # Return the MIME encoding
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
- APPLE = 0x000800 # Return the Apple creator and type
18
- NO_CHECK_COMPRESS = 0x001000 # Don't check for compressed files
19
- NO_CHECK_TAR = 0x002000 # Don't check for tar files
20
- NO_CHECK_SOFT = 0x004000 # Don't check magic entries
21
- NO_CHECK_APPTYPE = 0x008000 # Don't check application type
22
- NO_CHECK_ELF = 0x010000 # Don't check for elf details
23
- NO_CHECK_TEXT = 0x020000 # Don't check for text files
24
- NO_CHECK_CDF = 0x040000 # Don't check for cdf files
25
- NO_CHECK_TOKENS = 0x100000 # Don't check tokens
26
- NO_CHECK_ENCODING = 0x200000 # Don't check text encodings
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
@@ -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
- def file(file)
22
- result = Api.magic_file(@magic_set, file)
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
@@ -1,3 +1,5 @@
1
1
  module Magic
2
- class Exception < StandardError; end
2
+ # General Exception class
3
+ class Exception < StandardError
4
+ end
3
5
  end
@@ -0,0 +1 @@
1
+ Magic® File™
@@ -1,10 +1,13 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
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
@@ -1,7 +1,45 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestMagic < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
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.2
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 for Magic
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: Ruby bindings for Magic
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