diff options
author | delphij <delphij@FreeBSD.org> | 2016-05-02 05:46:47 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2016-05-02 05:46:47 +0000 |
commit | 8b0d0aa157352d8605d3aafe9a5ccc61e4859dd5 (patch) | |
tree | 1f94604626bee5b4b127def37e34edb0c2bc250b /contrib/file/python/magic.py | |
parent | aeea68e0cff52be10208981137fc8ef073c2a02b (diff) | |
download | FreeBSD-src-8b0d0aa157352d8605d3aafe9a5ccc61e4859dd5.zip FreeBSD-src-8b0d0aa157352d8605d3aafe9a5ccc61e4859dd5.tar.gz |
MFC r298192: MFV r298178:
Update file to 5.26.
Relnotes: yes
Diffstat (limited to 'contrib/file/python/magic.py')
-rw-r--r-- | contrib/file/python/magic.py | 90 |
1 files changed, 73 insertions, 17 deletions
diff --git a/contrib/file/python/magic.py b/contrib/file/python/magic.py index a17e8da..c48f7d5 100644 --- a/contrib/file/python/magic.py +++ b/contrib/file/python/magic.py @@ -1,10 +1,13 @@ -#!/usr/bin/env python +# coding: utf-8 + ''' Python bindings for libmagic ''' import ctypes +from collections import namedtuple + from ctypes import * from ctypes.util import find_library @@ -32,7 +35,7 @@ MAGIC_PRESERVE_ATIME = PRESERVE_ATIME = 128 MAGIC_RAW = RAW = 256 MAGIC_ERROR = ERROR = 512 MAGIC_MIME_ENCODING = MIME_ENCODING = 1024 -MAGIC_MIME = MIME = 1040 +MAGIC_MIME = MIME = 1040 # MIME_TYPE + MIME_ENCODING MAGIC_APPLE = APPLE = 2048 MAGIC_NO_CHECK_COMPRESS = NO_CHECK_COMPRESS = 4096 @@ -47,6 +50,8 @@ MAGIC_NO_CHECK_ENCODING = NO_CHECK_ENCODING = 2097152 MAGIC_NO_CHECK_BUILTIN = NO_CHECK_BUILTIN = 4173824 +FileMagic = namedtuple('FileMagic', ('mime_type', 'encoding', 'name')) + class magic_set(Structure): pass @@ -118,14 +123,18 @@ class Magic(object): as a filename or None if an error occurred and the MAGIC_ERROR flag is set. A call to errno() will return the numeric error code. """ - try: # attempt python3 approach first - if isinstance(filename, bytes): - bi = filename - else: + if isinstance(filename, bytes): + bi = filename + else: + try: # keep Python 2 compatibility bi = bytes(filename, 'utf-8') - return str(_file(self._magic_t, bi), 'utf-8') - except: - return _file(self._magic_t, filename.encode('utf-8')) + except TypeError: + bi = bytes(filename) + r = _file(self._magic_t, bi) + if isinstance(r, str): + return r + else: + return str(r).encode('utf-8') def descriptor(self, fd): """ @@ -139,20 +148,22 @@ class Magic(object): as a buffer or None if an error occurred and the MAGIC_ERROR flag is set. A call to errno() will return the numeric error code. """ - try: # attempt python3 approach first - return str(_buffer(self._magic_t, buf, len(buf)), 'utf-8') - except: - return _buffer(self._magic_t, buf, len(buf)) + r = _buffer(self._magic_t, buf, len(buf)) + if isinstance(r, str): + return r + else: + return str(r).encode('utf-8') def error(self): """ Returns a textual explanation of the last error or None if there was no error. """ - try: # attempt python3 approach first - return str(_error(self._magic_t), 'utf-8') - except: - return _error(self._magic_t) + e = _error(self._magic_t) + if isinstance(e, str): + return e + else: + return str(e).encode('utf-8') def setflags(self, flags): """ @@ -219,3 +230,48 @@ def open(flags): Flags argument as for setflags. """ return Magic(_open(flags)) + + +# Objects used by `detect_from_` functions +mime_magic = Magic(_open(MAGIC_MIME)) +mime_magic.load() +none_magic = Magic(_open(MAGIC_NONE)) +none_magic.load() + + +def _create_filemagic(mime_detected, type_detected): + mime_type, mime_encoding = mime_detected.split('; ') + + return FileMagic(name=type_detected, mime_type=mime_type, + encoding=mime_encoding.replace('charset=', '')) + + +def detect_from_filename(filename): + '''Detect mime type, encoding and file type from a filename + + Returns a `FileMagic` namedtuple. + ''' + + return _create_filemagic(mime_magic.file(filename), + none_magic.file(filename)) + + +def detect_from_fobj(fobj): + '''Detect mime type, encoding and file type from file-like object + + Returns a `FileMagic` namedtuple. + ''' + + file_descriptor = fobj.fileno() + return _create_filemagic(mime_magic.descriptor(file_descriptor), + none_magic.descriptor(file_descriptor)) + + +def detect_from_content(byte_content): + '''Detect mime type, encoding and file type from bytes + + Returns a `FileMagic` namedtuple. + ''' + + return _create_filemagic(mime_magic.buffer(byte_content), + none_magic.buffer(byte_content)) |