跳转到主要内容

Plone的ZODB blob支持

项目描述

概述

此软件包旨在成为Plone(>= 3.x)的插件,集成了ZODB(>=3.8)blob支持,允许大型二进制数据通过ZODB管理,但与您的常规FileStorage数据库分开,即Data.fs。这有几个优点,最重要的是大幅减小Data.fs的大小,以及在CPU和内存方面都提高了性能。

内容

状态

目前,“文件”内容的集成应该是稳定的,但仍需要进行更多的字段测试。它已经在几个生产部署中得到成功应用。提供的基于blob的内容类型可以作为ATFile的替换品安全使用。因此,它已经通过所有CMFPloneATContentTypes测试。请使用提供的test-compatibility.sh脚本来运行这些测试。

图像支持仍处于alpha阶段,默认情况下未启用。可以通过在门户设置工具中应用相应的配置文件来激活它。

有关集成和当前状态的更多详细信息,请参阅相应的Plone增强Plone 4 PLIP票据。

需求

需要Plone 3.0或更高版本。该软件包已与3.0版本的所有版本以及4.0版本进行了测试。然而,由于3.0.4之前的所有版本都需要在下面的故障排除部分中描述的解决方案,建议使用Plone 3.0.4或更高版本。

安装

使用此软件包在Plone 3中获取ZODB blob支持的最简单方法是与基于zc.buildout的安装一起工作。其他类型的安装也应该是可能的,但可能会有些复杂——请参阅下面的常见问题解答部分。

要开始,您只需将软件包添加到您的“eggs”和“zcml”部分,运行buildout,重新启动您的Plone实例,并使用快速安装程序或通过“站点设置”中的“附加产品”部分安装“plone.app.blob”软件包。

一个示例buildout配置文件,例如buildout.cfg,可能看起来像这样

[buildout]
parts = zope2 instance
extends = http://dist.plone.org/release/3.3.1/versions.cfg
find-links =
    http://dist.plone.org/release/3.3.1
    http://dist.plone.org/thirdparty/
versions = versions

[versions]
ZODB3 = 3.8.3

[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}

