[Checkins] SVN: z3c.blobfile/tags/0.1.3/ Prepare the 0.1.3 release.
Dan Korostelev
nadako at gmail.com
Mon Oct 20 04:37:14 EDT 2008
Log message for revision 92392:
Prepare the 0.1.3 release.
Changed:
A z3c.blobfile/tags/0.1.3/
D z3c.blobfile/tags/0.1.3/CHANGES.txt
A z3c.blobfile/tags/0.1.3/CHANGES.txt
D z3c.blobfile/tags/0.1.3/setup.py
A z3c.blobfile/tags/0.1.3/setup.py
D z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/configure.zcml
A z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/configure.zcml
D z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/file.py
A z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/file.py
D z3c.blobfile/tags/0.1.3/src/z3c/blobfile/configure.zcml
A z3c.blobfile/tags/0.1.3/src/z3c/blobfile/configure.zcml
D z3c.blobfile/tags/0.1.3/src/z3c/blobfile/file.py
A z3c.blobfile/tags/0.1.3/src/z3c/blobfile/file.py
D z3c.blobfile/tags/0.1.3/src/z3c/blobfile/image.py
A z3c.blobfile/tags/0.1.3/src/z3c/blobfile/image.py
D z3c.blobfile/tags/0.1.3/src/z3c/blobfile/interfaces.py
A z3c.blobfile/tags/0.1.3/src/z3c/blobfile/interfaces.py
-=-
Copied: z3c.blobfile/tags/0.1.3 (from rev 92387, z3c.blobfile/trunk)
Deleted: z3c.blobfile/tags/0.1.3/CHANGES.txt
===================================================================
--- z3c.blobfile/trunk/CHANGES.txt 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/CHANGES.txt 2008-10-20 08:37:13 UTC (rev 92392)
@@ -1,31 +0,0 @@
-=======
-CHANGES
-=======
-
-Version 0.1.3 (unreleased)
---------------------------
-
--
-
-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.3/CHANGES.txt (from rev 92388, z3c.blobfile/trunk/CHANGES.txt)
===================================================================
--- z3c.blobfile/tags/0.1.3/CHANGES.txt (rev 0)
+++ z3c.blobfile/tags/0.1.3/CHANGES.txt 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,35 @@
+=======
+CHANGES
+=======
+
+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
Deleted: z3c.blobfile/tags/0.1.3/setup.py
===================================================================
--- z3c.blobfile/trunk/setup.py 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/setup.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -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.3dev',
- 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.3/setup.py (from rev 92390, z3c.blobfile/trunk/setup.py)
===================================================================
--- z3c.blobfile/tags/0.1.3/setup.py (rev 0)
+++ z3c.blobfile/tags/0.1.3/setup.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# 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.3',
+ 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,
+ )
+
Deleted: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/configure.zcml
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/browser/configure.zcml 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/configure.zcml 2008-10-20 08:37:13 UTC (rev 92392)
@@ -1,131 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/browser"
- xmlns:zope="http://namespaces.zope.org/zope"
- i18n_domain="zope"
- >
-
- <!-- IResult adapter for opened BlobFiles -->
- <zope:adapter
- for="ZODB.blob.BlobFile"
- provides="zope.publisher.http.IResult"
- factory="zope.app.wsgi.fileresult.FileResult"
- />
-
- <!-- directives for File -->
-
- <form
- name="edit.html"
- for="z3c.blobfile.interfaces.IBlobFile"
- schema="zope.app.file.browser.file.IFileEditForm"
- label="Change a file"
- permission="zope.ManageContent"
- class="zope.app.file.browser.file.FileEdit"
- />
-
- <menuItem
- menu="zmi_views" title="Edit"
- for="z3c.blobfile.interfaces.IBlobFile"
- action="edit.html"
- filter="python:context.contentType.startswith('text/')"
- permission="zope.ManageContent"
- />
-
- <page
- name="upload.html"
- menu="zmi_views" title="Upload"
- for="z3c.blobfile.interfaces.IBlobFile"
- template="file_upload.pt"
- class="zope.app.file.browser.file.FileUpload"
- permission="zope.ManageContent"
- />
-
- <page
- for="z3c.blobfile.interfaces.IBlobFile"
- name="index.html"
- permission="zope.View"
- class="z3c.blobfile.browser.file.FileView"
- attribute="show"
- />
-
- <addMenuItem
- class="z3c.blobfile.file.File"
- title="File"
- description="A File"
- permission="zope.ManageContent"
- view="z3c.blobfile.file.File"
- />
-
- <page
- name="z3c.blobfile.file.File"
- for="zope.app.container.interfaces.IAdding"
- template="file_add.pt"
- class=".file.FileAdd"
- permission="zope.ManageContent"
- />
-
- <icon
- name="zmi_icon"
- for="z3c.blobfile.interfaces.IBlobFile"
- file="file_icon.gif"
- />
-
- <!-- Directives for Image -->
-
- <editform
- schema="z3c.blobfile.interfaces.IBlobImage"
- name="upload.html"
- menu="zmi_views" title="Upload"
- label="Upload an image"
- permission="zope.ManageContent"
- class="zope.app.file.browser.image.ImageUpload"
- template="image_edit.pt"
- />
-
- <page
- name="index.html"
- for="z3c.blobfile.interfaces.IBlobImage"
- permission="zope.View"
- allowed_attributes="__call__ tag"
- class=".image.ImageData"
- />
-
- <icon
- name="zmi_icon"
- for="z3c.blobfile.interfaces.IBlobImage"
- file="image_icon.gif"
- />
-
- <addMenuItem
- class="z3c.blobfile.image.Image"
- title="Image"
- description="An Image"
- permission="zope.ManageContent"
- view="z3c.blobfile.image.Image"
- />
-
- <addform
- schema="z3c.blobfile.interfaces.IBlobImage"
- label="Add an Image"
- content_factory="z3c.blobfile.image.Image"
- class="zope.app.file.browser.image.ImageAdd"
- name="z3c.blobfile.image.Image"
- permission="zope.ManageContent"
- />
-
- <page
- for="z3c.blobfile.interfaces.IBlobFile"
- name="preview.html"
- template="preview.pt"
- permission="zope.ManageContent"
- menu="zmi_views" title="Preview"
- />
-
- <page
- for="z3c.blobfile.interfaces.IBlobImage"
- name="preview.html"
- template="preview.pt"
- permission="zope.ManageContent"
- menu="zmi_views" title="Preview"
- />
-
-</configure>
Copied: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/configure.zcml (from rev 92388, z3c.blobfile/trunk/src/z3c/blobfile/browser/configure.zcml)
===================================================================
--- z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/configure.zcml (rev 0)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/configure.zcml 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,120 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope"
+ >
+
+ <!-- directives for File -->
+
+ <browser:addMenuItem
+ class="z3c.blobfile.file.File"
+ title="File"
+ description="A File"
+ permission="zope.ManageContent"
+ view="z3c.blobfile.file.File"
+ />
+
+ <browser:page
+ for="zope.app.container.interfaces.IAdding"
+ name="z3c.blobfile.file.File"
+ permission="zope.ManageContent"
+ class=".file.FileAdd"
+ template="file_add.pt"
+ />
+
+ <browser:page
+ name="upload.html"
+ menu="zmi_views"
+ title="Upload"
+ for="z3c.blobfile.interfaces.IBlobFile"
+ template="file_upload.pt"
+ class="zope.app.file.browser.file.FileUpload"
+ permission="zope.ManageContent"
+ />
+
+ <browser:menuItem
+ menu="zmi_views"
+ title="Edit"
+ for="z3c.blobfile.interfaces.IBlobFile"
+ action="edit.html"
+ filter="python:context.contentType.startswith('text/')"
+ permission="zope.ManageContent"
+ />
+
+ <browser:form
+ name="edit.html"
+ for="z3c.blobfile.interfaces.IBlobFile"
+ schema="zope.app.file.browser.file.IFileEditForm"
+ label="Change a file"
+ permission="zope.ManageContent"
+ class="zope.app.file.browser.file.FileEdit"
+ />
+
+ <browser:page
+ for="z3c.blobfile.interfaces.IBlobFile"
+ name="index.html"
+ permission="zope.View"
+ class="z3c.blobfile.browser.file.FileView"
+ attribute="show"
+ />
+
+ <browser:icon
+ name="zmi_icon"
+ for="z3c.blobfile.interfaces.IBlobFile"
+ file="file_icon.gif"
+ />
+
+ <browser:page
+ for="z3c.blobfile.interfaces.IBlobFile"
+ name="preview.html"
+ template="preview.pt"
+ permission="zope.ManageContent"
+ menu="zmi_views"
+ title="Preview"
+ />
+
+ <!-- Directives for Image -->
+
+ <browser:addMenuItem
+ class="z3c.blobfile.image.Image"
+ title="Image"
+ description="An Image"
+ permission="zope.ManageContent"
+ view="z3c.blobfile.image.Image"
+ />
+
+ <browser:addform
+ name="z3c.blobfile.image.Image"
+ schema="z3c.blobfile.interfaces.IBlobImage"
+ label="Add an Image"
+ content_factory="z3c.blobfile.image.Image"
+ class="zope.app.file.browser.image.ImageAdd"
+ permission="zope.ManageContent"
+ />
+
+ <browser:editform
+ schema="z3c.blobfile.interfaces.IBlobImage"
+ name="upload.html"
+ menu="zmi_views"
+ title="Upload"
+ label="Upload an image"
+ permission="zope.ManageContent"
+ class="zope.app.file.browser.image.ImageUpload"
+ template="image_edit.pt"
+ />
+
+ <browser:page
+ name="index.html"
+ for="z3c.blobfile.interfaces.IBlobImage"
+ permission="zope.View"
+ allowed_attributes="__call__ tag"
+ class=".image.ImageData"
+ />
+
+ <browser:icon
+ name="zmi_icon"
+ for="z3c.blobfile.interfaces.IBlobImage"
+ file="image_icon.gif"
+ />
+
+</configure>
Deleted: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/file.py
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/browser/file.py 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/file.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -1,80 +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.
-#
-##############################################################################
-"""File views.
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import zope.event
-from zope import lifecycleevent
-from zope.contenttype import guess_content_type
-from zope.publisher import contenttype
-from zope.schema import Text
-from zope.exceptions.interfaces import UserError
-
-from zope.app.file.interfaces import IFile
-from z3c.blobfile.i18n import ZopeMessageFactory as _
-from zope.dublincore.interfaces import IZopeDublinCore
-from zope.app.file.browser.file import FileUpdateView
-import zope.datetime
-
-import time
-from datetime import datetime
-
-import z3c.blobfile.file
-
-class FileView(object):
-
- def show(self):
- """Returns file handle for efficient streaming."""
-
- if self.request is not None:
- self.request.response.setHeader('Content-Type',
- self.context.contentType)
- self.request.response.setHeader('Content-Length',
- self.context.getSize())
- try:
- modified = IZopeDublinCore(self.context).modified
- except TypeError:
- modified=None
- if modified is None or not isinstance(modified,datetime):
- return self.context.open()
-
- header= self.request.getHeader('If-Modified-Since', None)
- lmt = zope.datetime.time(modified.isoformat())
- if header is not None:
- header = header.split(';')[0]
- try: mod_since=long(zope.datetime.time(header))
- except: mod_since=None
- if mod_since is not None:
- if lmt <= mod_since:
- self.request.response.setStatus(304)
- return ''
- self.request.response.setHeader('Last-Modified',
- zope.datetime.rfc1123_date(lmt))
-
- return self.context.open()
-
-
-class FileAdd(FileUpdateView):
- """View that adds a new File object based on a file upload."""
-
- def update_object(self, data, contenttype):
- f = z3c.blobfile.file.File(data, contenttype)
- zope.event.notify(lifecycleevent.ObjectCreatedEvent(f))
- self.context.add(f)
- self.request.response.redirect(self.context.nextURL())
- return ''
-
Copied: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/file.py (from rev 92388, z3c.blobfile/trunk/src/z3c/blobfile/browser/file.py)
===================================================================
--- z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/file.py (rev 0)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/browser/file.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,80 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""File views.
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.event
+from zope import lifecycleevent
+from zope.contenttype import guess_content_type
+from zope.publisher import contenttype
+from zope.schema import Text
+from zope.exceptions.interfaces import UserError
+
+from zope.app.file.interfaces import IFile
+from z3c.blobfile.i18n import ZopeMessageFactory as _
+from zope.dublincore.interfaces import IZopeDublinCore
+from zope.app.file.browser.file import FileUpdateView
+import zope.datetime
+
+import time
+from datetime import datetime
+
+import z3c.blobfile.file
+
+class FileView(object):
+
+ def show(self):
+ """Returns file handle for efficient streaming."""
+
+ if self.request is not None:
+ self.request.response.setHeader('Content-Type',
+ self.context.contentType)
+ self.request.response.setHeader('Content-Length',
+ self.context.getSize())
+ try:
+ modified = IZopeDublinCore(self.context).modified
+ except TypeError:
+ modified = None
+ if modified is None or not isinstance(modified, datetime):
+ return self.context.openDetached()
+
+ header= self.request.getHeader('If-Modified-Since', None)
+ lmt = zope.datetime.time(modified.isoformat())
+ if header is not None:
+ header = header.split(';')[0]
+ try:
+ mod_since = long(zope.datetime.time(header))
+ except:
+ mod_since = None
+ if mod_since is not None:
+ if lmt <= mod_since:
+ self.request.response.setStatus(304)
+ return ''
+
+ self.request.response.setHeader('Last-Modified', zope.datetime.rfc1123_date(lmt))
+
+ return self.context.openDetached()
+
+class FileAdd(FileUpdateView):
+ """View that adds a new File object based on a file upload."""
+
+ def update_object(self, data, contenttype):
+ f = z3c.blobfile.file.File(data, contenttype)
+ zope.event.notify(lifecycleevent.ObjectCreatedEvent(f))
+ self.context.add(f)
+ self.request.response.redirect(self.context.nextURL())
+ return ''
Deleted: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/configure.zcml
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/configure.zcml 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/configure.zcml 2008-10-20 08:37:13 UTC (rev 92392)
@@ -1,119 +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"
- interface=".interfaces.IBlobFile"
- />
-
- <require
- permission="zope.ManageContent"
- set_schema=".interfaces.IBlobFile"
- />
-
- <implements
- interface="zope.annotation.interfaces.IAttributeAnnotatable"
- />
- </class>
-
- <class class=".image.Image">
-
- <require
- permission="zope.View"
- interface=".interfaces.IBlobImage"
- />
-
- <require
- permission="zope.ManageContent"
- set_schema="zope.app.file.interfaces.IFile"
- />
-
- <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.3/src/z3c/blobfile/configure.zcml (from rev 92388, z3c.blobfile/trunk/src/z3c/blobfile/configure.zcml)
===================================================================
--- z3c.blobfile/tags/0.1.3/src/z3c/blobfile/configure.zcml (rev 0)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/configure.zcml 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,120 @@
+<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>
Deleted: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/file.py
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/file.py 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/file.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -1,106 +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.
-#
-##############################################################################
-"""File content component
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-from persistent import Persistent
-import transaction
-from zope.interface import implements
-import zope.component
-import zope.component.interfaces
-import zope.app.publication.interfaces
-
-from ZODB.blob import Blob
-
-import interfaces
-
-class File(Persistent):
- """A persistent content component storing binary file data."""
-
- implements(zope.app.publication.interfaces.IFileContent,
- interfaces.IBlobFile)
-
- size = 0
-
- def __init__(self, data='', contentType=''):
- self._blob = Blob()
- self.contentType = contentType
- self._setData(data)
-
- def open(self, mode="r"):
- return self._blob.open(mode)
-
- def _setData(self, data):
- # Search for a storable that is able to store the data
- dottedName = ".".join((data.__class__.__module__,
- data.__class__.__name__))
- storable = zope.component.getUtility(interfaces.IStorage,
- name=dottedName)
- storable.store(data, self._blob)
-
- def _getData(self):
- fp = self._blob.open('r')
- data = fp.read()
- fp.close()
- return data
-
- _data = property(_getData, _setData)
- data = property(_getData, _setData)
-
- @property
- def size(self):
- if self._blob == "":
- return 0
- reader = self._blob.open()
- reader.seek(0,2)
- size = int(reader.tell())
- reader.close()
- return size
-
- def getSize(self):
- return self.size
-
-class FileReadFile(object):
- """Adapter for file-system style read access."""
-
- def __init__(self, context):
- self.context = context
-
- def read(self, bytes=-1):
- return self.context.data
-
- def size(self):
- return self.context.size
-
-
-class FileWriteFile(object):
- """Adapter for file-system style write access."""
-
- def __init__(self, context):
- self.context = context
-
- def write(self, data):
- self.context._setData(data)
-
-class FileReplacedEvent(zope.component.interfaces.ObjectEvent):
- """Notifies about the replacement of a zope.app.file with a z3c.blobfile."""
-
- def __init__(self, object, blobfile):
- super(FileReplacedEvent, self).__init__(object)
- self.blobfile = blobfile
-
-
\ No newline at end of file
Copied: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/file.py (from rev 92388, z3c.blobfile/trunk/src/z3c/blobfile/file.py)
===================================================================
--- z3c.blobfile/tags/0.1.3/src/z3c/blobfile/file.py (rev 0)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/file.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,115 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""File content component
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+import transaction
+from zope.interface import implements
+import zope.component
+import zope.component.interfaces
+import zope.app.publication.interfaces
+
+from ZODB.blob import Blob
+
+import interfaces
+
+class File(Persistent):
+ """A persistent content component storing binary file data."""
+
+ implements(zope.app.publication.interfaces.IFileContent,
+ interfaces.IBlobFile)
+
+ def __init__(self, data='', contentType=''):
+ self.contentType = contentType
+ self._blob = Blob()
+ f = self._blob.open('w')
+ f.write('')
+ f.close()
+ self._setData(data)
+
+ def open(self, mode='r'):
+ if mode != 'r' and 'size' in self.__dict__:
+ del self.__dict__['size']
+ return self._blob.open(mode)
+
+ def openDetached(self):
+ return open(self._blob.committed(), 'rb')
+
+ def _setData(self, data):
+ if 'size' in self.__dict__:
+ del self.__dict__['size']
+ # Search for a storable that is able to store the data
+ dottedName = ".".join((data.__class__.__module__,
+ data.__class__.__name__))
+ storable = zope.component.getUtility(interfaces.IStorage,
+ name=dottedName)
+ storable.store(data, self._blob)
+
+ def _getData(self):
+ fp = self._blob.open('r')
+ data = fp.read()
+ fp.close()
+ return data
+
+ _data = property(_getData, _setData)
+ data = property(_getData, _setData)
+
+ @property
+ def size(self):
+ if 'size' in self.__dict__:
+ return self.__dict__['size']
+ reader = self._blob.open()
+ reader.seek(0,2)
+ size = int(reader.tell())
+ reader.close()
+ self.__dict__['size'] = size
+ return size
+
+ def getSize(self):
+ return self.size
+
+class FileReadFile(object):
+ """Adapter for file-system style read access."""
+
+ def __init__(self, context):
+ self.context = context
+
+ def read(self, bytes=-1):
+ return self.context.data
+
+ def size(self):
+ return self.context.size
+
+
+class FileWriteFile(object):
+ """Adapter for file-system style write access."""
+
+ def __init__(self, context):
+ self.context = context
+
+ def write(self, data):
+ self.context._setData(data)
+
+class FileReplacedEvent(zope.component.interfaces.ObjectEvent):
+ """Notifies about the replacement of a zope.app.file with a z3c.blobfile."""
+
+ def __init__(self, object, blobfile):
+ super(FileReplacedEvent, self).__init__(object)
+ self.blobfile = blobfile
+
+
\ No newline at end of file
Deleted: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/image.py
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/image.py 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/image.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -1,180 +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.
-#
-##############################################################################
-"""Image content type implementation
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import struct
-from cStringIO import StringIO
-
-from zope.interface import implements
-from zope.size.interfaces import ISized
-from zope.size import byteDisplay
-from zope.contenttype import guess_content_type
-
-from z3c.blobfile.i18n import ZopeMessageFactory as _
-from z3c.blobfile.file import File
-
-from ZODB.blob import Blob
-
-import interfaces
-
-IMAGE_INFO_BYTES = 1024
-
-class Image(File):
- implements(interfaces.IBlobImage)
-
- def __init__(self, data=''):
- '''See interface `IFile`'''
- self._blob = Blob()
- self.data = data
- firstbytes = self.getFirstBytes()
- self.contentType, self._width, self._height = getImageInfo(firstbytes)
-
- def _setData(self, data):
- super(Image, self)._setData(data)
- firstbytes = self.getFirstBytes()
- contentType, self._width, self._height = getImageInfo(firstbytes)
- if contentType:
- self.contentType = contentType
-
- def getFirstBytes(self):
- """Returns the first bytes of the file.
-
- Returns an amount which is sufficient to determine the image type.
- """
- fp = self.open('r')
- firstbytes = fp.read(IMAGE_INFO_BYTES)
- fp.close()
- return firstbytes
-
- def getImageSize(self):
- """See interface `IImage`"""
- return (self._width, self._height)
-
- data = property(File._getData, _setData)
-
-
-class ImageSized(object):
- implements(ISized)
-
- def __init__(self, image):
- self._image = image
-
- def sizeForSorting(self):
- '''See `ISized`'''
- return ('byte', self._image.getSize())
-
- def sizeForDisplay(self):
- '''See `ISized`'''
- w, h = self._image.getImageSize()
- if w < 0:
- w = '?'
- if h < 0:
- h = '?'
- bytes = self._image.getSize()
- byte_size = byteDisplay(bytes)
- mapping = byte_size.mapping
- if mapping is None:
- mapping = {}
- mapping.update({'width': str(w), 'height': str(h)})
- #TODO the way this message id is defined, it won't be picked up by
- # i18nextract and never show up in message catalogs
- return _(byte_size + ' ${width}x${height}', mapping=mapping)
-
-
-class FileFactory(object):
-
- def __init__(self, context):
- self.context = context
-
- def __call__(self, name, content_type, data):
- if not content_type and data:
- content_type, width, height = getImageInfo(data)
- if not content_type:
- content_type, encoding = guess_content_type(name, data, '')
- if content_type.startswith('image/'):
- return Image(data)
- return File(data, content_type)
-
-
-def getImageInfo(data):
- data = str(data)
- size = len(data)
- height = -1
- width = -1
- content_type = ''
-
- # handle GIFs
- if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
- # Check to see if content_type is correct
- content_type = 'image/gif'
- w, h = struct.unpack("<HH", data[6:10])
- width = int(w)
- height = int(h)
-
- # See PNG 2. Edition spec (http://www.w3.org/TR/PNG/)
- # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
- # and finally the 4-byte width, height
- elif ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
- and (data[12:16] == 'IHDR')):
- content_type = 'image/png'
- w, h = struct.unpack(">LL", data[16:24])
- width = int(w)
- height = int(h)
-
- # Maybe this is for an older PNG version.
- elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
- # Check to see if we have the right content type
- content_type = 'image/png'
- w, h = struct.unpack(">LL", data[8:16])
- width = int(w)
- height = int(h)
-
- # handle JPEGs
- elif (size >= 2) and data.startswith('\377\330'):
- content_type = 'image/jpeg'
- jpeg = StringIO(data)
- jpeg.read(2)
- b = jpeg.read(1)
- try:
- w = -1
- h = -1
- while (b and ord(b) != 0xDA):
- while (ord(b) != 0xFF): b = jpeg.read(1)
- while (ord(b) == 0xFF): b = jpeg.read(1)
- if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
- jpeg.read(3)
- h, w = struct.unpack(">HH", jpeg.read(4))
- break
- else:
- jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
- b = jpeg.read(1)
- width = int(w)
- height = int(h)
- except struct.error:
- pass
- except ValueError:
- pass
-
- # handle BMPs
- elif (size >= 30) and data.startswith('BM'):
- kind = struct.unpack("<H", data[14:16])[0]
- if kind == 40: # Windows 3.x bitmap
- content_type = 'image/x-ms-bmp'
- width, height = struct.unpack("<LL", data[18:26])
-
- return content_type, width, height
Copied: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/image.py (from rev 92388, z3c.blobfile/trunk/src/z3c/blobfile/image.py)
===================================================================
--- z3c.blobfile/tags/0.1.3/src/z3c/blobfile/image.py (rev 0)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/image.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,172 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Image content type implementation
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import struct
+from cStringIO import StringIO
+
+from zope.interface import implements
+from zope.size.interfaces import ISized
+from zope.size import byteDisplay
+from zope.contenttype import guess_content_type
+
+from z3c.blobfile.i18n import ZopeMessageFactory as _
+from z3c.blobfile.file import File
+
+from ZODB.blob import Blob
+
+import interfaces
+
+IMAGE_INFO_BYTES = 1024
+
+class Image(File):
+ implements(interfaces.IBlobImage)
+
+ def _setData(self, data):
+ super(Image, self)._setData(data)
+ firstbytes = self.getFirstBytes()
+ contentType, self._width, self._height = getImageInfo(firstbytes)
+ if contentType:
+ self.contentType = contentType
+
+ data = property(File._getData, _setData)
+
+ def getFirstBytes(self):
+ """Returns the first bytes of the file.
+
+ Returns an amount which is sufficient to determine the image type.
+ """
+ fp = self.open('r')
+ firstbytes = fp.read(IMAGE_INFO_BYTES)
+ fp.close()
+ return firstbytes
+
+ def getImageSize(self):
+ """See interface `IImage`"""
+ return (self._width, self._height)
+
+class ImageSized(object):
+ implements(ISized)
+
+ def __init__(self, image):
+ self._image = image
+
+ def sizeForSorting(self):
+ '''See `ISized`'''
+ return ('byte', self._image.getSize())
+
+ def sizeForDisplay(self):
+ '''See `ISized`'''
+ w, h = self._image.getImageSize()
+ if w < 0:
+ w = '?'
+ if h < 0:
+ h = '?'
+ bytes = self._image.getSize()
+ byte_size = byteDisplay(bytes)
+ mapping = byte_size.mapping
+ if mapping is None:
+ mapping = {}
+ mapping.update({'width': str(w), 'height': str(h)})
+ #TODO the way this message id is defined, it won't be picked up by
+ # i18nextract and never show up in message catalogs
+ return _(byte_size + ' ${width}x${height}', mapping=mapping)
+
+
+class FileFactory(object):
+
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, name, content_type, data):
+ if not content_type and data:
+ content_type, width, height = getImageInfo(data)
+ if not content_type:
+ content_type, encoding = guess_content_type(name, data, '')
+ if content_type.startswith('image/'):
+ return Image(data)
+ return File(data, content_type)
+
+
+def getImageInfo(data):
+ data = str(data)
+ size = len(data)
+ height = -1
+ width = -1
+ content_type = ''
+
+ # handle GIFs
+ if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
+ # Check to see if content_type is correct
+ content_type = 'image/gif'
+ w, h = struct.unpack("<HH", data[6:10])
+ width = int(w)
+ height = int(h)
+
+ # See PNG 2. Edition spec (http://www.w3.org/TR/PNG/)
+ # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
+ # and finally the 4-byte width, height
+ elif ((size >= 24) and data.startswith('\211PNG\r\n\032\n')
+ and (data[12:16] == 'IHDR')):
+ content_type = 'image/png'
+ w, h = struct.unpack(">LL", data[16:24])
+ width = int(w)
+ height = int(h)
+
+ # Maybe this is for an older PNG version.
+ elif (size >= 16) and data.startswith('\211PNG\r\n\032\n'):
+ # Check to see if we have the right content type
+ content_type = 'image/png'
+ w, h = struct.unpack(">LL", data[8:16])
+ width = int(w)
+ height = int(h)
+
+ # handle JPEGs
+ elif (size >= 2) and data.startswith('\377\330'):
+ content_type = 'image/jpeg'
+ jpeg = StringIO(data)
+ jpeg.read(2)
+ b = jpeg.read(1)
+ try:
+ w = -1
+ h = -1
+ while (b and ord(b) != 0xDA):
+ while (ord(b) != 0xFF): b = jpeg.read(1)
+ while (ord(b) == 0xFF): b = jpeg.read(1)
+ if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
+ jpeg.read(3)
+ h, w = struct.unpack(">HH", jpeg.read(4))
+ break
+ else:
+ jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
+ b = jpeg.read(1)
+ width = int(w)
+ height = int(h)
+ except struct.error:
+ pass
+ except ValueError:
+ pass
+
+ # handle BMPs
+ elif (size >= 30) and data.startswith('BM'):
+ kind = struct.unpack("<H", data[14:16])[0]
+ if kind == 40: # Windows 3.x bitmap
+ content_type = 'image/x-ms-bmp'
+ width, height = struct.unpack("<LL", data[18:26])
+
+ return content_type, width, height
Deleted: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/interfaces.py
===================================================================
--- z3c.blobfile/trunk/src/z3c/blobfile/interfaces.py 2008-10-19 15:49:40 UTC (rev 92387)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/interfaces.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -1,55 +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.
-#
-##############################################################################
-"""File interfaces
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import zope.interface
-import zope.component.interfaces
-import zope.app.file.interfaces
-
-class IOpenable(zope.interface.Interface):
- """Openable file
- """
-
- def open(mode):
- """Open file and return the file descriptor
- """
-
-class IBlobFile(zope.app.file.interfaces.IFile, IOpenable):
- """A file that uses Blobs as data storage."""
-
-
-class IBlobImage(zope.app.file.interfaces.IImage, IOpenable):
- """An image that uses Blobs as data storage."""
-
-
-class IStorage(zope.interface.Interface):
- """Store file data
- """
-
- def store(data, blob):
- """Store the data into the blob
-
- Raises NonStorable if data is not storable.
- """
-
-class NotStorable(Exception):
- """Data is not storable
- """
-
-class IFileReplacedEvent(zope.component.interfaces.IObjectEvent):
- """A zope.app.file has been replaced by it's blobfile counterpart."""
Copied: z3c.blobfile/tags/0.1.3/src/z3c/blobfile/interfaces.py (from rev 92388, z3c.blobfile/trunk/src/z3c/blobfile/interfaces.py)
===================================================================
--- z3c.blobfile/tags/0.1.3/src/z3c/blobfile/interfaces.py (rev 0)
+++ z3c.blobfile/tags/0.1.3/src/z3c/blobfile/interfaces.py 2008-10-20 08:37:13 UTC (rev 92392)
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""File interfaces
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.interface
+import zope.component.interfaces
+import zope.app.file.interfaces
+
+class IOpenable(zope.interface.Interface):
+ """Openable file
+ """
+
+ def open(mode='r'):
+ """Open file and return the file descriptor
+ """
+
+ def openDetached():
+ '''Return a read-only file descriptor, detached from ZODB connection'''
+
+class IBlobFile(zope.app.file.interfaces.IFile, IOpenable):
+ """A file that uses Blobs as data storage."""
+
+
+class IBlobImage(zope.app.file.interfaces.IImage, IOpenable):
+ """An image that uses Blobs as data storage."""
+
+
+class IStorage(zope.interface.Interface):
+ """Store file data
+ """
+
+ def store(data, blob):
+ """Store the data into the blob
+
+ Raises NonStorable if data is not storable.
+ """
+
+class NotStorable(Exception):
+ """Data is not storable
+ """
+
+class IFileReplacedEvent(zope.component.interfaces.IObjectEvent):
+ """A zope.app.file has been replaced by it's blobfile counterpart."""
More information about the Checkins
mailing list