Deleted Added
full compact
magic.py (267897) magic.py (298192)
1#!/usr/bin/env python
1# coding: utf-8
2
2'''
3Python bindings for libmagic
4'''
5
6import ctypes
7
3'''
4Python bindings for libmagic
5'''
6
7import ctypes
8
9from collections import namedtuple
10
8from ctypes import *
9from ctypes.util import find_library
10
11
12def _init():
13 """
14 Loads the shared library through ctypes and returns a library
15 L{ctypes.CDLL} instance

--- 11 unchanged lines hidden (view full) ---

27MAGIC_DEVICES = DEVICES = 8
28MAGIC_MIME_TYPE = MIME_TYPE = 16
29MAGIC_CONTINUE = CONTINUE = 32
30MAGIC_CHECK = CHECK = 64
31MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128
32MAGIC_RAW = RAW = 256
33MAGIC_ERROR = ERROR = 512
34MAGIC_MIME_ENCODING = MIME_ENCODING = 1024
11from ctypes import *
12from ctypes.util import find_library
13
14
15def _init():
16 """
17 Loads the shared library through ctypes and returns a library
18 L{ctypes.CDLL} instance

--- 11 unchanged lines hidden (view full) ---

30MAGIC_DEVICES = DEVICES = 8
31MAGIC_MIME_TYPE = MIME_TYPE = 16
32MAGIC_CONTINUE = CONTINUE = 32
33MAGIC_CHECK = CHECK = 64
34MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128
35MAGIC_RAW = RAW = 256
36MAGIC_ERROR = ERROR = 512
37MAGIC_MIME_ENCODING = MIME_ENCODING = 1024
35MAGIC_MIME = MIME = 1040
38MAGIC_MIME = MIME = 1040 # MIME_TYPE + MIME_ENCODING
36MAGIC_APPLE = APPLE = 2048
37
38MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096
39MAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192
40MAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384
41MAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768
42MAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536
43MAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072
44MAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144
45MAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576
46MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152
47
48MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824
49
39MAGIC_APPLE = APPLE = 2048
40
41MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096
42MAGIC_NO_CHECK_TAR = NO_CHECK_TAR = 8192
43MAGIC_NO_CHECK_SOFT = NO_CHECK_SOFT = 16384
44MAGIC_NO_CHECK_APPTYPE = NO_CHECK_APPTYPE = 32768
45MAGIC_NO_CHECK_ELF = NO_CHECK_ELF = 65536
46MAGIC_NO_CHECK_TEXT = NO_CHECK_TEXT = 131072
47MAGIC_NO_CHECK_CDF = NO_CHECK_CDF = 262144
48MAGIC_NO_CHECK_TOKENS = NO_CHECK_TOKENS = 1048576
49MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152
50
51MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824
52
53FileMagic = namedtuple('FileMagic', ('mime_type', 'encoding', 'name'))
50
54
55
51class magic_set(Structure):
52 pass
53magic_set._fields_ = []
54magic_t = POINTER(magic_set)
55
56_open = _libraries['magic'].magic_open
57_open.restype = magic_t
58_open.argtypes = [c_int]

--- 54 unchanged lines hidden (view full) ---

113 _close(self._magic_t)
114
115 def file(self, filename):
116 """
117 Returns a textual description of the contents of the argument passed
118 as a filename or None if an error occurred and the MAGIC_ERROR flag
119 is set. A call to errno() will return the numeric error code.
120 """
56class magic_set(Structure):
57 pass
58magic_set._fields_ = []
59magic_t = POINTER(magic_set)
60
61_open = _libraries['magic'].magic_open
62_open.restype = magic_t
63_open.argtypes = [c_int]

--- 54 unchanged lines hidden (view full) ---

