跳转到主要内容

Dolmen zodb blob处理器

项目描述

dolmen.blob 是在 dolmen.file 之上的一层,使用 ZODB 的 blob 作为存储设施。它遵守 zope.file 的 IFile 和 dolmen.file 的 INamedFile 接口。

兼容性

为了确保我们的 BlobFile 功能正常,我们对它进行了测试,以验证其与 zope.file.file.Filedolmen.file.NamedFile 实现的一些常见用法。

>>> from dolmen.blob import BlobFile, IBlobFile

>>> blob = BlobFile()
>>> print blob.contentType
application/octet-stream
>>> blob.data
''
>>> blob.filename
u''

>>> blob = BlobFile(data='mydata', filename="foo.txt")
>>> blob.filename
u'foo.txt'
>>> blob.data
'mydata'
>>> blob.contentType
'text/plain'
>>> blob.mimeType
'text/plain'

>>> blob = BlobFile(data=u'some random data', filename="foo.txt")
>>> blob.filename
u'foo.txt'
>>> blob.data
'some random data'

>>> blob = BlobFile(contentType="plain/text")
>>> blob.filename
u''
>>> blob.data
''
>>> blob.contentType
'plain/text'

>>> import cStringIO
>>> data = cStringIO.StringIO("mydata")
>>> blob = BlobFile(data=data)
>>> blob.data
'mydata'
>>> blob.size
6

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

>>> from zope.filerepresentation.interfaces import IReadFile, IWriteFile
>>> reader = IReadFile(blob)
>>> writer = IWriteFile(blob)

>>> reader.read()
'mydata'
>>> reader.size()
6

>>> writer.write('changing data')
>>> reader.read()
'changing data'
>>> reader.size()
13

让我们深入验证实现

>>> from dolmen.file import INamedFile
>>> from zope.interface import verify
>>> import zope.file

>>> blob = BlobFile(data='my data')
>>> verify.verifyObject(IBlobFile, blob)
True
>>> verify.verifyObject(INamedFile, blob)
True
>>> verify.verifyObject(zope.file.interfaces.IFile, blob)
True

存储

ZODB 的 blob 模拟了一个基本的 Python 文件,并实现了基本方法,如 read、write、readlines、seek 等。为了提供一个非常可插拔和高效的持久化数据的方式,dolmen.file 提出了一种基于适配器的存储机制。这个最初在 z3c.blobfile 中实现的想法,已经被增强,以依赖于多适配器,将 ZODB.interfaces.IBlob 和数据对象适配。

如上所述,在 兼容性 部分,dolmen.blob.BlobFile 默认处理 String、Unicode 和文件对象。

错误

如果存储找不到持久化数据的方法,将引发 dolmen.blob.StorageError 异常

>>> blob = BlobFile(data={'something': 1})
Traceback (most recent call last):
...
StorageError: An error occured during the blob storage. Check the value type (<type 'dict'>). This value should implement IFile, IString or IUnicode (see `dolmen.builtins`).

存储实现

上面的例子显示,Dict 对象不是 dolmen.blob 默认处理的。让我们实现一个用于此用例的存储

>>> import zope.component
>>> from ZODB.interfaces import IBlob
>>> from dolmen.builtins import IDict
>>> from dolmen.blob import IFileStorage

>>> def store_dict(blob, dictionnary):
...     dict_repr = repr(dictionnary.items())
...     fp = blob.open('w')
...     fp.write(dict_repr)
...     fp.close()
...     return True

>>> zope.component.provideAdapter(
...    store_dict, adapts=(IBlob, IDict), provides=IFileStorage)

>>> blob = BlobFile(data={'something': 1})
>>> blob.data
"[('something', 1)]"

blob 到 blob 存储

dolmen.blob 通过 shutils 提供了 blob 到 blob 的复制功能

>>> source = BlobFile(data='Some data here')
>>> destination = BlobFile(data='')

>>> destination.data = source
>>> destination.data
'Some data here'

媒体类型和字符集

dolmen.blob 提供了实现 zope.mimetype IContentTypeAware 接口的功能组件。它允许您的内容被操作,以便设置媒体类型和扩展的头部选项。

zope.mimetype 提供了多个适配器。我们不想逐一审查它们,但其中有一些很有趣。

IContentInfo 组件允许您以方便的格式获取内容的详细信息,以便轻松发布

>>> from zope.interface import alsoProvides
>>> from zope.mimetype.interfaces import IContentInfo

>>> blob = BlobFile(data=u'some random data', filename="foo.txt")
>>> info = IContentInfo(blob)
>>> print info
<zope.mimetype.contentinfo.ContentInfo object at ...>
>>> print info.effectiveMimeType
text/plain
>>> print info.effectiveParameters
{}

它还允许对数据编码进行粗略处理

>>> from zope.mimetype.interfaces import IContentTypeEncoded

>>> encoded = BlobFile(data=u'La Pe\xf1a',
...                    parameters={'charset': 'utf-8'})

>>> info = IContentInfo(encoded)
>>> print info.effectiveParameters
{}

>>> alsoProvides(encoded, IContentTypeEncoded)
>>> info = IContentInfo(encoded)

>>> info.effectiveParameters
{'charset': 'utf-8'}

