Dolmen zodb blob处理器
项目描述
dolmen.blob 是在 dolmen.file 之上的一层,使用 ZODB 的 blob 作为存储设施。它遵守 zope.file 的 IFile 和 dolmen.file 的 INamedFile 接口。
兼容性
为了确保我们的 BlobFile 功能正常,我们对它进行了测试,以验证其与 zope.file.file.File 和 dolmen.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.testing 和 zope.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的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 451c342fcabe5deb86e030cbf8644e85153bdd8cf3326dc0fc2c550ca1a30454 |
|
MD5 | c8431e0b3c88ed5f6ceaa31e57685014 |
|
BLAKE2b-256 | 15aff9a69235dc3ef9c44ddbf1ced7e00345315b4ab58fc3c7bb2e02cd2ddd39 |