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)) |
|