Monday, October 15, 2007

buildout recipe for installing Selenium RC

This weekend at the Plone Naples Sprint one of the things I worked on was a buildout to download and install Selenium RC. It is now available from PYPI under the name collective.recipe.seleniumrc For some reason the Selenium RC distribution zip file contains version numbers on each subdirectory so this meant I couldn't just use one of the existing download scripts. But I didn't want to re-invent the download recipe wheel, so I decided to base this recipe on a well-written existing download recipe, I asked on IRC if the author was present at the sprint and ironically enough he was sitting in the same room as me only two rows away ;) With some simple changes to his recipe I was able to derive collective.recipe.seleniumrc from it and gain features like download caching and md5 file hash verification. Along the way I learned that if you want your buildout recipe to be derived by others you should make it a new-style Python class so that super() works. Also that it helps to factor your install() method into submethods for overriding. The changes I made to were cleaned up and integrated into a 1.1.0 release that we made yesterday, along with the 0.1 release of collective.recipe.seleniumrc If you want to try out the Selenium RC recipe just create a simple buildout.cfg:

After you are finished running this buildout you will get a nice wrapper script in your bin folder named by the part, in this case seleniumrc. Happy testing!

Wednesday, August 15, 2007

WebDAV, cadaver and metadata

Recently I wanted to automate some document management processes against a Plone site and was trying to figure out how to do set the Title property on the newly created objects via WebDAV, using the cadaver command line client. This led me to look a little more closely at how WebDAV does properties. In fact it is not like a simple Python dictionary, rather there is a nested structure like a dictionary of dictionaries. Each application can have its own namespace. By default cadaver will set properties in its own custom namespace. So you need to use the set namespace command to use the Zope namespace identified by its namespace: The following example uses cadaver and creates a collection (folder) and sets the title property:
mkcol just_a_folder
set namespace
propset just_a_folder title “A long title”

Thursday, April 19, 2007

Zope 3 Book Arrived!

The book Web Component Development with Zope 3, 2nd Ed. by Philipp von Weitershausen has been on my wishlist for a while now and I finally got around to ordering it. I only got it last night and already I've made it half way through, though certainly I will re-read it all several times. The book offers very excellent descriptions of the component architecture and its applications throughout the rest of the Zope 3 framework. The progression of chapters in the book shows the reuse of the basic building blocks of interfaces, adapters & utilities. And one of the things I also liked was the "Rocky says" section where the relevant technologies of J2EE were constrasted with those of Zope. The explanation of ZCML in the book finally made it clear to me. ZCML is on purpose ;) It forces a separation of roles and make sure that things that would be considered 'configuration' are easily accessible to a non-programmer like a system administrator or integrator. My impression so far the from the book is one that really showcases Zope 3 as a enterprise-grade framework that is solidly Pythonic. For more info you can check' the website for Web Component Development with Zope 3, 2nd Ed.

Monday, April 16, 2007


How annoying is it to deploy an application? How prone to errors due to the sheer repetitiveness of the common deployment? Buildouts to the rescue! What is a buildout? It's a automated set of steps for creating a deployment environment. This could mean one little application, or it could be several and they would setup to talk to each other. zc.buildout came out sometime last year and I've had my eye on it since then. I'd wanted to do Jim Fulton's tutorial on it at Pycon this year but wasn't able to schedule it in! I've had the opportunity in the last couple weeks to start using a bit more and I really appreciate the conceptual basis for this framework. The idea that a deployment consists of parts is something you can explain to anyone, for example. A web app needs a webserver, some kind of storage backend, the application code and some preexisting data: parts=apache mysql application-data application or full Zope-based solution: parts=apache zope zeo plone mywebsite mywebsite-data What I've noticed so far is that for a particular application even though someone might have already wrote a recipe for it actually getting it configured the way you want usually requires extending that recipe slightly. If the recipe was written with this in mind its easy enough to extend. I did have a bit of problems extending some of the plone.recipe.* recipes because they were old style classes and so I couldn't use super() to extend the default behaviour. Easy to fix though!

ZOPE / ZEO buildout recipe with multiple database support

I created a branch that adds the ability to configure multiple databases in your configuration files which I needed for a project, so this should be a fairly decent example for anyone else needed to something similar. See the jbb666-multiple-dbs branch for zeo instance and the corresponding branch for the zope recipe. For a lot of the Zope recipes the config knobs that need to be exposed will be determined and you won't need to touch the underlying recipe except in well exceptional circumstances.

Thursday, April 12, 2007

copying a plone site

Copying sites has recently gotten a lot better since 2.5.2 fixed some bugs with modification times getting reset but still you generally can't use copy & paste to copy sites as I have found it doesn't retain the review state of your documents (and this is by design actually I think). Another approach is to import/export. This actually works great so I put together a script that will automate this process. You need to call this from either an External Method or from zopectl debug (or ipython). That's an exercise up to the reader... #
# Move a Plone site without losing the modification times and workflow status
# we rely on export/import to do this
# You need to provide a valid REQUEST so that the import doesn't fail
# if running from zopectl debug you can use makerequest to wrap your app object
# with a fake request
# Author: Jordan Baker (
import tempfile
import os

def moveSite(portal, new_location):
# export the site to a tempfile
f = tempfile.NamedTemporaryFile()
portal._p_jar.exportFile(portal._p_oid, f)
# re-import in the correct location
new_location._importObjectFromFile(f, verify=False, set_owner=False)
# delete the old site
oid =
# update the catalog in the new site
# NamedTemporaryFile should delete the underlying temporary file
# when its object is garbage collected

Thursday, March 22, 2007

I've Joined the Toastmasters!

I've recently joined the Liberty Village Toastmasters. The name perhaps evokes the spirit of another time but Toastmasters is a very relevant organization for today. The picture from my induction ceremony: me on the right, and Ian Garmaise, the club President on the left. Ian had introduced me to the club. We have a neat connection because we are also both fans of the Python programming language. We'd first met at PyGTA, the Toronto Python Users Group. Toastmasters is a bit like a DIY communications class. At the weekly meetings we are working on our communication and presentation skills among many other things. Learning to refine and hone the delivery of ideas for impact all the while feeling natural in front of the audience you are addressing. But the best part is probably all the smart, interesting and generous people I've met at this group. My first speech, known as an Ice Breaker, is only two weeks away. I'm getting nervous just thinking about it.
At last week's meeting on March 14th, Ted Blanchard gave a great educational talk with some tips. I noted down only a scant few of them that I've tried to summarize here: Set Goals - there are a series of 10 speeches in the first stage of the Toastmasters. Put yourself on a regular schedule, like a speech every 4 weeks. Topic Generation Exercise. Make a Speech Topic List in 15 minutes by getting a pen and a piece of paper and writing down:
  • 5 current events
  • 5 things you enjoy doing
  • 5 things that bug you
  • 5-20 action words
Learn to do an outline. An outline is not finished thinking, just the waypoints your speeches' route. It gets you out of the editing chaos of continual revision.

Friday, February 23, 2007

Blogging live from PyCon 2007

I finally made it! Got switched to another hotel but I will be in the right place for tonight. Immediately I ran into a couple familiar faces from last October's Plone Conference, Chris Calloway and Josten Ma. Now I'm sitting in the main room waiting for the morning's keynote to start. More to come... Update Well I didn't end up blogging much at Pycon this year. But I have some pretty wonderful excuses. ;)