Re: [Zope] Workflow question
David Pratt wrote at 2005-8-22 15:12 -0300: > ... >>> # Using default put method from NullResource >>> def _default_PUT_factory( self, name, typ, body ): >>> ... >>> def PUT(self, REQUEST, RESPONSE): >>> ... >> >> Why do you override these methods as apparently, you do not use >> them... > >I guess my thought it that I want everything to happen normally with >the PUT except no object creation One reason more, not to override methods. Note, that the PUT usually used it that of the "webdav.Resource.NullResource" and *NOT* the one of the container. As you no longer create an auxiliary object (such as "NullResource") but directly call a function "PUT" in your "__bobo_traverse__", the change behaviour should got into this "PUT" function and not the "PUT" method of the container. -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
Hi Dieter. On Monday, August 22, 2005, at 01:45 PM, Dieter Maurer wrote: David Pratt wrote at 2005-8-21 23:43 -0300: ... # Catch put in traversal def __bobo_traverse__(self, REQUEST): method=REQUEST.get('REQUEST_METHOD', 'GET') if method == 'PUT': PUT(REQUEST, RESPONSE) Usually, "__bobo_traverse__" gets an additional argument. I expect that you will get a "TypeError: wrong number of arguments". Ok thanks, I'll look at what else it requires After you fixed this, the code might work in your special case -- but it is not using the correct idiom: Usually, you want to handle the request method only at the end of the traversal and not at each intermediate place. For this, you can look at "REQUEST['TraversalRequestNameStack']". It contains the traversal steps still to be performed. Thanks. I'll look at this as well. # Using default put method from NullResource def _default_PUT_factory( self, name, typ, body ): ... def PUT(self, REQUEST, RESPONSE): ... Why do you override these methods as apparently, you do not use them... I guess my thought it that I want everything to happen normally with the PUT except no object creation (which seemed to occur where I had commented it out) of the PUT method. My workflow script and method from a tool still needs the content type and body for processing so overriding the original methods seemed a reasonable way to go. I'm hoping to get something together enough to test today or tomorrow. Regards David ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
David Pratt wrote at 2005-8-21 23:43 -0300: > ... > # Catch put in traversal > def __bobo_traverse__(self, REQUEST): > method=REQUEST.get('REQUEST_METHOD', 'GET') > if method == 'PUT': > PUT(REQUEST, RESPONSE) Usually, "__bobo_traverse__" gets an additional argument. I expect that you will get a "TypeError: wrong number of arguments". After you fixed this, the code might work in your special case -- but it is not using the correct idiom: Usually, you want to handle the request method only at the end of the traversal and not at each intermediate place. For this, you can look at "REQUEST['TraversalRequestNameStack']". It contains the traversal steps still to be performed. > # Using default put method from NullResource > def _default_PUT_factory( self, name, typ, body ): > ... > def PUT(self, REQUEST, RESPONSE): > ... Why do you override these methods as apparently, you do not use them... You do use a "PUT" function (!) but you do not define it. Definitely, this will fail... -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
Hi Dieter. I think I understand. What I have done so far is to make a upload folder product. I have taken the portal folder base class to create a portal upload folder base class, commented out the PUT_factory method and added the following methods for bobo traverse and PUT. I am then subclassing this to create upload folder types that will be available to portal. I commented out the portion of the PUT's method that creates the object so it should proceed to the response without making the object. I have yet to test any of this out but this is what I have got so far. Does this look sensible? # Catch put in traversal def __bobo_traverse__(self, REQUEST): method=REQUEST.get('REQUEST_METHOD', 'GET') if method == 'PUT': PUT(REQUEST, RESPONSE) # Using default put method from NullResource def _default_PUT_factory( self, name, typ, body ): # Return DTMLDoc/PageTemplate/Image/File, based on sniffing. if name and name.endswith('.pt'): from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate ob = ZopePageTemplate(name, body, content_type=typ) elif typ in ('text/html', 'text/xml', 'text/plain'): from OFS.DTMLDocument import DTMLDocument ob = DTMLDocument( '', __name__=name ) elif typ[:6]=='image/': from OFS.Image import Image ob=Image(name, '', body, content_type=typ) else: from OFS.Image import File ob=File(name, '', body, content_type=typ) return ob # Modified PUT from NullResource PUT__roles__ = ('Anonymous',) def PUT(self, REQUEST, RESPONSE): """Create a new non-collection resource. """ from ZServer import LARGE_FILE_THRESHOLD self.dav__init(REQUEST, RESPONSE) name = self.__name__ parent = self.__parent__ ifhdr = REQUEST.get_header('If', '') if WriteLockInterface.isImplementedBy(parent) and parent.wl_isLocked(): if ifhdr: parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1) else: # There was no If header at all, and our parent is locked, # so we fail here raise Locked elif ifhdr: # There was an If header, but the parent is not locked raise PreconditionFailed # SDS: Only use BODY if the file size is smaller than # LARGE_FILE_THRESHOLD, otherwise read LARGE_FILE_THRESHOLD # bytes from the file which should be enough to trigger # content_type detection, and possibly enough for CMF's # content_type_registry too. # # Note that body here is really just used for detecting the # content type and figuring out the correct factory. The correct # file content will be uploaded on ob.PUT(REQUEST, RESPONSE) after # the object has been created. # # A problem I could see is content_type_registry predicates # that do depend on the whole file being passed here as an # argument. There's none by default that does this though. If # they really do want to look at the file, they should use # REQUEST['BODYFILE'] directly and try as much as possible not # to read the whole file into memory. if int(REQUEST.get('CONTENT_LENGTH') or 0) > LARGE_FILE_THRESHOLD: file = REQUEST['BODYFILE'] body = file.read(LARGE_FILE_THRESHOLD) file.seek(0) else: body = REQUEST.get('BODY', '') typ=REQUEST.get_header('content-type', None) if typ is None: typ, enc=OFS.content_types.guess_content_type(name, body) factory = getattr(parent, 'PUT_factory', self._default_PUT_factory ) ob = factory(name, typ, body) if ob is None: ob = self._default_PUT_factory(name, typ, body) # We call _verifyObjectPaste with verify_src=0, to see if the # user can create this type of object (and we don't need to # check the clipboard. try: parent._verifyObjectPa
Re: [Zope] Workflow question
David Pratt wrote at 2005-8-19 15:38 -0300: >First step is to make new type - will >do this today but might need to ask a question or two when I get to >bobo traverse portion. When you say another auxillary object, what kind >of object is this so I understand a bit better? One similar to "webdav.Resource.NullResource" (and probably deriving from it) but with a PUT method that does what you want. -- Dieter ___ Zope maillist - [EMAIL PROTECTED] http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
Hi Dieter. This is an excellent idea! I was looking at this to restrict the content that could be put into the folder as well. This fits really well with this too. First step is to make new type - will do this today but might need to ask a question or two when I get to bobo traverse portion. When you say another auxillary object, what kind of object is this so I understand a bit better? In anycase, I'll get going on making the type so I can look at this part with something that is ready to go. Regards David I would approach this task by means of a specialized folder (say some "UploadFolder"). In its "__bobo_traverse__" method, it would not return a "webdav.NullResource" but instead another auxiliary object. Its "PUT" method can do whatever you want it to do, e.g. not creating an object but telling FTP/WebDAV about a successful operation. -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
David Pratt wrote at 2005-8-18 20:57 -0300: > ... >All for exception of one thing - I want to >delete the object as part of the workflow since it is no longer needed. > ... >I use manage_delObjects like so: > > # Delete original object from the upload folder > upload_dir.manage_delObjects([id,]) > >method it raises following traceback: > >Traceback (innermost last): > > * Module ZPublisher.Publish, line 113, in publish > * Module ZPublisher.mapply, line 88, in mapply > * Module ZPublisher.Publish, line 40, in call_object > * Module webdav.NullResource, line 138, in PUT > * Module Products.CMFCore.PortalFolder, line 393, in PUT_factory > * Module OFS.ObjectManager, line 261, in _getOb > >AttributeError: A1032.JPG > >I guess my question is how can you delete an object that really is not >there yet, correct Correct. > ... >Because I already have already obtained what I need from the FTP'd >file, is there a way to give the FTP process something after the PIL >process to have it think it has completed its job and send a 226 >Transfer complete. This way I think workflow should be happy, FTP will >be happy because it gets a successful transfer, and I will be happy >because there is no file in the upload directory to worry about >deleting. Even it is a very different kind of situation, perhaps it >can still work. I would approach this task by means of a specialized folder (say some "UploadFolder"). In its "__bobo_traverse__" method, it would not return a "webdav.NullResource" but instead another auxiliary object. Its "PUT" method can do whatever you want it to do, e.g. not creating an object but telling FTP/WebDAV about a successful operation. -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
Hi Dieter! I believe you on the spot about it not being in the heirarchy yet. There are a couple of interesting things: First, it is a different sort of workflow because it is automatically activated with contents being dropped in folder but original object is deleted as part of worklow too. To start # Get the object and its id image_obj = state_change.object id = image_obj.getId() This gives me a handle on the state change object but it is really not in the heirarchy yet. I do get an id and FTP does give me the data but not in the way I may have expected but still perhaps enough to do something with. This seems to be why I could not get the objects data yesterday. So I am instead testing request method and using request_body (context.REQUEST.BODY) to get data when PUT method is being used (since normal method getting .data attribute works fine for HTTP uploads and cut and paste into specific folder. if request_method == 'PUT': image_file = StringIO(str(request_body)) image = PIL.Image.open(image_file) else: image_file = StringIO(str(image_obj.data)) image = PIL.Image.open(image_file) The workflow has an automatic trigger from a state called preprocessed to destination state of private (since I don't want to affect all images or the regular workflow, only the images that go into a specific folder). The script is a before script that gathers information and gives info to a tool method for PIL. With what I am doing above, I get data for PIL and I end up with my images sized and in the right places which is what I want with no 426 error. All for exception of one thing - I want to delete the object as part of the workflow since it is no longer needed. Here again I can raise 426 Error with FTP since if I use manage_delObjects like so: # Delete original object from the upload folder upload_dir.manage_delObjects([id,]) method it raises following traceback: Traceback (innermost last): * Module ZPublisher.Publish, line 113, in publish * Module ZPublisher.mapply, line 88, in mapply * Module ZPublisher.Publish, line 40, in call_object * Module webdav.NullResource, line 138, in PUT * Module Products.CMFCore.PortalFolder, line 393, in PUT_factory * Module OFS.ObjectManager, line 261, in _getOb AttributeError: A1032.JPG I guess my question is how can you delete an object that really is not there yet, correct - and at the same time have FTP think the object has landed in the folder? If I omit my delete statement, the workflow finishes and FTP is happy - if only I were happy too because this is not quite right - even though I have my sized images and in folders and types I want, I also want the object in the upload_dir to disappear as well. Because I already have already obtained what I need from the FTP'd file, is there a way to give the FTP process something after the PIL process to have it think it has completed its job and send a 226 Transfer complete. This way I think workflow should be happy, FTP will be happy because it gets a successful transfer, and I will be happy because there is no file in the upload directory to worry about deleting. Even it is a very different kind of situation, perhaps it can still work. Regards, David On Thursday, August 18, 2005, at 05:00 PM, Dieter Maurer wrote: David Pratt wrote at 2005-8-17 18:08 -0300: Hi Dieter. Many thanks for your reply. The place in my workflow that it failed was opening the image. IOError: cannot identify image file ... error here --> image = PIL.Image.open(original_file) This does not look like a workflow problem. Instead, PIL seems to be unable to determine the type of image ("jpg", "png", "gif", ...). I cannot tell you why. Looking at the traceback (where is the exception raised?) and then at the corresponding code may give you a hint. ... I discovered that it does not appear possible to have a workflow act on content immediately after being FTP'd to a site without generating the 'FTP 426 Error creating file' error. If I FTP an image to the folder as Manager with copy or move permission, it will trigger 426 Error creating file and the following traceback. The workflow will work for regular operations within the portal, just not FTP. * Module OFS.CopySupport, line 92, in manage_cutObjects Copy Error: The action against the A084.JPG object could not be carried out. One of the following constraints caused the problem:i * The object does not support this operation -- OR -- * The currently logged-in user does not have the Copy or Move permission respective to the object. X. Almost a Windows like message :-( But, your traceback was definitely larger. Please post the whole one. Probably, your workflow gets fired too early -- at a time when the object i
Re: [Zope] Workflow question
David Pratt wrote at 2005-8-17 18:08 -0300: >Hi Dieter. Many thanks for your reply. The place in my workflow that it >failed was opening the image. > >IOError: cannot identify image file > ... >error here --> image = PIL.Image.open(original_file) This does not look like a workflow problem. Instead, PIL seems to be unable to determine the type of image ("jpg", "png", "gif", ...). I cannot tell you why. Looking at the traceback (where is the exception raised?) and then at the corresponding code may give you a hint. > ... >I discovered that it does not appear possible to have a workflow act on >content immediately after being FTP'd to a site without generating the >'FTP 426 Error creating file' error. If I FTP an image to the folder >as Manager with copy or move permission, it will trigger 426 Error >creating file and the following traceback. The workflow will work for >regular operations within the portal, just not FTP. > > * Module OFS.CopySupport, line 92, in manage_cutObjects > >Copy Error: The action against the >A084.JPG object could not be carried out. One of the following >constraints caused the problem:i > * The object does not support this operation > -- OR -- > * The currently logged-in user does not have the >Copy or Move permission respective to the object. X. Almost a Windows like message :-( But, your traceback was definitely larger. Please post the whole one. Probably, your workflow gets fired too early -- at a time when the object is not yet put placed inside the Zope object hierarchy. At such a time, Zope permission system does not yet work (the permissions defined at objects in the hierarchy are passed down to lower level -- however, they can only reach objects placed in the tree). The full traceback may tell us whether this hypothesis is true. -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question - sort of solved
I guess what I have learned so far is that the data of an object in an automatic workflow transition from a PUT is not there until it completes - but the good thing is that the data is in the request body variable. So I can check the request method and if a PUT, use the request's body variable and the transaction completes on PUT and no more 426 Error. Yay! I am not sure if there is any other way to go but interested if there is a better solution. Regards, David On Wednesday, August 17, 2005, at 06:08 PM, David Pratt wrote: Hi Dieter. Many thanks for your reply. The place in my workflow that it failed was opening the image. IOError: cannot identify image file for image_data in image_data_list: # Get original image data into string object original_file = StringIO(str(image_obj.data)) image_size_px = image_data['size'] # Create an image instance error here --> image = PIL.Image.open(original_file) This had me puzzled since my workflow works in all other cases in the portal including cutting an image from one folder and pasting into the folder the workflow acts on (just not FTP case). So I wrote a very simple workflow script that will only cut and paste an image back in same folder to see what would happen: # Get the object and its id image_obj = state_change.object id = image_obj.getId() # This is the folder we are starting from upload_dir = image_obj.aq_parent # Do cut and paste objs = upload_dir.manage_cutObjects([id]) upload_dir.manage_pasteObjects(objs) return I discovered that it does not appear possible to have a workflow act on content immediately after being FTP'd to a site without generating the 'FTP 426 Error creating file' error. If I FTP an image to the folder as Manager with copy or move permission, it will trigger 426 Error creating file and the following traceback. The workflow will work for regular operations within the portal, just not FTP. * Module OFS.CopySupport, line 92, in manage_cutObjects Copy Error: Not Supported BGCOLOR="#FF"> BORDER="0" WIDTH="100%" CELLPADDING="10"> ! The action against the A084.JPG object could not be carried out. One of the following constraints caused the problem: The object does not support this operation.-- OR --The currently logged-in user does not have the Copy or Move permission respective to the object. VALIGN="TOP"> The body of the image appears in my traceback as well My folders work fine with FTP without the workflow - no errors. Only generates errors when workflow is attached to type it acts on and then 426 error appears. Regards, David On Wednesday, August 17, 2005, at 05:07 PM, Dieter Maurer wrote: David Pratt wrote at 2005-8-17 00:13 -0300: ... but when I FTP my images to this directory it fails giving me a 426 Error creating file. Look at your "error_log" object to find out the real reason (and get the traceback). -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev ) ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
Hi Dieter. Many thanks for your reply. The place in my workflow that it failed was opening the image. IOError: cannot identify image file for image_data in image_data_list: # Get original image data into string object original_file = StringIO(str(image_obj.data)) image_size_px = image_data['size'] # Create an image instance error here --> image = PIL.Image.open(original_file) This had me puzzled since my workflow works in all other cases in the portal including cutting an image from one folder and pasting into the folder the workflow acts on (just not FTP case). So I wrote a very simple workflow script that will only cut and paste an image back in same folder to see what would happen: # Get the object and its id image_obj = state_change.object id = image_obj.getId() # This is the folder we are starting from upload_dir = image_obj.aq_parent # Do cut and paste objs = upload_dir.manage_cutObjects([id]) upload_dir.manage_pasteObjects(objs) return I discovered that it does not appear possible to have a workflow act on content immediately after being FTP'd to a site without generating the 'FTP 426 Error creating file' error. If I FTP an image to the folder as Manager with copy or move permission, it will trigger 426 Error creating file and the following traceback. The workflow will work for regular operations within the portal, just not FTP. * Module OFS.CopySupport, line 92, in manage_cutObjects Copy Error: Not Supported BGCOLOR="#FF"> BORDER="0" WIDTH="100%" CELLPADDING="10"> ! The action against the A084.JPG object could not be carried out. One of the following constraints caused the problem: The object does not support this operation.-- OR --The currently logged-in user does not have the Copy or Move permission respective to the object. VALIGN="TOP"> The body of the image appears in my traceback as well My folders work fine with FTP without the workflow - no errors. Only generates errors when workflow is attached to type it acts on and then 426 error appears. Regards, David On Wednesday, August 17, 2005, at 05:07 PM, Dieter Maurer wrote: David Pratt wrote at 2005-8-17 00:13 -0300: ... but when I FTP my images to this directory it fails giving me a 426 Error creating file. Look at your "error_log" object to find out the real reason (and get the traceback). -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question
David Pratt wrote at 2005-8-17 00:13 -0300: > ... >but when I FTP >my images to this directory it fails giving me a 426 Error creating >file. Look at your "error_log" object to find out the real reason (and get the traceback). -- Dieter ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Workflow question - additional information
I should have stated that my workflow script checks for image type in this directory. It uses PIL to make a variety of image sizes, but uses the pil image data to create a new object type in another directory. The workflow script deletes the image in the original directory after this has been done. Is there some way to perhaps test the size of the image's data and have the script wait until the data is there or involve the temp directory in some way (since uploading images through a form works with this workflow) so that the image is whole before the workflow script attempts to use it? Regards, David On Wednesday, August 17, 2005, at 12:13 AM, David Pratt wrote: I created a workflow for my images so that they would be processed as soon as they are transferred into a specific directory. It works fine when I cut and paste images to the directory it acts on but when I FTP my images to this directory it fails giving me a 426 Error creating file. My thinking is that the workflow may trying to use the image before its data has arrived. I can FTP into the directory normally if I temporarily change my workflow to act on a different directory - so this verifies that the problem is between my workflow and FTP. Can someone suggest a workaround to ensure the image is completely available before the workflow tries to use it. I want to avoid any kind of cron process in a big way as well. Many thanks, Regards, David ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev ) ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )