buildout section in emacs

Add this on your .emacs and alt-x bsection give you a cool buffer for navigate on buildout section name.

(defun bsection()
(occur "\\\[.*\\\]
(other-window 1)
(if (get-buffer "*buildout-section*") (kill-buffer "*buildout-section*"))
(rename-buffer "*buildout-section*")
(goto-char (search-forward ":["))


supervisor on windows ?

aws.windowsplonecluster is a tool that is tailored to supervise zope architecture on windows systems.

Regards Youenn.

how to remove dev in stdist name egg ?

You have created a new package.

When you build egg in order to distribute ir you have always an dev in the name of tar.gz of file and you don’t understand.
In your , your egg version is good (without dev word). You don’t know where this dev is provided.
Please , look to setup.cfg file. If there is those lines , you’re on the good way :

tag_build = dev

A new tool for profiling zope application : collective.profiler


I’ve just release yesterday a little tool call collective.profiler. It’s just an interface to profilehook eggs which define a set of decorators for profiling application.

With collective profiler you define via zcml function to be traced. The profiling decorator is apply at zope startup. To see result , please start in fg mode ( print information on stdout) . You can also save profiling data on a filename (see options on README.txt)  in order to analyze your code with the fantastic graphviz (convert data with gprof2dot first).

It’s not a replacement of zope.profiler but another tool to track performance issue. The typical use case is , you find a fonction that take time. First apply timecall hook to see how time it took really. Second apply the profile hook to see where the time is consume.

Regards Youenn.

Automate action with mechanize

Mechanize is a great tool for web ressources access . It simulates a web browser. This library is part of zope.testbrowser so if you have zope.testbrowser you have mechanize.

A little exemple : login in a plone portal

## first log to portal

>>> br = mechanize.Browser()

>>> br.forms()[0].find_control(‘__ac_name’) = ‘admin’
>>> br.forms()[0].find_control(‘__ac_password’) = ‘admin’
<response_seek_wrapper …
>>> ‘admin’ in

And as you can simulate navigation zope.testbrowser by clicking on links,submit forms … A handy tool to perform operations on the tedious zmi.

Launch zope instance with emacs

I use Emacs for my developpement.

Shell mode is great. Interactive debugging on emacs also. But I always repeat the same thing : open an emacs shell , rename it, go to my instance and launch it . Well with emacs ,very easy to automate this with a simple function :

(defun launch-instance ()
   " launch zopeinstance  "
   (shell-command "cd path_to_your_buildout;bin/instance fg&" "*zopeinstance*") 

And M-x launch-instance open a new shell and launch your zopeinstance in debug mode.
Very easy isn’t it !

setuptools takes care of dependency

If you specify them !!!

Buildout is a fantastic tool to build environnement isolated with eggs. But virtualenv with setuptools too !!

When you create an egg  you can specify yours dependency in in install_requires section. Setuptools or Distribute take care of that so all things take care of that. The generation of script via entry_point or via zc.recipe.egg also. Sys path generated included dependency and it’s simply work. Number of buildout after one year break because a lack of specification of dependency (with specific version of course). IMO install_requires is better than fixing version in your buildout because it’s simply works without or with buildout.

AllowedContentType in Plone2.5


I notice that the method allowedContentTypes cost time when you have a lot of type in plone2.5.I don’t know if plone3 or plone4 are impacted of that. I have 120 types and the time of execution of context.allowedContentTypes is about 0.32sec.

The path of allowedContentTypes is :

allowedContentTypes -> portal_types.listTypeInfo -> for each content type: portal_types.isConstructionAllowed -> portal_types._queryFactoryMethod -> Products.Five.pythonproducts.patch_ProductDispatcher__bobo_traverse__ -> Products.Five.pythonproducts.product_packages

and Products.Five.pythonproducts.product_packages time call is 0,003s

When you have 100 content type only product_packages is responsible of 0,3sec , this method is a performance bottleneck.

So add this patch fix the problem :

from Products.Five import pythonproducts
old_product_packages = pythonproducts.product_packages
pythonproducts.product_packages =  forever.memoize(old_product_packages)

Regards Youenn

New Release of iw.fss

I’ve just released a new version of iw.fss (2.8rc2 for plone 3) and FileSystemStorage (2.6.3 the same but for plone2.5).

Those releases change the behaviour of getData method which retrieve data from filesystem.
This change is important in case of big file because now all data are handled by filestream_iterator (in all case). So no memory is consumed when we access directly to the data (if you respect this new API)

For the developper point of view , getData works like OFS.Pdata. So to get all data (don’t do that please) just call str(field.get(instance)), and to get the first block of data call field.get(instance).data and you have a pointer to the next block in calling field.get(instance).next.

So if you are using iw.fss for yours projects please update it, our plone will thank you after that !!

Regards Youenn

Asynchronous task with plone : easy !!


Most of time in plone we do the work during the transaction. Or some task could be defered after it and better in an another client. collective.indexing do that for catalog indexing.
There is a simple solution to do that with Products.CMFSquidTool wich implements all hard work of assynchrone task.

So first import this:

from Products.CMFSquidTool.queue import Queue
from Products.CMFSquidTool.utils import pruneAsync

And add a new class that send http url after the transaction

class CallAsynchronous(Queue):
    Sends requests on transaction commit

    def _finish(self):
        # Process any pending url invalidations. This should *never*
        # fail.
        for url in self.urls():
           ## you can change this to post
            pruneAsync(url, purge_type='GET')
        # Empty urls queue for this thread

    def queue(self, url_view):

call_utility = CallAsynchronous()

You add an instance in your code at the start of zope wich
And now in your code you can call assynchronous task like this


So at the end of the transaction url are called . You can by this method delegate some heavy operation to other zeoclient. That’s all !! easy no ?

Regards Youenn.

« Older entries