[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