118 _close(self._magic_t)
119
120 def file(self, filename):
121 """
122 Returns a textual description of the contents of the argument passed
123 as a filename or None if an error occurred and the MAGIC_ERROR flag
124 is set. A call to errno() will return the numeric error code.
125 """
121 try: # attempt python3 approach first
122 if isinstance(filename, bytes):
123 bi = filename
124 else:
126 if isinstance(filename, bytes):
127 bi = filename
128 else:
129 try: # keep Python 2 compatibility
125 bi = bytes(filename, 'utf-8')
130 bi = bytes(filename, 'utf-8')
126 return str(_file(self._magic_t, bi), 'utf-8')
127 except:
128 return _file(self._magic_t, filename.encode('utf-8'))
131 except TypeError:
132 bi = bytes(filename)
133 r = _file(self._magic_t, bi)
134 if isinstance(r, str):
135 return r
136 else:
137 return str(r).encode('utf-8')
129
130 def descriptor(self, fd):
131 """
132 Like the file method, but the argument is a file descriptor.
133 """
134 return _descriptor(self._magic_t, fd)
135
136 def buffer(self, buf):
137 """
138 Returns a textual description of the contents of the argument passed
139 as a buffer or None if an error occurred and the MAGIC_ERROR flag
140 is set. A call to errno() will return the numeric error code.
141 """
138
139 def descriptor(self, fd):
140 """
141 Like the file method, but the argument is a file descriptor.
142 """
143 return _descriptor(self._magic_t, fd)
144
145 def buffer(self, buf):
146 """
147 Returns a textual description of the contents of the argument passed
148 as a buffer or None if an error occurred and the MAGIC_ERROR flag
149 is set. A call to errno() will return the numeric error code.
150 """
142 try: # attempt python3 approach first
143 return str(_buffer(self._magic_t, buf, len(buf)), 'utf-8')
144 except:
145 return _buffer(self._magic_t, buf, len(buf))
151 r = _buffer(self._magic_t, buf, len(buf))
152 if isinstance(r, str):
153 return r
154 else:
155 return str(r).encode('utf-8')
146
147 def error(self):
148 """
149 Returns a textual explanation of the last error or None
150 if there was no error.
151 """
156
157 def error(self):
158 """
159 Returns a textual explanation of the last error or None
160 if there was no error.
161 """
152 try: # attempt python3 approach first
153 return str(_error(self._magic_t), 'utf-8')
154 except:
155 return _error(self._magic_t)
162 e = _error(self._magic_t)
163 if isinstance(e, str):
164 return e
165 else:
166 return str(e).encode('utf-8')
156
157 def setflags(self, flags):
158 """
159 Set flags on the magic object which determine how magic checking
160 behaves; a bitwise OR of the flags described in libmagic(3), but
161 without the MAGIC_ prefix.
162
163 Returns -1 on systems that don't support utime(2) or utimes(2)

--- 50 unchanged lines hidden (view full) ---

214
215
216def open(flags):
217 """
218 Returns a magic object on success and None on failure.
219 Flags argument as for setflags.
220 """
221 return Magic(_open(flags))
167
168 def setflags(self, flags):
169 """
170 Set flags on the magic object which determine how magic checking
171 behaves; a bitwise OR of the flags described in libmagic(3), but
172 without the MAGIC_ prefix.
173
174 Returns -1 on systems that don't support utime(2) or utimes(2)

--- 50 unchanged lines hidden (view full) ---

225
226
227def open(flags):
228 """
229 Returns a magic object on success and None on failure.
230 Flags argument as for setflags.
231 """
232 return Magic(_open(flags))
233
234
235# Objects used by `detect_from_` functions
236mime_magic = Magic(_open(MAGIC_MIME))
237mime_magic.load()
238none_magic = Magic(_open(MAGIC_NONE))
239none_magic.load()
240
241
242def _create_filemagic(mime_detected, type_detected):
243 mime_type, mime_encoding = mime_detected.split('; ')
244
245 return FileMagic(name=type_detected, mime_type=mime_type,
246 encoding=mime_encoding.replace('charset=', ''))
247
248
249def detect_from_filename(filename):
250 '''Detect mime type, encoding and file type from a filename
251
252 Returns a `FileMagic` namedtuple.
253 '''
254
255 return _create_filemagic(mime_magic.file(filename),
256 none_magic.file(filename))
257
258
259def detect_from_fobj(fobj):
260 '''Detect mime type, encoding and file type from file-like object
261
262 Returns a `FileMagic` namedtuple.
263 '''
264
265 file_descriptor = fobj.fileno()
266 return _create_filemagic(mime_magic.descriptor(file_descriptor),
267 none_magic.descriptor(file_descriptor))
268
269
270def detect_from_content(byte_content):
271 '''Detect mime type, encoding and file type from bytes
272
273 Returns a `FileMagic` namedtuple.
274 '''
275
276 return _create_filemagic(mime_magic.buffer(byte_content),
277 none_magic.buffer(byte_content))