[Checkins] SVN: z3c.mimetype/trunk/s Add some more documentation. Use double quotes instead of single quotes for docstrings.
Dan Korostelev
nadako at gmail.com
Wed Feb 25 09:01:16 EST 2009
Log message for revision 97257:
Add some more documentation. Use double quotes instead of single quotes for docstrings.
Remove zope.component[zcml] from dependencies, as it is not really needed for core functionality and those who want to use zcml already have all packages, needed for zcml.
Changed:
U z3c.mimetype/trunk/setup.py
U z3c.mimetype/trunk/src/z3c/mimetype/__init__.py
U z3c.mimetype/trunk/src/z3c/mimetype/interfaces.py
U z3c.mimetype/trunk/src/z3c/mimetype/magic.py
U z3c.mimetype/trunk/src/z3c/mimetype/mimetype.py
U z3c.mimetype/trunk/src/z3c/mimetype/tests/__init__.py
U z3c.mimetype/trunk/src/z3c/mimetype/tests/test_doc.py
U z3c.mimetype/trunk/src/z3c/mimetype/util.py
U z3c.mimetype/trunk/src/z3c/mimetype/utility.py
-=-
Modified: z3c.mimetype/trunk/setup.py
===================================================================
--- z3c.mimetype/trunk/setup.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/setup.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -27,7 +27,7 @@
version='0.1.0dev',
url='http://pypi.python.org/pypi/z3c.mimetype',
license='ZPL 2.1',
- description='',
+ description='MIME type guessing framework for Zope, based on shared-mime-info',
author='Dan Korostelev and Zope Community',
author_email='zope-dev at zope.org',
long_description=\
@@ -39,10 +39,10 @@
namespace_packages=['z3c'],
install_requires=[
'setuptools',
- 'zope.component [zcml]',
- 'zope.interface',
+ 'zope.component',
'zope.i18n',
'zope.i18nmessageid',
+ 'zope.interface',
'zope.schema',
],
extras_require = dict(
Modified: z3c.mimetype/trunk/src/z3c/mimetype/__init__.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/__init__.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/__init__.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,16 +11,19 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''
+"""
$Id$
-'''
+"""
from zope.interface import moduleProvides
from z3c.mimetype.interfaces import IConvenienceAPI
from z3c.mimetype.utility import globalMIMETypesUtility
+
+
from z3c.mimetype.mimetype import lookup
def getType(filename=None, file=None):
return globalMIMETypesUtility.getType(filename, file)
+
moduleProvides(IConvenienceAPI)
__all__ = tuple(IConvenienceAPI)
Modified: z3c.mimetype/trunk/src/z3c/mimetype/interfaces.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/interfaces.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/interfaces.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,33 +11,35 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''MIME type guessing framework interface definitions
+"""MIME type guessing framework interface definitions
$Id$
-'''
+"""
from zope.interface import Interface
from zope.schema import ASCIILine, TextLine
+
class IMIMETypesUtility(Interface):
- '''MIME type guessing utility'''
+ """MIME type guessing utility"""
def getTypeByFileName(filename):
- '''Return type guessed by filename'''
+ """Return type guessed by filename"""
def getTypeByContents(file, min_priority=0, max_priority=100):
- '''Return type guessed by data. Accepts file-like object'''
+ """Return type guessed by data. Accepts file-like object"""
def getType(filename=None, file=None):
- '''Guess content type either by file name or contents or both.
+ """Guess content type either by file name or contents or both.
At least one of these arguments should be provided.
This method always returns some useful mimetype,
``application/octet-stream`` or ``text/plain``.
- '''
+ """
+
class IMIMEType(Interface):
- '''Single MIME type representation'''
+ """Single MIME type representation"""
media = ASCIILine(
title=u'Media',
@@ -55,21 +57,22 @@
readonly=True)
def __str__():
- '''Return a ``media/subtype`` presentation of mime type'''
+ """Return a ``media/subtype`` presentation of mime type"""
+
class IConvenienceAPI(Interface):
- '''Convenience API to be provided by the __init__ module.'''
+ """Convenience API to be provided by the __init__ module."""
def getType(filename=None, file=None):
- '''Guess content type either by file name or contents or both
+ """Guess content type either by file name or contents or both
See IMIMETypesUtility.getType documentation.
- '''
+ """
def lookup(media, subtype=None):
- '''Return a IMIMEType object for given string representation.
+ """Return a IMIMEType object for given string representation.
If ``media`` argument is in the "media/subtype" form, then the
``subtype`` argument should't be specified and will be extracted
from the ``media`` argument.
- '''
+ """
Modified: z3c.mimetype/trunk/src/z3c/mimetype/magic.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/magic.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/magic.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,13 +11,104 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''Magic type guessing utility classes
+"""Magic type guessing utility classes
$Id$
-'''
+"""
from z3c.mimetype.mimetype import lookup
+
+class MagicDB(object):
+ """A database of magic rules for guessing type based on file contents"""
+
+ def __init__(self):
+ self.types = {}
+ self.maxlen = 0
+
+ def mergeFile(self, fname):
+ """Merge specified shared-mime-info magic file into the database"""
+ 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):
+ """Try to guess type of specified file-like object"""
+ 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
+
+
+class MagicType(object):
+ """A representation of the mime type, determined by magic.
+
+ It can tell if some data matches its mime type or not.
+
+ """
+
+ def __init__(self, mtype):
+ self.mtype = mtype
+ self.top_rules = []
+ self.last_rule = None
+
+ def getLine(self, f):
+ """Process a portion of the magic database to build a rule tree for this type"""
+ 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):
+ """Try to match given contents using rules defined for this type"""
+ for rule in self.top_rules:
+ if rule.match(buffer):
+ return self.mtype
+
+
class MagicRule(object):
+ """A representation of a magic rule node as defined in the shared-mime-info"""
def __init__(self, f):
self.next = None
@@ -81,9 +172,11 @@
raise Exception('Malformed MIME magic line')
def getLength(self):
+ """Return needed amout of bytes that is required for this rule"""
return self.start + self.lenvalue + self.range
def appendRule(self, rule):
+ """Add a (sub)rule"""
if self.nest < rule.nest:
self.next = rule
rule.prev = self
@@ -91,12 +184,14 @@
self.prev.appendRule(rule)
def match(self, buffer):
+ """Try to match data with this rule and its subrules"""
if self.match0(buffer):
if self.next:
return self.next.match(buffer)
return True
def match0(self, buffer):
+ """Try to match data using this rule definition"""
l = len(buffer)
for o in xrange(self.range):
s = self.start + o
@@ -113,80 +208,3 @@
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
Modified: z3c.mimetype/trunk/src/z3c/mimetype/mimetype.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/mimetype.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/mimetype.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,10 +11,10 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''MIME type helper objects
+"""MIME type helper objects
$Id$
-'''
+"""
import os
from xml.dom import minidom, XML_NAMESPACE
@@ -32,12 +32,13 @@
MIME_TYPES = {}
+
def lookup(media, subtype=None):
- '''Lookup an IMIMEType object.
+ """Lookup an IMIMEType object.
Either a pair of arguments (media and subtype) or single argument in
the ``media/subtype`` form can be used.
- '''
+ """
if subtype is None and '/' in media:
media, subtype = media.split('/', 1)
@@ -45,12 +46,13 @@
MIME_TYPES[(media, subtype)] = _MIMEType(media, subtype)
return MIME_TYPES[(media, subtype)]
+
class _MIMEType(object):
- '''Single MIME type representation
+ """Single MIME type representation
Never create these objects using this class, use the ``lookup`` function
defined above instead.
- '''
+ """
implements(IMIMEType)
Modified: z3c.mimetype/trunk/src/z3c/mimetype/tests/__init__.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/tests/__init__.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/tests/__init__.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,6 +11,6 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''
+"""
$Id$
-'''
+"""
Modified: z3c.mimetype/trunk/src/z3c/mimetype/tests/test_doc.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/tests/test_doc.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/tests/test_doc.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,10 +11,10 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''Tests for z3c.mimetype functionality.
+"""Tests for z3c.mimetype functionality.
$Id$
-'''
+"""
import os
import unittest
@@ -24,11 +24,13 @@
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(
Modified: z3c.mimetype/trunk/src/z3c/mimetype/util.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/util.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/util.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,17 +11,18 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''Utility functions
+"""Utility functions
$Id$
-'''
+"""
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):
- '''Iterate over all ``data`` paths as defined by XDG standard'''
+ """Iterate over all ``data`` paths as defined by XDG standard"""
resource = os.path.join(*resource)
for data_dir in XDG_DATA_DIRS:
Modified: z3c.mimetype/trunk/src/z3c/mimetype/utility.py
===================================================================
--- z3c.mimetype/trunk/src/z3c/mimetype/utility.py 2009-02-25 12:04:45 UTC (rev 97256)
+++ z3c.mimetype/trunk/src/z3c/mimetype/utility.py 2009-02-25 14:01:16 UTC (rev 97257)
@@ -11,11 +11,11 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-'''The actual MIME type guessing utility class and global object (see the end
+"""The actual MIME type guessing utility class and global object (see the end
of file). You want to use the guessing via this utility. :-)
$Id$
-'''
+"""
import re
import os
import fnmatch
@@ -29,8 +29,9 @@
findBinary = re.compile('[\0-\7]').search
+
class MIMETypesUtility(object):
- '''MIME type guessing utility'''
+ """MIME type guessing utility"""
implements(IMIMETypesUtility)
@@ -73,7 +74,7 @@
self._literals[pattern] = mtype
def getTypeByFileName(self, filename):
- '''Return type guessed by filename'''
+ """Return type guessed by filename"""
if filename in self._literals:
return self._literals[filename]
@@ -109,12 +110,12 @@
return None
def getTypeByContents(self, file, min_priority=0, max_priority=100):
- '''Return type guessed by data. Accepts file-like object'''
+ """Return type guessed by data. Accepts file-like object"""
return self._magicDB.match(file, min_priority, max_priority)
def getType(self, filename=None, file=None):
- '''Try to guess content type either by file name or contents or both'''
+ """Try to guess content type either by file name or contents or both"""
if (filename is None) and (file is None):
raise TypeError('Either filename or file should be provided or both of them')
@@ -139,4 +140,5 @@
return type
+
globalMIMETypesUtility = MIMETypesUtility()
More information about the Checkins
mailing list