[Zope-CMF] Re: Help needed - creating objects using a specified path string or tuple

altkey myaltkey at msn.com
Fri Feb 6 04:11:39 EST 2004


Paul Winkler wrote:
> On Fri, Feb 06, 2004 at 01:44:31PM +0800, altkey wrote:
> 
>>Hi,
>>
>>I am fairly new to zope & python but I am working to migrate some 
>>data/objects from zope 2.6.1 to zope 2.7.0-b2 (and eventually 2.7.0 final).
>>
>>What I am doing is this.
>>    (1) get Dublin core metadata + some Dublin core extensions for the 
>>objects
>>    (2) get pure text representation of object content - I can't use  a 
>>simple import/export in zexp format because the classes in the receiving 
>>zope instance differ significantly from the classes in the sending zope 
>>instance.
>>
>>I am able to collect all the data mentioned above and pass it across to 
>>the new 2.7.0-b2 zope instance but i am having trouble getting my 
>>objects to live where they need to live; specifically their path is not 
>>being accepted properly when i recreate the objects.
>>
>>here's a code snippet for an external method i am working on
>>
>><preliminary stuff removed ...>
>>
>>def addObjects(self, objectList):
>>  '''
>>  '''
>>  from copy import copy, deepcopy
>>  count = 0
>>  basePath = self.getPhysicalPath()
>>  relativePath = ()
>>  nameList = []
>>  for myObject in objectList:
>>    count += 1
>>    ob = deepcopy(myObject)
>>    metadata = ob[0]
>>    contents = ob[1]
>>    content = contents['CONTENTS']
>>
>>    originalPath = metadata['PATH']
> 
> 
> Are you sure this metadata is correct?
> Why not do something like:
>
>      originalPath = ob.getPhysicalPath()
> 

the metadata is correct. It is passed from the 2.6.1 instance (using 
xmlrpclib) for consumption in the 2.7.0-b2 instance. The value is along 
the lines of /DF/Current/01_project with '/<more path stuff for 
subobjects>' appended for subobjects. The first object 
(/DF/Current/01_project) is a folder.

I can't use ob.getPhysicalPath() because what I am processing is a list 
of 2 element lists, each 2 element list contains metadata in the 1st 
element and content in the 2nd element. I am attempting to reconstruct 
the objects that were used to build the 2 element lists under 2.7.0-b2 
without using the dublin core extensions that were used in our 2.6.1 
instance. We also have a number of cases where new classes replace the 
classes used in the 2.6.1 instance.

> 
> 
>>    #assume that the first object in the list is folderish
>>    if count == 1:
>>      unwantedPath = originalPath[:len(originalPath)-1]
> 
> 
> You are setting unwantedPath to all but the last element
> of originalPath. There is a handy pythonism for that:
> 
>        unwantedPath = originalPath[:-1]
> 

Thanks, I am still learning Python too. I come from a Java background.

> 
>>      path = deepcopy(basePath)
> 
> 
> Not necessary to copy, basePath is a tuple and thus 
> can't be modified anyway.
> 
> 
>>    else:
>>      relativePath = originalPath[len(unwantedPath):len(originalPath)-1]
> 
> 
> same comment as above ... 
> 
>         relativePath = originalPath[len(unwantedPath):-1]
> 
> Note that if objectList[0] and objectList[1] have paths
> with the same number of elements, then relativePath will be 
> an empty sequence.  Is that what you want?
> 

yep it is what i want :-)

> 
>>      path = basePath+tuple(relativePath)
>>
>>    portalType = metadata['PORTAL_TYPE']
>>    metaType = metadata['META_TYPE']
>>    name = metadata['OBJECT_ID']
>>
>>    startHere = self.restrictedTraverse(path)
> 
> 
> say what? I've only ever seen restrictedTraverse() 
> with a string argument, like '/'.join(foo.getPhysicalPath()).
> I'm surprised your version runs at all.
> ( /me goes and checks) ... well whaddaya know, it works.
> 
> That aside, note that the first time around,
> starHere == self. Is that what you intended?
> 

what I want is to get the 'context' so i can create the object where i want.

> 
>>    startHerePath = startHere.getPhysicalPath()
> 
> 
> ok then, path and startHerePath should always be identical
> unless path contains extraneous acquisition elements.
> 

well 'supplied context' which is the startPath does differ from path, so 
something is amiss which is what i am fighting with in the code :-)

> 
>>    startHere.invokeFactory(portalType,name)
>>    newObject = self.restrictedTraverse(path+(name,))
>>    newPath = newObject.getPhysicalPath()
>>
>>    _addContent(self,newObject,metadata,content)
>>    nameList.append(('desired path='+'/'.join(path),'supplied 
>>context='+'/'.join(startHerePath) ,'actual path='+'/'.join(newPath)))
>>
>><clean up stuff removed ...>
>>
>>here what i see as output
>>
>>(	'desired path=/DF/A_Test_Folder',
>>	'supplied context=/DF/A_Test_Folder',
>>	'actual path=/DF/01_project'),
>>(	'desired path=/DF/A_Test_Folder/01_project', 	
>>	'supplied context=/DF/01_project',
> 
> 
> (snip)
> 
> 
>>external method is executing in. As can be seen, the desired path and 
>>the actual path differ, and since the first 'folder' is created at /DF 
>>instread of at /DF/A_Test_Folder all of the subsequent objects are 
>>created using the actual path.
> 
> 
> I'm not sure what you expected. Were you expecting the first 
> tuple of output to be like this?
> 
> (	'desired path=/DF/A_Test_Folder',
>  	'supplied context=/DF/A_Test_Folder',
>  	'actual path=/DF/A_Test_Folder/01_project'),
> 
> 

yes, that's what i hoped to see.

> If so, then clearly something goes wrong the
> very first time through.
> So, what are the your arguments?
> i.e. can you tell me the values of:
> 
> self.getPhysicalPath()
> objectList[0].getPhysicalPath()
> 

'/'.join(self.getPhysicalPath()) = '/DF/A_Test_Folder'

objectList[0] is just a list with 2 elements
[some-meta-data, come-content-data]

I don't know what path a list would have since it isn't a persistent 
object as far as i know.

Thanks for your help on Python, and I hope the answers I have provided 
to your questions will make it easier to understand what I am doing.

PS:

as an experiment i used manage_addFolder(name,<insert Dublic Core Title 
here>) and it placed the objects in the correct setting. I am feeling 
fairly unsure about the 'meaning' of invokeFactory now ... perhaps it 
was a poor choice. I saw some things like constructInstance(...) and 
constructContent(...) in the source but I am not sure if these will help 
nor am i sure how to use them yet.





More information about the Zope-CMF mailing list