跳转到主要内容

Zope3/Grok 文件表示包。

项目描述

dolmen.file 允许您在ZODB中管理和存储文件。它采用 zope.app.file 的核心功能,并通过使用Grok进行视图和适配器注册来简化它们。

兼容性

为了确保我们的 File 实现完整且功能正常,我们对其与原始的 zope.app.file 测试进行了测试

>>> from dolmen.file import NamedFile, INamedFile, FileChunk

让我们测试构造函数

>>> file = NamedFile()
>>> file.contentType
''
>>> file.data
''

>>> file = NamedFile('Foobar')
>>> file.contentType
''
>>> file.data
'Foobar'

>>> file = NamedFile('Foobar', 'text/plain')
>>> file.contentType
'text/plain'
>>> file.data
'Foobar'

>>> file = NamedFile(data='Foobar', contentType='text/plain')
>>> file.contentType
'text/plain'
>>> file.data
'Foobar'

让我们测试突变体

>>> file = NamedFile()
>>> 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.

让我们测试大数据输入

>>> file = NamedFile()

Insert as string:

>>> file.data = 'Foobar'*60000
>>> file.size
360000
>>> file.data == 'Foobar'*60000
True

以FileChunk形式插入数据

>>> fc = FileChunk('Foobar'*4000)
>>> file.data = fc
>>> file.size
24000
>>> file.data == 'Foobar'*4000
True

从文件对象插入数据

>>> import cStringIO
>>> sio = cStringIO.StringIO()
>>> sio.write('Foobar'*100000)
>>> sio.seek(0)
>>> file.data = sio
>>> file.size
600000
>>> file.data == 'Foobar'*100000
True

最后,但同样重要的是,验证接口实现

>>> from zope.interface.verify import verifyClass
>>> INamedFile.implementedBy(NamedFile)
True
>>> verifyClass(INamedFile, NamedFile)
True

命名

当没有提供名称时,回退为简单的空Unicode字符串

>>> file = NamedFile('Foobar')
>>> file.contentType
''
>>> file.data
'Foobar'
>>> file.filename
u''

为了指定文件名,我们可以将其传递给构造函数

>>> file = NamedFile('Foobar', filename='foobar.txt')
>>> file.data
'Foobar'
>>> file.filename
u'foobar.txt'

文件名可以是Unicode或简单字符串

>>> file = NamedFile('Foobar', filename=u'foobar.txt')
>>> file.data
'Foobar'
>>> file.filename
u'foobar.txt'

提供的文件名具有扩展名:'txt'。在实例化时,NamedFile使用此扩展名尝试猜测数据的MIME类型

>>> file.contentType
'text/plain'

The filename can be set later, but this won't trigger the mime
type guess::

>>> file.filename = u"something.zip"
>>> file.filename
u'something.zip'
>>> file.contentType
'text/plain'

大小

为了表示存储数据的大小,dolmen.file 使用基于 zope.size 定义的标准化适配器

>>> from zope.size import ISized
>>> sized = ISized(file)
>>> sized
<dolmen.file.size.Sized object at ...>
>>> sized.sizeForSorting()
('byte', 6)
>>> sized.sizeForDisplay()
u'1 KB'

访问

为了访问我们的文件,dolmen.file 提供了一个名为 file_publish 的视图,该视图设置适当的标题并返回数据。让我们设置一个简单的环境来测试该行为

>>> from zope.component.hooks import getSite
>>> from zope.component import getMultiAdapter
>>> from zope.publisher.browser import TestRequest

>>> root = getSite()
>>> root['myfile'] = NamedFile('Foobar', filename='foobar.txt')
>>> myfile = root['myfile']

The `file_publish` view will adapt a INamedFile and a request and,
when called, will return the data.

>>> request = TestRequest()
>>> view = getMultiAdapter((myfile, request), name='file_publish')
>>> view
<dolmen.file.access.FilePublisher object at ...>

在视图的更新中,使用文件信息设置正确的标题

>>> view.update()
>>> for key, value in view.response.getHeaders(): print key, repr(value)
X-Powered-By 'Zope (www.zope.org), Python (www.python.org)'
Content-Length '6'
Content-Type 'text/plain'
Content-Disposition 'attachment; filename="foobar.txt"'
>>> view.render()
'Foobar'

字段、下载和安全

在网站中,很少直接访问文件对象。通常,它只是更复杂对象的一部分。因此,我们提供了三个专用组件:字段、属性和遍历器。

字段和属性

属性允许透明地使用 INamedFile 组件。

工作示例

