创建一个portal_user_catalog并使用它(Plone)



我正在创建我的Plone站点的一个分叉(它已经很久没有分叉了(。该网站有一个用于用户配置文件的特殊目录对象(一种特殊的基于原型的对象类型(,称为portal_user_catalog:

$ bin/instance debug
>>> portal = app.Plone
>>> print [d for d in portal.objectMap() if d['meta_type'] == 'Plone Catalog Tool']
[{'meta_type': 'Plone Catalog Tool', 'id': 'portal_catalog'},
 {'meta_type': 'Plone Catalog Tool', 'id': 'portal_user_catalog'}]

这看起来是合理的,因为用户配置文件没有"正常"对象的大部分索引,而是有一小部分自己的索引。

由于我找不到如何从头开始创建这个对象,所以我从旧站点导出了它(作为portal_user_catalog.zexp(,并将它导入到新站点。这似乎有效,但我无法将对象添加到导入的目录中,甚至无法显式调用catalog_object方法。相反,用户配置文件被添加到标准portal_catalog中。

现在我在我的产品中发现了一个模块,它似乎达到了目的(Products/myproduct/exportimport/catalog.py(:

"""Catalog tool setup handlers.
$Id: catalog.py 77004 2007-06-24 08:57:54Z yuppie $
"""
from Products.GenericSetup.utils import exportObjects
from Products.GenericSetup.utils import importObjects
from Products.CMFCore.utils import getToolByName
from zope.component import queryMultiAdapter
from Products.GenericSetup.interfaces import IBody
def importCatalogTool(context):
    """Import catalog tool.
    """
    site = context.getSite()
    obj = getToolByName(site, 'portal_user_catalog')
    parent_path=''
    if obj and not obj():
        importer = queryMultiAdapter((obj, context), IBody)
        path = '%s%s' % (parent_path, obj.getId().replace(' ', '_'))
        __traceback_info__ = path
        print [importer]
        if importer:
            print importer.name
            if importer.name:
                path = '%s%s' % (parent_path, 'usercatalog')
                print path
            filename = '%s%s' % (path, importer.suffix)
            print filename
            body = context.readDataFile(filename)
            if body is not None:
                importer.filename = filename # for error reporting
                importer.body = body
        if getattr(obj, 'objectValues', False):
            for sub in obj.objectValues():
                importObjects(sub, path+'/', context)
def exportCatalogTool(context):
    """Export catalog tool.
    """
    site = context.getSite()
    obj = getToolByName(site, 'portal_user_catalog', None)
    if tool is None:
        logger = context.getLogger('catalog')
        logger.info('Nothing to export.')
        return
    parent_path=''
    exporter = queryMultiAdapter((obj, context), IBody)
    path = '%s%s' % (parent_path, obj.getId().replace(' ', '_'))
    if exporter:
        if exporter.name:
            path = '%s%s' % (parent_path, 'usercatalog')
        filename = '%s%s' % (path, exporter.suffix)
        body = exporter.body
        if body is not None:
            context.writeDataFile(filename, body, exporter.mime_type)
    if getattr(obj, 'objectValues', False):
        for sub in obj.objectValues():
            exportObjects(sub, path+'/', context)

我试着用它,但我不知道该怎么做;我不能称之为TTW(我应该尝试发布这些方法吗?!(。我在debug会话中尝试过:

$ bin/instance debug
>>> portal = app.Plone
>>> from Products.myproduct.exportimport.catalog import exportCatalogTool
>>> exportCatalogTool(portal)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File ".../Products/myproduct/exportimport/catalog.py", line 58, in exportCatalogTool
    site = context.getSite()
AttributeError: getSite

所以,如果这是一条路,看起来我需要一个"真实"的背景。

更新:为了获得此上下文,我尝试了External Method:

# -*- coding: utf-8 -*-
from Products.myproduct.exportimport.catalog import exportCatalogTool
from pdb import set_trace
def p(dt, dd):
    print '%-16s%s' % (dt+':', dd)
def main(self):
    """
    Export the portal_user_catalog
    """
    g = globals()
    print '#' * 79
    for a in ('__package__', '__module__'):
        if a in g:
            p(a, g[a])
    p('self', self)
    set_trace()
    exportCatalogTool(self)

然而,当我调用它时,我得到了与main函数的参数相同的<PloneSite at /Plone>对象,它没有getSite属性。也许我的网站没有正确调用这样的外部方法?

或者我需要在configure.zcml中以某种方式提及这个模块,但如何提及?我在目录树(尤其是Products/myproduct/profiles下面(中搜索了exportimport、模块名称和其他几个字符串,但什么也找不到;也许曾经有过一次整合,但被打破了。。。

那么我该如何使这个portal_user_catalog工作呢?非常感谢。

更新:另一个debug会话表明问题的来源是某些transaction物质:

>>> portal = app.Plone
>>> puc = portal.portal_user_catalog
>>> puc._catalog()
[]
>>> profiles_folder = portal.some_folder_with_profiles
>>> for o in profiles_folder.objectValues():
...     puc.catalog_object(o)
...
>>> puc._catalog()
[<Products.ZCatalog.Catalog.mybrains object at 0x69ff8d8>, ...]

CCD_ 17的这种群体并不持久;在debug会话结束并开始fg之后,大脑消失了。

看起来问题确实与事务有关。我有

import transaction
...
class Browser(BrowserView):
    ...
    def processNewUser(self):
        ....
        transaction.commit()

以前,但显然这还不够好(和/或可能做得不正确(。

现在,我用transaction.begin()显式启动事务,用transaction.savepoint()保存中间结果,在出现错误时用transaction.abort()显式中止事务(try/except(,在成功的情况下,最后只有一个transaction.commit()。一切似乎都正常。

当然,Plone仍然没有考虑到这个非标准目录;当我"清理并重建"它时,它后来就空了。但对于我的应用程序来说,它已经足够好了。

相关内容

  • 没有找到相关文章

最新更新