]> granicus.if.org Git - file/commitdiff
PR/477: Make python code pypi friendly.
authorChristos Zoulas <christos@zoulas.com>
Mon, 23 Nov 2015 20:41:43 +0000 (20:41 +0000)
committerChristos Zoulas <christos@zoulas.com>
Mon, 23 Nov 2015 20:41:43 +0000 (20:41 +0000)
python/CHANGELOG.md [new file with mode: 0644]
python/README
python/README.md [new file with mode: 0644]
python/magic.py
python/setup.py
python/tests.py [new file with mode: 0644]

diff --git a/python/CHANGELOG.md b/python/CHANGELOG.md
new file mode 100644 (file)
index 0000000..2ec1266
--- /dev/null
@@ -0,0 +1,8 @@
+# Python `file-magic` Log of Changes
+
+## `0.3.0`
+
+- Fix `setup.py` so we can upload to PyPI
+- Add function `detect_from_filename`
+- Add function `detect_from_fobj`
+- Add function `detect_from_content`
index 8b9a2a7e4074a7b3ed01a21320cac5795e84eeb5..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,13 +0,0 @@
-This directory contains Python bindings to allow you to access the
-libmagic api. At the moment their status is "experimental".
-
-You can install the modules either with:
-
-$ python setup.py build
-$ python setup.py install
-
-or, if you have easy_install:
-
-$ easy_install .
-
-magic-python should work now!
diff --git a/python/README.md b/python/README.md
new file mode 100644 (file)
index 0000000..68d3af2
--- /dev/null
@@ -0,0 +1,29 @@
+# `file-magic`: Python Bindings
+
+This library is a Python ctypes interface to `libmagic`.
+
+
+## Installing
+
+You can install `file-magic` either with:
+
+    python setup.py install
+    # or
+    easy_install .
+
+
+## Using
+
+    import magic
+
+    detected = magic.detect_from_filename('magic.py')
+    print 'Detected MIME type: {}'.format(detected.mime_type)
+    print 'Detected encoding: {}'.format(detected.encoding)
+    print 'Detected file type name: {}'.format(detected.name)
+
+
+## Developing/Contributing
+
+To run the tests:
+
+    python setup.py test
index 2c1c012be197bfa48b769502921448ea23fadcb3..8cff29a9c4aff6312c3e1dbd7322b3ade1da8a78 100644 (file)
@@ -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
@@ -222,3 +227,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))
index 2c3b527bb89062ee8fe5948ef55f8647eef2899b..24ae182fff6b8cd9e77c9c2adad869dfa59ec29e 100644 (file)
@@ -1,10 +1,22 @@
-# Python distutils build script for magic extension
-from distutils.core import setup
-
-setup(name = 'Magic file extensions',
-    version = '0.2',
-    author = 'Reuben Thomas',
-    author_email = 'rrt@sc3d.org',
-    license = 'BSD',
-    description = 'libmagic Python bindings',
-    py_modules = ['magic'])
+# coding: utf-8
+
+from __future__ import unicode_literals
+
+from setuptools import setup
+
+
+setup(name='file-magic',
+      version='0.3.0',
+      author='Reuben Thomas, Álvaro Justen',
+      author_email='rrt@sc3d.org, alvarojusten@gmail.com',
+      url='https://github.com/file/file',
+      license='BSD',
+      description='(official) libmagic Python bindings',
+      py_modules=['magic'],
+      test_suite='tests',
+      classifiers = [
+          'Intended Audience :: Developers',
+          'License :: OSI Approved :: BSD License',
+          'Natural Language :: English',
+          'Topic :: Software Development :: Libraries :: Python Modules',
+      ])
diff --git a/python/tests.py b/python/tests.py
new file mode 100644 (file)
index 0000000..197a8fc
--- /dev/null
@@ -0,0 +1,32 @@
+# coding: utf-8
+
+import unittest
+
+import magic
+
+
+class MagicTestCase(unittest.TestCase):
+
+    filename = 'magic.py'
+    expected_mime_type = 'text/x-python'
+    expected_encoding = 'us-ascii'
+    expected_name = 'Python script, ASCII text executable'
+
+    def assert_result(self, result):
+        self.assertEqual(result.mime_type, self.expected_mime_type)
+        self.assertEqual(result.encoding, self.expected_encoding)
+        self.assertEqual(result.name, self.expected_name)
+
+    def test_detect_from_filename(self):
+        result = magic.detect_from_filename(self.filename)
+        self.assert_result(result)
+
+    def test_detect_from_fobj(self):
+        with open(self.filename) as fobj:
+            result = magic.detect_from_fobj(fobj)
+        self.assert_result(result)
+
+    def test_detect_from_content(self):
+        with open(self.filename) as fobj:
+            result = magic.detect_from_content(fobj.read(4096))
+        self.assert_result(result)