[Checkins] SVN: Sandbox/nadako/z3c.mimetype/ Initial sandbox import.
Dan Korostelev
nadako at gmail.com
Wed Feb 18 07:33:04 EST 2009
Log message for revision 96694:
Initial sandbox import.
Changed:
_U Sandbox/nadako/z3c.mimetype/
A Sandbox/nadako/z3c.mimetype/CHANGES.txt
A Sandbox/nadako/z3c.mimetype/bootstrap.py
A Sandbox/nadako/z3c.mimetype/buildout.cfg
A Sandbox/nadako/z3c.mimetype/setup.py
A Sandbox/nadako/z3c.mimetype/src/
A Sandbox/nadako/z3c.mimetype/src/z3c/
A Sandbox/nadako/z3c.mimetype/src/z3c/__init__.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/README.txt
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/__init__.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/configure.zcml
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/index.txt
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/interfaces.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/magic.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/mimetype.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/__init__.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.binary
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.doc
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.html
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.pdf
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.png
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.unknown
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/test_doc.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/util.py
A Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/utility.py
-=-
Property changes on: Sandbox/nadako/z3c.mimetype
___________________________________________________________________
Added: svn:ignore
+ bin
coverage
docs
parts
.installed.cfg
Added: Sandbox/nadako/z3c.mimetype/CHANGES.txt
===================================================================
--- Sandbox/nadako/z3c.mimetype/CHANGES.txt (rev 0)
+++ Sandbox/nadako/z3c.mimetype/CHANGES.txt 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,8 @@
+=======
+CHANGES
+=======
+
+0.1.0 (unreleased)
+------------------
+
+- Initial release.
Added: Sandbox/nadako/z3c.mimetype/bootstrap.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/bootstrap.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/bootstrap.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,69 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 90507 2008-08-27 23:46:35Z georgyberdyshev $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+is_jython = sys.platform.startswith('java')
+
+if is_jython:
+ import subprocess
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+
+if is_jython:
+ assert subprocess.Popen(
+ [sys.executable] + ['-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout'],
+ env = dict(os.environ,
+ PYTHONPATH =
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ).wait() == 0
+
+else:
+ assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Added: Sandbox/nadako/z3c.mimetype/buildout.cfg
===================================================================
--- Sandbox/nadako/z3c.mimetype/buildout.cfg (rev 0)
+++ Sandbox/nadako/z3c.mimetype/buildout.cfg 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,25 @@
+[buildout]
+develop = .
+parts = test coverage-test coverage-report docs
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.mimetype [test]
+
+[docs]
+recipe = z3c.recipe.sphinxdoc
+eggs = z3c.mimetype [docs]
+build-dir = ${buildout:directory}/docs
+default.css =
+layout.html =
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = z3c.mimetype [test]
+defaults = ['--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('coverage', 'coverage/report')
Added: Sandbox/nadako/z3c.mimetype/setup.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/setup.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/setup.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,54 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup for z3c.mimetype package
+
+$Id$
+"""
+import os
+
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(
+ name='z3c.mimetype',
+ version='0.1.0dev',
+ url='http://pypi.python.org/pypi/z3c.mimetype',
+ license='ZPL 2.1',
+ description='',
+ author='Dan Korostelev and Zope Community',
+ author_email='zope-dev at zope.org',
+ long_description=\
+ read('src', 'z3c', 'mimetype', 'README.txt') + \
+ '\n\n' + \
+ read('CHANGES.txt'),
+ packages=find_packages('src'),
+ package_dir={'': 'src'},
+ namespace_packages=['z3c'],
+ install_requires=[
+ 'setuptools',
+ 'zope.component [zcml]',
+ 'zope.interface',
+ 'zope.i18n',
+ 'zope.i18nmessageid',
+ 'zope.schema',
+ ],
+ extras_require = dict(
+ docs=['Sphinx', 'z3c.recipe.sphinxdoc'],
+ test=['zope.testing'],
+ ),
+ include_package_data=True,
+ zip_safe=False,
+ )
Property changes on: Sandbox/nadako/z3c.mimetype/src
___________________________________________________________________
Added: svn:ignore
+ z3c.mimetype.egg-info
Added: Sandbox/nadako/z3c.mimetype/src/z3c/__init__.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/__init__.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/__init__.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,7 @@
+# this is a namespace package
+try:
+ import pkg_resources
+ pkg_resources.declare_namespace(__name__)
+except ImportError:
+ import pkgutil
+ __path__ = pkgutil.extend_path(__path__, __name__)
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/README.txt
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/README.txt (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/README.txt 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,174 @@
+Mime type guessing
+==================
+
+This package provides an utility for guessing mime type from filename and/or
+file contents. It's based on freedesktop.org's shared-mime-info database.
+
+The `shared-mime-info <http://freedesktop.org/wiki/Software/shared-mime-info>`_
+is a extensible database of common mime types. It provides powerful mime type
+detection mechanism as well as multi-lingual type descriptions.
+
+This package requires shared-mime-info to be installed and accessible. The
+easiest way to do that is to install it system-wide, for example installing
+the ``shared-mime-info`` package on Ubuntu. The specification_ also describes
+other ways to install and extend the database.
+
+.. _specification: http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.13.html#s2_layout
+
+The core of this package is the global IMIMETypesUtility component.
+
+ >>> from zope.component import getUtility
+ >>> from zope.interface.verify import verifyObject
+ >>> from z3c.mimetype.interfaces import IMIMETypesUtility
+
+ >>> util = getUtility(IMIMETypesUtility)
+ >>> verifyObject(IMIMETypesUtility, util)
+ True
+
+It has three methods for getting mime type. The mime type is the
+IMIMEType object.
+
+ >>> from zope.interface.verify import verifyClass
+ >>> from z3c.mimetype.mimetype import MIMEType
+ >>> from z3c.mimetype.interfaces import IMIMEType
+
+ >>> verifyClass(IMIMEType, MIMEType)
+ True
+
+Those three methods are ``getTypeByFileName``, ``getTypeByContents`` and
+``getType``. We will describe them in that order, but for applications,
+it's reccommended to use the latter, ``getType`` method as it's most
+generic and easy-to use.
+
+The simpliest method is ``getTypeByFileName`` that looks up the type by
+filename.
+
+ >>> mt = util.getTypeByFileName('example.doc')
+
+ >>> mt.media
+ 'application'
+
+ >>> mt.subtype
+ 'msword'
+
+ >>> str(mt)
+ 'application/msword'
+
+MIMEType object also has a title attribute that is a translatable string.
+
+ >>> mt.title
+ u'application/msword'
+
+ >>> from zope.i18nmessageid.message import Message
+ >>> isinstance(mt.title, Message)
+ True
+
+Shared-Mime-Info is nice, it can even detect mime type for file names like
+``Makefile``.
+
+ >>> print util.getTypeByFileName('Makefile')
+ text/x-makefile
+
+Also, it know the difference in extension letter case. For example the ``.C``
+should be detected as C++ file, when ``.c`` is plain C file.
+
+ >>> print util.getTypeByFileName('hello.C')
+ text/x-c++src
+
+ >>> print util.getTypeByFileName('main.c')
+ text/x-csrc
+
+The method returns None if it can determine type from file name.
+
+ >>> print util.getTypeByFileName('somefilename')
+ None
+
+Another useful method is ``getTypeByContents``. It's first argument should
+be an opened file. Also, it can take min_priority and max_priority arguments,
+but it's only useful if you know the shared-mime-info specification.
+
+We have some sample files that should be detected by contents
+
+ >>> import os
+ >>> def openSample(extension):
+ ... return open(os.path.join(SAMPLE_DATA_DIR, 'sample.' + extension))
+
+ >>> fdoc = openSample('doc')
+ >>> print util.getTypeByContents(fdoc)
+ application/msword
+
+ >>> fhtml = openSample('html')
+ >>> print util.getTypeByContents(fhtml)
+ text/html
+
+ >>> fpdf = openSample('pdf')
+ >>> print util.getTypeByContents(fpdf)
+ application/pdf
+
+ >>> fpng = openSample('png')
+ >>> print util.getTypeByContents(fpng)
+ image/png
+
+If we pass the file without any magic bytes, it will return None
+
+ >>> funknown = openSample('unknown')
+ >>> print util.getTypeByContents(funknown)
+ None
+
+And finally, the most useful method is simply ``getType``. It accepts
+two arguments - the filename and opened file object. At least one of
+them should be specified. This method tries to guess the mime type
+as specified in shared-mime-info specification document and always returns
+some useful mimetype (application/octet-stream or text/plain if cannot
+detect).
+
+It needs at least one argument, so you can't call it with no arguments.
+
+ >>> util.getType()
+ Traceback (most recent call last):
+ ...
+ TypeError: Either filename or file should be provided or both of them
+
+ >>> print util.getType(filename='wrong.doc')
+ application/msword
+
+ >>> print util.getType(file=fpng)
+ image/png
+
+If type cannot be detected, it WILL return either text/plain or
+application/octet-stream mime type. It will try to guess is it text
+or binary by checking first 32 bytes.
+
+ >>> print util.getType(filename='somefile', file=funknown)
+ text/plain
+
+ >>> funknownbinary = openSample('binary')
+ >>> print util.getType(filename='somefile2', file=funknownbinary)
+ application/octet-stream
+
+Let's close files, because we won't need them anymore.
+
+ >>> del fdoc, fhtml, fpdf, fpng, funknown, funknownbinary
+
+Finally, let's check the i18n features that comes with shared-mime-info
+and are supported by this package. All mimetype titles are translatable
+messages and can be easily rendered in UI.
+
+Let's get some mime type to play with.
+
+ >>> mt = util.getTypeByFileName('example.png')
+
+By default, mimetype title message id is its media/subtype form.
+
+ >>> mt.title
+ u'image/png'
+
+But if we translate it, we'll get a human-friendly string.
+
+ >>> from zope.i18n import translate
+
+ >>> translate(mt.title)
+ u'PNG image'
+
+ >>> translate(mt.title, target_language='ru')
+ u'\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 PNG'
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/__init__.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/__init__.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/__init__.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/configure.zcml
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/configure.zcml (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/configure.zcml 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,10 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+ <utility component=".utility.globalMIMETypesUtility" />
+
+ <utility
+ component=".mimetype.mimeTypesTranslationDomain"
+ name="shared-mime-info"
+ />
+
+</configure>
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/index.txt
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/index.txt (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/index.txt 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,16 @@
+Welcome to z3c.mimetype's documentation!
+========================================
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ README
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/interfaces.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/interfaces.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/interfaces.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+from zope.interface import Interface
+from zope.schema import ASCIILine, TextLine
+
+class IMIMETypesUtility(Interface):
+
+ def getTypeByFileName(filename):
+ '''Return type guessed by filename'''
+
+ def getTypeByContents(file, min_priority=0, max_priority=100):
+ '''Return type guessed by data. Accepts file-like object'''
+
+ def getType(filename=None, file=None):
+ '''Try to guess content type either by file name or contents or both'''
+
+class IMIMEType(Interface):
+
+ media = ASCIILine(
+ title=u'Media',
+ required=True,
+ readonly=True)
+
+ subtype = ASCIILine(
+ title=u'Subtype',
+ required=True,
+ readonly=True)
+
+ title = TextLine(
+ title=u'Title',
+ required=True,
+ readonly=True)
+
+ def __str__():
+ '''Return a ``media/subtype`` presentation of mime type'''
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/magic.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/magic.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/magic.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,188 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+from z3c.mimetype.mimetype import lookup
+
+class MagicRule(object):
+
+ def __init__(self, f):
+ self.next = None
+ self.prev = None
+
+ indent = ''
+ while True:
+ c = f.read(1)
+ if c == '>':
+ break
+ indent += c
+ if not indent:
+ self.nest = 0
+ else:
+ self.nest = int(indent)
+
+ start = ''
+ while True:
+ c = f.read(1)
+ if c == '=':
+ break
+ start += c
+ self.start = int(start)
+
+ hb = f.read(1)
+ lb = f.read(1)
+ self.lenvalue = ord(lb) + (ord(hb) << 8)
+
+ self.value = f.read(self.lenvalue)
+
+ c = f.read(1)
+ if c == '&':
+ self.mask = f.read(self.lenvalue)
+ c = f.read(1)
+ else:
+ self.mask = None
+
+ if c == '~':
+ w = ''
+ while c != '+' and c!='\n':
+ c = f.read(1)
+ if c == '+' or c == '\n':
+ break
+ w += c
+ self.word = int(w)
+ else:
+ self.word = 1
+
+ if c == '+':
+ r = ''
+ while c != '\n':
+ c = f.read(1)
+ if c == '\n':
+ break
+ r += c
+ self.range = int(r)
+ else:
+ self.range = 1
+
+ if c != '\n':
+ raise Exception('Malformed MIME magic line')
+
+ def getLength(self):
+ return self.start + self.lenvalue + self.range
+
+ def appendRule(self, rule):
+ if self.nest < rule.nest:
+ self.next = rule
+ rule.prev = self
+ elif self.prev:
+ self.prev.appendRule(rule)
+
+ def match(self, buffer):
+ if self.match0(buffer):
+ if self.next:
+ return self.next.match(buffer)
+ return True
+
+ def match0(self, buffer):
+ l = len(buffer)
+ for o in xrange(self.range):
+ s = self.start + o
+ e = s + self.lenvalue
+ if l < e:
+ return False
+ if self.mask:
+ test = ''
+ for i in xrange(self.lenvalue):
+ c = ord(buffer[s + i]) & ord(self.mask[i])
+ test += chr(c)
+ else:
+ test = buffer[s:e]
+
+ if test == self.value:
+ return True
+
+class MagicType(object):
+
+ def __init__(self, mtype):
+ self.mtype = mtype
+ self.top_rules = []
+ self.last_rule = None
+
+ def getLine(self, f):
+ nrule = MagicRule(f)
+ if nrule.nest and self.last_rule:
+ self.last_rule.appendRule(nrule)
+ else:
+ self.top_rules.append(nrule)
+ self.last_rule = nrule
+ return nrule
+
+ def match(self, buffer):
+ for rule in self.top_rules:
+ if rule.match(buffer):
+ return self.mtype
+
+class MagicDB(object):
+
+ def __init__(self):
+ self.types = {}
+ self.maxlen = 0
+
+ def mergeFile(self, fname):
+ f = open(fname, 'r')
+
+ line = f.readline()
+ if line != 'MIME-Magic\0\n':
+ raise Exception('Not a MIME magic file')
+
+ while True:
+ shead = f.readline()
+ if not shead:
+ break
+ if shead[0] != '[' or shead[-2:] != ']\n':
+ raise Exception('Malformed section heading')
+ pri, tname = shead[1:-2].split(':')
+ pri = int(pri)
+ mtype = lookup(tname)
+
+ ents = self.types.setdefault(pri, [])
+ magictype = MagicType(mtype)
+
+ c = f.read(1)
+ f.seek(-1, 1)
+ while c and c!='[':
+ rule = magictype.getLine(f)
+ if rule:
+ rulelen = rule.getLength()
+ if rulelen > self.maxlen:
+ self.maxlen = rulelen
+ c = f.read(1)
+ f.seek(-1, 1)
+
+ ents.append(magictype)
+
+ if not c:
+ break
+
+ def match(self, file, min_priority=0, max_priority=100):
+ file.seek(0, 0)
+ buf = file.read(self.maxlen)
+ for priority, types in sorted(self.types.items(), key=lambda ob:ob[0], reverse=True):
+ if priority > max_priority:
+ continue
+ if priority < min_priority:
+ break
+ for type in types:
+ m = type.match(buf)
+ if m:
+ return m
+ return None
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/mimetype.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/mimetype.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/mimetype.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,68 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import os
+from xml.dom import minidom, XML_NAMESPACE
+
+from zope.interface import implements
+from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
+from zope.i18nmessageid import MessageFactory
+
+from z3c.mimetype.interfaces import IMIMEType
+from z3c.mimetype.util import iterDataPaths
+
+SMI_NAMESPACE = 'http://www.freedesktop.org/standards/shared-mime-info'
+MIME_TYPES = {}
+
+msgfactory = MessageFactory('shared-mime-info')
+
+mimeTypesTranslationDomain = SimpleTranslationDomain('shared-mime-info')
+
+class MIMEType(object):
+
+ implements(IMIMEType)
+
+ _title = None
+
+ def __init__(self, media, subtype):
+ assert media and '/' not in media
+ assert subtype and '/' not in subtype
+ assert (media, subtype) not in MIME_TYPES
+ self.media = media
+ self.subtype = subtype
+ for path in iterDataPaths(os.path.join('mime', media, subtype + '.xml')):
+ doc = minidom.parse(path)
+ if doc is None:
+ continue
+ for comment in doc.documentElement.getElementsByTagNameNS(SMI_NAMESPACE, 'comment'):
+ data = ''.join([n.nodeValue for n in comment.childNodes]).strip()
+ lang = comment.getAttributeNS(XML_NAMESPACE, 'lang')
+ msgid = '%s/%s' % (media, subtype)
+ if not lang:
+ self._title = msgfactory(msgid, default=data)
+ else:
+ mimeTypesTranslationDomain.messages[(lang, msgid)] = data
+
+ @property
+ def title(self):
+ return self._title or unicode(self)
+
+ def __str__(self):
+ return self.media + '/' + self.subtype
+
+def lookup(media, subtype=None):
+ if subtype is None and '/' in media:
+ media, subtype = media.split('/', 1)
+ if (media, subtype) not in MIME_TYPES:
+ MIME_TYPES[(media, subtype)] = MIMEType(media, subtype)
+ return MIME_TYPES[(media, subtype)]
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/__init__.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/__init__.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/__init__.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.binary
===================================================================
(Binary files differ)
Property changes on: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.binary
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.doc
===================================================================
(Binary files differ)
Property changes on: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.doc
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.html
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.html (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.html 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+ <title>Sample HTML</title>
+</head>
+<body>
+ <h1>Hello, world</h1>
+ <p>Welcome to my page</p>
+</body>
+</html>
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.pdf
===================================================================
(Binary files differ)
Property changes on: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.pdf
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.png
===================================================================
(Binary files differ)
Property changes on: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.unknown
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.unknown (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/sample_data/sample.unknown 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1 @@
+No magic bytes here, so its mime type can not be detected by contents.
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/test_doc.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/test_doc.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/tests/test_doc.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import os
+import unittest
+
+from zope.testing import doctest
+from zope.component import provideUtility
+
+from z3c.mimetype.utility import globalMIMETypesUtility
+from z3c.mimetype.mimetype import mimeTypesTranslationDomain
+
+def setUp(test):
+ provideUtility(globalMIMETypesUtility)
+ provideUtility(mimeTypesTranslationDomain, name='shared-mime-info')
+ test.globs['SAMPLE_DATA_DIR'] = os.path.join(os.path.dirname(__file__), 'sample_data')
+
+def test_suite():
+ return unittest.TestSuite(
+ doctest.DocFileSuite(
+ '../README.txt',
+ setUp=setUp,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS)
+ )
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/util.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/util.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/util.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,24 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import os
+
+XDG_DATA_HOME = os.environ.get('XDG_DATA_HOME', os.path.join(os.environ.get('HOME', '/'), '.local', 'share'))
+XDG_DATA_DIRS = [XDG_DATA_HOME] + [dir for dir in os.environ.get('XDG_DATA_DIRS', '/usr/local/share:/usr/share').split(':') if dir]
+
+def iterDataPaths(*resource):
+ resource = os.path.join(*resource)
+ for data_dir in XDG_DATA_DIRS:
+ path = os.path.join(data_dir, resource)
+ if os.path.exists(path):
+ yield path
Added: Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/utility.py
===================================================================
--- Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/utility.py (rev 0)
+++ Sandbox/nadako/z3c.mimetype/src/z3c/mimetype/utility.py 2009-02-18 12:33:03 UTC (rev 96694)
@@ -0,0 +1,130 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import re
+import os
+import fnmatch
+
+from zope.interface import implements
+
+from z3c.mimetype.magic import MagicDB
+from z3c.mimetype.mimetype import lookup
+from z3c.mimetype.util import iterDataPaths
+from z3c.mimetype.interfaces import IMIMETypesUtility
+
+findBinary = re.compile('[\0-\7]').search
+
+class MIMETypesUtility(object):
+
+ implements(IMIMETypesUtility)
+
+ _extensions = None
+ _literals = None
+ _globs = None
+ _magicDB = None
+
+ def __init__(self):
+ self._extensions = {}
+ self._literals = {}
+ self._globs = []
+ self._magicDB = MagicDB()
+
+ for path in iterDataPaths(os.path.join('mime', 'globs')):
+ self._importGlobFile(path)
+ self._globs.sort(key=lambda ob:len(ob[0]), reverse=True)
+
+ for path in iterDataPaths(os.path.join('mime', 'magic')):
+ self._magicDB.mergeFile(path)
+
+ def _importGlobFile(self, path):
+ for line in open(path, 'r'):
+ if line.startswith('#'):
+ continue
+ line = line[:-1]
+
+ type_name, pattern = line.split(':', 1)
+ mtype = lookup(type_name)
+
+ if pattern.startswith('*.'):
+ rest = pattern[2:]
+ if not ('*' in rest or '[' in rest or '?' in rest):
+ self._extensions[rest] = mtype
+ continue
+
+ if '*' in pattern or '[' in pattern or '?' in pattern:
+ self._globs.append((pattern, mtype))
+ else:
+ self._literals[pattern] = mtype
+
+ def getTypeByFileName(self, filename):
+ if filename in self._literals:
+ return self._literals[filename]
+
+ lfilename = filename.lower()
+ if lfilename in self._literals:
+ return self._literals[lfilename]
+
+ ext = filename
+ while True:
+ p = ext.find('.')
+ if p < 0:
+ break
+ ext = ext[p + 1:]
+ if ext in self._extensions:
+ return self._extensions[ext]
+
+ ext = lfilename
+ while True:
+ p = ext.find('.')
+ if p < 0:
+ break
+ ext = ext[p + 1:]
+ if ext in self._extensions:
+ return self._extensions[ext]
+
+ for (glob, mime_type) in self._globs:
+ if fnmatch.fnmatch(filename, glob):
+ return mime_type
+ if fnmatch.fnmatch(lfilename, glob):
+ return mime_type
+
+ return None
+
+ def getTypeByContents(self, file, min_priority=0, max_priority=100):
+ return self._magicDB.match(file, min_priority, max_priority)
+
+ def getType(self, filename=None, file=None):
+ if (filename is None) and (file is None):
+ raise TypeError('Either filename or file should be provided or both of them')
+
+ type = None
+
+ if file:
+ type = self.getTypeByContents(file, min_priority=80)
+
+ if not type and filename:
+ type = self.getTypeByFileName(filename)
+
+ if not type and file:
+ type = self.getTypeByContents(file, max_priority=80)
+
+ if not type:
+ type = lookup('application', 'octet-stream')
+ if file:
+ file.seek(0, 0)
+ if not findBinary(file.read(32)):
+ type = lookup('text', 'plain')
+
+ return type
+
+globalMIMETypesUtility = MIMETypesUtility()
More information about the Checkins
mailing list