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:
- 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)
Problems with Team Development in Zope
- 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.
Possible solution
- 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.
While point 1 is covered well in the literature, it is not so easy to find scripts for setting up a Plone instance.
This hack shows a
bash script that sets up a Plone instance from a script and which installs the
MySkin product into this Plone instance.
This gives us the starting point for
File system based Plone development.
To execute this script and build plone 2.1 do the following (on linux, I use
Gentoo and gcc 3.4.4).
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
This should (all going well) leave you with the following directory structure
~/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)
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:
./startIPythonPlone2.1-rc3.sh
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,
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:
Try the following commands in ipython to get a feel for the plone api (make sure to test the TAB button for auto-completion.)
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()
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
./setupplonezeo.sh 0 TestSite 8888
This would leave you with the following directory structure (assuming you ran the command "./setupplonezeo.sh 1" previously)
~/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)
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
./setupplonezeo.sh 0 TestSite 8888 63
References
- 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
Scripts
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:
plonehelper.py
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()