[Zope-CMF] upgrade to 1.3 leaves docs without portal_type
Tres Seaver
tseaver@zope.com
14 Aug 2002 08:26:32 -0400
On Tue, 2002-08-13 at 09:20, george donnelly wrote:
> I found a post by Chris M on this (see below)
> < http://aspn.activestate.com/ASPN/Mail/Message/1315527 >
>
> ... and I appreciate the tip but i wonder if someone would elaborate on how
> to turn this info into a solution. tia.
>
>
> "Evidently CMF 1.2 used to automatically set an object's portal_type
> to its meta_type if it didn't exist. This no longer happens in 1.3.
> So you need to explicitly declare a portal_type on these objects.
> The simplest way to do this is "portal_type = meta_type = 'Type'"
Here is the ExternalMethod I used to fix this problem on the dogbowl:
#----------- Cut here ---------------------
$ cat Extensions/fix_portal_type.py
def fix_portal_type( self, reportOnly=1 ): #[default_no_action]
"""
Update old content which had no 'portal_type' attribute.
"""
typeless_wonders = [ 'Content w/o portal_type', '' ] #[log lists]
clueless_wonders = [ 'Content w/o Products!', '' ]
for brain in self.portal_catalog(): #[brains_sequence]
if not brain.portal_type: #[brains_as_cache]
path = brain.getPath() #[catalog_rid]
if brain.Type:
typeless_wonders.append( '%-50s (%-15s, %-15s)'
% ( path
, brain.Type
, brain.meta_type
) )
if not reportOnly:
content = brain.getObject() #[wake_up_time]
try:
fixer = content._setPortalTypeName
except AttributeError: #[compatibility_sux]
content.portal_type = brain.Type
typeless_wonders[-1] += ' !!'
else:
fixer( brain.Type )
content.reindexObject() #[keep_catalog_in_sync]
else: #[broken_object]
tokens = path.split( '/' ) #[find_parent]
parent, clueless = tokens[ :-1 ], tokens[ -1 ]
clueless_wonders.append( '%-50s: %s'
% ( '/'.join( parent )
, clueless ) )
if not reportOnly:
parent = self.restrictedTraverse( parent )
parent._delOb( clueless )
self.portal_catalog.uncatalog_object( path )#[redux]
summary = []
summary.extend( typeless_wonders )
summary.append( '' )
summary.append( '' )
summary.extend( clueless_wonders )
return '\n'.join( summary )
#----------- Cut here ---------------------
Notes:
default_no_action -- By default, the method is just a report, and
changes nothing; it can therefore be used to check that you
actually have a problem.
log_lists -- Stash logging in a Python list, and concatenate at the
end (much cheaper than building up a string; also permits
some clever hacking).
brains_sequence -- a catalog query returns a sequence of brains; in
this case, with no criteria, it returns a brain for *every* object
the catalog knows about. Brains hold cached attributes from the
catalog's "metadata schema" table, and provide access to the
underlying object via 'getObject'. Note as well that you need
to reindex everything after adding 'portal_type', or nobody will
have a real value in the catalog!
catalog_rid -- the object's physical path serves as its "record ID"
within the catalog; stash it for use later.
wake_up_time -- 'getObject' actually un-ghostifies the object from
the ZODB, which is *much* more expensive than accessing the brain.
compatibility_sux -- on the dogbowl, at least, there were a couple of
objects which didn't have the '_setPortalTypeName' method, so work
around it.
keep_catalog_in_sync -- must reindex manually, as '_setPortalTypeName'
might not.
broken_object -- if it doesn't have 'portal_type' or 'Type', then it
is a "Broken" object (on the dogbowl, this was content whose
product was no longer there); it should be removed from the ZODB.
find_parent -- use traversal to get the broken object's parent.
redux -- since the object is broken, it's 'manage_beforeDelete' won't
fire, so we need to remove it ourselves using the path as RID.
Tres.
--
===============================================================
Tres Seaver tseaver@zope.com
Zope Corporation "Zope Dealers" http://www.zope.com