{ "info": { "author": "Mathieu Pasquet, Jean-Philippe Camguilhem", "author_email": "kiorky@cryptelium.net, jean-philippe.camguilhem@makina-corpus.com", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "==========================\r\nIntroduction\r\n==========================\r\n\r\n.. contents::\r\n\r\n\r\nCGWB is a web interface to ``paster``, its goal is to generate a webinterface to selection options aggregated from a set of templates.\r\n\r\nImagine that you have 2 templates, the one that can deploy an application, and the other which generates the application in itself.\r\n\r\nDeclaring the two templates as a ``cgwb set`` will make a webinterface for those 2 templates. Answering correctly to the questions will produce a tarball that you ll be able download and unpack to have your base installation setup.\r\n\r\nTo make the templates available, you must define the set using ZCML.\r\n\r\n\r\nAs this server was developped as a quick and efficient interface to paster, *it is not safe to open it to wide internet.*\r\nFor security reason, just launch/use when you need it.\r\n\r\nNext versions will include some sessions/roles and improved security, it may be possible at this stage to leave it open.\r\n\r\n\r\nSee in action `here `_\r\n\r\n\r\n\r\nCredits\r\n=========================================\r\n\r\n\r\nCompanies\r\n----------------\r\n|makinacom|_\r\n\r\n* `Planet Makina Corpus `_\r\n* `Contact us `_\r\n\r\n.. |makinacom| image:: http://depot.makina-corpus.org/public/logo.gif\r\n.. _makinacom: http://www.makina-corpus.com\r\n\r\nAuthors\r\n---------------\r\n\r\n - kiorky \r\n - Jean-Philippe Camguilhem \r\n\r\n\r\n\r\nInstallation\r\n==============\r\n\r\nInstalling cgwb in a minitage\r\n-----------------------------------\r\nYou are not obliged to run with `minitage`_ even if it is the recommended mode for running at least the plones template.\r\n\r\nAssuming that your minitage lives in ~/minitage, issue the following::\r\n\r\n export MT=~/minitage\r\n\r\nInstall or udpate minitage in your dedicated virtualenv if any\r\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r\nJust do that (you must refer to `minitage installation`_ for prerequisites)\r\n\r\nInstall virtualenv\r\n::\r\n\r\n virtualenv --no-site-packages --distribute $MT\r\n\r\nUpdate minitage packages\r\n::\r\n\r\n source $MT/bin/activate\r\n easy_install -U minitage.core\r\n easy_install -U minitage.paste\r\n minimerge -s\r\n\r\n\r\nInstall cgwb\r\n++++++++++++++++++++++\r\nDownload & install via the minibuild\r\n::\r\n\r\n source $MT/bin/activate\r\n git clone http://github.com/collective/collective.generic.webbuilder-minilay.git $MT/minilays/cgwb\r\n minimerge -v cgwb\r\n\r\n\r\nCgwb lives in ``$MT/bfg/cgwb``.\r\n\r\nGenerating & deploying your project using minitage\r\n-----------------------------------------------------------\r\nLaunching the cgwb server\r\n++++++++++++++++++++++++++++++++\r\nLaunch via ``bin/cgwb``.\r\nThis binary includes some options to let you override the default port (--port) and listenning address (--host)\r\nTo see all the available options, just use::\r\n\r\n bin/cgwb --help\r\n\r\nIf you use minitage, mandatory to use the minitage.instances.env profile::\r\n\r\n $MT/bin/easy_install -U minitage.paste\r\n $MT/bin/paster create -t minitage.instances.env cgwb\r\n\r\nMINITAGE .ENV\r\n++++++++++++++++++++\r\nEach time you use cgwb, you use the .ENV::\r\n\r\n source $MT/bfg/cgwb/sys/share/minitage/minitage.env\r\n\r\nUse it\r\n++++++++++++++\r\nLaunch it::\r\n\r\n cd $INS\r\n ./bin/cgwb --port=6253\r\n\r\n\r\n- At the moment, cgwb do not have some session mecanism, so the only way to replay a generation is to use the selenium firefox plugin.\r\n- If you want to store your choices to redo an updated tarball later, just install the SeleniumIDE firefox plugin and use it to record your session.\r\n- Maybe, activate selenium and\r\n\r\n - Go to the `cgwb`_\r\n - Choose `Generic Portal Plone3`.\r\n\r\nFilling the settings, some notes\r\n+++++++++++++++++++++++++++++++++++++++++++\r\n- project name is mandatory and must be in the form in `project` or `subproject`.\r\n- You can choose in the `Plone Products to auto checkout in development mode` the products from the community from which we should check out & use in development mode\r\n\r\nTHE IMPORTANT PART AROUND INITIATING A PROJECT\r\n+++++++++++++++++++++++++++++++++++++++++++++++++\r\n- It would be good unless you have some minitage experience to version the code prior to build, because of minitage update mecanism.\r\n- Before version/import the code in your SCM you must elude the following points:\r\n\r\n * By default, the generated tarball contains the buildout layout and all the eggs in src, and the buildout use them as develop eggs and NOT WITH MR.DEVELOPER.\r\n Thus for running the buildout in standalone mode\r\n * You may decide not to include them as-is but to separate the code and version the code elsewhere.\r\n * I would advice you to checkout the packages with mr.developer.\r\n\r\nAn example of using svn which generic/pyramid\r\n+++++++++++++++++++++++++++++++++++++++++++++\r\nWhat i would do from a generated tarball for using subversion as my SCM could be to produce this layout::\r\n\r\n import\r\n |-- import/eggs\r\n | |-- import/eggs/myproject.core\r\n | | `-- import/eggs/myproject.core/trunk\r\n `-- import/buildout\r\n\r\n\r\n- Exporting base variables::\r\n\r\n export PROJECT=\"myproject\" # your project name as filled in the web interfacE\r\n export TARBALL=\"$(ls -1t ~/cgwb/${PROJECT}-*.tar.gz|head -n1)\" # produced tarball\r\n export IMPORT_URL=\"https://subversion.xxx.net/scrumpy/${PROJECT}/\" # base svn place to import\r\n\r\n- Create a temporary workspace::\r\n\r\n mkdir -p $PROJECT/tarball\r\n cd $PROJECT\r\n tar xzvf $TARBALL -C tarball/\r\n\r\n- Create the base layout to be imported::\r\n\r\n mkdir -p import/buildout import/eggs\r\n\r\n- Move the generated plone extensions eggs to a separate place to be imported::\r\n\r\n for i in tarball/src/${PROJECT}*;do if [[ -d $i ]] && [[ $(basename $i) != \"themes\" ]];then j=$(basename $i);dest=import/eggs/$j/trunk; mkdir -pv $(dirname $dest); mv -v $i $dest; fi; done\r\n\r\n- Move the buildout structure in the import layout::\r\n\r\n cp -rf tarball/* import/buildout\r\n\r\n- Update buildout to use mr.developer instead of basic develop::\r\n\r\n * move off the develop declaration::\r\n\r\n sed -re \"s:(src/)?$PROJECT\\.((skin)|(tma)|(core)|(testing))::g\" -i import//buildout/etc/project/$PROJECT.cfg\r\n\r\n * add to mr.developer sources::\r\n\r\n sed -re \"/\\[sources\\]/{\r\n a $PROJECT.core = svn $IMPORT_URL/eggs/$PROJECT.core/trunk\r\n }\" -i import/buildout/etc/project/sources.cfg\r\n\r\n * add to auto checkout packages::\r\n\r\n sed -re \"/auto-checkout \\+=/{\r\n a \\ $PROJECT.core\r\n }\" -i import/buildout/etc/project/sources.cfg\r\n sed -re \"/eggs \\+=.*buildout:eggs/{\r\n a \\ $PROJECT.core\r\n }\" -i import/buildout/etc/project/$PROJECT.cfg\r\n sed -re \"/zcml \\+=/{\r\n a \\ $PROJECT.core\r\n }\" -i import/buildout/etc/project/$PROJECT.cfg\r\n\r\n* be sure to use the right svn url to checkout::\r\n\r\n sed -re \"s|src_uri.*|src_uri=$IMPORT_URL/buildout/|g\" -i import/buildout/minilays/$PROJECT/*\r\n\r\n* Be sure to use svn\r\n\r\n sed -re \"s|src_type.*|src_type=svn|g\" -i import/buildout/minilays/$PROJECT/*\r\n\r\n* Import::\r\n\r\n svn import import/ $IMPORT_URL -m \"initial import\" \r\n\r\nAn example of using svn which generic/plone\r\n+++++++++++++++++++++++++++++++++++++++++++++\r\nWhat i would do from a generated tarball for using subversion as my SCM could be to produce this layout::\r\n\r\n import\r\n |-- import/eggs\r\n | |-- import/eggs/myproject.policy\r\n | | `-- import/eggs/myproject.policy/trunk\r\n | |-- import/eggs/myproject.skin\r\n | | `-- import/eggs/myproject.skin/trunk\r\n | |-- import/eggs/myproject.testing\r\n | | `-- import/eggs/myproject.testing/trunk\r\n | `-- import/eggs/myproject.tma\r\n | `-- import/eggs/myproject.tma/trunk\r\n `-- import/minitage\r\n |-- import/minitage/buildouts\r\n | `-- import/minitage/buildouts/zope\r\n | `-- import/minitage/buildouts/zope/myproject\r\n\r\n\r\n- Exporting base variables::\r\n\r\n export PROJECT=\"myproject\" # your project name as filled in the web interfacE\r\n export TARBALL=\"$(ls -1t ~/cgwb/${PROJECT}-*.tar.gz|head -n1)\" # produced tarball\r\n export IMPORT_URL=\"https://subversion.xxx.net/scrumpy/${PROJECT}/ # base svn place to import\r\n\r\n- Create a temporary workspace::\r\n\r\n mkdir -p $PROJECT/tarball\r\n cd $PROJECT\r\n tar xzvf $TARBALL -C tarball/\r\n\r\n- Create the base layout to be imported::\r\n\r\n mkdir -p import/buildout import/eggs\r\n\r\n- Move the generated plone extensions eggs to a separate place to be imported::\r\n\r\n for i in tarball/src/${PROJECT}*;do if [[ -d $i ]] && [[ $(basename $i) != \"themes\" ]];then j=$(basename $i);dest=import/eggs/$j/trunk; mkdir -pv $(dirname $dest); mv -v $i $dest; fi; done\r\n\r\n- Move the buildout structure in the import layout::\r\n\r\n cp -rf tarball/* import/buildout\r\n\r\n- Update buildout to use mr.developer instead of basic develop::\r\n\r\n * move off the develop declaration::\r\n\r\n sed -re \"s:(src/)?$PROJECT\\.((skin)|(tma)|(policy)|(testing))::g\" -i import//buildout/etc/project/$PROJECT.cfg\r\n\r\n * add to mr.developer sources::\r\n\r\n sed -re \"/\\[sources\\]/{\r\n a $PROJECT.policy = svn $IMPORT_URL/eggs/$PROJECT.policy/trunk\r\n a $PROJECT.tma = svn $IMPORT_URL/eggs/$PROJECT.tma/trunk\r\n a $PROJECT.skin = svn $IMPORT_URL/eggs/$PROJECT.skin/trunk\r\n a $PROJECT.testing = svn $IMPORT_URL/eggs/$PROJECT.testing/trunk\r\n }\" -i import/buildout/etc/project/sources.cfg\r\n\r\n * add to auto checkout packages::\r\n\r\n sed -re \"/auto-checkout \\+=/{\r\n a \\ $PROJECT.policy\r\n a \\ $PROJECT.tma\r\n a \\ $PROJECT.skin\r\n a \\ $PROJECT.testing\r\n }\" -i import/buildout/etc/project/sources.cfg\r\n sed -re \"/eggs \\+=.*buildout:eggs/{\r\n a \\ $PROJECT.policy\r\n a \\ $PROJECT.tma\r\n a \\ $PROJECT.skin\r\n a \\ $PROJECT.testing\r\n }\" -i import/buildout/etc/project/$PROJECT.cfg\r\n sed -re \"/zcml \\+=/{\r\n a \\ $PROJECT.policy\r\n a \\ $PROJECT.tma\r\n a \\ $PROJECT.skin\r\n }\" -i import/buildout/etc/project/$PROJECT.cfg\r\n\r\n* be sure to use the right svn url to checkout::\r\n\r\n sed -re \"s|src_uri.*|src_uri=$IMPORT_URL/buildout/|g\" -i import/buildout/minilays/$PROJECT/*\r\n\r\n* Be sure to use svn\r\n\r\n sed -re \"s|src_type.*|src_type=svn|g\" -i import/buildout/minilays/$PROJECT/*\r\n\r\n* Import::\r\n\r\n svn import import/ $IMPORT_URL -m \"initial import\"\r\n\r\nAn example of using git which generic\r\n++++++++++++++++++++++++++++++++++++++++\r\nWhat i would do from a generated tarball for using subversion as my SCM could be to produce this layout::\r\n\r\n import\r\n |-- myproject.policy\r\n |-- myproject.skin\r\n |-- myproject.testing\r\n `-- myproject.tma\r\n `-- myproject.buildout\r\n `-- myproject.minilay\r\n\r\n\r\n- Exporting base variables::\r\n\r\n export PROJECT=\"myproject\" # your project name as filled in the web interfacE\r\n export TARBALL=\"$(ls -1t ~/cgwb/${PROJECT}-*.tar.gz|head -n1)\" # produced tarball\r\n export IMPORT_URL=\"ssh://git.makina-corpus.net/var/git\" # base svn place to import\r\n\r\n- Create a temporary workspace & the base layout to be imported::\r\n\r\n mkdir -p $PROJECT/\r\n cd $PROJECT\r\n mkdir tarball import\r\n tar xzvf $TARBALL -C tarball/\r\n\r\n- Move the generated plone extensions eggs to a separate place to be imported::\r\n\r\n for i in tarball/src/*;do if [[ -d $i ]] && [[ $i != \"tarball/src/themes\" ]];then j=$(basename $i);dest=import/$j;mkdir -pv $(dirname $dest); mv -v $i $dest; fi; done\r\n\r\n- Move the buildout structure in the import layout::\r\n\r\n cp -rf tarball/minilays/$PROJECT import/$PROJECT.minilay\r\n rm -rf tarball/minilays\r\n cp -rf tarball/ import/$PROJECT.buildout\r\n\r\n- Update buildout to use mr.developer instead of basic develop::\r\n\r\n * move off the develop declaration::\r\n\r\n sed -re \"s:(src/)?$PROJECT\\.((skin)|(tma)|(policy)|(testing))::g\" -i import/$PROJECT.buildout/etc/project/$PROJECT.cfg\r\n\r\n * add to mr.developer sources::\r\n\r\n sed -re \"/\\[sources\\]/{\r\n a $PROJECT.policy = git $IMPORT_URL/$PROJECT.policy\r\n a $PROJECT.tma = git $IMPORT_URL/$PROJECT.tma\r\n a $PROJECT.skin = git $IMPORT_URL/$PROJECT.skin\r\n a $PROJECT.testing = git $IMPORT_URL/$PROJECT.testing\r\n }\" -i import/$PROJECT.buildout/etc/project/sources.cfg\r\n\r\n * add to auto checkout packages::\r\n\r\n sed -re \"/auto-checkout \\+=/{\r\n a \\ $PROJECT.policy\r\n a \\ $PROJECT.tma\r\n a \\ $PROJECT.skin\r\n a \\ $PROJECT.testing\r\n }\" -i import/$PROJECT.buildout/etc/project/sources.cfg\r\n sed -re \"/eggs \\+=.*buildout:eggs/{\r\n a \\ $PROJECT.policy\r\n a \\ $PROJECT.tma\r\n a \\ $PROJECT.skin\r\n a \\ $PROJECT.testing\r\n }\" -i import/$PROJECT.buildout/etc/project/$PROJECT.cfg\r\n sed -re \"/zcml \\+=/{\r\n a \\ $PROJECT.policy\r\n a \\ $PROJECT.tma\r\n a \\ $PROJECT.skin\r\n }\" -i import/$PROJECT.buildout/etc/project/$PROJECT.cfg\r\n\r\n* be sure to use the right git url to checkout::\r\n\r\n sed -re \"s|src_uri.*|src_uri=$IMPORT_URL/$PROJECT.buildout|g\" -i import/*.minilay/*\r\n\r\n* Be sure to use git\r\n\r\n sed -re \"s|src_type.*|src_type=git|g\" -i import/*.minilay/*\r\n\r\n* Import::\r\n\r\n pushd import;for i in *;do echo \"Importing $i\";pushd $i;git init;git add *;git commit -am \"initial revision\";git remote add origin \"$IMPORT_URL/$i\";git push --all origin;popd;done;popd\r\n\r\nDeploy the project\r\n++++++++++++++++++++++\r\n* install the minilay::\r\n\r\n export MT=~/minitage\r\n svn co $IMPORT_URL/buildout/minilays/$PROJECT/ $MT/minilays/$PROJECT\r\n # or\r\n git clone $IMPORT_URL/$PROJECT.minilay $MT/minilays/$PROJECT\r\n\r\n* Install it::\r\n\r\n minimerge -v $PROJECT\r\n\r\n.. _`minitage installation`: http://minitage.org/installation.html\r\n.. _`cgwb`: http://localhost:6253\r\n.. _`minitage`: http://www.minitage.org\r\n\r\n\r\n\r\n\r\nTests & docs\r\n==============\r\nDefining sets via ZCML\r\n---------------------------------------------------\r\n\r\nA set is a collection of templates, it is also known as a 'PasterConfiguration'.\r\n::\r\n\r\n -------------------------------------------\r\n |\u00a0configuration |\r\n | |\r\n | -----------------------------------\r\n | | templates |\r\n | -----------------------------------\r\n | | | group |\r\n |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 [--------------------------\r\n |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0| | options |\r\n | |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0--------------------\r\n | |\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0|\r\n -------------------------------------------\r\n\r\n\r\nWe will redefine the 'well known' plone template as an example.\r\n\r\nFirst of all, we need to define a template\r\n::\r\n\r\n >>> from zope.configuration import xmlconfig\r\n >>> from zope.configuration.config import ConfigurationMachine\r\n >>> from collective.generic.webbuilder.zcml import PasterConfiguration, Template, Group, ExcludeOption, Option\r\n >>> from collective.generic.webbuilder.models import root\r\n >>> from minitage.paste.projects import plone3\r\n >>> import collective.generic.webbuilder\r\n >>> context = ConfigurationMachine()\r\n >>> xmlconfig.registerCommonDirectives(context)\r\n >>> xmlconfig.include(context, 'meta.zcml', collective.generic.webbuilder)\r\n >>> context = xmlconfig.string(\"\"\"\r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \"\"\", context = context)\r\n\r\n\r\nIt will register/update the ``collective.generic.webbuilder.root.configurations`` module variable\r\n\r\nThe *genericpaster* directive\r\n++++++++++++++++++++++++++++++\r\n- Must be used at top level.\r\n- Name of a configuration of templates.\r\n\r\n::\r\n\r\n \r\n\r\nIt contains a list of underlying configurations\r\n::\r\n\r\n >>> 'Test Generic Portal Plone' in root.configurations\r\n True\r\n\r\nThe configurations objects contain a list of templates and plugins\r\n::\r\n\r\n >>> templates = root.configurations['Test Generic Portal Plone'].templates\r\n >>> sorted(templates.keys())\r\n ['collective.generic.policy', 'minitage.plone3']\r\n\r\n\r\nThe *template* directive\r\n+++++++++++++++++++++++++\r\n- Must be used at genericpaster level.\r\n- It describe a relative \"paster template\". The name which you could get with ``paster create -t --list-templates``.\r\n- It has also an order which is used to order templates in the webinterface for lower to upper.\r\n\r\n::\r\n\r\n \r\n \r\n \r\n\r\n\r\n\r\nThe paster dance\r\n--------------------------\r\n\r\nHeart of cgwb is pythonpaste, take some of paster templates, gather them in an ihm for user inputs and answears for generating a final composition of those templates, with or without been modificated by surrounded plugins.\r\n::\r\n\r\n User choose a configuration\r\n --------->\r\n read variables from templates which are in the configuration and give the appropriate choice to the user\r\n ------------->\r\n User inputs and submit it\r\n -------------------->\r\n We generate a tarball of the assembled templates according to the answers\r\n\r\n* An option is asked only once, only you make aliases for each of the options which have the same name among templates.\r\n* As a question is asked only once, if its type is not default, you must define it in the configuration of the template which has the less order number, because there will be there the question will be asked.\r\n\r\n\r\nLoading a zcml representation of a configuration\r\n---------------------------------------------------\r\n\r\nTesting the zcml to python represetation\r\n+++++++++++++++++++++++++++++++++++++++++++++\r\n\r\nLoad our test package where we have three templates\r\n::\r\n\r\n >>> import collective.generic.webbuilder.tests\r\n >>> testegg = os.path.join( collective.generic.webbuilder.tests.__path__[0], 'egg', 'src')\r\n >>> pkg_resources.working_set.add_entry(testegg)\r\n >>> env = pkg_resources.Environment()\r\n >>> egg = env['cgwb.tp'][0]\r\n\r\nThe configuration\r\n+++++++++++++++++++\r\nIt is more described in the zcml part of the documentation, but it's a zcml representation of which variables from the pastertemplates we want to extract and how we want to present them to users.\r\n\r\n\r\nA sample zcml needed to assemble the packages we declared before is as follow:\r\n::\r\n\r\n >>> paster_zcml = \"\"\"\r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \r\n ... \"\"\"\r\n >>> noecho = xmlconfig.string(paster_zcml)\r\n >>> root.configurations['test Assembler']\r\n \r\n\r\nWe will check now that the structure loaded is as we wanted\r\n::\r\n\r\n >>> t1 = pkg_resources.load_entry_point('cgwb.tp', 'paste.paster_create_template', 'cgwb.testpackage1')\r\n >>> t2 = pkg_resources.load_entry_point('cgwb.tp', 'paste.paster_create_template', 'cgwb.testpackage2')\r\n >>> t3 = pkg_resources.load_entry_point('cgwb.tp', 'paste.paster_create_template', 'cgwb.testpackage3')\r\n >>> server, url = launch_server()\r\n >>> browser = Browser(url)\r\n\r\nWe can see that in the main page we have the default configurations and the custom loaded one\r\n::\r\n\r\n >>> 'test Assembler' in browser.contents\r\n True\r\n >>> 'Generic Portal Plone4' in browser.contents\r\n True\r\n >>> 'Generic Portal Plone3' in browser.contents\r\n True\r\n\r\nFollowing the test assembler link\r\n::\r\n\r\n >>> browser.getLink('test Assembler').click()\r\n >>> htmlS(browser.contents).xpath('//input[@name=\"project\"]')[0]\r\n \r\n\r\nI can submit a form and a valid it\r\n::\r\n\r\n >>> browser.getControl(name='project').value = 'myproject'\r\n >>> browser.getControl(name='author').value = 'tim burton'\r\n >>> browser.getControl(name='author_email').value = 'tim burton@foo.com'\r\n >>> browser.getControl(name='tp1option').value = False\r\n >>> browser.getControl(name='tp1option2').value = 'Project Monster'\r\n >>> browser.getControl(name='project_name').value = 'My Big Project'\r\n >>> browser.getControl(name='submit_cgwbDownload').click()\r\n >>> '.tar' in browser.contents\r\n True\r\n\r\nThe sucessful produced result is a tarball\r\n::\r\n\r\n >>> pprint(browser.headers.headers)\r\n ['Server:...\r\n 'Date:...\r\n 'Content-Disposition: attachment; filename=\"myproject....tar.gz\"\\r\\n',\r\n 'Content-Transfer-Encoding: binary\\r\\n',\r\n 'Content-Length: ...\\r\\n']\r\n >>> import tarfile\r\n >>> tar = tarfile.open(fileobj=StringIO(browser.contents))\r\n\r\nIn the produced tarball, output directories present in the zcml configuration are respected in the tarball::\r\n\r\n >>> files = [a.name for a in tar];files.sort();pprint(files)\r\n ['.',\r\n '1',\r\n '1/myproject',\r\n '1/myproject/test',\r\n '2',\r\n '2/myproject',\r\n '2/myproject/test1',\r\n '3',\r\n '3/myproject',\r\n '3/myproject/test2']\r\n >>> templates = dict([(a.name,a) for a in tar if 'test' in a.name])\r\n >>> t2 = templates['2/myproject/test1']\r\n >>> t3 = templates['3/myproject/test2']\r\n >>> t1 = templates['1/myproject/test']\r\n\r\nOptions filled in the interface are well interpreted in templates\r\n::\r\n\r\n >>> pprint([a for a in tar.extractfile(t1).read().split('\\n') if a.strip()])\r\n ['namespace => %(namespace)s',\r\n 'nested_namespace => %(package)s',\r\n 'version => 1.0',\r\n 'author => tim burton',\r\n 'author_email => tim burton@foo.com',\r\n 'tp1option => False',\r\n 'tp1option2 => Project Monster',\r\n 'tp1option3 => True',\r\n 'keywords => ',\r\n 'license_name => GPL',\r\n 'project_name => My Big Project']\r\n\r\nThe project_name entered for project1 is shared in project2\r\n::\r\n\r\n >>> pprint([a for a in tar.extractfile(t2).read().split('\\n') if a.strip()])\r\n [\"'namespace' => '%(namespace)s'\",\r\n \"'nested_namespace' => '%(package)s'\",\r\n \"'version' => '1.0'\",\r\n \"'author' => 'tim burton'\",\r\n \"'author_email' => 'tim burton@foo.com'\",\r\n \"'keywords' => ''\",\r\n \"'license_name' => 'GPL'\",\r\n \"'project_name' => 'My Big Project'\",\r\n \"'tp2option' => 'tp2option'\",\r\n \"'tp2opton2' => 'tp2opton2'\"]\r\n\r\nthe aliased project_name (tma) takes efffect in the third template\r\n::\r\n\r\n >>> pprint([a for a in tar.extractfile(t3).read().split('\\n') if a.strip()])\r\n [\"'namespace' => '%(namespace)s'\",\r\n \"'nested_namespace' => '%(package)s'\",\r\n \"'version' => '1.0'\",\r\n \"'author' => 'tim burton'\",\r\n \"'author_email' => 'tim burton@foo.com'\",\r\n \"'keywords' => ''\",\r\n \"'license_name' => 'GPL'\",\r\n \"'project_name' => 'tma'\",\r\n \"'tp3option3' => 'Project %s'\",\r\n \"'tp3option' => 'Project %s'\"]\r\n\r\n\r\n\r\n\r\nChangelog\r\n=========\r\n\r\n1.1\r\n----------\r\n\r\n* documentation, because webbuilder needs to be installed in dev mode, anyhow.\r\n\r\n1.0 \r\n----------------\r\n* Initial release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/collective.generic.webbuilder", "keywords": "", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "collective.generic.webbuilder", "package_url": "https://pypi.org/project/collective.generic.webbuilder/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/collective.generic.webbuilder/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/collective.generic.webbuilder" }, "release_url": "https://pypi.org/project/collective.generic.webbuilder/1.1/", "requires_dist": null, "requires_python": null, "summary": "Yet another WSGI Paste factory for paste by Makina Corpus", "version": "1.1" }, "last_serial": 1030924, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "02377a230a6d976fbbbb7e38d15648dd", "sha256": "8e90347ffa4425e8a6dcd654b0703f512d62017299577fe575697b929c9c17d4" }, "downloads": -1, "filename": "collective.generic.webbuilder-1.0.tar.gz", "has_sig": false, "md5_digest": "02377a230a6d976fbbbb7e38d15648dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 231602, "upload_time": "2011-11-24T10:45:59", "url": "https://files.pythonhosted.org/packages/af/53/6262ef928aa3731eeadae90abf4dab134cae83c689dcfc46d4073615a55d/collective.generic.webbuilder-1.0.tar.gz" }, { "comment_text": "", "digests": { "md5": "4adf0c9aad7efce2aa0b73eaca19ff89", "sha256": "cf3175ad2b95cf5ce47824f5ad0ee62c24c5f3446e651bf359f30d6dc9832535" }, "downloads": -1, "filename": "collective.generic.webbuilder-1.0.zip", "has_sig": false, "md5_digest": "4adf0c9aad7efce2aa0b73eaca19ff89", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 328036, "upload_time": "2010-04-21T13:13:39", "url": "https://files.pythonhosted.org/packages/a0/bf/33c7be248d7a84e6c76796530b20a747ff4d6c6f6b06532dd4c834eaff87/collective.generic.webbuilder-1.0.zip" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "bfa3b0506e3af818e313940f5bd0396e", "sha256": "4ea38f499d564950fe98b8ae194fa6019f695d00adb66d9dc51cf2fa9480b04f" }, "downloads": -1, "filename": "collective.generic.webbuilder-1.1.tar.gz", "has_sig": false, "md5_digest": "bfa3b0506e3af818e313940f5bd0396e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 233630, "upload_time": "2011-11-24T11:01:58", "url": "https://files.pythonhosted.org/packages/bc/e4/34eb88dc9ada4d2c7f8be3adcc283be2aecf24626efdc82494883d0a0226/collective.generic.webbuilder-1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "bfa3b0506e3af818e313940f5bd0396e", "sha256": "4ea38f499d564950fe98b8ae194fa6019f695d00adb66d9dc51cf2fa9480b04f" }, "downloads": -1, "filename": "collective.generic.webbuilder-1.1.tar.gz", "has_sig": false, "md5_digest": "bfa3b0506e3af818e313940f5bd0396e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 233630, "upload_time": "2011-11-24T11:01:58", "url": "https://files.pythonhosted.org/packages/bc/e4/34eb88dc9ada4d2c7f8be3adcc283be2aecf24626efdc82494883d0a0226/collective.generic.webbuilder-1.1.tar.gz" } ] }