[Checkins] SVN: Sandbox/ulif/ZConfigParser/ZConfigParser/convert.py Better suited converter.

Uli Fouquet uli at gnufix.de
Tue Apr 7 04:59:00 EDT 2009


Log message for revision 98969:
  Better suited converter.

Changed:
  U   Sandbox/ulif/ZConfigParser/ZConfigParser/convert.py

-=-
Modified: Sandbox/ulif/ZConfigParser/ZConfigParser/convert.py
===================================================================
--- Sandbox/ulif/ZConfigParser/ZConfigParser/convert.py	2009-04-07 08:27:22 UTC (rev 98968)
+++ Sandbox/ulif/ZConfigParser/ZConfigParser/convert.py	2009-04-07 08:58:59 UTC (rev 98969)
@@ -1,20 +1,95 @@
 """Convert ZConfig configurations/files to ConfigParser style.
 """
-from ZConfigParser import schemaless
+import re
+import cStringIO as StringIO
+from ZConfigParser import schemaless, loadSchema
+from xml.dom.minidom import parse, parseString
 
-
 def convertFile(filepath):
-    config = schemaless.loadConfigFile(open(filepath, 'rb'))
-    return convertSection(config)
+    content = preprocess(open(filepath, 'rb').read())
+    tree = parseString(content)
+    defines, text = convertNode(tree.childNodes[0])
+    return postprocess(defines, text)
 
-def convertSection(section, prefix='zope'):
-    body = ''
-    if section.type:
-        prefix = '%s/%s' % (prefix, section.type)
-        body = '\n[%s]\n' % (prefix)
-    for key in list(section):
-        body += '%s = %s\n' % (key, section[key][0])
-    for section in section.sections:
-        body += '%s = %s/%s\n' % (section.type, prefix, section.type)
-        body += convertSection(section, prefix)
-    return body
+def preprocess(content):
+    # We need some encapsulating tag to get a complete tree.
+    content = '<zope>%s</zope>' % content
+    
+    # Replace 'invalid' tags like <server HTTP0> by valid tags, <server
+    # name='HTTP0'>. Otherwise the minidom parser will refuse our
+    # config.
+    content = re.sub('<([^ >]+) ([^>]+)>', '<\\1 name="\\2">', content)
+    return content
+
+def postprocess(defines, text):
+    if len(defines):
+        return '[DEFAULT]\n%s\n[zope]\n%s' % (defines, text)
+    return '[zope]\n%s' % (text)
+
+def convertNode(node, prefix='zope'):
+    body = ""
+    subsections = ""
+    defines = ""
+    references = []
+    for child in node.childNodes:
+        if child.nodeType == child.TEXT_NODE:
+            new_defines, text = handleTextNode(child)
+            body += text
+            defines += new_defines
+            continue
+        
+        # Get a unique subsection name if several with the same name
+        # occur in the same section.
+        num = 0
+        child_name = child.nodeName
+        while child_name in references:
+            num += 1
+            child_name = '%s.%s' % (child.nodeName, num)
+        references.append(child_name)
+        
+        child_prefix = '%s:%s' % (prefix, child_name)
+        body += '%s = %s\n' % (child_name, child_prefix)
+        subsections += "\n[%s]\n" % child_prefix
+        if child.hasAttributes() and 'name' in child.attributes.keys():
+            label = child.getAttribute('name').lower()
+            subsections += "config-section-label = %s\n" % label
+        new_defines, text = convertNode(child, prefix=child_prefix)
+        subsections +=  text
+        defines += new_defines
+    return defines, body + subsections
+
+def handleTextNode(node):
+    """Handle a text node.
+
+    Text nodes may consist of several lines. Handle each separately.
+    """
+    text = node.data.strip()
+    result = ""
+    defines = ""
+    if text == u'':
+        return '', ''
+    for line in text.split('\n'):
+        new_defines, text = handleTextLine(line)
+        defines += new_defines
+        result += text
+    return defines, result
+
+def handleTextLine(line):
+    """Handle a text line.
+
+    Replace defines, 
+    """
+    is_define = False
+    line = line.strip()
+    if line.startswith('%define'):
+        line = re.sub('%define\s+([^\s+].+)', '\\1', line)
+        is_define = True
+    if line.startswith('#'):
+        pass
+    elif ' ' in line:
+        line = re.sub('([^\s]+)\s+(.+)', '\\1 = \\2', line)
+    line = re.sub('\$([A-Za-z0-9_]+)', '%(\\1)s', line)
+    line += '\n'
+    if is_define:
+        return line, ''
+    return '', line



More information about the Checkins mailing list