Entries For: 2010
- August (1)
- May (1)
- February (2)
- January (3)
2010-08-22
Migrating content (folders) from Plone 3 to Plone 4 via zexp import
I had a need (and a problem) moving some content from a Zope 2.10/ Plone 3.3 instance to a Zope 2.12/Plone 4 instance. The path I have chosen was that of the least resistence, which for me was exporting the folder I was interested as a zexp file from the old instance and importing it in the new Plone instance. According to some members of the #plone IRC channel, this method of getting content from one zope instance to another is not possible, or at least not supported. I supposed that's correct, zexp import works best for moving content between identical zope instances, but, as they say, necessity is the mother of learning.
The issue is that the implementation of folders has changed from Plone 3 to 4 to use BTrees, which greatly improves performance. The problem is that, when viewing imported folders, I got the following traceback:
Traceback (innermost last):
* Module ZPublisher.Publish, line 116, in publish
* Module ZPublisher.BaseRequest, line 434, in traverse
* Module Products.CMFCore.DynamicType, line 150, in __before_publishing_traverse__
* Module Products.CMFDynamicViewFTI.fti, line 215, in queryMethodID
* Module Products.CMFDynamicViewFTI.fti, line 182, in defaultView
* Module Products.CMFPlone.PloneTool, line 840, in browserDefault
* Module Products.CMFPlone.PloneTool, line 708, in getDefaultPage
* Module Products.CMFPlone.utils, line 81, in getDefaultPage
* Module plone.app.layout.navigation.defaultpage, line 32, in getDefaultPage
* Module plone.app.layout.navigation.defaultpage, line 75, in getDefaultPage
* Module Products.BTreeFolder2.BTreeFolder2, line 337, in has_key
AttributeError: 'NoneType' object has no attribute 'has_key'
The solution was to call @@migrate-btrees on the imported folder, which fixes that folder and makes it conform to the latest implementation.
One final note, the default Plone buildout doesn't have a folder called "import" anywhere in the buildout, so one needs to be created inside the "client home folder", which is the folder of your plone and buildout instance, the one that hosts the bin, parts and var folders.
2010-05-12
Some issues with zc.recipe.egg's python option
I've recently had to integrate a script/package into a Plone 2.5 buildout that runs on top of Python 2.4. Due to that package's dependence of a sane imaplib (and the one in Python 2.4 is buggy), I had to run the script with python2.6. To make a script run on a different python, you need to do:
[myscript] recipe = zc.regipe.egg eggs = myegg IMAPClient python = python26
The python26 option is actually the name of a buildout part that configures the python executable path
[python26] python = /usr/bin/python26
Now the problems. I've had various buildouts fail with a message "Cannot find egg myegg". After a bit of effort, we managed to trace the cause to this problem:
First, the python path in the [python26] part was incorect. Second, even if it pointed to the proper binary, the -devel packages for that python needed to be installed.
Well, now I know. Hopefully I'll remember it for the next time when I'll encounter the problem.
2010-02-25
Can you do this on your shiny Mac?
Probably you can, but you have never done it because you have a shiny interface for everything. I'm talking about this discovery of mine:
svn diff | kompare -
What it does is to take the output from svn diff and pipe it into Kompare, a merge/diff utility from the KDE Project. I can do this from the command line, straight from the directory that I'm in, and bang! I get a nice graphical overview, complete with the tree structure that I can navigate to see what I'm about to commit. Honestly, this little command gets me excited everytime I run it.
2010-02-24
Generating products outside of the Products.* namespace with ArchGenXML
I'm a die hard in regards to ArchGenXML usage. The number of things to know about when creating new content types for Plone is just too high. Package structure, Zope package registration, content types registration, QuickInstaller registration, GenericSetup profiles, skins registration, workflows, etc. I can go in and do changes to the code, and add to it, but generating it from scratch is a gigantic task, especially for my use case, where I need to start a new project with about 7 content types.
Now to the problem: ArchGenXML assumes (and hardcodes in its templates) the Products.* prefix for your package. I don't have any problems with it, but my employer uses a different package structure so for uniformity I need to follow their standards. 15 minutes of poking and changing through agx enabled me to change it so it would generate GS xml files with the proper namespace (based on a new model level TGV named "namespace" that I have created). After assessing the difficulty of the task and being under time pressure, I've decided to go the dumb route, which I'm documenting below:
My generation script is something like this:
./archgenxml -c archgenxml.cfg myproduct.zuml #rename Products.myproduct to ns.myproduct find myproduct/* -type f -print | xargs sed -i 's/Products\.myproduct/ns\.myproduct/g' #in the xml type profiles, replace myproduct by ns.myproduct find myproduct/* -type f -print | xargs sed -i 's/>myproduct</>ns\.myproduct</g' #in the profiles.zcml, rename the profile to ns.myproduct find myproduct/* -type f -print | xargs sed -i 's/title=\"myproduct\"/title=\"ns\.myproduct\"/g'
Notice the sed lines, which change the source code to point to "ns.myproduct" instead of "Products.myproduct". Now there's just two more problems, which are actually AGX bugs:
- the FilesystemDirectoryViews registered for the skin are incorect, so you'll need to insert this in ns/myproduct/__init__.py
from Products.CMFCore import utils
from Globals import package_home
from os.path import dirname
ppath = utils.ProductsPath
utils.ProductsPath.append(dirname(package_home(product_globals)))
DirectoryView.registerDirectory('skins', product_globals)
utils.ProductsPath = ppath
- trying to get AGX to output the code inside a two level deep folder doesn't work (it crashes), so you'll need to move this script file and the model just above the "myproduct" folder, inside the "ns" namespace.
That's about it. Hopefully I'll find the time to fix the two bugs and add the namespace improvement in the next week. Still need to do the review for Plone for Education, which I have received for free from the publisher.
2010-01-28
Another cause for buildout failures: system distributed Python
Always compile your own! One day I'll even remember that...
I've had a buildout bootstrap process failure, this time a weird one, perhaps I should document the bug and report it.
The latest Ubuntu version which I have installed (Lucid Lynx) comes with a package called python-pkg-resources, which packages pkg_resources, which used to be available only through the setuptools distribution. Buildout's bootstrap.py tries to guess if Setuptools or Distribute are installed by checking the availability of pkg_resources; by guessing wrong it all comes to a crash at the end.
I'm not very interested in debugging these types of problems anymore. Distribution/packaging tools should just work. I want to focus on my work, not debug the toolchain. No more corner cases or whatver. So I'm gonna compile separate Pythons in the future, especially when dealing with older Zope/Plones.
Dear PyPi uploaders: don't use a download URL, upload your package instead!
Pypi's biggest mistake: allowing package entries without any upload
I think this is the Python Index biggest mistake, the one which makes it unreliable for serious development environments: exposing package entries with no real package files and just a download URL. To see what I'm talking about, just examine the PyPI records for BeautifulSoup or IPython, packages that are very common in buildouts. As soon as the author and publisher of that package has a hosting problem, the developer that uses that package also has a problem. Buildouts will completely fail and this will cause dead times and frustration for the developers.
Yes, there are a couple of PyPi mirrors, but they only mirror files hosted by PyPi. The central PyPi site will probably have better performance and availability then what individual groups and developers can provide and it's always easier to mirror one single website than many, so there's no shame or loss of pride in using the PyPi to host your files. Please do so!
2010-01-15
Test if developer mode is set in Zope 3 and Grok
I've started an application that uses Dolmen, a lightweight CMS built on top of Grok, and I want to be able to "rollup" the megrok.resource files based on the devmode setting that was set in the zope.conf file. After a bit of digging, I came up with this code that tells me the current devmode setting for the running instance:
from zope.app.applicationcontrol.applicationcontrol import applicationController from zope.app.applicationcontrol.interfaces import IRuntimeInfo def get_debug_mode(): """Returns the devmode setting for a running zope instance""" rti = IRuntimeInfo(applicationController) return rti.getDeveloperMode() == "On"