[Checkins] SVN: z3c.filetype/trunk/ - Because tests failed and the author of the changes did not fixed them after
Juergen Kartnaller
juergen at kartnaller.at
Mon Jan 19 07:42:05 EST 2009
Log message for revision 94829:
- Because tests failed and the author of the changes did not fixed them after
a year I reverted trunk to version 82160.
Changed:
U z3c.filetype/trunk/CHANGES.txt
U z3c.filetype/trunk/buildout.cfg
UU z3c.filetype/trunk/setup.py
U z3c.filetype/trunk/src/z3c/filetype/README.txt
U z3c.filetype/trunk/src/z3c/filetype/__init__.py
U z3c.filetype/trunk/src/z3c/filetype/adapters.py
U z3c.filetype/trunk/src/z3c/filetype/api.py
U z3c.filetype/trunk/src/z3c/filetype/configure.zcml
D z3c.filetype/trunk/src/z3c/filetype/converter.txt
D z3c.filetype/trunk/src/z3c/filetype/converters/
A z3c.filetype/trunk/src/z3c/filetype/event.py
U z3c.filetype/trunk/src/z3c/filetype/interfaces/__init__.py
D z3c.filetype/trunk/src/z3c/filetype/interfaces/api.py
D z3c.filetype/trunk/src/z3c/filetype/interfaces/converter.py
U z3c.filetype/trunk/src/z3c/filetype/interfaces/filetypes.py
D z3c.filetype/trunk/src/z3c/filetype/interfaces/magic.py
U z3c.filetype/trunk/src/z3c/filetype/magic.py
U z3c.filetype/trunk/src/z3c/filetype/size.py
U z3c.filetype/trunk/src/z3c/filetype/tests.py
D z3c.filetype/trunk/src/z3c/filetype/typeablefile.py
-=-
Modified: z3c.filetype/trunk/CHANGES.txt
===================================================================
--- z3c.filetype/trunk/CHANGES.txt 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/CHANGES.txt 2009-01-19 12:42:04 UTC (rev 94829)
@@ -5,14 +5,9 @@
After
=====
-2007/12/19 1.2.0
-================
+ - Because tests failed and the author of the changes did not fixed them after
+ a year I reverted trunk to version 82160.
- - code cleanup
- - use IFileData interface for data access
- - mimetype converting
-
-
2007/12/06 1.1.0
================
@@ -20,3 +15,4 @@
- mimetype extension for audio/mpeg layer 3
- removed setup.cfg
- added CHANGES.txt
+
Modified: z3c.filetype/trunk/buildout.cfg
===================================================================
--- z3c.filetype/trunk/buildout.cfg 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/buildout.cfg 2009-01-19 12:42:04 UTC (rev 94829)
@@ -5,4 +5,4 @@
[test]
recipe = zc.recipe.testrunner
-eggs = z3c.filetype [test]
+eggs = z3c.filetype
Modified: z3c.filetype/trunk/setup.py
===================================================================
--- z3c.filetype/trunk/setup.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/setup.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -13,63 +13,33 @@
##############################################################################
"""Setup for z3c.filetype package
-$Id$
+$Id: setup.py 82381 2007-12-21 10:08:32Z jukart $
"""
-import sys, os
+
from setuptools import setup, find_packages
-version = '1.2.0'
-
-def read(*rnames):
- return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
setup(
- name='z3c.filetype',
- version=version,
- description = 'Filetype Package',
- long_description=(
- 'Detailed Dcoumentation\n' +
- '======================\n'
- + '\n\n' +
- read('src', 'z3c', 'filetype', 'README.txt')
- + '\n\n' +
- read('CHANGES.txt')
- ),
- classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Web Environment',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: Zope Public License',
- 'Programming Language :: Python',
- 'Natural Language :: English',
- 'Operating System :: OS Independent',
- 'Topic :: Internet :: WWW/HTTP',
- 'Framework :: Zope3'],
- author='Zope Community',
- author_email='zope3-dev at zope.org',
- url='http://svn.zope.org/z3c.filetype',
- license='ZPL 2.1',
+ name="z3c.filetype",
+ version="1.1.0",
namespace_packages=["z3c"],
packages=find_packages("src"),
package_dir={"": "src"},
include_package_data=True,
install_requires=[
"setuptools",
+ "zope.cachedescriptors",
"zope.component",
- "zope.interface",
"zope.contenttype",
"zope.event",
"zope.i18nmessageid",
+ "zope.interface",
"zope.lifecycleevent",
"zope.proxy",
"zope.schema",
"zope.size",
],
extras_require={
- "test": [
- "zope.testing",
- 'zope.app.testing',
- ],
+ "test": ["zope.testing"],
},
zip_safe=False,
)
Property changes on: z3c.filetype/trunk/setup.py
___________________________________________________________________
Deleted: svn:keywords
- Id
Modified: z3c.filetype/trunk/src/z3c/filetype/README.txt
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/README.txt 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/README.txt 2009-01-19 12:42:04 UTC (rev 94829)
@@ -7,14 +7,12 @@
This package provides a way to get interfaces that are provided based
on their content, filename or mime-type.
- >>> from z3c.filetype import api, typeablefile
- >>> from zope import event, component
- >>> from zope.component import eventtesting
+ >>> from z3c.filetype import api
We take some files for demonstration from the testdata directory.
>>> import os
- >>> testData = os.path.join(os.path.dirname(api.__file__), 'testdata')
+ >>> testData = os.path.join(os.path.dirname(api.__file__),'testdata')
>>> fileNames = sorted(os.listdir(testData))
@@ -70,10 +68,7 @@
>>> sorted(api.getInterfacesFor(f))
[<InterfaceClass z3c.filetype.interfaces.filetypes.ITARFile>]
- >>> sorted(api.getInterfacesForFile(os.path.join(testData, 'test.tar')))
- [<InterfaceClass z3c.filetype.interfaces.filetypes.ITARFile>]
-
- >>> sorted(api.getInterfacesForFilename('x.png'))
+ >>> sorted(api.getInterfacesFor(filename="x.png"))
[<InterfaceClass z3c.filetype.interfaces.filetypes.IPNGFile>]
>>> sorted(api.getInterfacesFor(f, filename="x.png"))
@@ -92,7 +87,7 @@
>>> f.name
'...test.tar'
- >>> sorted(api.getInterfacesForFilename(f.name))
+ >>> sorted(api.getInterfacesFor(f.name))
[<InterfaceClass z3c.filetype.interfaces.filetypes.ITARFile>]
@@ -103,28 +98,34 @@
object. This object needs to implement ITypeableFile. So let us setup
the event handling.
+ >>> from zope.component import eventtesting
+ >>> eventtesting.setUp()
+
>>> from z3c.filetype import interfaces
>>> from zope import interface
>>> class Foo(object):
... interface.implements(interfaces.ITypeableFile)
... def __init__(self, f):
- ... f.seek(0)
- ... self.data = f.read()
+ ... self.data = f
>>> foo = Foo(f)
There is also an event handler registered for IObjectCreatedEvent and
-IObjectModified on ITypeableFile.
+IObjectModified on ITypeableFile. We register them here in the test.
+
+ >>> from zope import component
+ >>> component.provideHandler(api.handleCreated)
+ >>> component.provideHandler(api.handleModified)
+
So we need to fire an IObjectCreatedEvent. Which is normally done by a
factory.
>>> from zope.lifecycleevent import ObjectCreatedEvent
>>> from zope.lifecycleevent import ObjectModifiedEvent
-
+ >>> from zope.event import notify
>>> eventtesting.clearEvents()
- >>> event.notify(ObjectCreatedEvent(foo))
-
+ >>> notify(ObjectCreatedEvent(foo))
>>> sorted(eventtesting.getEvents())
- [<z3c.filetype.interfaces.FileTypeModifiedEvent object at ...>,
+ [<z3c.filetype.event.FileTypeModifiedEvent object at ...>,
<zope.app.event.objectevent.ObjectCreatedEvent object at ...>]
The object now implements the according interface. This is achieved by
@@ -145,15 +146,16 @@
If we change the object the interface changes too. We need to fire
an IObjectModifiedevent. Which is normally done by the implementation.
- >>> foo.data = file(os.path.join(testData,'test.flv'), 'rb').read()
+ >>> foo.data = file(os.path.join(testData,'test.flv'), 'rb')
>>> eventtesting.clearEvents()
- >>> event.notify(ObjectModifiedEvent(foo))
+ >>>
+ >>> notify(ObjectModifiedEvent(foo))
Now we have two events, one we fired and one from our handler.
>>> eventtesting.getEvents()
[<zope.app.event.objectevent.ObjectModifiedEvent object at ...>,
- <z3c.filetype.interfaces.FileTypeModifiedEvent object at ...>]
+ <z3c.filetype.event.FileTypeModifiedEvent object at ...>]
Now the file should implement another filetype.
@@ -161,22 +163,20 @@
[<InterfaceClass z3c.filetype.interfaces.filetypes.IFLVFile>]
-IContentType adapters
-=====================
+IFileType adapters
+==================
-There is also an adapter from ITypedFile to IContentType, which can be
+There is also an adapter from ITypedFile to IFileType, which can be
used to get the default content type for the interface.
>>> from z3c.filetype import adapters
- >>> component.provideAdapter(adapters.ContentType)
-
+ >>> component.provideAdapter(adapters.TypedFileType)
>>> for name in fileNames:
- ... if name==".svn":
- ... continue
+ ... if name==".svn": continue
... path = os.path.join(testData, name)
... i = Foo(file(path, 'rb'))
- ... event.notify(ObjectModifiedEvent(i))
- ... print name + " --> " + interfaces.IContentType(i).contentType
+ ... notify(ObjectModifiedEvent(i))
+ ... print name + " --> " + interfaces.IFileType(i).contentType
DS_Store --> application/octet-stream
IMG_0504.JPG --> image/jpeg
faces_gray.avi --> video/x-msvideo
@@ -210,22 +210,24 @@
>>> component.provideAdapter(size.PNGFileSized)
>>> component.provideAdapter(size.JPGFileSized)
- >>> foo.data = file(os.path.join(testData,'thumbnailImage_small.jpeg'), 'rb').read()
- >>> event.notify(ObjectModifiedEvent(foo))
+ >>> foo.data = file(os.path.join(testData,'thumbnailImage_small.jpeg'), 'rb')
+ >>> notify(ObjectModifiedEvent(foo))
>>> ISized(foo).sizeForDisplay().mapping
{'width': '120', 'height': '90', 'size': '3'}
- >>> foo.data = file(os.path.join(testData,'test.png'), 'rb').read()
- >>> event.notify(ObjectModifiedEvent(foo))
+ >>> foo.data = file(os.path.join(testData,'test.png'), 'rb')
+ >>> notify(ObjectModifiedEvent(foo))
>>> ISized(foo).sizeForDisplay().mapping
{'width': '279', 'height': '19', 'size': '4'}
- >>> foo.data = file(os.path.join(testData,'logo.gif'), 'rb').read()
- >>> event.notify(ObjectModifiedEvent(foo))
+ >>> foo.data = file(os.path.join(testData,'logo.gif'), 'rb')
+ >>> notify(ObjectModifiedEvent(foo))
>>> ISized(foo).sizeForDisplay().mapping
{'width': '201', 'height': '54', 'size': '2'}
- >>> foo.data = file(os.path.join(testData,'IMG_0504.JPG'), 'rb').read()
- >>> event.notify(ObjectModifiedEvent(foo))
+ >>> foo.data = file(os.path.join(testData,'IMG_0504.JPG'), 'rb')
+ >>> notify(ObjectModifiedEvent(foo))
>>> ISized(foo).sizeForDisplay().mapping
{'width': '1600', 'height': '1200', 'size': '499'}
+
+
Modified: z3c.filetype/trunk/src/z3c/filetype/__init__.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/__init__.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/__init__.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1 +1 @@
-# This file is necessary to make this directory a package.
+#package
Modified: z3c.filetype/trunk/src/z3c/filetype/adapters.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/adapters.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/adapters.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,29 +1,13 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-from zope import interface, component
-
+from zope.cachedescriptors.property import Lazy
import interfaces
-from interfaces.filetypes import MT, ITypedFile
+from interfaces import filetypes
+from zope import interface
+from zope import component
+class TypedFileType(object):
-class ContentType(object):
- component.adapts(ITypedFile)
- interface.implements(interfaces.IContentType)
+ interface.implements(interfaces.IFileType)
+ component.adapts(filetypes.ITypedFile)
def __init__(self, context):
self.context = context
@@ -32,13 +16,10 @@
def contentType(self):
decl = interface.Declaration(
*interface.directlyProvidedBy(self.context))
-
for iface in decl.flattened():
- if not iface.extends(ITypedFile):
+ if not issubclass(iface, filetypes.ITypedFile):
continue
-
- mt = iface.queryTaggedValue(MT)
+ mt = iface.queryTaggedValue(filetypes.MT)
if mt is not None:
return mt
- return 'application/octet-stream'
Modified: z3c.filetype/trunk/src/z3c/filetype/api.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/api.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/api.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,127 +1,71 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-from zope import interface
-from zope import component, event
-from zope.proxy import removeAllProxies
+from z3c.filetype import magic
+import interfaces
+from interfaces import filetypes
from zope.contenttype import guess_content_type
+from zope import interface, component
+from zope.lifecycleevent.interfaces import IObjectModifiedEvent
+from zope.lifecycleevent.interfaces import IObjectCreatedEvent
+from zope.event import notify
+from event import FileTypeModifiedEvent
-from z3c.filetype import magic, interfaces
-from z3c.filetype.interfaces.api import IAPI
-from z3c.filetype.interfaces import filetypes
-from z3c.filetype.interfaces.converter import IConverter, ConverterNotFound
-
-
magicFile = magic.MagicFile()
+def byMimeType(t):
-def byMimeType(mt):
"""returns interfaces implemented by mimeType"""
- ifaces = [iface for name, iface in vars(filetypes).items()
+
+ ifaces = [iface for name, iface in vars(filetypes).items() \
if name.startswith("I")]
res = InterfaceSet()
for iface in ifaces:
mtm = iface.queryTaggedValue(filetypes.MTM)
if mtm is not None:
- if mtm.match(mt):
+ if mtm.match(t):
res.add(iface)
return res
+def getInterfacesFor(file=None, filename=None, mimeType=None):
-def getInterfacesFor(file, filename=None, mimeType=None):
"""returns a sequence of interfaces that are provided by file like
- objects (file argument) or string with an optional
- filename as name or mimeType as mime-type
+ objects (file argument) with an optional filename as name or
+ mimeType as mime-type
"""
- file.seek(0)
-
+
ifaces = set()
- for mt in magicFile.detect(file):
- ifaces.update(byMimeType(mt))
-
+ if file is not None:
+ types = magicFile.detect(file)
+ for t in types:
+ ifaces.update(byMimeType(t))
if mimeType is not None:
ifaces.update(byMimeType(mimeType))
-
if filename is not None and not ifaces:
- mt = guess_content_type(filename)[0]
+ t = guess_content_type(filename)[0]
# dont trust this here because zope does not recognize some
# binary files.
- if mt not in ('application/octet-stream',
- 'text/x-unknown-content-type'):
- ifaces.update(byMimeType(mt))
-
+ if t and not t == 'text/x-unknown-content-type':
+ ifaces.update(byMimeType(t))
if not ifaces:
- ifaces.add(filetypes.IBinaryFile)
-
+ ifaces.add(interfaces.filetypes.IBinaryFile)
return InterfaceSet(*ifaces)
-
-def getInterfacesForFile(filename, mimeType=None):
- file = open(filename, 'r')
- try:
- ifaces = getInterfacesFor(file, filename, mimeType)
- finally:
- file.close()
- return ifaces
-
-
-def getInterfacesForFilename(filename):
- ifaces = set()
- mt = guess_content_type(filename)[0]
- if mt not in ('application/octet-stream',
- 'text/x-unknown-content-type'):
- ifaces.update(byMimeType(mt))
- if not ifaces:
- ifaces.add(filetypes.IBinaryFile)
- return InterfaceSet(*ifaces)
-
-
def applyInterfaces(obj):
- raw = interfaces.IFileData(obj, None)
- if raw is None:
- return False
-
- data = raw.open('r')
-
- ifaces = InterfaceSet(*getInterfacesFor(data))
+ assert(interfaces.ITypeableFile.providedBy(obj))
+ ifaces = InterfaceSet(*getInterfacesFor(obj.data))
provided = set(interface.directlyProvidedBy(obj))
for iface in provided:
- if not issubclass(iface, filetypes.ITypedFile):
+ if not issubclass(iface, interfaces.filetypes.ITypedFile):
ifaces.add(iface)
-
- data.close()
-
- ifaces = set(ifaces)
- if ifaces and (ifaces != provided):
- clean_obj = removeAllProxies(obj)
-
- for iface in interface.directlyProvidedBy(clean_obj):
- if not iface.isOrExtends(filetypes.ITypedFile):
- ifaces.add(iface)
-
- if ifaces:
- interface.directlyProvides(clean_obj, ifaces)
- event.notify(interfaces.FileTypeModifiedEvent(obj))
- return True
-
+ if set(ifaces)!=provided:
+ from zope.proxy import removeAllProxies
+ obj = removeAllProxies(obj)
+ for iface in ifaces:
+ interface.directlyProvides(obj, iface)
+ notify(FileTypeModifiedEvent(obj))
+ return True
return False
-
class InterfaceSet(object):
+
"""a set that only holds most specific interfaces
>>> s = InterfaceSet(filetypes.IBinaryFile, filetypes.IImageFile)
@@ -139,13 +83,14 @@
>>> sorted(s)
[<InterfaceClass z3c.filetype.interfaces.filetypes.IJPGFile>,
<InterfaceClass z3c.filetype.interfaces.filetypes.ITextFile>]
+
"""
def __init__(self, *ifaces):
self._data = set()
for iface in ifaces:
self.add(iface)
-
+
def add(self, iface):
assert(issubclass(iface, interface.Interface))
toDelete = set()
@@ -156,37 +101,20 @@
toDelete.add(i)
self._data.add(iface)
self._data.difference_update(toDelete)
-
+
def __iter__(self):
+
return iter(self._data)
+ at component.adapter(interfaces.ITypeableFile,IObjectModifiedEvent)
+def handleModified(typeableFile, event):
+ """handles modification of data"""
+ if interfaces.IFileTypeModifiedEvent.providedBy(event):
+ # do nothing if this is already a filetype modification event
+ return
+ applyInterfaces(typeableFile)
-def convert(obj, mimetype, name=None, converter=IConverter, *args, **kw):
- from z3c.filetype import typeablefile
-
- dest = typeablefile.TypeableFile()
- interface.directlyProvides(dest, mimetype)
-
- if name is None:
- for name, converter in component.getAdapters((obj, dest), converter):
- converter.convert(*args, **kw)
- return dest
- raise ConverterNotFound(
- "converter not found for (%s, %s)"%(obj, mimetype))
- else:
- if isinstance(name, basestring):
- name = [name]
-
- for nm in name:
- converter = component.queryMultiAdapter((obj, dest), converter, nm)
- if converter is not None:
- converter.convert(*args, **kw)
- return dest
-
- if converter is None:
- raise ConverterNotFound(
- "converter not found for (%s, %s)"%(obj, mimetype))
-
-
-interface.moduleProvides(IAPI)
-__all__ = tuple(IAPI)
+ at component.adapter(interfaces.ITypeableFile,IObjectCreatedEvent)
+def handleCreated(typeableFile, event):
+ """handles modification of data"""
+ applyInterfaces(typeableFile)
Modified: z3c.filetype/trunk/src/z3c/filetype/configure.zcml
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/configure.zcml 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/configure.zcml 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,23 +1,22 @@
<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:zcml="http://namespaces.zope.org/zcml"
- i18n_domain="zope">
+ xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="zope"
+ >
- <adapter factory=".adapters.ContentType" />
+ <subscriber for=".interfaces.ITypeableFile
+ zope.lifecycleevent.interfaces.IObjectModifiedEvent"
+ handler=".api.handleModified"/>
- <adapter factory=".typeablefile.TypeableFileData" />
- <subscriber handler=".typeablefile.handleCreated" />
- <subscriber handler=".typeablefile.handleModified" />
+ <subscriber for=".interfaces.ITypeableFile
+ zope.lifecycleevent.interfaces.IObjectCreatedEvent"
+ handler=".api.handleCreated"/>
- <adapter factory=".size.PNGFileSized" />
- <adapter factory=".size.JPGFileSized" />
- <adapter factory=".size.GIFFileSized" />
+
+ <adapter factory=".adapters.TypedFileType"/>
- <class class="z3c.blobfile.file.File"
- zcml:condition="installed z3c.blobfile">
- <implements interface=".interfaces.IFileData" />
- </class>
+ <adapter factory=".size.PNGFileSized" />
+ <adapter factory=".size.JPGFileSized" />
+ <adapter factory=".size.GIFFileSized" />
- <include package=".converters" />
-
+
</configure>
Deleted: z3c.filetype/trunk/src/z3c/filetype/converter.txt
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/converter.txt 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/converter.txt 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,72 +0,0 @@
- Converting
-~~~~~~~~~~~~~~
-
-We can convert data, for this we should register converter for required types
-
- >>> from zope import component, interface
- >>> from z3c.filetype import api, interfaces
- >>> from z3c.filetype.interfaces import filetypes
- >>> from z3c.filetype.converters import jpggif
-
-Now we need load files
-
- >>> import os.path
- >>> testData = os.path.join(os.path.dirname(api.__file__), 'testdata')
-
- >>> from z3c.filetype.typeablefile import TypeableFile
- >>> img1 = TypeableFile(file(os.path.join(testData, 'logo.gif'), 'rb').read())
-
- >>> sorted((interface.directlyProvidedBy(img1)))
- [<InterfaceClass z3c.filetype.interfaces.filetypes.IGIFFile>]
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile)
- Traceback (most recent call last):
- ...
- ConverterNotFound: ...
-
-Let's register simple image converters
-
- >>> component.provideAdapter(jpggif.GIFtoJPEGConverter)
- >>> component.provideAdapter(jpggif.JPEGtoGIFConverter)
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile)
- >>> sorted((interface.directlyProvidedBy(img2)))
- [<InterfaceClass z3c.filetype.interfaces.filetypes.IJPGFile>]
-
-Image converter can scale image
-
- >>> interfaces.IImageSized(img2).getImageSize()
- (201, 54)
-
-converter save width/height aspect retio
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile, width=100, height=54)
- >>> interfaces.IImageSized(img2).getImageSize()
- (100, 26)
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile, width=100, height=40)
- >>> interfaces.IImageSized(img2).getImageSize()
- (100, 26)
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile, scale=0.5)
- >>> interfaces.IImageSized(img2).getImageSize()
- (101, 27)
-
-Named converters, we can pass converter `name`. It can be string or sequence
-of names.
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile, name='MyConverter')
- Traceback (most recent call last):
- ...
- ConverterNotFound: ...
-
- >>> component.provideAdapter(jpggif.GIFtoJPEGConverter, name='MyConverter')
-
-Simple case with only one name
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile, name='MyConverter')
-
-With multple names, it will try get `MyConverter` if it is not
-exists it will try `PIL` etc.
-
- >>> img2 = api.convert(img1, filetypes.IJPGFile, name=['MyConverter', 'PIL', ''])
Copied: z3c.filetype/trunk/src/z3c/filetype/event.py (from rev 82160, z3c.filetype/trunk/src/z3c/filetype/event.py)
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/event.py (rev 0)
+++ z3c.filetype/trunk/src/z3c/filetype/event.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -0,0 +1,7 @@
+from zope.lifecycleevent import ObjectModifiedEvent
+from zope import interface
+import interfaces
+
+class FileTypeModifiedEvent(ObjectModifiedEvent):
+ interface.implements(interfaces.IFileTypeModifiedEvent)
+
Modified: z3c.filetype/trunk/src/z3c/filetype/interfaces/__init__.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/interfaces/__init__.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/interfaces/__init__.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,57 +1,18 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-from zope import interface, schema
-from zope.size.interfaces import ISized
-from zope.lifecycleevent import ObjectModifiedEvent
from zope.lifecycleevent.interfaces import IObjectModifiedEvent
+from zope import interface, schema
+class IFileType(interface.Interface):
-class IMimetypeType(interface.interfaces.IInterface):
- """ mimetype type """
+ contentType = schema.TextLine(title = u'Content Type')
+class IFileTypeModifiedEvent(IObjectModifiedEvent):
-class IContentType(interface.Interface):
+ """This event is fired when the filetypes change on an object"""
- contentType = schema.TextLine(
- title = u'Content Type')
-
-
-class IFileData(interface.Interface):
-
- def open(mode='r'):
- """ Open file, returns file(-like) object for handling the data """
-
-
-class IImageSized(ISized):
-
- def getImageSize():
- """ return width, height of image """
-
-
class ITypeableFile(interface.Interface):
+
"""A file object that is typeable"""
data = interface.Attribute('Data of the file')
-
-
-class IFileTypeModifiedEvent(IObjectModifiedEvent):
- """This event is fired when the filetypes change on an object"""
-
-
-class FileTypeModifiedEvent(ObjectModifiedEvent):
- interface.implements(IFileTypeModifiedEvent)
+
+
Deleted: z3c.filetype/trunk/src/z3c/filetype/interfaces/api.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/interfaces/api.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/interfaces/api.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,43 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-""" api interfaces
-
-$Id$
-"""
-from zope import interface
-
-
-class IAPI(interface.Interface):
- """ filetype api """
-
- def byMimeType(mt):
- """returns interfaces implemented by mimeType"""
-
- def getInterfacesFor(file, filename=None, mimeType=None):
- """ returns a sequence of interfaces that are provided by file like
- objects (file argument) with an optional
- filename as name or mimeType as mime-type """
-
- def getInterfacesForFile(filename, mimeType=None):
- """ returns a sequence of interfaces that are provided by file
- with filename as name and optional mimeType as mime-type """
-
- def getInterfacesForFilename(filename):
- """ returns a sequence of interfaces that are provided by filename """
-
- def applyInterfaces(obj):
- """ detect object mimetypes and set mimetype interfaces """
-
- def convert(obj, mimetype):
- """ convert obj to destination mimetype """
Deleted: z3c.filetype/trunk/src/z3c/filetype/interfaces/converter.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/interfaces/converter.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/interfaces/converter.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,50 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-""" converter interfaces
-
-$Id$
-"""
-from zope import interface
-
-
-class ConverterException(Exception):
- """ base converter exception """
-
-
-class ConverterNotFound(Exception):
- """ required converter not found """
-
-
-class IConverterModule(interface.Interface):
- """ converter module """
-
- def convert(context, mimetype):
- """ convert `context` data to mimetype data, return ITypeableFile object """
-
-
-class IConverter(interface.Interface):
- """ base interface for data converter """
-
- def __init__(context, destination):
- """ adapter """
-
- def convert():
- """ convert data """
-
-
-class ISimpleImageConverter(IConverter):
- """ simple image converter """
-
- def convert(width=None, height=None, scale=0):
- """ convert image """
Modified: z3c.filetype/trunk/src/z3c/filetype/interfaces/filetypes.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/interfaces/filetypes.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/interfaces/filetypes.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,157 +1,117 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import re
from zope import interface
+import re
# mimeTypeMatch holds regular expression for matching mime-types
MTM = 'mimeTypesMatch'
-
-# mimeType holds the preferred mime type to be returned for this interface
+# mimeType holds the preferred mime type to be returned for this
+# interface
MT = "mimeType"
-
class ITypedFile(interface.Interface):
"""A Type of a file"""
-
class IBinaryFile(ITypedFile):
"""Binary file"""
IBinaryFile.setTaggedValue(MTM,re.compile('application/octet-stream'))
IBinaryFile.setTaggedValue(MT,'application/octet-stream')
-
class IZIPFile(IBinaryFile):
"""Zip file"""
IZIPFile.setTaggedValue(MTM,re.compile('application/x-zip'))
IZIPFile.setTaggedValue(MT,'application/x-zip')
-
class ITARFile(IBinaryFile):
"""Binary file"""
ITARFile.setTaggedValue(MTM,re.compile('application/x-tar'))
ITARFile.setTaggedValue(MT,'application/x-tar')
-
class IBZIP2File(IBinaryFile):
"""BZIP2 file"""
IBZIP2File.setTaggedValue(MTM,re.compile('application/x-bzip2'))
IBZIP2File.setTaggedValue(MT,'application/x-bzip2')
-
class IGZIPFile(IBinaryFile):
"""Binary file"""
IGZIPFile.setTaggedValue(MTM,re.compile('application/x-gzip'))
IGZIPFile.setTaggedValue(MT,'application/x-gzip')
-
class ITextFile(ITypedFile):
"""text files"""
ITextFile.setTaggedValue(MTM,re.compile('^text/.+$'))
ITextFile.setTaggedValue(MT,'text/plain')
-
class IImageFile(ITypedFile):
"""image files"""
IImageFile.setTaggedValue(MTM,re.compile('^image/.+$'))
-
class IPDFFile(IBinaryFile):
"""pdf files"""
IPDFFile.setTaggedValue(MTM,re.compile('application/pdf'))
IPDFFile.setTaggedValue(MT,'application/pdf')
-
class IJPGFile(IImageFile, IBinaryFile):
"""jpeg file"""
IJPGFile.setTaggedValue(MTM,re.compile('image/jpe?g'))
IJPGFile.setTaggedValue(MT,'image/jpeg')
-
class IPNGFile(IImageFile, IBinaryFile):
"""png file"""
IPNGFile.setTaggedValue(MTM,re.compile('image/png'))
IPNGFile.setTaggedValue(MT,'image/png')
-
class IGIFFile(IImageFile, IBinaryFile):
"""gif file"""
IGIFFile.setTaggedValue(MTM,re.compile('image/gif'))
IGIFFile.setTaggedValue(MT,'image/gif')
-
class IVideoFile(IBinaryFile):
"""video file"""
IVideoFile.setTaggedValue(MTM,re.compile('^video/.+$'))
-
class IQuickTimeFile(IVideoFile):
"""Quicktime Video File Format"""
IQuickTimeFile.setTaggedValue(MTM,re.compile('video/quicktime'))
IQuickTimeFile.setTaggedValue(MT,'video/quicktime')
-
class IAVIFile(IVideoFile):
"""Quicktime Video File Format"""
IAVIFile.setTaggedValue(MTM,re.compile('video/x-msvideo'))
IAVIFile.setTaggedValue(MT,'video/x-msvideo')
-
class IMPEGFile(IVideoFile):
"""MPEG Video File Format"""
IMPEGFile.setTaggedValue(MTM,re.compile('video/mpe?g'))
IMPEGFile.setTaggedValue(MT,'video/mpeg')
-
class IMP4File(IQuickTimeFile):
"""IMP4File IPod Video File Format"""
IMP4File.setTaggedValue(MTM,re.compile('video/mp4'))
IMP4File.setTaggedValue(MT,'video/mp4')
-
class IFLVFile(IVideoFile):
"""Macromedia Flash FLV Video File Format"""
IFLVFile.setTaggedValue(MTM,re.compile('video/x-flv'))
IFLVFile.setTaggedValue(MT,'video/x-flv')
-
class IASFFile(IVideoFile):
"""Windows Media File Format"""
IASFFile.setTaggedValue(MTM,re.compile('video/x-ms-asf'))
IASFFile.setTaggedValue(MT,'video/x-ms-asf')
-
class IAudioFile(ITypedFile):
"""audio file"""
IAudioFile.setTaggedValue(MTM,re.compile('^audio/.+$'))
-
class IAudioMPEGFile(IAudioFile):
"""audio file"""
IAudioMPEGFile.setTaggedValue(MTM,re.compile('audio/mpeg'))
IAudioMPEGFile.setTaggedValue(MT,'audio/mpeg')
-
class IHTMLFile(ITextFile):
"""HTML file"""
IHTMLFile.setTaggedValue(MTM,re.compile('text/html'))
IHTMLFile.setTaggedValue(MT,'text/html')
-
class IXMLFile(ITextFile):
"""XML File"""
IXMLFile.setTaggedValue(MTM,re.compile('text/xml'))
Deleted: z3c.filetype/trunk/src/z3c/filetype/interfaces/magic.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/interfaces/magic.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/interfaces/magic.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,32 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-""" magic file interfaces
-
-$Id$
-"""
-
-class MagicError(Exception):
- pass
-
-
-class MagicTestError(MagicError):
- pass
-
-
-class OffsetError(MagicError):
- pass
-
-
-class MagicFileError(MagicError):
- pass
Modified: z3c.filetype/trunk/src/z3c/filetype/magic.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/magic.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/magic.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,13 +1,11 @@
# Found on a russian zope mailing list, and modified to fix bugs in parsing
-# the magic file and string making, cleanup
+# the magic file and string making
# -- Daniel Berlin <dberlin at dberlin.org>
-import sys, os.path
-import struct, time, re, pprint
+import sys, struct, time, re, exceptions, pprint, stat, os
-from z3c.filetype.interfaces.magic import \
- OffsetError, MagicFileError, MagicTestError
+_mew = 0
-default_magic = os.path.join(os.path.dirname(__file__), 'magic.mime')
+_magic = os.path.join(os.path.dirname(__file__),'magic.mime')
mime = 1
@@ -15,64 +13,104 @@
BUFFER_SIZE = 1024 * 128 # 128K should be enough...
+class MagicError(exceptions.Exception): pass
-def _handle(fmt='@x',adj=None):
- return fmt, struct.calcsize(fmt), adj
+def _handle(fmt='@x',adj=None): return fmt, struct.calcsize(fmt), adj
-
KnownTypes = {
- 'byte': _handle('@b'),
- 'byte': _handle('@B'),
- 'ubyte': _handle('@B'),
- 'string': ('s', 0, None),
- 'pstring': _handle('p'),
- 'short': _handle('@h'),
- 'beshort': _handle('>h'),
- 'leshort': _handle('<h'),
- 'short': _handle('@H'),
- 'beshort': _handle('>H'),
- 'leshort': _handle('<H'),
- 'ushort': _handle('@H'),
- 'ubeshort': _handle('>H'),
- 'uleshort': _handle('<H'),
+ 'byte':_handle('@b'),
+ 'byte':_handle('@B'),
+ 'ubyte':_handle('@B'),
+ 'string':('s',0,None),
+ 'pstring':_handle('p'),
+ 'short':_handle('@h'),
+ 'beshort':_handle('>h'),
+ 'leshort':_handle('<h'),
+ 'short':_handle('@H'),
+ 'beshort':_handle('>H'),
+ 'leshort':_handle('<H'),
+ 'ushort':_handle('@H'),
+ 'ubeshort':_handle('>H'),
+ 'uleshort':_handle('<H'),
- 'long': _handle('@l'),
- 'belong': _handle('>l'),
- 'lelong': _handle('<l'),
- 'ulong': _handle('@L'),
- 'ubelong': _handle('>L'),
- 'ulelong': _handle('<L'),
+ 'long':_handle('@l'),
+ 'belong':_handle('>l'),
+ 'lelong':_handle('<l'),
+ 'ulong':_handle('@L'),
+ 'ubelong':_handle('>L'),
+ 'ulelong':_handle('<L'),
- 'date': _handle('=l'),
- 'bedate': _handle('>l'),
- 'ledate': _handle('<l'),
- 'ldate': _handle('=l', _ldate_adjust),
- 'beldate': _handle('>l', _ldate_adjust),
- 'leldate': _handle('<l', _ldate_adjust),
+ 'date':_handle('=l'),
+ 'bedate':_handle('>l'),
+ 'ledate':_handle('<l'),
+ 'ldate':_handle('=l',_ldate_adjust),
+ 'beldate':_handle('>l',_ldate_adjust),
+ 'leldate':_handle('<l',_ldate_adjust),
}
+_mew_cnt = 0
+def mew(x):
+ global _mew_cnt
+ if _mew :
+ if x=='.' :
+ _mew_cnt += 1
+ if _mew_cnt % 64 == 0 : sys.stderr.write( '\n' )
+ sys.stderr.write( '.' )
+ else:
+ sys.stderr.write( '\b'+x )
def has_format(s):
n = 0
l = None
- for c in s:
- if c == '%':
- if l == '%': n -= 1
- else : n += 1
+ for c in s :
+ if c == '%' :
+ if l == '%' : n -= 1
+ else : n += 1
l = c
return n
+def read_asciiz(file,size=None,pos=None):
+ s = []
+ if pos :
+ mew('s')
+ file.seek( pos, 0 )
+ mew('z')
+ if size is not None :
+ s = [file.read( size ).split('\0')[0]]
+ else:
+ while 1 :
+ c = file.read(1)
+ if (not c) or (ord(c)==0) or (c=='\n') : break
+ s.append (c)
+ mew('Z')
+ return ''.join(s)
+def a2i(v,base=0):
+ if v[-1:] in 'lL' : v = v[:-1]
+ return int( v, base )
+
+_cmap = {
+ '\\' : '\\',
+ '0' : '\0',
+}
+for c in range(ord('a'),ord('z')+1) :
+ try : e = eval('"\\%c"' % chr(c))
+ except ValueError : pass
+ else : _cmap[chr(c)] = e
+else:
+ del c
+ del e
+
def make_string(s):
# hack, is this the right way?
- s = s.replace('\\<', '<')
- s = s.replace('\\ ', ' ')
- return eval('"%s"'%s.replace('"', '\\"'))
+ s = s.replace('\\<','<')
+ s = s.replace('\\ ',' ')
+ return eval( '"'+s.replace('"','\\"')+'"')
+class MagicTestError(MagicError): pass
class MagicTest:
-
- def __init__(self, offset, mtype, test, message, line=None, level=None):
+ def __init__(self,offset,mtype,test,message,line=None,level=None):
self.line, self.level = line, level
self.mtype = mtype
self.mtest = test
@@ -81,46 +119,45 @@
self.smod = None
self.nmod = None
self.offset, self.type, self.test, self.message = \
- offset, mtype, test, message
-
- if self.mtype == 'true':
- return # XXX hack to enable level skips
-
- if (test[-1:] == '\\') and (test[-2:] != '\\\\'):
+ offset,mtype,test,message
+ if self.mtype == 'true' : return # XXX hack to enable level skips
+ if test[-1:]=='\\' and test[-2:]!='\\\\' :
self.test += 'n' # looks like someone wanted EOL to match?
-
- if mtype[:6] == 'string':
+ if mtype[:6]=='string' :
if '/' in mtype : # for strings
self.type, self.smod = \
- mtype[:mtype.find('/')], mtype[mtype.find('/')+1:]
+ mtype[:mtype.find('/')], mtype[mtype.find('/')+1:]
else:
- for nm in '&+-':
- if nm in mtype: # for integer-based
- self.nmod = nm
- self.type = mtype[:mtype.find(nm)]
-
- # convert mask to int, autodetect base
- self.mask = int(mtype[mtype.find(nm)+1:], 0)
+ for nm in '&+-' :
+ if nm in mtype : # for integer-based
+ self.nmod, self.type, self.mask = (
+ nm,
+ mtype[:mtype.find(nm)],
+ # convert mask to int, autodetect base
+ int( mtype[mtype.find(nm)+1:], 0 )
+ )
break
-
- self.struct, self.size, self.cast = KnownTypes[self.type]
-
+ self.struct, self.size, self.cast = KnownTypes[ self.type ]
def __str__(self):
return '%s %s %s %s' % (
- self.offset, self.mtype, self.mtest, self.message)
-
+ self.offset, self.mtype, self.mtest, self.message
+ )
def __repr__(self):
return 'MagicTest(%s,%s,%s,%s,line=%s,level=%s,subtests=\n%s%s)' % (
`self.offset`, `self.mtype`, `self.mtest`, `self.message`,
`self.line`, `self.level`,
'\t'*self.level, pprint.pformat(self.subtests)
)
-
- def run(self, file):
+ def run(self,file):
result = ''
-
+ do_close = 0
try:
- if self.mtype != 'true':
+ if type(file) == type('x') :
+ file = open( file, 'r', BUFFER_SIZE )
+ do_close = 1
+# else:
+# saved_pos = file.tell()
+ if self.mtype != 'true' :
data = self.read(file)
try:
last = file.tell()
@@ -130,125 +167,92 @@
pass
else:
data = last = None
-
- if self.check(data):
- result = self.message + ' '
-
- if has_format(result):
- result %= data
-
- for test in self.subtests:
+ if self.check( data ) :
+ result = self.message+' '
+ if has_format( result ) : result %= data
+ for test in self.subtests :
m = test.run(file)
- if m is not None:
- result += m
-
- return make_string(result)
- except Exception, e:
- #log_info('Type detection: %s'%str(e)
- pass
-
- def a2i(self, v, base=0):
- if v[-1:] in 'lL':
- v = v[:-1]
- return int(v, base)
-
+ if m is not None : result += m
+ return make_string( result )
+ finally:
+ if do_close :
+ file.close()
+# else:
+# file.seek( saved_pos, 0 )
def get_mod_and_value(self):
- if self.type[-6:] == 'string':
- if self.test[0] in '=<>':
- mod = self.test[0]
- value = make_string(self.test[1:])
+ if self.type[-6:] == 'string' :
+# if 'ustar' in self.test:
+# import pdb;pdb.set_trace()
+ # "something like\tthis\n"
+ if self.test[0] in '=<>' :
+ mod, value = self.test[0], make_string( self.test[1:] )
else:
- mod = '='
- value = make_string( self.test )
+ mod, value = '=', make_string( self.test )
else:
- if self.test[0] in '=<>&^':
- mod = self.test[0]
- value = self.a2i(self.test[1:])
+ if self.test[0] in '=<>&^' :
+ mod, value = self.test[0], a2i(self.test[1:])
elif self.test[0] == 'x':
mod = self.test[0]
value = 0
else:
- mod = '='
- value = self.a2i(self.test)
+ mod, value = '=', a2i(self.test)
return mod, value
-
- def read(self, file):
- file.seek(self.offset(file), 0) # SEEK_SET
+ def read(self,file):
+ mew( 's' )
+ file.seek( self.offset(file), 0 ) # SEEK_SET
+ mew( 'r' )
try:
data = rdata = None
# XXX self.size might be 0 here...
- if self.size == 0:
+ if self.size == 0 :
# this is an ASCIIZ string...
size = None
- if self.test != '>\\0': # magic's hack for string read...
+ if self.test != '>\\0' : # magic's hack for string read...
value = self.get_mod_and_value()[1]
size = (value=='\0') and None or len(value)
-
- rdata = data = self.read_asciiz(file, size=size)
+ rdata = data = read_asciiz( file, size=size )
else:
- rdata = file.read(self.size)
- if not rdata or (len(rdata) != self.size):
- return None
-
- data = struct.unpack(self.struct, rdata)[0] # XXX hack??
+ rdata = file.read( self.size )
+ if not rdata or (len(rdata)!=self.size) : return None
+ data = struct.unpack( self.struct, rdata )[0] # XXX hack??
except:
- raise MagicTestError('@%s struct=%s size=%d rdata=%s' % (
- self.offset, `self.struct`, self.size, `rdata`))
-
- if self.cast:
- data = self.cast(data)
-
- if self.mask:
+ print >>sys.stderr, self
+ print >>sys.stderr, '@%s struct=%s size=%d rdata=%s' % (
+ self.offset, `self.struct`, self.size,`rdata`)
+ raise
+ mew( 'R' )
+ if self.cast : data = self.cast( data )
+ if self.mask :
try:
- if self.nmod == '&':
- data &= self.mask
- elif self.nmod == '+':
- data += self.mask
- elif self.nmod == '-':
- data -= self.mask
- else:
- raise MagicTestError(self.nmod)
+ if self.nmod == '&' : data &= self.mask
+ elif self.nmod == '+' : data += self.mask
+ elif self.nmod == '-' : data -= self.mask
+ else: raise MagicTestError(self.nmod)
except:
- raise MagicTestError('data=%s nmod=%s mask=%s' % (
- `data`, `self.nmod`, `self.mask`))
-
+ print >>sys.stderr,'data=%s nmod=%s mask=%s' % (
+ `data`, `self.nmod`, `self.mask`
+ )
+ raise
return data
-
- def read_asciiz(self, file, size=None):
- s = []
- if size is not None :
- s = [file.read(size).split('\0')[0]]
- else:
- while 1:
- c = file.read(1)
- if (not c) or (ord(c) == 0) or (c == '\n'):
- break
- s.append (c)
-
- return ''.join(s)
-
- def check(self, data):
+ def check(self,data):
+ mew('.')
if self.mtype == 'true' :
return '' # not None !
-
mod, value = self.get_mod_and_value()
if self.type[-6:] == 'string' :
# "something like\tthis\n"
if self.smod:
+ #import pdb;pdb.set_trace()
xdata = data
-
- if 'b' in self.smod: # all blanks are optional
- xdata = ''.join(data.split())
- value = ''.join(value.split())
-
- if 'c' in self.smod: # all blanks are optional
+ if 'b' in self.smod : # all blanks are optional
+ xdata = ''.join( data.split() )
+ value = ''.join( value.split() )
+ if 'c' in self.smod : # all blanks are optional
xdata = xdata.upper()
value = value.upper()
-
- if 'B' in self.smod: # compact blanks
- data = ' '.join(data.split())
- if ' ' not in data:
- return None
+ if 'B' in self.smod : # compact blanks
+ data = ' '.join( data.split() )
+ if ' ' not in data : return None
else:
xdata = data
try:
@@ -258,50 +262,46 @@
elif mod == '&' : result = data & value
elif mod == '^' : result = (data & (~value)) == 0
elif mod == 'x' : result = 1
- else:
- raise MagicTestError(self.test)
-
- if result:
+ else : raise MagicTestError(self.test)
+ if result :
zdata, zval = `data`, `value`
-
- if self.mtype[-6:] != 'string':
- try:
- zdata = hex(data)
- zval = hex(value)
- except:
- zdata = `data`
- zval = `value`
-
+ if self.mtype[-6:]!='string' :
+ try: zdata, zval = hex(data), hex(value)
+ except: zdata, zval = `data`, `value`
+ if 0 : print >>sys.stderr, '%s @%s %s:%s %s %s => %s (%s)' % (
+ '>'*self.level, self.offset,
+ zdata, self.mtype, `mod`, zval, `result`,
+ self.message
+ )
return result
except:
- raise MagicTestError('mtype=%s data=%s mod=%s value=%s' % (
- `self.mtype`, `data`, `mod`, `value`))
-
+ print >>sys.stderr,'mtype=%s data=%s mod=%s value=%s' % (
+ `self.mtype`, `data`, `mod`, `value`
+ )
+ raise
def add(self,mt):
- if not isinstance(mt, MagicTest):
- raise MagicTestError((mt, 'incorrect subtest type %s'%(type(mt),)))
-
- if mt.level == self.level+1:
- self.subtests.append(mt)
-
- elif self.subtests:
- self.subtests[-1].add(mt)
-
- elif mt.level > self.level+1:
+ if not isinstance(mt,MagicTest) :
+ raise MagicTestError((mt,'incorrect subtest type %s'%(type(mt),)))
+ if mt.level == self.level+1 :
+ self.subtests.append( mt )
+ elif self.subtests :
+ self.subtests[-1].add( mt )
+ elif mt.level > self.level+1 :
# it's possible to get level 3 just after level 1 !!! :-(
level = self.level + 1
- while level < mt.level:
- xmt = MagicTest(None, 'true', 'x', '', line=self.line, level=level)
- self.add(xmt)
+ while level < mt.level :
+ xmt = MagicTest(None,'true','x','',line=self.line,level=level)
+ self.add( xmt )
level += 1
else:
- self.add(mt) # retry...
+ self.add( mt ) # retry...
else:
- raise MagicTestError((mt, 'incorrect subtest level %s'%(`mt.level`,)))
-
+ raise MagicTestError((mt,'incorrect subtest level %s'%(`mt.level`,)))
def last_test(self):
return self.subtests[-1]
+#end class MagicTest
+class OffsetError(MagicError): pass
class Offset:
pos_format = {'b':'<B','B':'>B','s':'<H','S':'>H','l':'<I','L':'>I',}
@@ -337,137 +337,134 @@
)?
\)$''', re.X|re.I
)
-
def __init__(self,s):
self.source = s
self.value = None
- self.relative = False
+ self.relative = 0
self.base = self.type = self.sign = self.offs = None
-
- m = Offset.pattern0.match(s)
- if m: # just a number
- if s[0] == '&':
- self.relative = True
- self.value = int(s[1:], 0)
+ m = Offset.pattern0.match( s )
+ if m : # just a number
+ if s[0] == '&' :
+ self.relative, self.value = 1, int( s[1:], 0 )
else:
self.value = int( s, 0 )
return
-
- m = Offset.pattern1.match(s)
- if m: # real indirect offset
+ m = Offset.pattern1.match( s )
+ if m : # real indirect offset
try:
self.base = m.group('base')
- if self.base[0] == '&':
- self.relative = True
- self.base = int(self.base[1:], 0)
+ if self.base[0] == '&' :
+ self.relative, self.base = 1, int( self.base[1:], 0 )
else:
- self.base = int(self.base, 0)
-
- if m.group('type'):
- self.type = m.group('type')[1:]
-
+ self.base = int( self.base, 0 )
+ if m.group('type') : self.type = m.group('type')[1:]
self.sign = m.group('sign')
- if m.group('off'):
- self.offs = int( m.group('off'), 0 )
-
- if self.sign == '-':
- self.offs = 0 - self.offs
+ if m.group('off') : self.offs = int( m.group('off'), 0 )
+ if self.sign == '-' : self.offs = 0 - self.offs
except:
- raise OffsetError(m.groupdict())
-
+ print >>sys.stderr, '$$', m.groupdict()
+ raise
return
raise OffsetError(`s`)
-
- def __call__(self, file=None):
- if self.value is not None:
- return self.value
-
+ def __call__(self,file=None):
+ if self.value is not None : return self.value
pos = file.tell()
try:
- if not self.relative:
- file.seek(self.offset, 0)
-
- frmt = Offset.pos_format.get(self.type, 'I')
- size = struct.calcsize(frmt)
- data = struct.unpack(frmt, file.read(size))
-
- if self.offs:
- data += self.offs
-
+ if not self.relative : file.seek( self.offset, 0 )
+ frmt = Offset.pos_format.get( self.type, 'I' )
+ size = struct.calcsize( frmt )
+ data = struct.unpack( frmt, file.read( size ) )
+ if self.offs : data += self.offs
return data
finally:
- file.seek(pos, 0)
+ file.seek( pos, 0 )
+ def __str__(self): return self.source
+ def __repr__(self): return 'Offset(%s)' % `self.source`
+#end class Offset
- def __str__(self):
- return self.source
+class MagicFileError(MagicError): pass
- def __repr__(self):
- return 'Offset(%s)' % `self.source`
-
-
-class MagicFile(object):
-
- def __init__(self, filename=default_magic):
+class MagicFile:
+ def __init__(self,filename=_magic):
+ self.file = None
self.tests = []
self.total_tests = 0
- self.load(filename)
-
- def load(self, filename=None):
- file = open(filename, 'r', BUFFER_SIZE)
- self.parse(file)
- file.close()
-
- def parse(self, data):
+ self.load( filename )
+ self.ack_tests = None
+ self.nak_tests = None
+ def __del__(self):
+ self.close()
+ def load(self,filename=None):
+ self.open( filename )
+ self.parse()
+ self.close()
+ def open(self,filename=None):
+ self.close()
+ if filename is not None :
+ self.filename = filename
+ self.file = open( self.filename, 'r', BUFFER_SIZE )
+ def close(self):
+ if self.file :
+ self.file.close()
+ self.file = None
+ def parse(self):
line_no = 0
- for line in data:
+ for line in self.file.xreadlines() :
line_no += 1
-
- data = self.parse_line(line)
- if data is None:
- continue
-
+ if not line or line[0]=='#' : continue
+ line = line.lstrip().rstrip('\r\n')
+ if not line or line[0]=='#' : continue
+ try:
+ x = self.parse_line( line )
+ if x is None :
+ print >>sys.stderr, '#[%04d]#'%line_no, line
+ continue
+ except:
+ print >>sys.stderr, '###[%04d]###'%line_no, line
+ raise
self.total_tests += 1
-
- level = data[0]
- new_test = MagicTest(*data[1:], **{'line': line_no, 'level': data[0]})
+ level, offset, mtype, test, message = x
+ new_test = MagicTest(offset,mtype,test,message,
+ line=line_no,level=level)
try:
if level == 0 :
self.tests.append( new_test )
else:
self.tests[-1].add( new_test )
except:
- raise MagicFileError('total tests=%s, level=%s, tests=%s'%(
- len(self.total_tests),
- level, pprint.pformat(self.tests)))
+ if 1 :
+ print >>sys.stderr, 'total tests=%s' % (
+ `self.total_tests`,
+ )
+ print >>sys.stderr, 'level=%s' % (
+ `level`,
+ )
+ print >>sys.stderr, 'tests=%s' % (
+ pprint.pformat(self.tests),
+ )
+ raise
else:
while self.tests[-1].level > 0 :
self.tests.pop()
-
- def parse_line(self, line):
- line = line.lstrip().rstrip('\r\n')
-
- if not line or line[0]=='#':
- return None
-
+ def parse_line(self,line):
+ # print >>sys.stderr, 'line=[%s]' % line
+ if (not line) or line[0]=='#' : return None
level = 0
offset = mtype = test = message = ''
-
+ mask = None
# get optional level (count leading '>')
- while line and line[0]=='>':
+ while line and line[0]=='>' :
line, level = line[1:], level+1
-
# get offset
- while line and not line[0].isspace():
+ while line and not line[0].isspace() :
offset, line = offset+line[0], line[1:]
-
try:
offset = Offset(offset)
except:
- raise MagicFileError('line=[%s]' % line)
-
+ print >>sys.stderr, 'line=[%s]' % line
+ raise
# skip spaces
line = line.lstrip()
-
# get type
c = None
while line :
@@ -478,10 +475,8 @@
mtype += c
if last_c == '\\' :
c = None # don't fuck my brain with sequential backslashes
-
# skip spaces
line = line.lstrip()
-
# get test
c = None
while line :
@@ -492,23 +487,235 @@
test += c
if last_c == '\\' :
c = None # don't fuck my brain with sequential backslashes
-
# skip spaces
line = line.lstrip()
-
# get message
message = line
if mime and line.find("\t") != -1:
- message = line[0:line.find("\t")]
-
+ message=line[0:line.find("\t")]
+ #
+ # print '>>', level, offset, mtype, test, message
return level, offset, mtype, test, message
-
- def detect(self, file):
+ def detect(self,file):
+ self.ack_tests = 0
+ self.nak_tests = 0
answers = set()
- for test in self.tests:
- message = test.run(file)
+ for test in self.tests :
+ message = test.run( file )
if message and message.strip():
- msg = message.strip().split()[0]
- if msg not in answers:
- answers.add(msg)
- yield msg
+ self.ack_tests += 1
+ answers.add( message.strip().split()[0] )
+ else:
+ self.nak_tests += 1
+ return answers
+
+#end class MagicFile
+
+def username(uid):
+ try:
+ import pwd
+ return pwd.getpwuid( uid )[0]
+ except:
+ return '#%s'%uid
+
+def groupname(gid):
+ try:
+ import grp
+ return grp.getgrgid( gid )[0]
+ except:
+ return '#%s'%gid
+
+def get_file_type(fname,follow):
+ t = None
+ if not follow :
+ try:
+ st = os.lstat( fname ) # stat that entry, don't follow links!
+ except os.error, why :
+ pass
+ else:
+ if stat.S_ISLNK(st[stat.ST_MODE]) :
+ t = 'symbolic link'
+ try:
+ lnk = os.readlink( fname )
+ except:
+ t += ' (unreadable)'
+ else:
+ t += ' to '+lnk
+ if t is None :
+ try:
+ st = os.stat( fname )
+ except os.error, why :
+ return "can't stat `%s' (%s)." % (why.filename,why.strerror)
+
+ dmaj, dmin = (st.st_rdev>>8)&0x0FF, st.st_rdev&0x0FF
+
+ if 0 : pass
+ elif stat.S_ISSOCK(st.st_mode) : t = 'socket'
+ elif stat.S_ISLNK (st.st_mode) : t = follow and 'symbolic link' or t
+ elif stat.S_ISREG (st.st_mode) : t = 'file'
+ elif stat.S_ISBLK (st.st_mode) : t = 'block special (%d/%d)'%(dmaj,dmin)
+ elif stat.S_ISDIR (st.st_mode) : t = 'directory'
+ elif stat.S_ISCHR (st.st_mode) : t = 'character special (%d/%d)'%(dmaj,dmin)
+ elif stat.S_ISFIFO(st.st_mode) : t = 'pipe'
+ else: t = '<unknown>'
+
+ if st.st_mode & stat.S_ISUID :
+ t = 'setuid(%d=%s) %s'%(st.st_uid,username(st.st_uid),t)
+ if st.st_mode & stat.S_ISGID :
+ t = 'setgid(%d=%s) %s'%(st.st_gid,groupname(st.st_gid),t)
+ if st.st_mode & stat.S_ISVTX :
+ t = 'sticky '+t
+
+ return t
+
+HELP = '''%s [options] [files...]
+
+Options:
+
+ -?, --help -- this help
+ -m, --magic=<file> -- use this magic <file> instead of %s
+ -f, --files=<namefile> -- read filenames for <namefile>
+* -C, --compile -- write "compiled" magic file
+ -b, --brief -- don't prepend filenames to output lines
++ -c, --check -- check the magic file
+ -i, --mime -- output MIME types
+* -k, --keep-going -- don't stop st the first match
+ -n, --flush -- flush stdout after each line
+ -v, --verson -- print version and exit
+* -z, --compressed -- try to look inside compressed files
+ -L, --follow -- follow symlinks
+ -s, --special -- don't skip special files
+
+* -- not implemented so far ;-)
++ -- implemented, but in another way...
+'''
+
+def main():
+ import getopt
+ global _magic
+ try:
+ brief = 0
+ flush = 0
+ follow= 0
+ mime = 0
+ check = 0
+ special=0
+ try:
+ opts, args = getopt.getopt(
+ sys.argv[1:],
+ '?m:f:CbciknvzLs',
+ ( 'help',
+ 'magic=',
+ 'names=',
+ 'compile',
+ 'brief',
+ 'check',
+ 'mime',
+ 'keep-going',
+ 'flush',
+ 'version',
+ 'compressed',
+ 'follow',
+ 'special',
+ )
+ )
+ except getopt.error, why:
+ print >>sys.stderr, sys.argv[0], why
+ return 1
+ else:
+ files = None
+ for o,v in opts :
+ if o in ('-?','--help'):
+ print HELP % (
+ sys.argv[0],
+ _magic,
+ )
+ return 0
+ elif o in ('-f','--files='):
+ files = v
+ elif o in ('-m','--magic='):
+ _magic = v[:]
+ elif o in ('-C','--compile'):
+ pass
+ elif o in ('-b','--brief'):
+ brief = 1
+ elif o in ('-c','--check'):
+ check = 1
+ elif o in ('-i','--mime'):
+ mime = 1
+ if os.path.exists( _magic+'.mime' ) :
+ _magic += '.mime'
+ print >>sys.stderr,sys.argv[0]+':',\
+ "Using regular magic file `%s'" % _magic
+ elif o in ('-k','--keep-going'):
+ pass
+ elif o in ('-n','--flush'):
+ flush = 1
+ elif o in ('-v','--version'):
+ print 'VERSION'
+ return 0
+ elif o in ('-z','--compressed'):
+ pass
+ elif o in ('-L','--follow'):
+ follow = 1
+ elif o in ('-s','--special'):
+ special = 1
+ else:
+ if files :
+ files = map(lambda x: x.strip(), v.split(','))
+ if '-' in files and '-' in args :
+ error( 1, 'cannot use STDIN simultaneously for file list and data' )
+ for file in files :
+ for name in (
+ (file=='-')
+ and sys.stdin
+ or open(file,'r',BUFFER_SIZE)
+ ).xreadlines():
+ name = name.strip()
+ if name not in args :
+ args.append( name )
+ try:
+ if check : print >>sys.stderr, 'Loading magic database...'
+ t0 = time.time()
+ m = MagicFile(_magic)
+ t1 = time.time()
+ if check :
+ print >>sys.stderr, \
+ m.total_tests, 'tests loaded', \
+ 'for', '%.2f' % (t1-t0), 'seconds'
+ print >>sys.stderr, len(m.tests), 'tests at top level'
+ return 0 # XXX "shortened" form ;-)
+
+ mlen = max( map(len, args) )+1
+ for arg in args :
+ if not brief : print (arg + ':').ljust(mlen),
+ ftype = get_file_type( arg, follow )
+ if (special and ftype.find('special')>=0) \
+ or ftype[-4:] == 'file' :
+ t0 = time.time()
+ try:
+ t = m.detect( arg )
+ except (IOError,os.error), why:
+ t = "can't read `%s' (%s)" % (why.filename,why.strerror)
+ if ftype[-4:] == 'file' : t = ftype[:-4] + t
+ t1 = time.time()
+ print t and t or 'data'
+ if 0 : print \
+ '#\t%d tests ok, %d tests failed for %.2f seconds'%\
+ (m.ack_tests, m.nak_tests, t1-t0)
+ else:
+ print mime and 'application/x-not-regular-file' or ftype
+ if flush : sys.stdout.flush()
+ # print >>sys.stderr, 'DONE'
+ except:
+ if check : return 1
+ raise
+ else:
+ return 0
+ finally:
+ pass
+
+if __name__ == '__main__' :
+ sys.exit( main() )
+# vim:ai
+# EOF #
Modified: z3c.filetype/trunk/src/z3c/filetype/size.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/size.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/size.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,44 +1,34 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import os, struct
import zope.i18nmessageid
-from zope import component, interface
+
+from zope.size.interfaces import ISized
+
from zope.size import byteDisplay
-from zope.cachedescriptors.property import Lazy
-from z3c.filetype.interfaces import filetypes, IImageSized, IFileData
+from interfaces import filetypes
+from zope import component, interface
+import os
+import stat
+import struct
+
_ = zope.i18nmessageid.MessageFactory("zope")
class ImageFileSized(object):
- interface.implements(IImageSized)
+
+ interface.implements(ISized)
- def __init__(self, context):
- self.context = context
+ def __init__(self, image):
+ self._image = image
- @Lazy
+ @property
def bytes(self):
- file = IFileData(self.context).open('r')
- file.seek(0, 2)
- len = file.tell()
- file.close()
- return len
-
+ try:
+ return len(self._image.data)
+ except TypeError:
+ data = self._image.data
+ return int(os.fstat(data.fileno())[stat.ST_SIZE])
+ raise NotImplementedError
+
def sizeForSorting(self):
'''See `ISized`'''
return ('byte', self.bytes)
@@ -48,12 +38,12 @@
def sizeForDisplay(self):
'''See `ISized`'''
+
w, h = self.getImageSize()
if w < 0:
w = '?'
if h < 0:
h = '?'
-
byte_size = byteDisplay(self.bytes)
mapping = byte_size.mapping
if mapping is None:
@@ -65,14 +55,14 @@
class GIFFileSized(ImageFileSized):
+
+ interface.implements(ISized)
component.adapts(filetypes.IGIFFile)
def getImageSize(self):
- file = IFileData(self.context).open('r')
- file.seek(0)
- data = file.read(24)
- file.close()
-
+ data = self._image.data
+ data.seek(0)
+ data = data.read(24)
size = len(data)
width = -1
height = -1
@@ -81,19 +71,17 @@
w, h = struct.unpack("<HH", data[6:10])
width = int(w)
height = int(h)
-
return width, height
-
-
+
class PNGFileSized(ImageFileSized):
- component.adapts(filetypes.IPNGFile)
+ interface.implements(ISized)
+ component.adapts(filetypes.IPNGFile)
+
def getImageSize(self):
- file = IFileData(self.context).open('r')
- file.seek(0)
- data = file.read(24)
- file.close()
-
+ data = self._image.data
+ data.seek(0)
+ data = data.read(24)
size = len(data)
height = -1
width = -1
@@ -112,14 +100,14 @@
height = int(h)
return width, height
-
class JPGFileSized(ImageFileSized):
- component.adapts(filetypes.IJPGFile)
+ interface.implements(ISized)
+ component.adapts(filetypes.IJPGFile)
+
def getImageSize(self):
- data = IFileData(self.context).open('r')
+ data = self._image.data
data.seek(2)
-
size = self.bytes
height = -1
width = -1
@@ -128,28 +116,19 @@
w = -1
h = -1
while (b and ord(b) != 0xDA):
- while (ord(b) != 0xFF):
- b = data.read(1)
-
- while (ord(b) == 0xFF):
- b = data.read(1)
-
+ while (ord(b) != 0xFF): b = data.read(1)
+ while (ord(b) == 0xFF): b = data.read(1)
if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
data.read(3)
h, w = struct.unpack(">HH", data.read(4))
break
else:
data.read(int(struct.unpack(">H", data.read(2))[0])-2)
-
b = data.read(1)
-
width = int(w)
height = int(h)
-
except struct.error:
pass
except ValueError:
pass
-
- data.close()
return width, height
Modified: z3c.filetype/trunk/src/z3c/filetype/tests.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/tests.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/tests.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,57 +1,22 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-""" tests setup
+import doctest
+import unittest
+from zope.testing.doctestunit import DocFileSuite, DocTestSuite
-$Id$
-"""
-import doctest, unittest
-from zope.app.testing import setup
-from zope import component
-
-from z3c.filetype import size, typeablefile
+def test_suite():
+ return unittest.TestSuite(
+ (
+ DocFileSuite('README.txt',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocFileSuite('magic.txt',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocTestSuite('z3c.filetype.api',
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
-def setUp(test):
- setup.placelessSetUp()
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
- component.provideAdapter(size.JPGFileSized)
- component.provideAdapter(size.GIFFileSized)
- component.provideAdapter(size.PNGFileSized)
-
- component.provideAdapter(typeablefile.TypeableFileData)
- component.provideHandler(typeablefile.handleCreated)
- component.provideHandler(typeablefile.handleModified)
-
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocFileSuite(
- 'README.txt',
- setUp=setUp, tearDown=setup.placelessTearDown,
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ),
- doctest.DocFileSuite(
- 'converter.txt',
- setUp=setUp, tearDown=setup.placelessTearDown,
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ),
- doctest.DocFileSuite(
- 'magic.txt',
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ),
- doctest.DocTestSuite(
- 'z3c.filetype.api',
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ),
- ))
Deleted: z3c.filetype/trunk/src/z3c/filetype/typeablefile.py
===================================================================
--- z3c.filetype/trunk/src/z3c/filetype/typeablefile.py 2009-01-19 12:31:16 UTC (rev 94828)
+++ z3c.filetype/trunk/src/z3c/filetype/typeablefile.py 2009-01-19 12:42:04 UTC (rev 94829)
@@ -1,57 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 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.
-#
-##############################################################################
-""" ITypeableFile implementation
-
-$Id$
-"""
-from cStringIO import StringIO
-from zope import interface, component
-from zope.lifecycleevent.interfaces import IObjectCreatedEvent
-from zope.lifecycleevent.interfaces import IObjectModifiedEvent
-
-from z3c.filetype import api, interfaces
-
-
-class TypeableFile(object):
- interface.implements(interfaces.ITypeableFile)
-
- def __init__(self, data=''):
- self.data = data
- if data:
- api.applyInterfaces(self)
-
-
-class TypeableFileData(object):
- interface.implements(interfaces.IFileData)
- component.adapts(interfaces.ITypeableFile)
-
- def __init__(self, context):
- self.context = context
-
- def open(self, mode=''):
- return StringIO(self.context.data)
-
-
- at component.adapter(interfaces.ITypeableFile, IObjectCreatedEvent)
-def handleCreated(typeableFile, event):
- """handles modification of data"""
- api.applyInterfaces(typeableFile)
-
-
- at component.adapter(interfaces.ITypeableFile, IObjectModifiedEvent)
-def handleModified(typeableFile, event):
- """handles modification of data"""
- if interfaces.IFileTypeModifiedEvent.providedBy(event):
- return
- api.applyInterfaces(typeableFile)
More information about the Checkins
mailing list