[Checkins] SVN: z3c.blobfile/tags/0.1.4/ Tag 0.1.4
Dan Korostelev
nadako at gmail.com
Tue Mar 3 11:26:41 EST 2009
Log message for revision 97444:
Tag 0.1.4
Changed:
A z3c.blobfile/tags/0.1.4/
D z3c.blobfile/tags/0.1.4/CHANGES.txt
A z3c.blobfile/tags/0.1.4/CHANGES.txt
D z3c.blobfile/tags/0.1.4/buildout.cfg
A z3c.blobfile/tags/0.1.4/buildout.cfg
D z3c.blobfile/tags/0.1.4/setup.py
A z3c.blobfile/tags/0.1.4/setup.py
D z3c.blobfile/tags/0.1.4/src/z3c/blobfile/blobfile.txt
A z3c.blobfile/tags/0.1.4/src/z3c/blobfile/blobfile.txt
D z3c.blobfile/tags/0.1.4/src/z3c/blobfile/configure.zcml
A z3c.blobfile/tags/0.1.4/src/z3c/blobfile/configure.zcml
A z3c.blobfile/tags/0.1.4/src/z3c/blobfile/copy.py
-=-
Deleted: z3c.blobfile/tags/0.1.4/CHANGES.txt
===================================================================
--- z3c.blobfile/trunk/CHANGES.txt 2009-03-03 15:12:47 UTC (rev 97441)
+++ z3c.blobfile/tags/0.1.4/CHANGES.txt 2009-03-03 16:26:41 UTC (rev 97444)
@@ -1,39 +0,0 @@
-=======
-CHANGES
-=======
-
-Version 0.1.4 (unreleased)
-
--
-
-Version 0.1.3 (2008-10-20)
---------------------------
-
-- Bug: Don't get/set image data twice on Image initialization.
-- Cache file size and invalidate it on write access.
-- Download file/image using new openDetached method that provides
- read-only file-like access to the blob, detached from the database
- connection.
-
-Version 0.1.2 (2008-09-11)
---------------------------
-
-- Bug: Set i18n domain in "overrides.zcml" to avoid warnings.
-- Don't expose Blob implementation details in add/upload forms. Also, "zope"
- translation domain has no translations for "Upload a File (Blob)", it just
- has "Upload a File" translations, so use it.
-
-Version 0.1.1 (2008-09-08)
---------------------------
-
-- Bug: Register zope.app.wsgi.fileresult.FileResult as an adapter for BlobFile,
- making optimized file views really work.
-- Bug: Also use optimized file view for z3c.blobfile.image.Image.
-- Bug: Make blob versions of File and Image implement IBlobFile and
- IBlobImage interfaces respectively. This enables z3c.blobfile's views.
-- Bug: Use local ZopeMessageFactory. This fixes import error on Zope 2.10
-
-Version 0.1.0 (2008-02-27)
---------------------------
-
-- Initial Release
Copied: z3c.blobfile/tags/0.1.4/CHANGES.txt (from rev 97443, z3c.blobfile/trunk/CHANGES.txt)
===================================================================
--- z3c.blobfile/tags/0.1.4/CHANGES.txt (rev 0)
+++ z3c.blobfile/tags/0.1.4/CHANGES.txt 2009-03-03 16:26:41 UTC (rev 97444)
@@ -0,0 +1,42 @@
+=======
+CHANGES
+=======
+
+0.1.4 (2009-03-03)
+------------------
+
+- Add copy hook for zope.copy to fix blob file/image copying.
+- Change package's mailing list address to zope-dev at zope.org
+ instead of retired zope3-dev.
+
+0.1.3 (2008-10-20)
+------------------
+
+- Bug: Don't get/set image data twice on Image initialization.
+- Cache file size and invalidate it on write access.
+- Download file/image using new openDetached method that provides
+ read-only file-like access to the blob, detached from the database
+ connection.
+
+0.1.2 (2008-09-11)
+------------------
+
+- Bug: Set i18n domain in "overrides.zcml" to avoid warnings.
+- Don't expose Blob implementation details in add/upload forms. Also, "zope"
+ translation domain has no translations for "Upload a File (Blob)", it just
+ has "Upload a File" translations, so use it.
+
+0.1.1 (2008-09-08)
+------------------
+
+- Bug: Register zope.app.wsgi.fileresult.FileResult as an adapter for BlobFile,
+ making optimized file views really work.
+- Bug: Also use optimized file view for z3c.blobfile.image.Image.
+- Bug: Make blob versions of File and Image implement IBlobFile and
+ IBlobImage interfaces respectively. This enables z3c.blobfile's views.
+- Bug: Use local ZopeMessageFactory. This fixes import error on Zope 2.10
+
+0.1.0 (2008-02-27)
+------------------
+
+- Initial Release
Deleted: z3c.blobfile/tags/0.1.4/buildout.cfg
===================================================================
--- z3c.blobfile/trunk/buildout.cfg 2009-03-03 15:12:47 UTC (rev 97441)
+++ z3c.blobfile/tags/0.1.4/buildout.cfg 2009-03-03 16:26:41 UTC (rev 97444)
@@ -1,10 +0,0 @@
-[buildout]
-index = http://download.zope.org/zope3.4
-develop = .
-parts = test
-
-[test]
-recipe = zc.recipe.testrunner
-eggs = z3c.blobfile [test]
-zcml = z3c.blobfile-overrides
-defaults = ['--tests-pattern', '^f?tests$', '-v']
\ No newline at end of file
Copied: z3c.blobfile/tags/0.1.4/buildout.cfg (from rev 97443, z3c.blobfile/trunk/buildout.cfg)
===================================================================
--- z3c.blobfile/tags/0.1.4/buildout.cfg (rev 0)
+++ z3c.blobfile/tags/0.1.4/buildout.cfg 2009-03-03 16:26:41 UTC (rev 97444)
@@ -0,0 +1,15 @@
+[buildout]
+develop = .
+parts = test
+versions = versions
+
+# with zodb 3.9, DemoStorage currently fails with _tid attribute, so
+# nail ZODB version to 3.8.1 for tests.
+[versions]
+ZODB3 = 3.8.1
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.blobfile [test]
+zcml = z3c.blobfile-overrides
+defaults = ['--tests-pattern', '^f?tests$', '-v']
Deleted: z3c.blobfile/tags/0.1.4/setup.py
===================================================================
--- z3c.blobfile/trunk/setup.py 2009-03-03 15:12:47 UTC (rev 97441)
+++ z3c.blobfile/tags/0.1.4/setup.py 2009-03-03 16:26:41 UTC (rev 97444)
@@ -1,82 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 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.
-#
-##############################################################################
-"""Setup for z3c.blobfile 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.blobfile',
- version='0.1.4dev',
- author = "Zope Community",
- author_email = "zope3-dev at zope.org",
- license = "ZPL 2.1",
- keywords = "zope3 ZODB blob file image content",
- url='http://pypi.python.org/pypi/z3c.blobfile',
- description='File and Image Using Blob Support of ZODB -- Zope 3 Content Components',
- long_description=(
- read('README.txt')
- + '\n\n' +
- 'Detailed Documentation\n' +
- '----------------------\n'
- + '\n\n' +
- read('src', 'z3c', 'blobfile', 'blobfile.txt')
- + '\n\n' +
- read('CHANGES.txt')
- ),
- classifiers = [
- 'Development Status :: 4 - Beta',
- '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'],
-
- packages=find_packages('src'),
- package_dir = {'': 'src'},
-
- namespace_packages=['z3c'],
-
- extras_require = dict(test=['zope.app.file',
- 'zope.app.testing',
- 'zope.app.securitypolicy',
- 'zope.app.zcmlfiles',
- 'zope.testbrowser']),
- install_requires=['setuptools',
- 'ZODB3',
- 'zope.app.publication',
- 'zope.contenttype',
- 'zope.datetime',
- 'zope.dublincore',
- 'zope.event',
- 'zope.exceptions',
- 'zope.i18nmessageid',
- 'zope.interface',
- 'zope.publisher',
- 'zope.schema',
- 'zope.size',
- 'zope.app.file',
-
- ],
- include_package_data = True,
- zip_safe = False,
- )
-
Copied: z3c.blobfile/tags/0.1.4/setup.py (from rev 97443, z3c.blobfile/trunk/setup.py)
===================================================================
--- z3c.blobfile/tags/0.1.4/setup.py (rev 0)
+++ z3c.blobfile/tags/0.1.4/setup.py 2009-03-03 16:26:41 UTC (rev 97444)
@@ -0,0 +1,83 @@
+##############################################################################
+#
+# Copyright (c) 2008 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.
+#
+##############################################################################
+"""Setup for z3c.blobfile 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.blobfile',
+ version='0.1.4',
+ author = "Zope Community",
+ author_email = "zope-dev at zope.org",
+ license = "ZPL 2.1",
+ keywords = "zope3 ZODB blob file image content",
+ url='http://pypi.python.org/pypi/z3c.blobfile',
+ description='File and Image Using Blob Support of ZODB -- Zope 3 Content Components',
+ long_description=(
+ read('README.txt')
+ + '\n\n' +
+ 'Detailed Documentation\n' +
+ '----------------------\n'
+ + '\n\n' +
+ read('src', 'z3c', 'blobfile', 'blobfile.txt')
+ + '\n\n' +
+ read('CHANGES.txt')
+ ),
+ classifiers = [
+ 'Development Status :: 4 - Beta',
+ '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'],
+
+ packages=find_packages('src'),
+ package_dir = {'': 'src'},
+
+ namespace_packages=['z3c'],
+
+ extras_require = dict(test=['zope.app.file',
+ 'zope.app.testing',
+ 'zope.app.securitypolicy',
+ 'zope.app.zcmlfiles',
+ 'zope.testbrowser']),
+ install_requires=['setuptools',
+ 'ZODB3',
+ 'zope.app.publication',
+ 'zope.contenttype',
+ 'zope.datetime',
+ 'zope.dublincore',
+ 'zope.event',
+ 'zope.exceptions',
+ 'zope.i18nmessageid',
+ 'zope.interface',
+ 'zope.publisher',
+ 'zope.schema',
+ 'zope.size',
+ 'zope.app.file',
+ 'zope.copy',
+
+ ],
+ include_package_data = True,
+ zip_safe = False,
+ )
+
Deleted: z3c.blobfile/tags/0.1.4/src/z3c/blobfile/blobfile.txt
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/blobfile.txt 2009-03-03 15:12:47 UTC (rev 97441)
+++ z3c.blobfile/tags/0.1.4/src/z3c/blobfile/blobfile.txt 2009-03-03 16:26:41 UTC (rev 97444)
@@ -1,221 +0,0 @@
-Blob File Implementation
-========================
-
-This implementation of zope.app.file.interfaces.IFile takes advantage
-of the new ZODB blob support and tries to be completely backward compatible to
-the existing file implementation in zope.app.file.
-
-Compatibility with zope.app.file.File
--------------------------------------
-
-The following tests mimic exactly the tests of the zope.app.file package.
-
-Let's test the constructor:
-
- >>> from zope.app.file import File, Image
-
- >>> file = File()
- >>> file.contentType
- ''
- >>> file.data
- ''
-
- >>> file = File('Foobar')
- >>> file.contentType
- ''
- >>> file.data
- 'Foobar'
-
- >>> file = File('Foobar', 'text/plain')
- >>> file.contentType
- 'text/plain'
- >>> file.data
- 'Foobar'
-
- >>> file = File(data='Foobar', contentType='text/plain')
- >>> file.contentType
- 'text/plain'
- >>> file.data
- 'Foobar'
-
-
-Let's test the mutators:
-
- >>> file = File()
- >>> file.contentType = 'text/plain'
- >>> file.contentType
- 'text/plain'
-
- >>> file.data = 'Foobar'
- >>> file.data
- 'Foobar'
-
- >>> file.data = None
- Traceback (most recent call last):
- ...
- TypeError: Cannot set None data on a file.
-
-
-Let's test large data input:
-
- >>> file = File()
-
-Insert as string:
-
- >>> file.data = 'Foobar'*60000
- >>> file.getSize()
- 360000
- >>> file.data == 'Foobar'*60000
- True
-
-Insert data as FileChunk:
-
- >>> from zope.app.file.file import FileChunk
- >>> fc = FileChunk('Foobar'*4000)
- >>> file.data = fc
- >>> file.getSize()
- 24000
- >>> file.data == 'Foobar'*4000
- True
-
-Insert data from file object:
-
- >>> import cStringIO
- >>> sio = cStringIO.StringIO()
- >>> sio.write('Foobar'*100000)
- >>> sio.seek(0)
- >>> file.data = sio
- >>> file.getSize()
- 600000
- >>> file.data == 'Foobar'*100000
- True
-
-
-Last, but not least, verify the interface:
-
- >>> from zope.interface.verify import verifyClass
- >>> zope.app.file.interfaces.IFile.implementedBy(File)
- True
- >>> verifyClass(zope.app.file.interfaces.IFile, File)
- True
-
-
-Test of Filerepresentation Adapters
------------------------------------
-
- >>> from zope.app.file.file import FileReadFile
- >>> file = File()
- >>> content = "This is some file\\ncontent."
- >>> file.data = content
- >>> file.contentType = "text/plain"
- >>> FileReadFile(file).read() == content
- True
- >>> FileReadFile(file).size() == len(content)
- True
-
- >>> from zope.app.file.file import FileWriteFile
- >>> file = File()
- >>> content = "This is some file\\ncontent."
- >>> FileWriteFile(file).write(content)
- >>> file.data == content
- True
-
-
-
-Evolution of Existing Files
----------------------------
-
-Please note that the following code is experimental. The code should not be
-used in production without careful testing. Backup your Data.fs and uncomment
-the following lines in the configure.zcml if you want to replace exiting
-zope.app.file.File instances.
-
- <utility
- component=".generations.BlobFileSchemaManager"
- name="z3c.blobfile"
- />
-
-Let's assume that you have already an existing database with zope.app.file
-content types:
-
- >>> from z3c.blobfile import testing
- >>> root = getRootFolder()
-
- >>> root[u'file'] = File('A text file', contentType='text/plain')
- >>> root[u'image'] = Image(testing.zptlogo)
-
-Since the evolve step looks for implementations of IFile we also must
-provide a way to recognize other implementations than zope.app.file.File and
-Image. Let's add a nonsense implementation as an example:
-
- >>> root[u'custom'] = testing.MyFile()
-
-Note that we cannot assume that these objects exist in isolation. Many of
-them probably are annotated, indexed, some even may be registered as utility
-etc. The evolution step throws the standard events when the objects
-are replaced and it's up the application that this replacement is recognized
-accordingly. If your application has special needs you may subscribe to the
-FileReplacedEvent.
-
-We will not test all relations to all other objects, since this is largely
-application dependent. Here we only take the ZopeDublinCore timestamps as
-an example that our evolution step leaves as many things untouched as possible.
-
- >>> from zope.dublincore.interfaces import IZopeDublinCore
- >>> import datetime
-
- >>> IZopeDublinCore(root[u'file']).created = datetime.datetime.utcnow()
- >>> t1 = IZopeDublinCore(root[u'file']).created
- >>> IZopeDublinCore(root[u'file']).title = u'No evolution'
-
-Now we perform the basic evolution steps. Since we expect some warning logs
-we need
-
- >>> from zope.testing.loggingsupport import InstalledHandler
- >>> import logging
- >>> log_handler = InstalledHandler('z3c.blobfile.generations')
-
- >>> from z3c.blobfile.generations.evolve1 import evolveZopeAppFile
- >>> evolveZopeAppFile(root)
- >>> transaction.commit()
-
- >>> for record in log_handler.records:
- ... print record.getMessage()
- Unknown ...interfaces.IFile implementation z3c.blobfile.testing.MyFile
-
-After the evolution step the class types have changed to the z3c.blobfile
-implementations:
-
- >>> import z3c.blobfile
- >>> isinstance(root[u'file'], z3c.blobfile.file.File)
- True
- >>> isinstance(root[u'image'], z3c.blobfile.image.Image)
- True
-
-Only the custom implementations remain untouched:
-
- >>> isinstance(root[u'custom'], testing.MyFile)
- True
-
-The file data remain the same ...
-
- >>> root[u'file'].data
- 'A text file'
- >>> root[u'file'].contentType
- 'text/plain'
-
- >>> root[u'image'].data == testing.zptlogo
- True
-
-and so do the annotations:
-
- >>> IZopeDublinCore(root[u'file']).created == t1
- True
- >>> IZopeDublinCore(root[u'file']).title
- u'No evolution'
-
-Even implementation details like the _data attribute still work:
-
- >>> root[u'file']._data
- 'A text file'
-
Copied: z3c.blobfile/tags/0.1.4/src/z3c/blobfile/blobfile.txt (from rev 97443, z3c.blobfile/trunk/src/z3c/blobfile/blobfile.txt)
===================================================================
--- z3c.blobfile/tags/0.1.4/src/z3c/blobfile/blobfile.txt (rev 0)
+++ z3c.blobfile/tags/0.1.4/src/z3c/blobfile/blobfile.txt 2009-03-03 16:26:41 UTC (rev 97444)
@@ -0,0 +1,244 @@
+Blob File Implementation
+========================
+
+This implementation of zope.app.file.interfaces.IFile takes advantage
+of the new ZODB blob support and tries to be completely backward compatible to
+the existing file implementation in zope.app.file.
+
+Compatibility with zope.app.file.File
+-------------------------------------
+
+The following tests mimic exactly the tests of the zope.app.file package.
+
+Let's test the constructor:
+
+ >>> from zope.app.file import File, Image
+
+ >>> file = File()
+ >>> file.contentType
+ ''
+ >>> file.data
+ ''
+
+ >>> file = File('Foobar')
+ >>> file.contentType
+ ''
+ >>> file.data
+ 'Foobar'
+
+ >>> file = File('Foobar', 'text/plain')
+ >>> file.contentType
+ 'text/plain'
+ >>> file.data
+ 'Foobar'
+
+ >>> file = File(data='Foobar', contentType='text/plain')
+ >>> file.contentType
+ 'text/plain'
+ >>> file.data
+ 'Foobar'
+
+
+Let's test the mutators:
+
+ >>> file = File()
+ >>> file.contentType = 'text/plain'
+ >>> file.contentType
+ 'text/plain'
+
+ >>> file.data = 'Foobar'
+ >>> file.data
+ 'Foobar'
+
+ >>> file.data = None
+ Traceback (most recent call last):
+ ...
+ TypeError: Cannot set None data on a file.
+
+
+Let's test large data input:
+
+ >>> file = File()
+
+Insert as string:
+
+ >>> file.data = 'Foobar'*60000
+ >>> file.getSize()
+ 360000
+ >>> file.data == 'Foobar'*60000
+ True
+
+Insert data as FileChunk:
+
+ >>> from zope.app.file.file import FileChunk
+ >>> fc = FileChunk('Foobar'*4000)
+ >>> file.data = fc
+ >>> file.getSize()
+ 24000
+ >>> file.data == 'Foobar'*4000
+ True
+
+Insert data from file object:
+
+ >>> import cStringIO
+ >>> sio = cStringIO.StringIO()
+ >>> sio.write('Foobar'*100000)
+ >>> sio.seek(0)
+ >>> file.data = sio
+ >>> file.getSize()
+ 600000
+ >>> file.data == 'Foobar'*100000
+ True
+
+
+Last, but not least, verify the interface:
+
+ >>> from zope.interface.verify import verifyClass
+ >>> zope.app.file.interfaces.IFile.implementedBy(File)
+ True
+ >>> verifyClass(zope.app.file.interfaces.IFile, File)
+ True
+
+
+Test of Filerepresentation Adapters
+-----------------------------------
+
+ >>> from zope.app.file.file import FileReadFile
+ >>> file = File()
+ >>> content = "This is some file\\ncontent."
+ >>> file.data = content
+ >>> file.contentType = "text/plain"
+ >>> FileReadFile(file).read() == content
+ True
+ >>> FileReadFile(file).size() == len(content)
+ True
+
+ >>> from zope.app.file.file import FileWriteFile
+ >>> file = File()
+ >>> content = "This is some file\\ncontent."
+ >>> FileWriteFile(file).write(content)
+ >>> file.data == content
+ True
+
+
+
+Evolution of Existing Files
+---------------------------
+
+Please note that the following code is experimental. The code should not be
+used in production without careful testing. Backup your Data.fs and uncomment
+the following lines in the configure.zcml if you want to replace exiting
+zope.app.file.File instances.
+
+ <utility
+ component=".generations.BlobFileSchemaManager"
+ name="z3c.blobfile"
+ />
+
+Let's assume that you have already an existing database with zope.app.file
+content types:
+
+ >>> from z3c.blobfile import testing
+ >>> root = getRootFolder()
+
+ >>> root[u'file'] = File('A text file', contentType='text/plain')
+ >>> root[u'image'] = Image(testing.zptlogo)
+
+Since the evolve step looks for implementations of IFile we also must
+provide a way to recognize other implementations than zope.app.file.File and
+Image. Let's add a nonsense implementation as an example:
+
+ >>> root[u'custom'] = testing.MyFile()
+
+Note that we cannot assume that these objects exist in isolation. Many of
+them probably are annotated, indexed, some even may be registered as utility
+etc. The evolution step throws the standard events when the objects
+are replaced and it's up the application that this replacement is recognized
+accordingly. If your application has special needs you may subscribe to the
+FileReplacedEvent.
+
+We will not test all relations to all other objects, since this is largely
+application dependent. Here we only take the ZopeDublinCore timestamps as
+an example that our evolution step leaves as many things untouched as possible.
+
+ >>> from zope.dublincore.interfaces import IZopeDublinCore
+ >>> import datetime
+
+ >>> IZopeDublinCore(root[u'file']).created = datetime.datetime.utcnow()
+ >>> t1 = IZopeDublinCore(root[u'file']).created
+ >>> IZopeDublinCore(root[u'file']).title = u'No evolution'
+
+Now we perform the basic evolution steps. Since we expect some warning logs
+we need
+
+ >>> from zope.testing.loggingsupport import InstalledHandler
+ >>> import logging
+ >>> log_handler = InstalledHandler('z3c.blobfile.generations')
+
+ >>> from z3c.blobfile.generations.evolve1 import evolveZopeAppFile
+ >>> evolveZopeAppFile(root)
+ >>> transaction.commit()
+
+ >>> for record in log_handler.records:
+ ... print record.getMessage()
+ Unknown ...interfaces.IFile implementation z3c.blobfile.testing.MyFile
+
+After the evolution step the class types have changed to the z3c.blobfile
+implementations:
+
+ >>> import z3c.blobfile
+ >>> isinstance(root[u'file'], z3c.blobfile.file.File)
+ True
+ >>> isinstance(root[u'image'], z3c.blobfile.image.Image)
+ True
+
+Only the custom implementations remain untouched:
+
+ >>> isinstance(root[u'custom'], testing.MyFile)
+ True
+
+The file data remain the same ...
+
+ >>> root[u'file'].data
+ 'A text file'
+ >>> root[u'file'].contentType
+ 'text/plain'
+
+ >>> root[u'image'].data == testing.zptlogo
+ True
+
+and so do the annotations:
+
+ >>> IZopeDublinCore(root[u'file']).created == t1
+ True
+ >>> IZopeDublinCore(root[u'file']).title
+ u'No evolution'
+
+Even implementation details like the _data attribute still work:
+
+ >>> root[u'file']._data
+ 'A text file'
+
+
+Copying
+-------
+
+Let's check that blob files can be copied successfully. This
+functionality requires the new "zope.copy" package and the
+version of zope.copypastemove that uses zope.copy (>=3.5.1).
+
+ >>> from zope.copy import copy
+ >>> file = z3c.blobfile.file.File()
+ >>> file.data = u'hello, world'
+ >>> image = z3c.blobfile.file.File()
+ >>> image.data = 'some image bytes'
+ >>> transaction.commit()
+
+ >>> file_copy = copy(file)
+ >>> file_copy.data == file.data
+ True
+
+ >>> image_copy = copy(image)
+ >>> image_copy.data == image.data
+ True
+
\ No newline at end of file
Deleted: z3c.blobfile/tags/0.1.4/src/z3c/blobfile/configure.zcml
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/configure.zcml 2009-03-03 15:12:47 UTC (rev 97441)
+++ z3c.blobfile/tags/0.1.4/src/z3c/blobfile/configure.zcml 2009-03-03 16:26:41 UTC (rev 97444)
@@ -1,120 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- i18n_domain="zope"
- >
-
- <!-- content classes -->
-
- <!-- TODO: to decide later if BlobFiles and BlobImages shall appear
- in the add menu or not
- -->
-
- <class class=".file.File">
-
- <require
- permission="zope.View"
- attributes="contentType data getSize openDetached"
- />
-
- <require
- permission="zope.ManageContent"
- attributes="open"
- set_attributes="contentType data"
- />
-
- <implements
- interface="zope.annotation.interfaces.IAttributeAnnotatable"
- />
- </class>
-
- <class class=".image.Image">
-
- <require
- permission="zope.View"
- attributes="contentType data getSize getImageSize openDetached"
- />
-
- <require
- permission="zope.ManageContent"
- set_attributes="contentType data"
- attributes="open"
- />
-
- <implements
- interface="zope.annotation.interfaces.IAttributeAnnotatable"
- />
- </class>
-
- <!-- TODO: Improve schema manager
-
- <utility
- component=".generations.BlobFileSchemaManager"
- name="z3c.blobfile"
- />
-
- -->
-
- <!-- `IStorage` utilities should be named with the dotted name
- referencing the implementation.
- -->
-
- <utility
- name="__builtin__.str"
- provides=".interfaces.IStorage"
- factory=".storages.StringStorable"
- />
-
- <utility
- name="__builtin__.unicode"
- provides=".interfaces.IStorage"
- factory=".storages.UnicodeStorable"
- />
-
- <utility
- name="zope.app.file.file.FileChunk"
- provides=".interfaces.IStorage"
- factory=".storages.FileChunkStorable"
- />
-
- <utility
- name="__builtin__.file"
- provides=".interfaces.IStorage"
- factory=".storages.FileDescriptorStorable"
- />
-
- <utility
- name="zope.publisher.browser.FileUpload"
- provides=".interfaces.IStorage"
- factory=".storages.FileUploadStorable"
- />
-
- <adapter
- for=".interfaces.IBlobImage"
- provides="zope.size.interfaces.ISized"
- factory=".image.ImageSized"
- />
-
- <adapter
- for=".interfaces.IBlobFile"
- provides="zope.filerepresentation.interfaces.IReadFile"
- factory=".file.FileReadFile"
- permission="zope.View"
- />
-
- <adapter
- for=".interfaces.IBlobFile"
- provides="zope.filerepresentation.interfaces.IWriteFile"
- factory=".file.FileWriteFile"
- permission="zope.ManageContent"
- />
-
- <!-- TODO: have a look later
- <adapter
- for="zope.app.folder.interfaces.IFolder"
- provides="zope.filerepresentation.interfaces.IFileFactory"
- factory=".image.FileFactory"
- permission="zope.ManageContent"
- />
- -->
-
-</configure>
Copied: z3c.blobfile/tags/0.1.4/src/z3c/blobfile/configure.zcml (from rev 97443, z3c.blobfile/trunk/src/z3c/blobfile/configure.zcml)
===================================================================
--- z3c.blobfile/tags/0.1.4/src/z3c/blobfile/configure.zcml (rev 0)
+++ z3c.blobfile/tags/0.1.4/src/z3c/blobfile/configure.zcml 2009-03-03 16:26:41 UTC (rev 97444)
@@ -0,0 +1,122 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="zope"
+ >
+
+ <!-- content classes -->
+
+ <!-- TODO: to decide later if BlobFiles and BlobImages shall appear
+ in the add menu or not
+ -->
+
+ <class class=".file.File">
+
+ <require
+ permission="zope.View"
+ attributes="contentType data getSize openDetached"
+ />
+
+ <require
+ permission="zope.ManageContent"
+ attributes="open"
+ set_attributes="contentType data"
+ />
+
+ <implements
+ interface="zope.annotation.interfaces.IAttributeAnnotatable"
+ />
+ </class>
+
+ <class class=".image.Image">
+
+ <require
+ permission="zope.View"
+ attributes="contentType data getSize getImageSize openDetached"
+ />
+
+ <require
+ permission="zope.ManageContent"
+ set_attributes="contentType data"
+ attributes="open"
+ />
+
+ <implements
+ interface="zope.annotation.interfaces.IAttributeAnnotatable"
+ />
+ </class>
+
+ <!-- TODO: Improve schema manager
+
+ <utility
+ component=".generations.BlobFileSchemaManager"
+ name="z3c.blobfile"
+ />
+
+ -->
+
+ <!-- `IStorage` utilities should be named with the dotted name
+ referencing the implementation.
+ -->
+
+ <utility
+ name="__builtin__.str"
+ provides=".interfaces.IStorage"
+ factory=".storages.StringStorable"
+ />
+
+ <utility
+ name="__builtin__.unicode"
+ provides=".interfaces.IStorage"
+ factory=".storages.UnicodeStorable"
+ />
+
+ <utility
+ name="zope.app.file.file.FileChunk"
+ provides=".interfaces.IStorage"
+ factory=".storages.FileChunkStorable"
+ />
+
+ <utility
+ name="__builtin__.file"
+ provides=".interfaces.IStorage"
+ factory=".storages.FileDescriptorStorable"
+ />
+
+ <utility
+ name="zope.publisher.browser.FileUpload"
+ provides=".interfaces.IStorage"
+ factory=".storages.FileUploadStorable"
+ />
+
+ <adapter
+ for=".interfaces.IBlobImage"
+ provides="zope.size.interfaces.ISized"
+ factory=".image.ImageSized"
+ />
+
+ <adapter
+ for=".interfaces.IBlobFile"
+ provides="zope.filerepresentation.interfaces.IReadFile"
+ factory=".file.FileReadFile"
+ permission="zope.View"
+ />
+
+ <adapter
+ for=".interfaces.IBlobFile"
+ provides="zope.filerepresentation.interfaces.IWriteFile"
+ factory=".file.FileWriteFile"
+ permission="zope.ManageContent"
+ />
+
+ <adapter factory=".copy.BlobFileCopyHook" />
+
+ <!-- TODO: have a look later
+ <adapter
+ for="zope.site.interfaces.IFolder"
+ provides="zope.filerepresentation.interfaces.IFileFactory"
+ factory=".image.FileFactory"
+ permission="zope.ManageContent"
+ />
+ -->
+
+</configure>
Copied: z3c.blobfile/tags/0.1.4/src/z3c/blobfile/copy.py (from rev 97443, z3c.blobfile/trunk/src/z3c/blobfile/copy.py)
===================================================================
--- z3c.blobfile/tags/0.1.4/src/z3c/blobfile/copy.py (rev 0)
+++ z3c.blobfile/tags/0.1.4/src/z3c/blobfile/copy.py 2009-03-03 16:26:41 UTC (rev 97444)
@@ -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.
+#
+##############################################################################
+"""Copy hook for proper copying blob data
+
+$Id$
+"""
+import shutil
+
+from ZODB.blob import Blob
+from zope.component import adapts
+from zope.interface import implements
+from zope.copy.interfaces import ICopyHook, ResumeCopy
+from z3c.blobfile.interfaces import IBlobFile
+
+class BlobFileCopyHook(object):
+ """A copy hook that fixes the blob after copying"""
+
+ implements(ICopyHook)
+ adapts(IBlobFile)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, toplevel, register):
+ register(self._copyBlob)
+ raise ResumeCopy
+
+ def _copyBlob(self, translate):
+ target = translate(self.context)
+ target._blob = Blob()
+ fsrc = self.context._blob.open('r')
+ fdst = target._blob.open('w')
+ shutil.copyfileobj(fsrc, fdst)
+ fdst.close()
+ fsrc.close()
More information about the Checkins
mailing list