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 if isinstance(filename, bytes):
151 try: # keep Python 2 compatibility
152 bi = bytes(filename, 'utf-8')
155 r = _file(self._magic_t, bi)
156 if isinstance(r, str):
159 return str(r).encode('utf-8')
161 def descriptor(self, fd):
163 Returns a textual description of the contents of the argument passed
164 as a file descriptor or None if an error occurred and the MAGIC_ERROR
165 flag is set. A call to errno() will return the numeric error code.
167 return Magic.__tostr(_descriptor(self._magic_t, fd))
169 def buffer(self, buf):
171 Returns a textual description of the contents of the argument passed
172 as a buffer or None if an error occurred and the MAGIC_ERROR flag
173 is set. A call to errno() will return the numeric error code.
175 return Magic.__tostr(_buffer(self._magic_t, buf, len(buf)))
179 Returns a textual explanation of the last error or None
180 if there was no error.
182 return Magic.__tostr(_error(self._magic_t))
184 def setflags(self, flags):
186 Set flags on the magic object which determine how magic checking
187 behaves; a bitwise OR of the flags described in libmagic(3), but
188 without the MAGIC_ prefix.
190 Returns -1 on systems that don't support utime(2) or utimes(2)
191 when PRESERVE_ATIME is set.
193 return _setflags(self._magic_t, flags)
195 def load(self, filename=None):
197 Must be called to load entries in the colon separated list of database
198 files passed as argument or the default database file if no argument
199 before any magic queries can be performed.
201 Returns 0 on success and -1 on failure.
203 return _load(self._magic_t, Magic.__tobytes(filename))
205 def compile(self, dbs):
207 Compile entries in the colon separated list of database files
208 passed as argument or the default database file if no argument.
209 The compiled files created are named from the basename(1) of each file
210 argument with ".mgc" appended to it.
212 Returns 0 on success and -1 on failure.
214 return _compile(self._magic_t, Magic.__tobytes(dbs))
216 def check(self, dbs):
218 Check the validity of entries in the colon separated list of
219 database files passed as argument or the default database file
222 Returns 0 on success and -1 on failure.
224 return _check(self._magic_t, Magic.__tobytes(dbs))
228 Check the validity of entries in the colon separated list of
229 database files passed as argument or the default database file
232 Returns 0 on success and -1 on failure.
234 return _list(self._magic_t, Magic.__tobytes(dbs))
238 Returns a numeric error code. If return value is 0, an internal
239 magic error occurred. If return value is non-zero, the value is
240 an OS error code. Use the errno module or os.strerror() can be used
241 to provide detailed error information.
243 return _errno(self._magic_t)
248 Returns a magic object on success and None on failure.
249 Flags argument as for setflags.
251 return Magic(_open(flags))
254 # Objects used by `detect_from_` functions
255 mime_magic = Magic(_open(MAGIC_MIME))
257 none_magic = Magic(_open(MAGIC_NONE))
261 def _create_filemagic(mime_detected, type_detected):
262 mime_type, mime_encoding = mime_detected.split('; ')
264 return FileMagic(name=type_detected, mime_type=mime_type,
265 encoding=mime_encoding.replace('charset=', ''))
268 def detect_from_filename(filename):
269 '''Detect mime type, encoding and file type from a filename
271 Returns a `FileMagic` namedtuple.
274 return _create_filemagic(mime_magic.file(filename),
275 none_magic.file(filename))
278 def detect_from_fobj(fobj):
279 '''Detect mime type, encoding and file type from file-like object
281 Returns a `FileMagic` namedtuple.
284 file_descriptor = fobj.fileno()
285 return _create_filemagic(mime_magic.descriptor(file_descriptor),
286 none_magic.descriptor(file_descriptor))
289 def detect_from_content(byte_content):
290 '''Detect mime type, encoding and file type from bytes
292 Returns a `FileMagic` namedtuple.
295 return _create_filemagic(mime_magic.buffer(byte_content),
296 none_magic.buffer(byte_content))