[CMF-checkins] SVN: CMF/branches/yuppie-catalog_setup-redo/ added
missing files and changes. should work now.
Yvo Schubbe
y.2005- at wcm-solutions.de
Sun Sep 25 17:00:36 EDT 2005
Log message for revision 38629:
added missing files and changes. should work now.
(there is still some test failures if all tests are run)
Changed:
A CMF/branches/yuppie-catalog_setup-redo/CMFCalendar/profiles/default/catalog.xml
U CMF/branches/yuppie-catalog_setup-redo/CMFCalendar/setuphandlers.py
A CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/catalog.xml
U CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/export_steps.xml
U CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/import_steps.xml
A CMF/branches/yuppie-catalog_setup-redo/CMFSetup/catalog.py
A CMF/branches/yuppie-catalog_setup-redo/CMFSetup/tests/test_catalog.py
A CMF/branches/yuppie-catalog_setup-redo/GenericSetup/configure.zcml
U CMF/branches/yuppie-catalog_setup-redo/GenericSetup/interfaces.py
A CMF/branches/yuppie-catalog_setup-redo/GenericSetup/testing.py
U CMF/branches/yuppie-catalog_setup-redo/GenericSetup/utils.py
-=-
Copied: CMF/branches/yuppie-catalog_setup-redo/CMFCalendar/profiles/default/catalog.xml (from rev 38606, CMF/branches/yuppie-catalog_setup/CMFCalendar/profiles/default/catalog.xml)
Modified: CMF/branches/yuppie-catalog_setup-redo/CMFCalendar/setuphandlers.py
===================================================================
--- CMF/branches/yuppie-catalog_setup-redo/CMFCalendar/setuphandlers.py 2005-09-25 17:47:34 UTC (rev 38628)
+++ CMF/branches/yuppie-catalog_setup-redo/CMFCalendar/setuphandlers.py 2005-09-25 21:00:35 UTC (rev 38629)
@@ -17,7 +17,6 @@
from Products.CMFCore.utils import getToolByName
-from exceptions import CatalogError
from exceptions import MetadataError
@@ -28,27 +27,8 @@
are implemented for these steps.
"""
site = context.getSite()
- ctool = getToolByName(site, 'portal_catalog')
mdtool = getToolByName(site, 'portal_metadata')
- # Set up a catalog indexes and metadata
- try:
- ctool.addIndex('start', 'DateIndex')
- except CatalogError:
- pass
- try:
- ctool.addIndex('end', 'DateIndex')
- except CatalogError:
- pass
- try:
- ctool.addColumn('start')
- except CatalogError:
- pass
- try:
- ctool.addColumn('end')
- except CatalogError:
- pass
-
# Set up a MetadataTool element policy for events
try:
_ = str # MetadataTool ist not aware of MessageIDs
Copied: CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/catalog.xml (from rev 38606, CMF/branches/yuppie-catalog_setup/CMFDefault/profiles/default/catalog.xml)
Modified: CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/export_steps.xml
===================================================================
--- CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/export_steps.xml 2005-09-25 17:47:34 UTC (rev 38628)
+++ CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/export_steps.xml 2005-09-25 21:00:35 UTC (rev 38629)
@@ -22,6 +22,17 @@
</export-step>
+ <export-step id="catalog"
+ handler="Products.CMFSetup.catalog.exportCatalogTool"
+ title="Catalog Tool">
+
+
+
+ Export catalog tool's sub-objects, indexes and columns.
+
+
+
+ </export-step>
<export-step id="properties"
handler="Products.CMFSetup.properties.exportSiteProperties"
title="Site Properties">
Modified: CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/import_steps.xml
===================================================================
--- CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/import_steps.xml 2005-09-25 17:47:34 UTC (rev 38628)
+++ CMF/branches/yuppie-catalog_setup-redo/CMFDefault/profiles/default/import_steps.xml 2005-09-25 21:00:35 UTC (rev 38629)
@@ -27,6 +27,19 @@
</import-step>
+ <import-step id="catalog" version="20050918-01"
+ handler="Products.CMFSetup.catalog.importCatalogTool"
+ title="Catalog Tool">
+ <dependency step="toolset"/>
+
+
+
+ Import catalog tool's sub-objects, indexes and columns.
+
+
+
+
+ </import-step>
<import-step id="properties" version="20041215-01"
handler="Products.CMFSetup.properties.importSiteProperties"
title="Site Properties">
Copied: CMF/branches/yuppie-catalog_setup-redo/CMFSetup/catalog.py (from rev 38606, CMF/branches/yuppie-catalog_setup/CMFSetup/catalog.py)
===================================================================
--- CMF/branches/yuppie-catalog_setup/CMFSetup/catalog.py 2005-09-24 22:35:29 UTC (rev 38606)
+++ CMF/branches/yuppie-catalog_setup-redo/CMFSetup/catalog.py 2005-09-25 21:00:35 UTC (rev 38629)
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Catalog tool setup handlers.
+
+$Id$
+"""
+
+from xml.dom.minidom import parseString
+
+from Products.CMFCore.utils import getToolByName
+from Products.GenericSetup.interfaces import INodeExporter
+from Products.GenericSetup.interfaces import INodeImporter
+from Products.GenericSetup.interfaces import PURGE, UPDATE
+from Products.GenericSetup.utils import PrettyDocument
+
+_FILENAME = 'catalog.xml'
+
+
+def importCatalogTool(context):
+ """ Import catalog tool.
+ """
+ site = context.getSite()
+ mode = context.shouldPurge() and PURGE or UPDATE
+ ctool = getToolByName(site, 'portal_catalog')
+
+ body = context.readDataFile(_FILENAME)
+ if body is None:
+ return 'Catalog tool: Nothing to import.'
+
+ importer = INodeImporter(ctool, None)
+ if importer is None:
+ return 'Catalog tool: Import adapter misssing.'
+
+ importer.importNode(parseString(body).documentElement, mode=mode)
+ return 'Catalog tool imported.'
+
+def exportCatalogTool(context):
+ """ Export catalog tool.
+ """
+ site = context.getSite()
+
+ ctool = getToolByName(site, 'portal_catalog', None)
+ if ctool is None:
+ return 'Catalog tool: Nothing to export.'
+
+ exporter = INodeExporter(ctool)
+ if exporter is None:
+ return 'Catalog tool: Export adapter misssing.'
+
+ doc = PrettyDocument()
+ doc.appendChild(exporter.exportNode(doc))
+ context.writeDataFile(_FILENAME, doc.toprettyxml(' '), 'text/xml')
+ return 'Catalog tool exported.'
Copied: CMF/branches/yuppie-catalog_setup-redo/CMFSetup/tests/test_catalog.py (from rev 38606, CMF/branches/yuppie-catalog_setup/CMFSetup/tests/test_catalog.py)
Copied: CMF/branches/yuppie-catalog_setup-redo/GenericSetup/configure.zcml (from rev 38606, CMF/branches/yuppie-catalog_setup/CMFSetup/configure.zcml)
Modified: CMF/branches/yuppie-catalog_setup-redo/GenericSetup/interfaces.py
===================================================================
--- CMF/branches/yuppie-catalog_setup-redo/GenericSetup/interfaces.py 2005-09-25 17:47:34 UTC (rev 38628)
+++ CMF/branches/yuppie-catalog_setup-redo/GenericSetup/interfaces.py 2005-09-25 21:00:35 UTC (rev 38629)
@@ -18,7 +18,8 @@
from zope.interface import Interface
-BASE, EXTENSION = range(2)
+BASE, EXTENSION = range(1,3)
+PURGE, UPDATE = range(1, 3)
class IPseudoInterface( Interface ):
@@ -511,3 +512,23 @@
o If 'ignore_whitespace', then suppress diffs due only to whitespace
(c.f: 'diff -wbB')
"""
+
+
+class INodeExporter(Interface):
+
+ """Node exporter.
+ """
+
+ def exportNode(doc):
+ """Export the object as a DOM node.
+ """
+
+
+class INodeImporter(Interface):
+
+ """Node importer.
+ """
+
+ def importNode(node, mode=PURGE):
+ """Import the object from the DOM node.
+ """
Copied: CMF/branches/yuppie-catalog_setup-redo/GenericSetup/testing.py (from rev 38606, CMF/branches/yuppie-catalog_setup/CMFSetup/testing.py)
Modified: CMF/branches/yuppie-catalog_setup-redo/GenericSetup/utils.py
===================================================================
--- CMF/branches/yuppie-catalog_setup-redo/GenericSetup/utils.py 2005-09-25 17:47:34 UTC (rev 38628)
+++ CMF/branches/yuppie-catalog_setup-redo/GenericSetup/utils.py 2005-09-25 21:00:35 UTC (rev 38629)
@@ -17,6 +17,11 @@
import os
from inspect import getdoc
+from xml.dom.minidom import _nssplit
+from xml.dom.minidom import _write_data
+from xml.dom.minidom import Document
+from xml.dom.minidom import Element
+from xml.dom.minidom import Node
from xml.dom.minidom import parseString as domParseString
from xml.sax.handler import ContentHandler
@@ -27,8 +32,12 @@
from Globals import InitializeClass
from Globals import package_home
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from zope.interface import implements
from exceptions import BadRequest
+from interfaces import INodeExporter
+from interfaces import INodeImporter
+from interfaces import PURGE
from permissions import ManagePortal
@@ -38,6 +47,7 @@
_xmldir = os.path.join( _pkgdir, 'xml' )
CONVERTER, DEFAULT, KEY = range(3)
+I18NURI = 'http://xml.zope.org/namespaces/i18n'
def _getDottedName( named ):
@@ -512,3 +522,264 @@
return _coalesceTextNodeChildren(d_nodes[0], encoding)
else:
return ''
+
+
+# XXX: Is there any code available in Zope that generates pretty XML? If not,
+# this code has to be improved.
+class _Element(Element):
+
+ """minidom element with 'pretty' XML output.
+ """
+
+ def writexml(self, writer, indent="", addindent="", newl=""):
+ # indent = current indentation
+ # addindent = indentation to add to higher levels
+ # newl = newline string
+ writer.write(indent+"<" + self.tagName)
+
+ attrs = self._get_attributes()
+ a_names = attrs.keys()
+ a_names.sort()
+ if 'title' in a_names:
+ a_names.remove('title')
+ a_names.insert(0, 'title')
+ if 'meta_type' in a_names:
+ a_names.remove('meta_type')
+ a_names.insert(0, 'meta_type')
+ if 'name' in a_names:
+ a_names.remove('name')
+ a_names.insert(0, 'name')
+
+ for a_name in a_names:
+ writer.write(" %s=\"" % a_name)
+ _write_data(writer, attrs[a_name].value)
+ writer.write("\"")
+ if self.childNodes:
+ if self.firstChild.nodeType == Node.TEXT_NODE:
+ writer.write(">")
+ else:
+ writer.write(">%s"%(newl))
+ for node in self.childNodes:
+ if node.nodeType == Node.TEXT_NODE:
+ writer.write(node.data)
+ else:
+ node.writexml(writer,indent+addindent,addindent,newl)
+ if self.lastChild.nodeType == Node.TEXT_NODE:
+ writer.write("</%s>%s" % (self.tagName,newl))
+ else:
+ writer.write("%s</%s>%s" % (indent,self.tagName,newl))
+ else:
+ writer.write("/>%s"%(newl))
+
+
+class PrettyDocument(Document):
+
+ """minidom document with 'pretty' XML output.
+ """
+
+ def createElement(self, tagName):
+ e = _Element(tagName)
+ e.ownerDocument = self
+ return e
+
+ def createElementNS(self, namespaceURI, qualifiedName):
+ prefix, localName = _nssplit(qualifiedName)
+ e = _Element(qualifiedName, namespaceURI, prefix)
+ e.ownerDocument = self
+ return e
+
+ def writexml(self, writer, indent="", addindent="", newl="",
+ encoding = None):
+ if encoding is None:
+ writer.write('<?xml version="1.0"?>\n')
+ else:
+ writer.write('<?xml version="1.0" encoding="%s"?>\n' % encoding)
+ for node in self.childNodes:
+ node.writexml(writer, indent, addindent, newl)
+
+
+class NodeAdapterBase(object):
+
+ """Node im- and exporter base.
+ """
+
+ implements(INodeExporter, INodeImporter)
+
+ def __init__(self, context):
+ self.context = context
+
+ def exportNode(self, doc):
+ """Export the object as a DOM node.
+ """
+ self._doc = doc
+ return self._getObjectNode('object')
+
+ def importNode(self, node, mode=PURGE):
+ """Import the object from the DOM node.
+ """
+
+ def _getObjectNode(self, name):
+ node = self._doc.createElement(name)
+ node.setAttribute('name', self.context.getId())
+ node.setAttribute('meta_type', self.context.meta_type)
+ i18n_domain = getattr(self.context, 'i18n_domain', None)
+ if i18n_domain:
+ node.setAttributeNS(I18NURI, 'i18n:domain', i18n_domain)
+ self._i18n_props = ('title', 'description')
+ return node
+
+ def _getNodeText(self, node):
+ text = ''
+ for child in node.childNodes:
+ if child.nodeName != '#text':
+ continue
+ text += child.nodeValue.lstrip()
+ return text
+
+ def _getNodeTextBoolean(self, node):
+ text = self._getNodeText(node)
+ return text.lower() in ('true', 'yes', '1')
+
+
+class ObjectManagerHelpers(object):
+
+ """ObjectManager im- and export helpers.
+ """
+
+ def _extractObjects(self):
+ fragment = self._doc.createDocumentFragment()
+ for obj in self.context.objectValues():
+ exporter = INodeExporter(obj, None)
+ if exporter is None:
+ continue
+ fragment.appendChild(exporter.exportNode(self._doc))
+ return fragment
+
+ def _purgeObjects(self):
+ for obj_id in self.context.objectIds():
+ self.context._delObject(obj_id)
+
+ def _initObjects(self, node, mode):
+ for child in node.childNodes:
+ if child.nodeName != 'object':
+ continue
+ if child.hasAttribute('deprecated'):
+ continue
+ parent = self.context
+
+ obj_id = str(child.getAttribute('name'))
+ if obj_id not in parent.objectIds():
+ meta_type = str(child.getAttribute('meta_type'))
+ for mt_info in Products.meta_types:
+ if mt_info['name'] == meta_type:
+ parent._setObject(obj_id, mt_info['instance'](obj_id))
+ break
+ else:
+ raise ValueError('unknown meta_type \'%s\'' % obj_id)
+
+ if child.hasAttribute('insert-before'):
+ insert_before = child.getAttribute('insert-before')
+ if insert_before == '*':
+ parent.moveObjectsToTop(obj_id)
+ else:
+ try:
+ position = parent.getObjectPosition(insert_before)
+ parent.moveObjectToPosition(obj_id, position)
+ except ValueError:
+ pass
+ elif child.hasAttribute('insert-after'):
+ insert_after = child.getAttribute('insert-after')
+ if insert_after == '*':
+ parent.moveObjectsToBottom(obj_id)
+ else:
+ try:
+ position = parent.getObjectPosition(insert_after)
+ parent.moveObjectToPosition(obj_id, position+1)
+ except ValueError:
+ pass
+
+ obj = getattr(self.context, obj_id)
+ INodeImporter(obj).importNode(child, mode)
+
+
+class PropertyManagerHelpers(object):
+
+ """PropertyManager im- and export helpers.
+ """
+
+ def _extractProperties(self):
+ fragment = self._doc.createDocumentFragment()
+
+ for prop_map in self.context._propertyMap():
+ if prop_map['id'] == 'i18n_domain':
+ continue
+ node = self._doc.createElement('property')
+
+ prop_id = prop_map['id']
+ node.setAttribute('name', prop_id)
+
+ prop = self.context.getProperty(prop_id)
+ if isinstance(prop, (tuple, list)):
+ for value in prop:
+ child = self._doc.createElement('element')
+ child.setAttribute('value', value)
+ node.appendChild(child)
+ else:
+ if not isinstance(prop, basestring):
+ prop = str(prop)
+ child = self._doc.createTextNode(prop)
+ node.appendChild(child)
+
+ if 'd' in prop_map.get('mode', 'wd') and not prop_id == 'title':
+ type = prop_map.get('type', 'string')
+ node.setAttribute('type', type)
+ select_variable = prop_map.get('select_variable', None)
+ if select_variable is not None:
+ node.setAttribute('select_variable', select_variable)
+
+ if hasattr(self, '_i18n_props') and prop_id in self._i18n_props:
+ node.setAttribute('i18n:translate', '')
+
+ fragment.appendChild(node)
+
+ return fragment
+
+ def _purgeProperties(self):
+ #XXX: not implemented
+ pass
+
+ def _initProperties(self, node, mode):
+ self.context.i18n_domain = node.getAttribute('i18n:domain')
+ for child in node.childNodes:
+ if child.nodeName != 'property':
+ continue
+ obj = self.context
+ prop_id = str(child.getAttribute('name'))
+ prop_map = obj.propdict().get(prop_id, None)
+
+ if prop_map is None:
+ if child.hasAttribute('type'):
+ val = child.getAttribute('select_variable')
+ obj._setProperty(prop_id, val, child.getAttribute('type'))
+ prop_map = obj.propdict().get(prop_id, None)
+ else:
+ raise ValueError('undefined property \'%s\'' % prop_id)
+
+ if not 'w' in prop_map.get('mode', 'wd'):
+ raise BadRequest('%s cannot be changed' % prop_id)
+
+ elements = []
+ for sub in child.childNodes:
+ if sub.nodeName == 'element':
+ elements.append(sub.getAttribute('value'))
+
+ if elements or prop_map.get('type') == 'multiple selection':
+ prop_value = tuple(elements) or ()
+ elif prop_map.get('type') == 'boolean':
+ prop_value = self._getNodeTextBoolean(child)
+ else:
+ # if we pass a *string* to _updateProperty, all other values
+ # are converted to the right type
+ prop_value = self._getNodeText(child)
+
+ obj._updateProperty(prop_id, prop_value)
More information about the CMF-checkins
mailing list