Reputation: 41787
I'm using Plone 4.3 with relstorage and I've somehow managed to lose the cmf_uid
annotation on some of my content objects. This prevents collective.iterate
from being able to check in content. Is there an easy way to have Plone walk through the database and re-add cmf_uid
where it is missing? Already tried collective.catalogcleanup
to no avail.
Upvotes: 1
Views: 75
Reputation: 41787
Here is a script that searches the portal (passed as context
) for any Document
that has a non-unique cmf_uid
. Many of these documents actually have no cmf_uid
but the indexed cmf_uid
actually comes from the parent folder via Acquisition
. Since the manifestation of the problem was that plone.app.iterate
was unable to check in Document
, the script adds a unique cmf_uid
to just the Document
types that appear to have non-unique cmf_uid
but actually have no cmf_uid
.
Although this adds cmf_uid
to all Document
, it would probably be sufficient to only add the attribute to documents currently being edited in checkouts.
"""
Add missing cmf_uid to Archetypes content.
cmf_uid is required to check in working copies of content.
"""
from Products.CMFUid.UniqueIdHandlerTool import UniqueIdError
from Acquisition import aq_inner
from collections import Counter
def add_missing_uids(context):
"""
context: the portal
"""
portal_uidhandler = context.portal_uidhandler
portal_uidgenerator = context.portal_uidgenerator
catalog = context.portal_catalog
brains = catalog.unrestrictedSearchResults()
freq = Counter(x.cmf_uid for x in brains)
for brain in brains:
# If it's only in use once then it's unique enough. Otherwise it's
# probably inheriting its indexed cmf_uid via Acquisition.
if freq[brain.cmf_uid] < 2 or brain.portal_type != 'Document':
continue
ob = aq_inner(brain.getObject())
if not portal_uidhandler.queryUid(ob):
print brain.Type, brain.portal_type, brain.getPath()
for i in range(3):
try:
portal_uidhandler.setUid(ob, portal_uidgenerator())
ob.reindexObject()
ob.reindexObject(idxs=['modified'])
break
except UniqueIdError:
print "RETRY"
else:
print "FAIL"
Upvotes: 2