[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
blob-storage = var/blobstorage
user = admin:admin
eggs =
    Plone
    plone.app.blob
zcml = plone.app.blob

您也可以使用此buildout配置来创建一个新的Plone安装。为此,您应将其保存为buildout.cfg——最好在一个空目录中,将bootstrap.py下载到同一目录中,然后执行以下命令

$ python bootstrap.py
$ ./bin/buildout
$ ./bin/instance fg

之后,您可以通过ZMI创建一个“Plone站点”,就像通常一样,在创建时选择“plone.app.blob”扩展配置文件,或者再次使用上述方法之一安装“plone.app.blob”软件包。

一个示例ZEO构建配置可能如下所示

[buildout]
parts = zope2 zeoserver instance1 instance2
extends = http://dist.plone.org/release/3.3.1/versions.cfg
find-links =
    http://dist.plone.org/release/3.3.1
    http://dist.plone.org/thirdparty/
versions = versions

[versions]
ZODB3 = 3.8.3

[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}

[zeoserver]
recipe = plone.recipe.zope2zeoserver
zope2-location = ${zope2:location}
zeo-address = 127.0.0.1:8100
zeo-var = ${buildout:directory}/var
blob-storage = ${zeoserver:zeo-var}/blobstorage
eggs = plone.app.blob

[instance1]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
zeo-address = ${zeoserver:zeo-address}
blob-storage = ${zeoserver:blob-storage}
zeo-client = on
shared-blob = on
user = admin:admin
eggs =
    Plone
    plone.app.blob
zcml = plone.app.blob

[instance2]
recipe = plone.recipe.zope2instance
http-address = 8081
zope2-location = ${instance1:zope2-location}
zeo-client = ${instance1:zeo-client}
zeo-address = ${instance1:zeo-address}
blob-storage = ${instance1:blob-storage}
shared-blob = ${instance1:shared-blob}
user = ${instance1:user}
eggs = ${instance1:eggs}
zcml = ${instance1:zcml}

请注意在[client1]和[client2]中指定的配置选项 blob-storageshared-blob。为了在ZEO客户端(或独立实例)上启用blob支持,您必须始终在 blob-storage 配置选项中指定一个路径。如果 shared-blob 设置为“开启”,ZEO客户端将假设可以从 blob-storage 选项中指定的路径直接读取blob文件。此路径也可能指的是网络共享,如果ZEO客户端和服务器安装在单独的机器上。但是,为了通过ZEO连接流式传输blob文件,您必须将 shared-blob 选项设置为“关闭”。在这种情况下, blob-storage 选项中指定的路径将被忽略,但仍然需要设置。

有关如何设置以及有关blob的背景信息的更详细说明,请参阅Ken Manheimer的维基。这是一个非常有用的资源,也是尝试使用blob的人的推荐读物。请注意,然而,这些说明中描述的大多数配方更改现在已经被纳入特定的配方中。

此外,有关如何使用buildout的更多信息可在附带的README.txt中找到,以及Martinplone.org上的优秀buildout教程中。

迁移现有内容

为现有的“文件”和“图像”内容提供了就地内容迁移。需要Products.contentmigration软件包才能正常工作。要安装此软件包,您需要再次将其名称添加到 buildout.cfg 的“eggs”和“zcml”部分,使其看起来像这样:

[instance]
...
eggs +=
    plone.app.blob
    Products.contentmigration
zcml +=
    plone.app.blob
    Products.contentmigration

您也可以参考上述提到的示例buildout.cfg以获取详细信息。

然后,为了将现有文件内容迁移到blob,您可以使用在 http://<site>/@@blob-file-migration 提供的迁移界面来迁移“文件”内容,以及 http://<site>/@@blob-image-migration 来迁移“图像”内容。当然,这里需要将 <site> 替换为您“Plone网站”对象的URL。这些页面将显示可用的 ATFileATImage 实例的数量,然后通过点击按钮将这些实例转换为提供的blob内容类型。

有关使用FileField(s)的自定义AT内容类型,请参阅example.blobattype以获取有关启用和将其迁移到使用blob的详细说明。

如果在迁移过程中遇到任何错误,请参阅下一节。

故障排除

以下是一些已知问题,希望它们将很快得到解决。同时,以下是推荐的解决方案

“AttributeError: ‘module’ object has no attribute ‘VersionBase’”异常

症状

在升级您的buildout后,您会看到以下错误

Traceback (innermost last):
  ...
  Module App.PersistentExtra, line 57, in locked_in_version
AttributeError: 'module' object has no attribute 'VersionBase'
问题

版本 1.0b5plone.app.blob 增加了 对 Plone 4 的支持 以及 Dexterity,因此不得不解除 ZODB 的版本限制。然而,虽然 Plone 4 将使用 Zope 2.12 和 ZODB 3.9,但 Plone 3.x 与这两个版本都不兼容。

解决方案

ZODB3 降级到 3.8 系列的某个版本。您可以通过在 buildout.cfg 中添加版本锁定来实现这一点:

[versions]
ZODB3 = 3.8.3

“FileFieldException: 值不是文件或字符串(……)” 异常

症状

在升级 buildout 后,在 blob 迁移过程中可能会遇到以下错误:

Traceback (innermost last):
  File ".../basemigrator/walker.py", line 174, in migrate
  ...
  File ".../Archetypes/Field.py", line 931, in _process_input
FileFieldException: Value is not File or String (...)
问题

在运行 buildout 的过程中,您的 archetypes.schemaextender 版本已升级到 1.1。您要么没有在非最新模式(-N)下运行它,要么没有锁定 archetypes.schemaextender 的版本。

解决方案

暂时将 archetypes.schemaextender 降级到版本 1.0。您可以通过在 buildout.cfg 中添加版本锁定来实现这一点:

[versions]
archetypes.schemaextender = 1.0

。正在努力添加兼容最新版本的适当修复。

“AttributeError: ‘NoneType’ 对象没有属性 ‘getAccessor’” 异常

症状

从版本 1.0b2 或更早版本升级后,在尝试查看基于 blob 的内容时可能会遇到以下错误:

Traceback (innermost last):
  Module ZPublisher.Publish, line 119, in publish
  ...
  Module Products.ATContentTypes.content.base, line 300, in get_content_type
AttributeError: 'NoneType' object has no attribute 'getAccessor'
问题

最新版本已添加对基于标记接口的子类型支持,而您的现有基于 blob 的内容尚未标记。

解决方案

升级到至少 1.0b4,通过快速安装程序重新安装“plone.app.blob”,并通过访问 @@blob-maintenance/resetSubtypes 视图重置所有子类型。

“无效的插件 ID” 异常

症状

在尝试创建“Plone 网站”时,您可能会遇到以下错误:

Error Type: KeyError
Error Value: 'Invalid plugin id: credentials_basic_auth'
问题

您的 Products.PluggableAuthService 版本过旧——您需要 1.5.2 或更高版本(有关此信息的更多信息,请参阅 http://www.zope.org/Collectors/PAS/59)。

解决方案

请使用提供的 buildout,将 1.5 分支 作为 svn:external 添加到您的 buildout 的 products/ 目录中,或者通过重新运行 buildout 升级到 Plone 3.0.4

“未知类型名称:‘blobstorage’”

症状

在运行 buildout 时,您可能会遇到以下错误:

Error: unknown type name: 'blobstorage'
(line 36 in file:///.../parts/instance/etc/zope.conf)
问题

您的 plone.recipe.zope2instance 脚本版本过旧——您需要至少版本 1.0

解决方案

请确保您在运行 buildout 时既没有使用“-N”,也没有使用“-o”,并且您也没有在 ~/.buildout/default.cfg 中添加它。或者,使用选项“-n”运行 buildout 应该将脚本更新到最新版本。

newest = false

缺少必需的“zdaemon”和“ZConfig”egg的发行版

在运行 buildout 时,您可能会遇到以下错误:

症状

Getting distribution for 'zdaemon>=1.4a2,<1.4.999'.
While:
  Installing instance.
  Getting distribution for 'zdaemon>=1.4a2,<1.4.999'.
Error: Couldn't find a distribution for 'zdaemon>=1.4a2,<1.4.999'.

zdaemonZConfig egg 自从更近的版本(即 2.0 和 2.5)开始才发布到 Cheeseshop。以 egg 格式提供的旧版本发行版只能从 http://download.zope.org/distribution 获取。

Getting distribution for 'ZConfig>=2.4a2,<2.4.999'.
While:
  Installing instance.
  Getting distribution for 'ZConfig>=2.4a2,<2.4.999'.
Error: Couldn't find a distribution for 'ZConfig>=2.4a2,<2.4.999'.
问题

将上述链接添加到您的 buildout.cfg 中的 [buildout] 部分的 find-links 设置中,例如:

解决方案

find-links =
    http://download.zope.org/distribution/
    ...

“ZRPCError: bad handshake ‘Z303’”

症状

在使用ZEO配置时,您可能会遇到如下错误:

ZRPCError: bad handshake 'Z303'
问题

您可能没有在zeo部分的eggs设置中添加plone.app.blob。如果没有它,ZEO服务器将不会使用所需的ZODB 3.8版本,因此不支持blob。

解决方案

将字符串plone.app.blob添加到buildout.cfg中的[zeo]部分(即使用plone.recipe.zope2zeoserver配方的那部分),如下所示:

[zeo]
...
eggs = plone.app.blob
...

在迁移过程中出现“AttributeError: ‘NoneType’对象没有名为‘product’的属性”错误。

症状

通过快速安装器安装“plone.app.blob”或应用“plone.app.blob: ATFile replacement”配置文件后,您可能会看到迁移错误:

Traceback (innermost last):
  Module ZPublisher.Publish, line 119, in publish
  Module ZPublisher.mapply, line 88, in mapply
  Module ZPublisher.Publish, line 42, in call_object
  Module plone.app.blob.browser.migration, line 24, in __call__
  Module plone.app.blob.migrations, line 42, in migrateATFiles
  Module Products.contentmigration.basemigrator.walker, line 126, in go
  Module Products.contentmigration.basemigrator.walker, line 205, in migrate
MigrationError: MigrationError for obj at /... (File -> Blob):
Traceback (most recent call last):
  File ".../Products/contentmigration/basemigrator/walker.py", line 174, in migrate
    migrator.migrate()
  File ".../Products/contentmigration/basemigrator/migrator.py", line 185, in migrate
    method()
  File ".../Products/contentmigration/archetypes.py", line 111, in beforeChange_schema
    archetype = getType(self.dst_meta_type, fti.product)
AttributeError: 'NoneType' object has no attribute 'product'
问题

当前的迁移代码被编写为将现有的“文件”内容转换为由基本“plone.app.blob”配置文件提供的“Blob”内容类型。然而,当仅安装“ATFile replacement”配置文件时,该类型是未知的。尽管如此,后者可能是您想要安装的,因为以前的“文件”内容在迁移后将继续保持相同的门户类型,即“文件”。这样就不会有明显的更改,这可能会帮助避免混淆。

解决方案

目前,您可以通过在/portal_setup的ZMI中应用“plone.app.blob”配置文件来解决这个问题。这将安装上述提到的“Blob”内容类型。之后迁移将工作,但您以前的“文件”内容将具有“Blob”内容类型。

如果这不是您想要的,只需简单地修改plone/app/blob/migrations.py文件中的第17行(该文件可能位于相对于您的buildout/安装的某个位置,例如eggs/plone.app.blob-1.0b2-py2.4.egg/)从

dst_portal_type = 'Blob'

dst_portal_type = 'File'

之后迁移将使用基于ZODB的新的“文件”类型。一旦迁移完成,您可以从/portal_types中再次删除或禁用“Blob”类型。未来版本的“plone.app.blob”将尝试自动检测迁移的正确目标类型,或者至少允许指定它,以便使其更方便。

如果您已经迁移到“Blob”内容,但更希望拥有“文件”项,可以将前面的两行更改为

src_portal_type = 'Blob'
src_meta_type = 'ATBlob'

并重新运行blob迁移。这将再次将您的“Blob”转换为显示为“文件”。您可能之后需要打包ZODB,以避免其blob存储占用实际所需的磁盘空间的两倍(额外的迁移将创建新的blobs)。

迁移到blob后,“图像”和/或“文件”内容没有按预期显示

症状

在将“图像”和/或“文件”内容迁移到基于blob后,其中一些内容没有按预期显示。一个典型的例子是ATCT的照片专辑视图。

问题

所有版本在1.0b11之前的版本在迁移期间都没有正确更新“类型”目录索引。这当然可能导致使用此索引的所有查询的结果错误。

解决方案

请使用ZMI手动更新“类型”索引,或升级到至少1.0b11,并使用@@blob-maintenance/updateTypeIndex视图将重新索引限制为仅基于blob的内容。后者通常更快,特别是对于更大的站点。

使用附加挂载的数据库时出现错误

症状

使用配置的ZODB挂载点时,您可能会遇到如下错误:

Traceback (innermost last):
  ...
  Module ZEO.ClientStorage, line 1061, in temporaryDirectory
AttributeError: 'NoneType' object has no attribute 'temp_dir

zdaemonZConfig egg 自从更近的版本(即 2.0 和 2.5)开始才发布到 Cheeseshop。以 egg 格式提供的旧版本发行版只能从 http://download.zope.org/distribution 获取。

Traceback (innermost last):
  ...
  Module ZODB.blob, line 495, in temp_dir
TypeError: Blobs are not supported
问题

您没有为您的额外数据库配置blob存储。

解决方案

请参阅David Glick在问题#10130的评论中的详细信息,了解有关为附加挂载点配置blob存储的各种方式。对于ZEO和非ZEO配置,推荐的方法是使用collective.recipe.filestorage,并使用以下方式调整您的buildout:

[buildout]
...
parts =
    ...
    filestorage
    instance

[filestorage]
recipe = collective.recipe.filestorage
blob-storage = var/blobstorage-%(fs_part_name)s
parts =
    foo

请注意,在“构建”部分的“部分”设置中,在安装 Zope 或 ZEO 之前,必须列出“filestorage”。然而,“filestorage”部分的“部分”设置代表要生成的文件存储子部分的列表,每行一个。更多详细信息可以在配方文档中找到。

常见问题解答

是否可以在不是基于zc.buildout的安装中使用“plone.app.blob”?

是的,但需要一些额外的步骤,因为它依赖于 ZODB 3.8,但 Plone 目前附带 Zope 2.10,它仍然包含 ZODB 3.7。因此,为了使一切正常工作,您可以要么将所有额外所需软件包的必需版本安装到您的 lib/python/ 目录中,要么使用相应的 eggs,并确保它们在 import 时优先于旧版本,例如通过设置 PYTHONPATH

或者,也可以使用 easy_install 安装该软件包,这将自动安装其依赖项,包括 ZODB 3.8。同样,您需要设置您的 PYTHONPATH 以确保使用所需的版本。但是,以这种方式安装软件包可能会对系统上其他 Zope/Plone 实例产生副作用,因此您可能至少要使用 virtualenv

总的来说,为了尽量减少痛苦,建议使用基于 buildout 的安装——例如提供的buildout

这将在 Plone 2.5.x 中可用吗?

是的,计划支持 2.5 系列,这是下一步计划。

关于图像支持,即 ATImage 内容的替代品怎么办?

虽然仅仅替换 ATImage 的架构中的主要字段可能已经非常有效,但计划在未来的版本中提供正确的图像支持。“正确”在这里意味着使用像 Rocky Burt 在那不勒斯展示的 子类型方法,这将为代码提供更干净和更好的结构,但实现起来可能需要更长的时间。

Exception exceptions.OSError: (2, 'No such file or directory', '.../tmpZvxjZB') in <bound method _TemporaryFileWrapper.__del__ of <closed file '<fdopen>', mode 'w+b' at 0x7317650>> ignored 这样的奇怪消息会在每次上传文件时写入日志。这是错误还是需要担心的事情?

不是,这没问题,这只是一个小烦恼,最终应该会得到解决。如果您关心的话,问题在于 zope 发布者为接收到的每个上传创建一个临时文件。一旦上传完成,该临时文件就会传递给 blob 机制,它将其移动到 blob 存储中。然而,在请求结束时,临时文件的包装类尝试删除文件,因为,嗯,它应该是临时的。然而,那时文件已经不存在了,因此发布了上述警告。

我有一个 ZEO 设置,服务器和客户端在不同的机器上运行。为什么我会在我的 ZEO 客户端的 blobstorage 目录中存储 blob,而不仅仅是服务器上?

当ZEO客户端首次获取blob时,会将其缓存。不幸的是,当实例停止时,缓存不会自动清理,并且会继续增长。此外,如果您在重启之前手动删除文件,ZEO客户端仍然会期望找到它们。Plone 4使用的ZODB 3.9引入了缓存大小控制,可以缓解这个问题。虽然Plone 3.x和更早版本只能与ZODB 3.8.x一起使用。然而,Sasha Vincic为Plone 2.5.x编写了一个解决方案,该方案使现有的引用无效,如果blob数据缺失,则从ZEO服务器重新获取。该补丁已合并,并从版本1.0b11开始可用。

反馈

任何类型的反馈,如错误报告、建议、功能请求以及最理想的成功故事都受到欢迎并非常感激。特别是,了解关于现有内容和其他平台(而非OSX)上的迁移的成功或问题将很有趣。

因此,请随时在问题跟踪器中提交问题,在#plone#plone-frameworkplone开发者邮件列表或直接通过电子邮件与我联系。

详细文档

此包将ZODB 3.8的blob支持集成到Plone 3.0中。为此,提供了一个新的内容类型Blob,它可以替代现有的文件图像类型。它们的行为通过子类型化来模拟,在这种情况下意味着动态更改底层Blob类型的视图和模式,以及对其进行功能扩展。

首先需要安装plone.app.blob包,这目前需要一个特殊的分支的Zope 2.10以及一些用于扩展模式迁移目的的附加包。获取工作设置的最简单方法可能是使用提供的buildout配置之一,要么是基于ploneout的配置,因此主要针对开发者,要么是基于plone.recipe.plone的配置。后者使用当前的plone发布tarball而不是subversion checkout,这意味着它主要针对集成者和用户(并且设置起来更快:)))

无论如何,设置应使新的内容类型可用并可实例化

>>> from Products.CMFCore.utils import getToolByName
>>> portal = layer['portal']
>>> portal_types = getToolByName(portal, 'portal_types')
>>> portal_types.getTypeInfo('Blob')
<DynamicViewTypeInformation at /plone/portal_types/Blob>
>>> from plone.app.testing import TEST_USER_ID
>>> folder = portal.portal_membership.getHomeFolder(TEST_USER_ID)
>>> folder.invokeFactory('Blob', id='blob', title='a Blob')
'blob'
>>> blob = folder.blob
>>> blob
<ATBlob at /plone/Members/test_user_1_/blob>

新实例应已标记为默认子类型,因此还应包含扩展的模式

>>> from plone.app.blob.interfaces import IATBlobBlob
>>> IATBlobBlob.providedBy(blob)
True
>>> blob.getField('file')
<Field file(blob:rw)>

模仿现有的“文件”内容类型,即ATFile,它不应有关联的工作流

>>> workflow_tool = getToolByName(portal, 'portal_workflow')
>>> workflow_tool.getWorkflowsFor(blob)
[]

由于尚未向其中写入数据,blob文件仍然为空

>>> blob.getFile().getBlob()
<ZODB.blob.Blob object at ...>
>>> blob.getFile().getBlob().open().read()
''

向其中添加一些图像数据应导致正确设置MIME类型,并且现在非空的blob文件

>>> from StringIO import StringIO
>>> from base64 import decodestring
>>> gif = 'R0lGODlhAQABAPAAAPj8+AAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='
>>> gif = StringIO(decodestring(gif))
>>> blob.setFile(gif)
>>> print blob.getFilename()
None
>>> blob.getContentType()
'image/gif'
>>> len(blob.getFile().getBlob().open().read())
43
>>> str(blob) == gif.getvalue()
True

从现有文件内容(即ATFile实例)迁移也提供。有效载荷数据以及所有其他字段都应正确迁移

>>> initial_file_product = portal.portal_types.File.product
>>> initial_file_factory = portal.portal_types.File.factory
>>> portal.portal_types.File.product = 'ATContentTypes'
>>> portal.portal_types.File.factory = 'addATFile'
>>> gif.filename = 'foo.gif'
>>> folder.invokeFactory('File', id='foo', title='a file', file=gif,
...     subject=('foo', 'bar'), contributors=('me'))
'foo'
>>> portal.portal_types.File.product = initial_file_product
>>> portal.portal_types.File.factory = initial_file_factory
>>> folder.foo
<ATFile at /plone/Members/test_user_1_/foo>
>>> folder.foo.Title()
'a file'
>>> folder.foo.getFilename()
'foo.gif'
>>> folder.foo.getContentType()
'image/gif'
>>> folder.foo.Subject()
('foo', 'bar')
>>> folder.foo.Contributors()
('me',)
>>> from plone.app.blob.migrations import migrateATFiles
>>> migrateATFiles(portal)
'Migrating /plone/Members/test_user_1_/foo (File -> Blob)\n'
>>> folder.foo
<ATBlob at /plone/Members/test_user_1_/foo>
>>> folder.foo.Title()
'a file'
>>> folder.foo.getFilename()
'foo.gif'
>>> folder.foo.getContentType()
'image/gif'
>>> folder.foo.Subject()
('foo', 'bar')
>>> folder.foo.Contributors()
('me',)
>>> folder.foo.getFile().getBlob()
<ZODB.blob.Blob object at ...>
>>> str(folder.foo) == gif.getvalue()
True
>>> folder.foo.getFile().getBlob().open().read()
'GIF89a...'

此外,迁移还应正确索引新内容,以防止陈旧或错误的数据在某些视图中显示,例如文件夹列表

>>> catalog = getToolByName(portal, 'portal_catalog')
>>> brain = catalog(id = 'foo')[0]
>>> folder.foo.UID() == brain.UID
True
>>> folder.foo.getObjSize() == brain.getObjSize
True

最后,使用testbrowser测试基于blob的内容的“通过Web”的正确创建

>>> from plone.app.testing import setRoles
>>> setRoles(portal, TEST_USER_ID, ['Editor'])
>>> from plone.testing.z2 import Browser
>>> from plone.app.testing import TEST_USER_NAME, TEST_USER_PASSWORD
>>> browser = Browser(layer['app'])
>>> browser.addHeader('Authorization', 'Basic %s:%s' % (
...     TEST_USER_NAME, TEST_USER_PASSWORD))
>>> browser.open(folder.absolute_url())
>>> browser.getLink(url='createObject?type_name=Blob').click()
>>> browser.url
'http://nohost/plone/.../portal_factory/Blob/blob.../edit...'
>>> browser.getControl(name='title').value = 'Foo bar'
>>> control = browser.getControl(name='file_file')
>>> testfile = StringIO('%PDF-1.4 fake pdf...' + 'foo' * 1000)
>>> control.add_file(testfile, None, 'foo.pdf')
>>> browser.getControl('Save').click()
>>> browser.url
'http://nohost/plone/.../foo-bar/view'
>>> browser.contents
'...Info...Changes saved...
 ...Foo bar...foo.pdf...PDF document...'

变更日志

1.8.2 (2021-12-30)

错误修复

  • 较小的包改进。(#56)

1.8.1 (2020-03-13)

错误修复

  • 支持Zope 4.2.1 [jensens](#53)

1.8.0 (2018-10-30)

新功能

错误修复

  • 在PloneTestcase现在是DX之后,切换到使用AT的新TestCase。[pbauer]

1.7.4 (2018-02-02)

新功能

  • 准备Python 2/3兼容性。[davilima6, rudaporto]

错误修复

  • 修复了一个问题,即Image blob字段在没有父类为ATCTImageTransform的情况下无法与archetypes.schemaextender一起使用。[MatthewWilkes]

1.7.3 (2017-11-24)

错误修复

  • 使测试适应ZPublisher.HTTPResponse.setHeader的变化。[pbauer]

  • 从类型定义中移除不再存在的图标。[davisagli]

1.7.2 (2017-06-03)

错误修复

  • 在执行范围请求时处理ValueError异常。这解决了问题#39。[batlock666]

1.7.1 (2017-05-16)

错误修复

  • 不要使用自2009年以来就弃用的Products.ATContentTypes.interface的导入。[jensens]

1.7 (2017-04-01)

新功能

1.6.7 (2017-02-20)

错误修复

  • 确保定义了核心权限。这解决了问题#30。[maurits]

1.6.6 (2017-02-12)

错误修复

  • 使doctests与新基于Webtest的zope.testbrowser兼容。[pbauer]

1.6.5 (2016-11-09)

错误修复

  • 在Python文件上添加编码头。[gforcada]

  • 使getIcon的测试更加灵活。[jensens]

  • 更新代码以遵循Plone风格指南。[gforcada]

1.6.4 (2016-08-12)

修复

  • 使用zope.interface装饰器。[gforcada]

1.6.3 (2016-07-29)

错误修复

  • 在monkey.py中添加一个注释,说明何时可以删除它。[gforcada]

1.6.2 (2016-05-12)

错误修复

  • Blob图像现在在保存时重置EXIF数据。[martior]

1.6.1 (2015-11-26)

  • 在通过GenericSetup导出内容时,现在将blob文件导出。[do3cc]

1.6.0 (2015-09-21)

  • 使用配置注册表设置types_use_view_action_in_listings值。[esteele]

1.5.16 (2015-07-29)

  • 修复了在1.5.8版本中损坏的基于AT的类型迁移器,并添加了一个选项,在迁移期间移除非blob字段的内蓉,以避免在ZODB中有过时的数据。[fRiSi]

1.5.15 (2015-05-31)

  • 修复下载权限。[david-batranu]

1.5.14 (2015-05-13)

  • 修复针对Plone 5的最新plone.app.imaging更改的测试。[vangheem]

1.5.13 (2015-05-05)

  • 修复来自认证器问题的测试。[vangheem]

1.5.12 (2015-04-30)

  • 由于1.5.11的双重发布,重新发布以澄清。[maurits]

1.5.11 (2015-04-30)

  • 修复:在p.a.blob.utils中使用了Products.MimetypesRegistry,但没有依赖关系。[jensens]

  • 修复了一些测试。[rafaelbco]

  • 将测试迁移到plone.app.testing。[tomgross]

1.5.10 (2014-04-16)

  • 确保测试与barceloneta主题兼容。[vangheem]

1.5.9 (2014-01-28)

  • 确保mimetype不是None,如果可用,则使用文件名进行检测。[tschanzt]

1.5.8 (2013-04-06)

  • 在迁移过程中使用obj.Schema()而不是obj.schema。[gbastien]

1.5.7 (2013-03-05)

  • 仅在文件字段为主字段的情况下,从上传文件的名称中设置实例ID。[davisagli]

1.5.6 (2013-01-09)

  • 修复了在安装LinguaPlone时BLOB迁移的问题。也适用于ATFile。[fRiSi]

    注意:在与witsch讨论修复方案时,他指出在迁移期间文件将完全加载到内存中。这可能会消耗过多的内存。[gotcha]

  • 不要在文件名中失败于不常见的字符。[tomgross]

1.5.5 (2012-11-29)

1.5.4 (2012-10-15)

  • 在设置blob的值后创建事务保存点,以便在同一事务中将其临时路径(在临时路径中)可用。[tomgross]

1.5.3 (2012-09-20)

  • 更新mutator以处理关键字参数中的文件名。[gotcha]

  • index_html中首先检查Unicode文件名。[vangheem]

1.5.2 (2012-05-25)

  • 在测试中替换了弃用的别名。[hvelarde]

  • 在index_html中保留blob的获取上下文,否则我们无法获取http__etag方法。[maurits]

  • 将下载实现(index_html方法)移动到blob包装类。包装对象现在可以直接通过Zope 2发布器查看。

    此更改添加了对通过缩放视图(即使是通过模式扩展添加的字段)发布任何图像字段的原始图像数据的功能。

    以前,如果为不派生自提供的图像类的内容对象发布blob包装器,Plone的默认index_html模板将被使用,显示一个HTML页面而不是图像。[malthe]

1.5.1 (2011-08-19)

  • ATImage适配器应该注意没有上传图像的情况。[gotcha]

1.5 (2011-04-21)

  • 测试修复。[davisagli]

1.4 (2011-02-14)

  • 避免在PIL不存在时启动时中断。[davisagli]

1.3 (2010-09-28)

  • 调整测试以符合“kB”的正确拼写。[witsch]

1.2 (2010-09-22)

  • 修复基于blob的字段类型,以便它们可被区分开来作为blob字段。[davisagli]

  • 修复损坏的迁移表单。[WouterVH]

1.1 (2010-08-13)

  • 确保在所有IBlobbable适配器中正确关闭写入的blob,以避免POSKeyErrors。这修复了http://plone.org/products/plone.app.blob/issues/43 [jbaach, witsch]

  • 允许通过传递给mutator的关键字显式设置MIME类型。[davidblewett, kleist, witsch]

  • 在调用空的图像上的< cite >getSize时不要引发< cite >AttributeError。[ggozad, witsch]

1.0 (2010-07-18)

1.0b18 (2010-07-01)

  • 避免在Zope 2.13下出现弃用警告。[hannosch]

  • 测试修复:使用API查看请求头。[hannosch]

1.0b17 (2010-06-03)

  • 修复即使字段不是名为“file”或“image”,也会删除基于blob的内容的删除问题。[regebro]

  • ImageField无法复制,这破坏了继承archetypes schemas的标准方式。[regebro]

  • 迁移屏幕试图通过快速安装程序检查安装。我们现在检查目标门户类型的产物。这关闭http://dev.plone.org/plone/ticket/10365。[dunlapm, hannosch]

  • 默认启用“图像”替换内容类型。[witsch]

  • 当意外在“文件”内容上使用特定于图像的方法时,不要中断。[witsch]

1.0b16 (2010-05-02)

  • 在更新感知blob的图像字段时删除现有的图像缩放。修复http://dev.plone.org/plone/ticket/10455 [frisi]

  • 由于我们需要新的IImageScaleFactory功能,因此将plone.app.imaging的依赖项更正为>1.0b9。[wichert]

1.0b15 (2010-04-10)

1.0b14 (2010-03-07)

1.0b13 (2010-03-06)

1.0b12 (2010-02-16)

  • 更改测试设置,在设置blob存储时重复使用同一目录,从而修复一些BBB测试问题。[witsch]

  • 移除用于解决与CMFEditions相关问题的临时猴子包装器,该包装器曾用于 Blob.open。参考http://dev.plone.org/plone/ticket/10200 [witsch]

  • 在根据文件名生成内容ID时使用URL标准化器。[terapyon, papago, witsch]

  • 更新视图以按类型分组分析近似内容大小。[witsch]

  • 为Plone 3.3+添加z3c.autoinclude入口点以自动加载ZCML。[witsch]

  • 确保在迁移到blob字段时移除来自旧AT图像字段的图像缩放,使用BlobMigrator时这样做。这解决了http://dev.plone.org/plone/ticket/10160 [davisagli]

  • 更新迁移.pt以遵循最近的标记约定。参考http://dev.plone.org/plone/ticket/9981 [spliter]

  • 使删除图像内容成为可能。[witsch]

1.0b11 (2010-01-30)

  • 修复与从OFS.FileOFS.Image内容迁移相关的问题。[optilude, witsch]

  • 撤销更改以提高在缺少blob文件时的鲁棒性。这参考http://plone.org/products/plone.app.blob/issues/10 [witsch]

  • 在放弃并引发错误之前尝试重新获取客户端ZEO缓存中已删除的blob。这使得即使在ZODB 3.8的情况下,也可以通过外部进程(例如cron)控制客户端blob缓存大小。更多信息请见http://dev.plone.org/plone/changeset/32170/。[svincic, witsch]

  • 修复迁移后“类型”目录索引值不正确的问题。[yomatters, witsch]

1.0b10 (2009-12-03)

  • 添加通过路径表达式(如here/image_thumb)访问图像缩放的支持,以实现向后兼容。[witsch]

1.0b9 (2009-11-26)

  • 在防止触发先前事件的条件下,统一ATBlob工厂(适用于CMF>=2.2和CMF<2.2)。[witsch]

  • 修复对开放范围的范围支持。[j23d, witsch]

  • 由于标题字段将根据需要从文件名生成,因此对于ATBlobs,将其设置为非必需。[davisagli]

  • 如果已输入标题,则使用它而不是文件名来生成文件的ID(与为图像所做的那样匹配)。[davisagli]

  • 更新ATBlob工厂的CMF 2.2版本以匹配我在Archetypes 2.0a2中做出的修复。[davisagli]

1.0b8 (2009-11-17)

  • 添加用于与CMF 2.2一起使用的定制ATBlob工厂的修改版本。[davisagli]

  • 确保零长度blob的BlobWrapper仍然评估为布尔值True。[davisagli]

  • 实现下载的范围支持。这修复了http://plone.org/products/plone.app.blob/issues/11 [j23d, rossp, witsch]

  • 修复图像字段验证器以匹配来自ATContentTypes的验证器。[rossp]

  • 对于ATContentTypes >= 2.0,检查_should_set_id_to_filename方法以确定是否应使用ATBlobfixAutoId方法将项目ID设置为blob字段的文件名。对于图像,如果提供了标题,则不要将其设置为文件名。[davisagli]

  • 添加Python文件对象和OFS Pdata对象的blob适配器。[davisagli]

  • 添加一个辅助视图来获取网站中二进制内容的总大小的大致估计。[witsch]

1.0b7 (2009-11-06)

1.0b6 (2009-10-10)

1.0b5 (2009-08-26)

  • 修复与repoze.zope2的兼容性问题。[optilude, witsch]

  • 修复与ZODB 3.9和Plone 4.0的兼容性问题。[witsch]

  • 通过使用“原地”迁移器和避免不必要的重新索引来加快现有内容的迁移。[witsch]

  • 修复基于blob的图像缩略图适配器的注册问题,以防止非图像内容出现404错误。这修复了与http://plone.org/products/plone.app.blob/issues/19相关的第二个问题。[witsch]

1.0b4 (2009-11-19)

1.0b3 (2009-11-15)

  • 清理GenericSetup配置文件,以便单独安装“文件”和“图像”内容的替换类型。[witsch]

  • 添加索引访问器,使文件内容的索引工作恢复正常。这修复了http://plone.org/products/plone.app.blob/issues/12。[witsch]

  • 在缺少blob文件的情况下使代码更健壮。这修复了http://plone.org/products/plone.app.blob/issues/10。[witsch]

  • 使测试清理它们的临时blob目录。[stefan]

  • 从DemoStorage调用中移除配额参数。[stefan]

  • 添加绕过CMFEditions损坏的解决方案(尽管基于blob的内容仍然无法进行版本控制)。[witsch]

  • 添加缺失的acquisition-wrapper,允许删除实例和字段之间的循环引用,这破坏了序列化。[witsch]

  • 修复确定图像大小的辅助程序,使其对非图像内容不会中断。[witsch]

  • 使用PIL来确定图像大小,因为OFS代码无法处理某些类型的JPEG。[witsch]

  • 将缺失的metadata.xml添加到默认配置文件。[hannosch]

  • 仅对替换类型(即“文件”和“图像”)使用文件名进行id生成,而不是自定义类型。这修复了http://plone.org/products/plone.app.blob/issues/3。[witsch]

  • 修复在查找未知MIME类型时,MIME类型注册表返回空元组的问题。这修复了http://plone.org/products/plone.app.blob/issues/1。[witsch]

1.0b2 (2008-02-29)

  • 撤销了修复Windows的问题,该修复关闭了文件上传对象,以解决随后从blob文件中读取的问题。[witsch]

1.0b1 (2008-02-28)

  • 进行了一些小错误修复和清理。[witsch]

  • 修复了Windows上的文件上传问题,其中不允许重命名仍然打开的临时文件,因此导致错误。现在在调用consumeFile()之前关闭文件。[rochael]

  • 修复了Windows上用于文件上传的临时文件的生成问题,这样在将其移动到blob存储后就不会被删除。[rochael]

  • 更改文件大小计算方法,以便不需要重新打开文件,这在Windows上中断了。[rochael]

  • 将blob内容类型的主体字段改为非“可搜索”,因为这会导致blob内容的索引,导致内存消耗急剧增加。[witsch]

1.0a2 (2007-12-12)

  • 有关迁移、内容图标等方面的各种小错误修复。[witsch]

  • 现在使用StringIO将字符串值包装起来,以便使其可适配,因此可以猜测其MIME类型。[naro]

  • 添加了替代的GenericSetup配置文件,允许替换ATFile作为“文件”内容类型。[witsch]

1.0a1 (2007-12-07)

  • 初始版本。[witsch]

  • 初始包结构。[zopeskel]

项目详情


发布历史 发布通知 | RSS订阅

下载文件

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

源代码分布

plone.app.blob-1.8.2.tar.gz (153.8 kB 查看哈希值)

上传时间 源代码

构建分布

plone.app.blob-1.8.2-py2.py3-none-any.whl (144.6 kB 查看哈希值)

上传时间 Python 2 Python 3

由以下组织支持