Team Development with Plone/ Zope/ ZEO/ Subversion/ ipython
Introduction
Team Development with Zope (7) can be problematic (1). The ZODB is a large binary file (var/Data.fs) that stores all information about a Zope instance, the ZODB is opaque to all but python. The ZODB is typically accessed Through The Web (TTW) using the Zope Management Interface (ZMI) typically http://localhost:8080/manage. All data controlled and published by Zope are held in this ZODB, while almost all available Source Control Management (SCM) and replication tools needed for version management and staging require a traditional file system representation of data. Though there is a simple version control mechanism built-in to the ZODB (one development line for single objects), this soon proves insufficient even for small applications (4). This post shows how to set up a zeo server with 2 clients, one acting as a web server, the other as an ipython interpreter (this gives us access to the ZODB object for debugging purposes) The following are typical requirements for Team Development in Plone:
This should (all going well) leave you with the following directory structure
To start the zeo server running on port 8100 and plone listening on port 8080 run the following
To start an ipython prompt with the ZODB app object in your namespace, run the following:
The script also builds a demo Plone instance called Acme with a custom filesystemskin located in the products directory at AcmeSkin (you should see that the plone logo has been replaced when you browse to http://localhost:8080/Acme. IPython can be set up for different colour console types.
I had to edit ~/.ipython/ipythonrc as follows for my white background gnome-terminal,
Try the following commands in ipython to get a feel for the plone api (make sure to test the TAB button for auto-completion.)
Ctrl-d gets you out of the IPython prompt.
Any changes you make to filesystem products are picked up automatically (if there is a refresh.txt file in the Products root directory) as Zope is setup here to run with debug-mode on.
Don't forget to run ./stopPlone2.1-rc3.sh when you are finished to close the ZEO server and the Zope server. You can also use this script to set up a Plone 2.0.5 development environment e.g. to setup Plone 2.0.5 with a PloneId of TestSite on port 8888
This would leave you with the following directory structure (assuming you ran the command "./setupplonezeo.sh 1" previously)
This setup has the advantage that you can easily and quickly test your Zope products across two versions of Plone.
If you get locking errors and ipython doesn't start you need to increase the sleep time to allow servers to start, e.g. to increase the sleep time to 63 seconds
References
setupplonezeo.sh
plonehelper.py
Team Development with Zope (7) can be problematic (1). The ZODB is a large binary file (var/Data.fs) that stores all information about a Zope instance, the ZODB is opaque to all but python. The ZODB is typically accessed Through The Web (TTW) using the Zope Management Interface (ZMI) typically http://localhost:8080/manage. All data controlled and published by Zope are held in this ZODB, while almost all available Source Control Management (SCM) and replication tools needed for version management and staging require a traditional file system representation of data. Though there is a simple version control mechanism built-in to the ZODB (one development line for single objects), this soon proves insufficient even for small applications (4). This post shows how to set up a zeo server with 2 clients, one acting as a web server, the other as an ipython interpreter (this gives us access to the ZODB object for debugging purposes) The following are typical requirements for Team Development in Plone:
- Use Source Control (CVS, Subversion, etc.).
- Setup environment so debugging is possible (11)
- File system based.
- Don't modify Zope or Plone through the ZMI so that different versions of Zope/Plone can be setup and tested without requiring TTW intervention.
- Allow off line development (Don't use a central development server)
- Objects (Python Scripts, Images ZSQL Methods, etc.) are stored as binary objects in the Zope Object Database (ZODB).
- Can't use file system utilities such as grep, find for development.
- Editing documents is painful if your "favorite editor" doesn't work with the external editor tool (9).
- Can't use source control management, e.g. CVS, Subversion, on objects in the ZODB (exception: (CVSFile) and (ExternalFile) provide CVS through the ZMI).
- Can't write test suites for binary objects in database.
- Do not use ZMI at all ever!, use Filesystem Products (2) (6) (16).
- Build products for each major feature (19) (20)
- Build a site product for site customization (16)
- Avoid disconnected External methods, scripts etc.
- Write scripts for creating your Plone instance and configuration (involves learning Zope/Plone api), commit these scripts to SCM.
mkdir ~/plonedev cd ~/plonedev wget -c http://homepage.eircom.net/~rachra/setupplonezeo.sh wget -c http://homepage.eircom.net/~rachra/plonehelper.py chmod +x setupplonezeo.sh ./setupplonezeo.sh 1 Acme
~/plonedev/
startPlone2.1-rc3.sh # this script starts the zeo server on port 8100 and plone listening on port 8080
startIPythonPlone2.1-rc3.sh # this script starts an IPython interpreter on your zeo_client1 (port 9080)
debugPlone2.1-rc3.py # a python script to start zeo_client0 (port 8080)
plonehelper.py # python helper script for creating a plone instance
# installing products and selecting a skin using the plone api
myproducts/ # this is where you develop your Zope/Plone products
build/ # the directory where you built Zope and Python
src/ # the directory where all downloads get stored
zeo_py2.3.5_zo2.8.1-final_pl2.1-rc3/
Python-2.3.5/ # a full python installation including ipython
Zope-2.8.1-final/ # a full zope installation
thirdpartyproducts/ # all 3rd party products for both zeo clients are stored (symlinked) here,
# you shouldn't edit these when developing as you may break your upgrade path
zeo_server/ # the zeo server that contains the shared ZODB
zeo_client0/ # the zeo client that will act as our webserver on port 8080
zeo_client1/ # the zeo client that will act as our interactive debugger (port 9080)./startPlone2.1-rc3.sh
./startIPythonPlone2.1-rc3.sh
115:# colors - Coloring option for prompts and traceback printouts. 116: 117:# Currently available schemes: NoColor, Linux, LightBG. 118: 119:# This option allows coloring the prompts and traceback printouts. This 120:# requires a terminal which can properly handle color escape sequences. If you 121:# are having problems with this, use the NoColor scheme (uses no color escapes 122:# at all). 123: 124:# The Linux option works well in linux console type environments: dark 125:# background with light fonts. 126: 127:# LightBG is similar to Linux but swaps dark/light colors to be more readable 128:# in light background terminals. 129: 130:# keep uncommented only the one you want: 131:#colors Linux 132:colors LightBG 133:#colors NoColor 134:
from Products.CMFPlone import transaction for id, ref in app.objectItems(): print "%-25s: %s"% (id, repr(ref)) app.Acme.objectIds?? app.Acme.objectIds() for k,v in app.Acme.contentItems(): print "%-11s: %s"%(k,repr(v)) # try out any of your own commands here, # DocFinderTab is installed and viewable through the ZMI for help with the Zope api # to synchronize with the ZODB app._p_jar.sync() # to commit your changes to the database transaction.commit()
./setupplonezeo.sh 0 TestSite 8888
~/plonedev/
startPlone2.1-rc3.sh # this script starts the zeo server on port 8100 and plone listening on port 8080
startPlone2.0.5.sh # this script starts the zeo server on port 9999 abd plone listening on port 8888
startIPythonPlone2.1-rc3.sh # this script starts an IPython interpreter on your zeo_client1 (port 9080)
startIPythonPlone2.0.5.sh # this script starts an IPython interpreter on your zeo_client1 (port 9888)
debugPlone2.1-rc3.py # a python script to start zeo_client0 (port 8080)
debugPlone2.0.5.py # a python script to start zeo_client0 (port 9080)
plonehelper.py # python helper script for creating a plone instance
# installing products and selecting a skin using the plone api
myproducts/ # this is where you develop your Zope/Plone products
build/ # the directory where you built Zope and Python
src/ # the directory where all downloads get stored
zeo_py2.3.5_zo2.8.1-final_pl2.1-rc3/
Python-2.3.5/ # a full python installation including ipython
Zope-2.8.1-final/ # a full zope installation
thirdpartyproducts/ # all 3rd party products for both zeo clients are stored (symlinked) here,
# you shouldn't edit these when developing as you may break your upgrade path
zeo_server/ # the zeo server that contains the shared ZODB
zeo_client0/ # the zeo client that will act as our webserver on port 8080
zeo_client1/ # the zeo client that will act as our interactive debugger (port 9080)
zeo_py2.3.4_zo2.7.4_pl2.0.5/
Python2.3.4/ # a full python installation including ipython
Zope-2.7.4-0/ # a full zope installation
thirdpartyproducts/ # all 3rd party products for both zeo clients are stored (symlinked) here,
# you shouldn't edit these when developing as you may break your upgrade path
zeo_server/ # the zeo server that contains the shared ZODB
zeo_client0/ # the zeo client that will act as our webserver on port 8888
zeo_client1/ # the zeo client that will act as our interactive debugger (port 9888)./setupplonezeo.sh 0 TestSite 8888 63
- Why not to use Zope: http://www.amk.ca/python/writing/why-not-zope.html
- Plone best practices: https://plone.org/documentation/tutorial/best-practices/
- Team development with Plone/Zope: http://www.zope.org/Members/k_vertigo/Stories/TeamZope
- zsync: http://www.elegosoft.com/index_zync.html
- Unit testing plone: http://www.zope.org/Members/shh/Tutorial/PloneTestCase.pdf
- Scripting plone: http://docs.neuroinf.de/programming-plone
- Beginners guide to Zope/Plone: http://www.neuroinf.de/Miscellaneous/BeginnersGuide
- Introduction to Plone: http://docs.neuroinf.de/PloneBook
- Zope External Editor: http://www.zope.org/Members/Caseman/ExternalEditor
- Zope Test Case: http://www.zope.org/Members/shh/ZopeTestCase
- Debugging Zope: http://plone.org/Members/pupq/debug
- Debugging Zope: http://www.zope.org/Members/klm/ZopeDebugging/ConversingWithZope
- ZEO and debugging: http://www.zope.org/Members/dshaw/AdvancedSiteSetup
- Installing ZEO: http://www.plope.com/Books/2_7Edition/ZEO.stx
- Debugging Zope: http://zopewiki.org/DebuggingZopeWithPythonDebugger2
- MySkin Plone customization: http://www.ucl.ac.uk/is/fiso/engsciences/tutorials/plone/plone_pages/customise_plone2.htm
- Archetypes Development environment setup: http://plone.org/documentation/archetypes/wiki/SettingUpArchetypesProductDevelopmentEnvironment
- Archetypes home page: http://plone.org/documentation/archetypes
- Archetypes developers guide: http://plone.org/documentation/archetypes/ArchetypesDeveloperGuide
- ArchGenXML: http://plone.org/documentation/tutorial/archgenxml-getting-started
- Robust Plone installation with ZEO: http://plone.org/documentation/tutorial/robust-installation
- ipython: http://ipython.scipy.org/
- ipython tutorial: http://www.onlamp.com/pub/a/python/2005/01/27/ipython.html
- BoaDebugger: http://plone.org/documentation/how-to/how-to-debug-products-with-boa-constructor
- Installing Zope and Pone http://docs.neuroinf.de/programming-plone/appendixC#1-5
setupplonezeo.sh
1:#!/bin/bash 2:E_NOARGS=65 3:PloneId="Acme" 4:ZOPE_PORT=8080 5:SLEEPTIME=20 6:if [ -z "$1" ] 7:then 8: echo "Usage: `basename $0` [plone-version, 0 or 1] [ploneid, default $PloneId] [zope-port, default $ZOPE_PORT] [sleep-time, default $SLEEPTIME]" 9: echo "e.g. to build Plone 2.1 with a PloneId of TestSite allowing 15 seconds for server to start on port 8888" 10: echo "`basename $0` 1 TestSite 8888 15" 11: exit $E_NOARGS 12:fi 13:#set -x 14: 15:base=`pwd` 16:mkdir $base/{src,build} 17:cd $base/src 18:if [ "$1" -ne "0" ] 19:then 20: PythonVersion="2.3.5" 21: ZopeVersion="2.8.1-final" 22: PloneVersion="2.1-rc3" 23: ZEO_PORT=8100 24: wget -c http://www.zope.org/Products/Zope/2.8.1/Zope-$ZopeVersion.tgz 25:else 26: PythonVersion="2.3.4" 27: ZopeVersion="2.7.4-0" 28: PloneVersion="2.0.5" 29: ZEO_PORT=9999 30: wget -c http://www.zope.org/Products/Zope/2.7.4/Zope-$ZopeVersion.tgz 31:fi 32:StartPloneScript=startPlone$PloneVersion.sh 33:StopPloneScript=stopPlone$PloneVersion.sh 34:StartIPythonScript=startIPython$PloneVersion.sh 35:PythonDebugScript=debugPlone$PloneVersion.py 36:if [ -n "$2" ] 37:then 38: PloneId=$2 39:fi 40:if [ -n "$3" ] 41:then 42: ZOPE_PORT=$3 43:fi 44:if [ -n "$4" ] 45:then 46: SLEEPTIME=$4 47:fi 48:PloneTitle=$PloneId 49:PloneDescription="CMS Prototype" 50:SkinName="${PloneId}Skin" 51:INSTALL_HOME=$base/zeo_py${PythonVersion}_zo${ZopeVersion}_pl$PloneVersion 52:# remove existing install 53:rm -rf $INSTALL_HOME 54:PYTHON_HOME=$INSTALL_HOME/Python-$PythonVersion 55:ZOPE_HOME=$INSTALL_HOME/Zope-$ZopeVersion 56:PYTHON=$PYTHON_HOME/bin/python 57:PRODUCTS_DIR=$INSTALL_HOME/thirdpartyproducts 58:MYPRODUCTS_DIR=$base/myproducts 59:ZEOSERVER_DIR=$INSTALL_HOME/zeo_server 60:ZEOCLIENT0_DIR=$INSTALL_HOME/zeo_client0 61:ZEOCLIENT1_DIR=$INSTALL_HOME/zeo_client1 62:INSTANCE_USER=manager 63:INSTANCE_PASSWORD=manager 64: 65:# Get Python, Zope, Plone, MySkin, ipython and a sample logo 66:wget -c http://www.python.org/ftp/python/$PythonVersion/Python-$PythonVersion.tgz 67:wget -c http://heanet.dl.sourceforge.net/sourceforge/plone/Plone-$PloneVersion.tar.gz 68:wget -c http://plone.org/products/myskin/releases/0.1/MySkin-0.1.tar.gz 69:wget -c http://www.zope.org/Members/shh/DocFinderTab/0.5.2/DocFinderTab-0.5.2.tar.gz 70:wget -c http://homepage.eircom.net/~rachra/acme.jpg 71:wget -c http://ipython.scipy.org/dist/ipython-0.6.15.tar.gz 72:wget -c http://wingware.com/pub/wingide/2.0.3/WingDBG-2.0.3-2.tar 73: 74:# build Python 75:cd $base/build 76:tar -zxf $base/src/Python-$PythonVersion.tgz 77:cd Python-$PythonVersion 78:./configure --prefix=$PYTHON_HOME --enable-unicode=ucs4 79:make 80:make install 81: 82:# install ipython 83:cd $base/build 84:tar -zxvf $base/src/ipython-0.6.15.tar.gz 85:cd ipython-0.6.15 86:$PYTHON setup.py install 87: 88:# build Zope 89:cd $base/build 90:tar -zxf $base/src/Zope-$ZopeVersion.tgz 91:cd Zope-$ZopeVersion 92:./configure --prefix=$ZOPE_HOME --with-python=$PYTHON 93:make 94:make install 95: 96:# make a zeo server instance 97:$PYTHON $ZOPE_HOME/bin/mkzeoinstance.py $ZEOSERVER_DIR 98: 99:# make 2 zeo client instances 100:$PYTHON $ZOPE_HOME/bin/mkzopeinstance.py -d $ZEOCLIENT0_DIR -u $INSTANCE_USER:$INSTANCE_PASSWORD 101:$PYTHON $ZOPE_HOME/bin/mkzopeinstance.py -d $ZEOCLIENT1_DIR -u $INSTANCE_USER:$INSTANCE_PASSWORD 102: 103:# unzip Plone and copy into Products directory 104:mkdir $PRODUCTS_DIR 105:cd $base/build 106:tar -zxf $base/src/Plone-$PloneVersion.tar.gz 107:cd Plone-$PloneVersion 108:cp -R * $PRODUCTS_DIR 109: 110:# install docfinder 111:cd $PRODUCTS_DIR 112:tar -zxf $base/src/DocFinderTab-0.5.2.tar.gz 113: 114:# install WingDebugger 115:tar -xf $base/src/WingDBG-2.0.3-2.tar 116: 117:# install our own filesystem skin, this would come from source control normally 118:# install MySkin Product 119:mkdir $MYPRODUCTS_DIR 120:cd $MYPRODUCTS_DIR 121:tar -zxf $base/src/MySkin-0.1.tar.gz 122: 123:# move MySkin directories to $SkinName 124:mv MySkin $SkinName 125:mv $SkinName/skins/MySkin $SkinName/skins/$SkinName 126: 127:# Convert all instances of MySkin to $SkinName in all files 128:cd $SkinName 129:find . -exec sed -i -e "s/MySkin/$SkinName/g" {} \; 130: 131:# copy a logo in here to test if filesystem skin is working 132:cp $base/src/acme.jpg $MYPRODUCTS_DIR/$SkinName/skins/$SkinName/logo.jpg 133: 134:# symlink Product directories between clients 135:rm -rf $ZEOCLIENT0_DIR/Products 136:ln -s $PRODUCTS_DIR $ZEOCLIENT0_DIR/Products 137:rm -rf $ZEOCLIENT1_DIR/Products 138:ln -s $PRODUCTS_DIR $ZEOCLIENT1_DIR/Products 139: 140:# write out the zope.conf files for each client 141:# client0 listens on port $ZOPE_PORT 142:cat << EOF > $ZEOCLIENT0_DIR/etc/zope.conf 143:%define INSTANCE $ZEOCLIENT0_DIR 144:%define ZOPE $ZOPE_HOME 145:instancehome \$INSTANCE 146:debug-mode on 147:products $MYPRODUCTS_DIR 148:<eventlog> 149: level info 150: <logfile> 151: path \$INSTANCE/log/event.log 152: level info 153: </logfile> 154:</eventlog> 155:<logger access> 156: level WARN 157: <logfile> 158: path \$INSTANCE/log/Z2.log 159: format %(message)s 160: </logfile> 161:</logger> 162:<http-server> 163: # valid keys are "address" and "force-connection-close" 164: address $ZOPE_PORT 165: # force-connection-close on 166:</http-server> 167:<zodb_db temporary> 168: # Temporary storage database (for sessions) 169: <temporarystorage> 170: name temporary storage for sessioning 171: </temporarystorage> 172: mount-point /temp_folder 173: container-class Products.TemporaryFolder.TemporaryContainer 174:</zodb_db> 175:<zodb_db main> 176: mount-point / 177: # ZODB cache, in number of objects 178: cache-size 5000 179: <zeoclient> 180: server localhost:$ZEO_PORT 181: storage 1 182: name zeostorage 183: var \$INSTANCE/var 184: # ZEO client cache, in bytes 185: cache-size 20MB 186: # Uncomment to have a persistent disk cache 187: #client zeo1 188: </zeoclient> 189:</zodb_db> 190:EOF 191: 192:# client1 listens on port $ZOPE_PORT+1000 193:cat << EOF > $ZEOCLIENT1_DIR/etc/zope.conf 194:%define INSTANCE $ZEOCLIENT1_DIR 195:%define ZOPE $ZOPE_HOME 196:instancehome \$INSTANCE 197:debug-mode on 198:products $MYPRODUCTS_DIR 199:port-base 1000 200:<eventlog> 201: level info 202: <logfile> 203: path \$INSTANCE/log/event.log 204: level info 205: </logfile> 206:</eventlog> 207:<logger access> 208: level WARN 209: <logfile> 210: path \$INSTANCE/log/Z2.log 211: format %(message)s 212: </logfile> 213:</logger> 214:<http-server> 215: # valid keys are "address" and "force-connection-close" 216: address $ZOPE_PORT 217: # force-connection-close on 218:</http-server> 219:<zodb_db temporary> 220: # Temporary storage database (for sessions) 221: <temporarystorage> 222: name temporary storage for sessioning 223: </temporarystorage> 224: mount-point /temp_folder 225: container-class Products.TemporaryFolder.TemporaryContainer 226:</zodb_db> 227:<zodb_db main> 228: mount-point / 229: # ZODB cache, in number of objects 230: cache-size 5000 231: <zeoclient> 232: server localhost:$ZEO_PORT 233: storage 1 234: name zeostorage 235: var \$INSTANCE/var 236: # ZEO client cache, in bytes 237: cache-size 20MB 238: # Uncomment to have a persistent disk cache 239: #client zeo1 240: </zeoclient> 241:</zodb_db> 242:EOF 243: 244:# start the zeo server 245:$ZEOSERVER_DIR/bin/zeoctl start 246:sleep $SLEEPTIME # give the zeo server a chance to start 247: 248:# add a Plone Site Instance 249:cd $base 250:export PYTHONPATH=$ZOPE_HOME/lib/python:$PYTHONPATH 251:$PYTHON plonehelper.py -c $ZEOCLIENT0_DIR/etc/zope.conf -i $PloneId -t $PloneTitle -d "$PloneDescription" -u $INSTANCE_USER -p $INSTANCE_PASSWORD 252: 253:# Install our new skin product 254:$PYTHON plonehelper.py -c $ZEOCLIENT0_DIR/etc/zope.conf -i $PloneId -n $SkinName 255: 256:# Set the default skin to our skin 257:$PYTHON plonehelper.py -c $ZEOCLIENT0_DIR/etc/zope.conf -i $PloneId -s $SkinName 258: 259:$ZEOSERVER_DIR/bin/zeoctl stop 260: 261:cat << EOF > $base/$StartPloneScript 262:#!/bin/bash 263:set -x 264:$ZEOSERVER_DIR/bin/zeoctl start 265:sleep $SLEEPTIME # to allow zeo to start 266:$ZEOCLIENT0_DIR/bin/zopectl start 267:sleep $SLEEPTIME # to allow client 0 to start 268:echo "Plone site is running on http://localhost:$ZOPE_PORT/$PloneId" 269:EOF 270: 271:cat << EOF > $base/$StopPloneScript 272:#!/bin/bash 273:set -x 274:$ZEOCLIENT0_DIR/bin/zopectl stop 275:$ZEOSERVER_DIR/bin/zeoctl stop 276:EOF 277: 278:chmod +x $base/$StartPloneScript 279:chmod +x $base/$StopPloneScript 280: 281:# set up the ipython zope script 282:cat << EOF > $base/$StartIPythonScript 283:#!/bin/bash 284:set -x 285:export PYTHONPATH=$ZOPE_HOME/lib/python:$PYTHONPATH 286:$PYTHON -i -c "from Zope import configure;configure('$ZEOCLIENT1_DIR/etc/zope.conf');import Zope; app=Zope.app();ns={'__name__':'blah','app':app};import IPython;IPython.Shell.IPShell(user_ns=ns).mainloop(sys_exit=1);" 287:EOF 288: 289:chmod +x $base/$StartIPythonScript 290: 291:# set up a python script to allow debugging from various python debuggers 292:cat << EOF > $base/$PythonDebugScript 293:import sys, os, time 294:print 'starting zeo server' 295:os.system("$ZEOSERVER_DIR/bin/zeoctl start") 296:print 'waiting for $SLEEPTIME seconds to allow zeo server to complete startup' 297:time.sleep($SLEEPTIME) 298:ZOPE_HOME="$ZOPE_HOME" 299:SOFTWARE_HOME= os.path.join(ZOPE_HOME,"lib","python") 300:sys.path.insert(0, SOFTWARE_HOME ) 301:import Zope , ZPublisher 302:sys.argv = ['run.py', '-C', '$ZEOCLIENT0_DIR/etc/zope.conf'] 303:Zope.Startup.run.run() 304:EOF 305: 306:echo "Finished, you can either:" 307:echo "run ./$StartPloneScript to start plone on http://localhost:$ZOPE_PORT/$PloneId" 308:echo "the run ./$StartIPythonScript to inspect zope/plone api and ZODB" 309:echo "run ./$StopPloneScript to stop plone" 310:echo "or run (from your development environment)" 311:echo "python $PythonDebugScript" 312:echo "run ./$StopPloneScript to stop the zeo server when you stop the python script" 313:
1:""" 2:plonehelper.py -c configFile -i plone_id -t plone_title -d plone_description -u username -p password 3: 4:functions to add and adminsiter a Plone Site from script 5:""" 6:import sys 7:import getopt 8:from Zope.Startup.run import configure 9:import Zope 10:import urllib 11:#from Products.CMFPlone import transaction 12:import time 13: 14:version=0.1 15: 16:def add_plone_site(app, plone_id, plone_title, plone_description, username, password): 17: req ='/manage_addProduct/CMFPlone/manage_addSite?id=%s&title=%s&create_userfolder=1&description=%s&custom_policy=Default+Plone&submit=+Add+Plone+Site+'%(urllib.quote(plone_id), urllib.quote(plone_title), urllib.quote(plone_description)) 18: Zope.debug(req,u='%s:%s'%(username, password)) 19: 20:def set_default_skin(ploneSite, skin_name): 21: # set our new skin as the default skin 22: ploneSite.portal_skins.default_skin = skin_name 23: 24:def install_product(ploneSite, product_name): 25: # install the product 26: quick_installer = ploneSite.portal_quickinstaller 27: quick_installer.installProduct(product_name) 28: #print quick_installer.listInstalledProducts() 29: 30:def main(argv = None): 31: if argv is None: 32: argv = sys.argv 33: config_file = None 34: username = '' 35: password = '' 36: plone_id = '' 37: plone_title = None 38: plone_description = '' 39: skin_name = None 40: product_name = None 41: try: 42: opts, args = getopt.getopt(argv[1:], "hvc:i:t:d:u:p:s:n:", ["help", "version"]) 43: except getopt.error, msg: 44: print msg 45: print(__doc__) 46: sys.exit(0) 47: for o, a in opts: 48: if o in ("-h", "--help"): 49: print(__doc__) 50: sys.exit(0) 51: elif o in ("-v", "--version"): 52: log("version: %s"%version) 53: sys.exit(0) 54: elif o in ("-c"): 55: config_file = a 56: elif o in ("-u"): 57: username = a 58: elif o in ("-p"): 59: password = a 60: elif o in ("-i"): 61: plone_id = a 62: elif o in ("-t"): 63: plone_title = a 64: elif o in ("-d"): 65: plone_description = a 66: elif o in ("-s"): 67: skin_name = a 68: elif o in ("-n"): 69: product_name = a 70: 71: if config_file is not None: 72: configure(config_file) 73: app = Zope.app() 74: if plone_id is not None: 75: if plone_title is not None: 76: add_plone_site(app, plone_id, plone_title, plone_description, username, password) 77: else: 78: ploneSite = eval('app.'+plone_id) 79: if ploneSite != None: 80: if product_name is not None: 81: install_product(ploneSite, product_name) 82: if skin_name is not None: 83: set_default_skin(ploneSite, skin_name) 84: else: 85: print 'Could not find plone site with id ', plone_id 86: # commit these changes 87: get_transaction().commit() 88: #transaction.commit() 89: else: 90: print 'you must specify a unique plone id to create a plone site' 91: else: 92: print 'you must supply a configuration file: /path/to/zope.conf' 93: 94:if __name__=='__main__': 95: main()

1 Comments:
Thanks for pulling all this stuff together!
Post a Comment
<< Home