4 Python bindings for libmagic
9 from collections import namedtuple
12 from ctypes.util import find_library
17 Loads the shared library through ctypes and returns a library
18 L{ctypes.CDLL} instance
20 return ctypes.cdll.LoadLibrary(find_library('magic'))
23 _libraries['magic'] = _init()
25 # Flag constants for open and setflags
27 MAGIC_DEBUG = DEBUG = 1
28 MAGIC_SYMLINK = SYMLINK = 2
29 MAGIC_COMPRESS = COMPRESS = 4
30 MAGIC_DEVICES = DEVICES = 8
31 MAGIC_MIME_TYPE = MIME_TYPE = 16
32 MAGIC_CONTINUE = CONTINUE = 32
33 MAGIC_CHECK = CHECK = 64
34 MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128
36 MAGIC_ERROR = ERROR = 512
37 MAGIC_MIME_ENCODING = MIME_ENCODING = 1024
38 MAGIC_MIME = MIME = 1040 # MIME_TYPE + MIME_ENCODING
39 MAGIC_APPLE = APPLE = 2048
41 MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096
42 MAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192
43 MAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384
44 MAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768
45 MAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536
46 MAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072
47 MAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144
48 MAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576
49 MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152
51 MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824
53 FileMagic = namedtuple('FileMagic', ('mime_type', 'encoding', 'name'))
56 class magic_set(Structure):
58 magic_set._fields_ = []
59 magic_t = POINTER(magic_set)
61 _open = _libraries['magic'].magic_open
62 _open.restype = magic_t
63 _open.argtypes = [c_int]
65 _close = _libraries['magic'].magic_close
67 _close.argtypes = [magic_t]
69 _file = _libraries['magic'].magic_file
70 _file.restype = c_char_p
71 _file.argtypes = [magic_t, c_char_p]
73 _descriptor = _libraries['magic'].magic_descriptor
74 _descriptor.restype = c_char_p
75 _descriptor.argtypes = [magic_t, c_int]
77 _buffer = _libraries['magic'].magic_buffer
78 _buffer.restype = c_char_p
79 _buffer.argtypes = [magic_t, c_void_p, c_size_t]
81 _error = _libraries['magic'].magic_error
82 _error.restype = c_char_p
83 _error.argtypes = [magic_t]
85 _setflags = _libraries['magic'].magic_setflags
86 _setflags.restype = c_int
87 _setflags.argtypes = [magic_t, c_int]
89 _load = _libraries['magic'].magic_load
91 _load.argtypes = [magic_t, c_char_p]
93 _compile = _libraries['magic'].magic_compile
94 _compile.restype = c_int
95 _compile.argtypes = [magic_t, c_char_p]
97 _check = _libraries['magic'].magic_check
98 _check.restype = c_int
99 _check.argtypes = [magic_t, c_char_p]
101 _list = _libraries['magic'].magic_list
102 _list.restype = c_int
103 _list.argtypes = [magic_t, c_char_p]
105 _errno = _libraries['magic'].magic_errno
106 _errno.restype = c_int
107 _errno.argtypes = [magic_t]
111 def __init__(self, ms):
116 Closes the magic database and deallocates any resources used.
118 _close(self._magic_t)
124 if isinstance(s, str):
126 try: # keep Python 2 compatibility
127 return str(s, 'utf-8')
135 if isinstance(b, bytes):
137 try: # keep Python 2 compatibility
138 return bytes(b, 'utf-8')
142 def file(self, filename):
144 Returns a textual description of the contents of the argument passed
145 as a filename or None if an error occurred and the MAGIC_ERROR flag
146 is set. A call to errno() will return the numeric error code.
148 return Magic.__tostr(_file(self._magic_t, Magic.__tobytes(filename)))
150 def descriptor(self, fd):
152 Returns a textual description of the contents of the argument passed
153 as a file descriptor or None if an error occurred and the MAGIC_ERROR
154 flag is set. A call to errno() will return the numeric error code.
156 return Magic.__tostr(_descriptor(self._magic_t, fd))
158 def buffer(self, buf):
160 Returns a textual description of the contents of the argument passed
161 as a buffer or None if an error occurred and the MAGIC_ERROR flag
162 is set. A call to errno() will return the numeric error code.
164 return Magic.__tostr(_buffer(self._magic_t, buf, len(buf)))
168 Returns a textual explanation of the last error or None
169 if there was no error.
171 return Magic.__tostr(_error(self._magic_t))
173 def setflags(self, flags):
175 Set flags on the magic object which determine how magic checking
176 behaves; a bitwise OR of the flags described in libmagic(3), but
177 without the MAGIC_ prefix.
179 Returns -1 on systems that don't support utime(2) or utimes(2)
180 when PRESERVE_ATIME is set.
182 return _setflags(self._magic_t, flags)
184 def load(self, filename=None):
186 Must be called to load entries in the colon separated list of database
187 files passed as argument or the default database file if no argument
188 before any magic queries can be performed.
190 Returns 0 on success and -1 on failure.
192 return _load(self._magic_t, Magic.__tobytes(filename))
194 def compile(self, dbs):
196 Compile entries in the colon separated list of database files
197 passed as argument or the default database file if no argument.
198 The compiled files created are named from the basename(1) of each file
199 argument with ".mgc" appended to it.
201 Returns 0 on success and -1 on failure.
203 return _compile(self._magic_t, Magic.__tobytes(dbs))
205 def check(self, dbs):
207 Check the validity of entries in the colon separated list of
208 database files passed as argument or the default database file
211 Returns 0 on success and -1 on failure.
213 return _check(self._magic_t, Magic.__tobytes(dbs))
217 Check the validity of entries in the colon separated list of
218 database files passed as argument or the default database file
221 Returns 0 on success and -1 on failure.
223 return _list(self._magic_t, Magic.__tobytes(dbs))
227 Returns a numeric error code. If return value is 0, an internal
228 magic error occurred. If return value is non-zero, the value is
229 an OS error code. Use the errno module or os.strerror() can be used
230 to provide detailed error information.
232 return _errno(self._magic_t)
237 Returns a magic object on success and None on failure.
238 Flags argument as for setflags.
240 return Magic(_open(flags))
243 # Objects used by `detect_from_` functions
244 mime_magic = Magic(_open(MAGIC_MIME))
246 none_magic = Magic(_open(MAGIC_NONE))
250 def _create_filemagic(mime_detected, type_detected):
252 mime_type, mime_encoding = mime_detected.split('; ')
254 raise ValueError(mime_detected)
256 return FileMagic(name=type_detected, mime_type=mime_type,
257 encoding=mime_encoding.replace('charset=', ''))
260 def detect_from_filename(filename):
261 '''Detect mime type, encoding and file type from a filename
263 Returns a `FileMagic` namedtuple.
266 return _create_filemagic(mime_magic.file(filename),
267 none_magic.file(filename))
270 def detect_from_fobj(fobj):
271 '''Detect mime type, encoding and file type from file-like object
273 Returns a `FileMagic` namedtuple.
276 file_descriptor = fobj.fileno()
277 return _create_filemagic(mime_magic.descriptor(file_descriptor),
278 none_magic.descriptor(file_descriptor))
281 def detect_from_content(byte_content):
282 '''Detect mime type, encoding and file type from bytes
284 Returns a `FileMagic` namedtuple.
287 return _create_filemagic(mime_magic.buffer(byte_content),
288 none_magic.buffer(byte_content))