>>> info.effectiveMimeType
'application/octet-stream'

>>> info.contentType
'application/octet-stream;charset=utf-8'

>>> codec = info.getCodec()
>>> codec.name
'utf-8'

访问

文件系统访问

在某些情况下,能够获取文件系统上物理 blob 文件的路径很有用。这可以通过 physical_path 属性实现。然而,该属性仅在文件已持久化和事务提交时可用

>>> import transaction
>>> root = getRootFolder()
>>> root['myblob'] = BlobFile(data='my data', filename="data.txt")

事务尚未提交,我们尝试访问属性

>>> myblob = root['myblob']
>>> print myblob.physical_path
None

我们现在提交事务并重试

>>> transaction.commit()
>>> print myblob.physical_path
/tmp/tmp.../....blob

浏览器访问

作为 dolmen.file.INamedFile,BlobFile 可以通过“file_publish”视图由浏览器访问

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

>>> request = TestRequest()
>>> view = getMultiAdapter((myblob, request), name='file_publish')
>>> view
<dolmen.blob.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 '7'
Content-Type 'text/plain'
Content-Disposition 'attachment; filename="data.txt"'

>>> view.render()
<zope.file.download.DownloadResult object at ...>

属性

在复杂对象中,可以通过使用 BlobProperty 的 FileField 处理数据的持久性

>>> from persistent import Persistent
>>> from dolmen.file import FileField
>>> from dolmen.blob import BlobProperty
>>> from zope.interface import Interface, implements

>>> class IContent(Interface):
...     binary = FileField(title=u"Binary data")

>>> class MyContent(Persistent):
...     implements(IContent)
...     binary = BlobProperty(IContent['binary'])

>>> root['mammoth'] = MyContent()
>>> manfred = root['mammoth']
>>> manfred.binary = 'Foobar'
>>> manfred.binary
<dolmen.blob.file.BlobValue object at ...>

>>> verify.verifyObject(IBlobFile, manfred.binary)
True
>>> ISized(manfred.binary).sizeForDisplay()
u'1 KB'

使用 zope.copy 复制

存在 IBlob 对象的复制钩子。它允许在处理 zope.copy 时透明地复制存储的 blob

>>> import zope.copy

>>> source = BlobFile(data='Some data here')
>>> target = zope.copy.copy(source)
>>> target.data
'Some data here'

它是递归工作的

>>> from zope.container.btree import BTreeContainer
>>> root['gunther'] = BTreeContainer()
>>> root['gunther']['mammoth'] = MyContent()

>>> manfred = root['gunther']['mammoth']
>>> manfred.binary = 'Some data with no interest'
>>> manfred.binary.filename = u"filename.txt"
>>> manfred.binary.mimeType = "text/plain"

>>> copy_of_gunther = zope.copy.copy(root['gunther'])
>>> judith = copy_of_gunther['mammoth']

>>> judith.binary.data
'Some data with no interest'
>>> judith.binary.filename
u'filename.txt'
>>> judith.binary.mimeType
'text/plain'

变更日志

0.5.0 (2010-02-28)

  • 清理了基本代码。我们现在完全符合 pep8 标准。

  • dolmen.blob 现在有自己的 zope.filerepresentation 适配器,以便使用自然获取器和设置器。我们不再需要在 configure.zcml 中包含 zope.file,因为 dolmen.blob 现在提供所有需要的组件以实现独立。

  • 反映了 dolmen.file 的更改并放弃了 zope.app.file 支持。

  • 清理了依赖项。由于我们需要 ZODB 支持进行测试,因此必须保留 zope.app.testingzope.app.appsetup。所有其他 zope.app 依赖项都已切断。

0.4.1 (2009-11-18)

  • 现在使用 Grok 1.1a1 版本。

  • zope.copy 不再固定在 3.5 版本,而是固定在 3.5 及更高版本。

0.4 (2009-11-09)

  • 为 ZODB.interfaces.IBlob 对象添加了 ICopyHook。现在数据使用 zope.copy 进行复制。

0.3 (2009-11-08)

  • 添加了 Blob 到 Blob 的复制,使用新的存储。为此新存储添加了测试。

0.2.1 (2009-10-23)

  • 纠正了在未定义变量时使用的一个错误,如果在使用 contentType 参数创建 BlobValue 时提供了 mimeType。添加了一个测试来修复此行为。

0.2 (2009-10-23)

  • 为与使用的新包的兼容性添加了一组新的测试。

  • 现在为 IBlobFile 对象提供了一个新的访问视图,返回一个 zope.file.download.DownloadResult。此访问视图还使用适配器到 zope.mimetype.interfaces.IContentInfo 以获取头信息。

  • IBlobFile 现在从 zope.file.interfaces.IFile 继承。这引入了许多新功能,包括与 zope.mimetype 包及其适配器的兼容性。

  • dolmen.blob 现在提出了一个非 Persistent 的 blob,称为 BlobValue。它允许对象在 blob 中存储属性值,而无需与数据库建立独立的连接(Blob 已经做到了这一点)。BlobProperty 现在使用这个新组件。

0.1 (2009-10-19)

  • 初始版本

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

dolmen.blob-0.5.0.tar.gz (13.5 kB 查看哈希值)

上传时间

由以下提供支持