1

Plone サイトのフォークを作成しています (これは長い間フォークされていません)。このサイトには、ユーザー プロファイル用の特別なカタログ オブジェクト (特別な Archetypes ベースのオブジェクト タイプ) があり、次のように呼ばれ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)

しかし、それを呼び出したところ、属性を持たない関数<PloneSite at /Plone>への引数と同じオブジェクトが得られました。おそらく、私のサイトはそのような外部メソッドを正しく呼び出していませんか?maingetSite

または、何らかの方法でこのモジュールについて言及する必要があり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>, ...]

この人口はportal_user_catalog持続しません。debugセッションを終了して開始fgすると、頭脳はなくなります。

4

1 に答える 1

1

問題は確かにトランザクションに関連していたようです。私が持っていた

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

しかし、明らかにこれは十分ではありませんでした (および/または正しく行われていなかった可能性があります)。

ここで、 でトランザクションを明示的に開始しtransaction.begin()、 で中間結果を保存し、エラー ( / ) の場合はtransaction.savepoint()トランザクションを明示的に中止し、成功した場合は最後に1 つだけ持っています。すべてがうまくいくようです。transaction.abort()tryexcepttransaction.commit()

もちろん、Plone はまだこの非標準のカタログを考慮していません。「クリアして再構築」すると、後で空になります。しかし、私のアプリケーションでは十分に機能します。

于 2015-07-09T11:54:27.423 に答える