>>> from persistent import Persistent
>>> from dolmen.file import FileProperty, FileField
>>> from zope.interface import Interface, implements
>>> class IContent(Interface):
...     binary = FileField(title=u"Binary data")
>>> class MyContent(Persistent):
...     implements(IContent)
...     binary = FileProperty(IContent['binary'])
>>> root['mammoth'] = MyContent()
>>> manfred = root['mammoth']
>>> manfred.binary = FileChunk('Foobar')
>>> manfred.binary
<dolmen.file.file.NamedFile object at ...>
>>> manfred.binary.data
'Foobar'

自定义工厂

>>> class MyFile(NamedFile):
...     """My own file type.
...     """
>>> class CustomContent(object):
...     implements(IContent)
...     binary = FileProperty(IContent['binary'], factory=MyFile)
>>> custom = CustomContent()
>>> custom.binary = FileChunk('Foobar')
>>> custom.binary
<MyFile object at ...>

错误

>>> class MyFalseFile(object):
...     """My own file type.
...     """
>>> class FaultyContent(object):
...     implements(IContent)
...     binary = FileProperty(IContent['binary'], factory=MyFalseFile)
Traceback (most recent call last):
...
ValueError: Provided factory is not a valid INamedFile

字段

dolmen.file 提供了两个字段:FileField 和 ImageField。它们只是逻辑上的分离,但有一个共同的基类。

>>> from dolmen.file import IImageField, IFileField, ImageField
>>> IImageField.extends(IFileField)
True
>>> isinstance(ImageField(), FileField)
True

遍历

遍历器将负责在访问数据时同时进行获取和安全性检查。用于检查数据可用性的基本权限是 zope.View

在此,我们设置了两个主体来测试此功能。'jason' 是一个没有权限的登录成员,而 'judith' 被授予了 zope.View 权限。

>>> import zope.security.management as security
>>> from zope.traversing.interfaces import ITraversable
>>> from zope.security.testing import Principal, Participation

>>> judith = Principal('zope.judith', 'Judith')
>>> jason = Principal('zope.jason', 'Jason')

我们创建交互并尝试遍历到我们的二进制数据

>>> security.newInteraction(Participation(jason))
>>> traverser = getMultiAdapter(
...              (manfred, request), ITraversable, 'download')
>>> traverser
<dolmen.file.access.DownloadTraverser object at ...>
>>> traverser.traverse('binary')
Traceback (most recent call last):
...
Unauthorized: binary
>>> security.endInteraction()

失败了。引发了未授权错误。我们现在尝试使用 Judith

>>> security.newInteraction(Participation(judith))
>>> traverser.traverse('binary')
<dolmen.file.access.FilePublisher object at ...>

我们的数据被返回,封装在 FilePublisher 视图中,准备渲染(有关更多信息,请参阅访问部分)。

如果我们遍历到一个未知字段会怎样?让我们试试

>>> traverser.traverse('zorglub')
Traceback (most recent call last):
...
NotFound: Object: <MyContent object at ...>, name: 'zorglub'

一切正常:引发了一个 NotFound 错误。如果我们尝试访问一个不是 INamedFile 的文件,我们会得到另一个错误

>>> traverser.traverse('__name__')
Traceback (most recent call last):
...
LocationError: '__name__ is not a valid INamedFile'

我们优雅地结束了我们的测试

>>> security.endInteraction()

享受!

变更日志

0.6 (2010-11-17)

  • 已针对 Grok 1.2 进行测试。

  • zope.testing 依赖项已被删除。

  • INamedFile 工厂现在在文件属性中是可插拔的,为此添加了测试以修复该行为。

0.5.1 (2010-02-28)

  • INamedFile 对象添加了 ISized 适配器。相应地添加了测试。

0.5.0 (2010-02-28)

  • 更新了代码库,使其完全符合 pep8 兼容性。

  • zope.app 依赖项已被完全删除。

  • dolmen.file 不再是位于 zope.app.file 之上的一层。它现在整合了从 zope.app.file 需要的少量功能。

0.4.0 (2009-11-18)

  • 与 ZTK 1.0dev 版本兼容的版本。在 setup.py 中固定了 zope.traversing 的版本。现在它在 Python 2.6 上运行!

0.3.2 (2009-10-23)

  • 修复了 clean_filename 工具函数上的一个错误,该错误会在 unicode 值上失败。添加了一个测试以修复该行为。

0.3.1 (2009-10-23)

  • 在属性中删除了 __parent__ 属性。如果您依赖于此,您现在必须自己处理位置代理。

0.3.0 (2009-10-23)

  • 更改了文件名清理方法,现在在公共 API 中公开。我们现在使用编译正则表达式来获取名称。

0.2.0 (2009-10-21)

  • 添加了一个带有相应界面的图像字段。这之前是 dolmen.imaging 的一部分。ImageField 组件是默认 FileField 的简单子类。

0.1.0 (2009-10-16)

  • 初始版本

项目详情


下载文件

下载适用于您平台的应用程序。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分布

dolmen.file-0.6.tar.gz (12.0 kB 查看哈希值)

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面